An HTTP/1.x server.
| 768 | |
| 769 | |
| 770 | class HTTP1ServerConnection(object): |
| 771 | """An HTTP/1.x server.""" |
| 772 | |
| 773 | def __init__( |
| 774 | self, |
| 775 | stream: iostream.IOStream, |
| 776 | params: Optional[HTTP1ConnectionParameters] = None, |
| 777 | context: Optional[object] = None, |
| 778 | ) -> None: |
| 779 | """ |
| 780 | :arg stream: an `.IOStream` |
| 781 | :arg params: a `.HTTP1ConnectionParameters` or None |
| 782 | :arg context: an opaque application-defined object that is accessible |
| 783 | as ``connection.context`` |
| 784 | """ |
| 785 | self.stream = stream |
| 786 | if params is None: |
| 787 | params = HTTP1ConnectionParameters() |
| 788 | self.params = params |
| 789 | self.context = context |
| 790 | self._serving_future = None # type: Optional[Future[None]] |
| 791 | |
| 792 | async def close(self) -> None: |
| 793 | """Closes the connection. |
| 794 | |
| 795 | Returns a `.Future` that resolves after the serving loop has exited. |
| 796 | """ |
| 797 | self.stream.close() |
| 798 | # Block until the serving loop is done, but ignore any exceptions |
| 799 | # (start_serving is already responsible for logging them). |
| 800 | assert self._serving_future is not None |
| 801 | try: |
| 802 | await self._serving_future |
| 803 | except Exception: |
| 804 | pass |
| 805 | |
| 806 | def start_serving(self, delegate: httputil.HTTPServerConnectionDelegate) -> None: |
| 807 | """Starts serving requests on this connection. |
| 808 | |
| 809 | :arg delegate: a `.HTTPServerConnectionDelegate` |
| 810 | """ |
| 811 | assert isinstance(delegate, httputil.HTTPServerConnectionDelegate) |
| 812 | fut = gen.convert_yielded(self._server_request_loop(delegate)) |
| 813 | self._serving_future = fut |
| 814 | # Register the future on the IOLoop so its errors get logged. |
| 815 | self.stream.io_loop.add_future(fut, lambda f: f.result()) |
| 816 | |
| 817 | async def _server_request_loop( |
| 818 | self, delegate: httputil.HTTPServerConnectionDelegate |
| 819 | ) -> None: |
| 820 | try: |
| 821 | while True: |
| 822 | conn = HTTP1Connection(self.stream, False, self.params, self.context) |
| 823 | request_delegate = delegate.start_request(self, conn) |
| 824 | try: |
| 825 | ret = await conn.read_response(request_delegate) |
| 826 | except ( |
| 827 | iostream.StreamClosedError, |