Handle an HTTP/2 connection. Runs in a worker thread. HTTP/2 connections are persistent and multiplex multiple streams. We handle all streams until the connection is closed. Returns: False (HTTP/2 connections don't use keepalive polling)
(self, conn)
| 514 | return False |
| 515 | |
| 516 | def handle_http2(self, conn): |
| 517 | """Handle an HTTP/2 connection. Runs in a worker thread. |
| 518 | |
| 519 | HTTP/2 connections are persistent and multiplex multiple streams. |
| 520 | We handle all streams until the connection is closed. |
| 521 | |
| 522 | Returns: |
| 523 | False (HTTP/2 connections don't use keepalive polling) |
| 524 | """ |
| 525 | h2_conn = conn.parser # HTTP2ServerConnection |
| 526 | |
| 527 | try: |
| 528 | while not h2_conn.is_closed and self.alive: |
| 529 | # Receive data and get completed requests |
| 530 | requests = h2_conn.receive_data() |
| 531 | |
| 532 | for req in requests: |
| 533 | try: |
| 534 | self.handle_http2_request(req, conn, h2_conn) |
| 535 | except Exception as e: |
| 536 | self.log.exception("Error handling HTTP/2 request") |
| 537 | try: |
| 538 | h2_conn.send_error(req.stream.stream_id, 500, str(e)) |
| 539 | except Exception: |
| 540 | pass |
| 541 | finally: |
| 542 | # Cleanup stream after processing |
| 543 | h2_conn.cleanup_stream(req.stream.stream_id) |
| 544 | |
| 545 | # Check if we need to close |
| 546 | if not self.alive: |
| 547 | h2_conn.close() |
| 548 | break |
| 549 | |
| 550 | except http.errors.NoMoreData: |
| 551 | self.log.debug("HTTP/2 connection closed by client") |
| 552 | except ssl.SSLError as e: |
| 553 | if e.args[0] == ssl.SSL_ERROR_EOF: |
| 554 | self.log.debug("HTTP/2 SSL connection closed") |
| 555 | else: |
| 556 | self.log.debug("HTTP/2 SSL error: %s", e) |
| 557 | except OSError as e: |
| 558 | if e.errno not in (errno.EPIPE, errno.ECONNRESET, errno.ENOTCONN): |
| 559 | self.log.exception("HTTP/2 socket error") |
| 560 | except Exception: |
| 561 | self.log.exception("HTTP/2 connection error") |
| 562 | |
| 563 | return False |
| 564 | |
| 565 | def handle_http2_request(self, req, conn, h2_conn): |
| 566 | """Handle a single HTTP/2 request/stream.""" |
no test coverage detected