self._finish_future = None
def start_serving(self, delegate):
- assert isinstance(delegate, httputil.HTTPConnectionDelegate)
+ assert isinstance(delegate, httputil.HTTPServerConnectionDelegate)
# Register the future on the IOLoop so its errors get logged.
- self.stream.io_loop.add_future(self._process_requests(delegate),
+ self.stream.io_loop.add_future(self._server_request_loop(delegate),
lambda f: f.result())
@gen.coroutine
- def _process_requests(self, delegate):
+ def _server_request_loop(self, delegate):
while True:
request_delegate = delegate.start_request(self)
try:
- ret = yield self._process_message(request_delegate, False)
+ ret = yield self._read_message(request_delegate, False)
except iostream.StreamClosedError:
self.close()
return
if not ret:
return
- def process_response(self, delegate, method):
- return self._process_message(delegate, True, method=method)
+ def read_response(self, delegate, method):
+ return self._read_message(delegate, True, method=method)
@gen.coroutine
- def _process_message(self, delegate, is_client, method=None):
- assert isinstance(delegate, httputil.HTTPStreamDelegate)
+ def _read_message(self, delegate, is_client, method=None):
+ assert isinstance(delegate, httputil.HTTPMessageDelegate)
try:
header_data = yield self.stream.read_until_regex(b"\r?\n\r?\n")
self._finish_future = Future()
if code == 304:
skip_body = True
if code >= 100 and code < 200:
- yield self._process_message(delegate, is_client, method=method)
+ yield self._read_message(delegate, is_client, method=method)
else:
if headers.get("Expect") == "100-continue":
self.stream.write(b"HTTP/1.1 100 (Continue)\r\n\r\n")
yield body_future
delegate.finish()
yield self._finish_future
- except httputil.BadRequestException as e:
- gen_log.info("Malformed HTTP request from %r: %s",
+ except httputil.HTTPMessageException as e:
+ gen_log.info("Malformed HTTP message from %r: %s",
self.address, e)
self.close()
raise gen.Return(False)
headers = httputil.HTTPHeaders.parse(data[eol:])
except ValueError:
# probably form split() if there was no ':' in the line
- raise httputil.BadRequestException("Malformed HTTP headers")
+ raise httputil.HTTPMessageException("Malformed HTTP headers")
return start_line, headers
def _read_body(self, is_client, headers, delegate):
if content_length:
content_length = int(content_length)
if content_length > self.stream.max_buffer_size:
- raise httputil.BadRequestException("Content-Length too long")
+ raise httputil.HTTPMessageException("Content-Length too long")
return self._read_fixed_body(content_length, delegate)
if headers.get("Transfer-Encoding") == "chunked":
return self._read_chunked_body(delegate)
import socket
-from tornado import http1connection, httputil
+from tornado.http1connection import HTTP1Connection
+from tornado import httputil
from tornado import netutil
from tornado.tcpserver import TCPServer
-class HTTPServer(TCPServer, httputil.HTTPConnectionDelegate):
+class HTTPServer(TCPServer, httputil.HTTPServerConnectionDelegate):
r"""A non-blocking, single-threaded HTTP server.
A server is defined by a request callback that takes an HTTPRequest
**kwargs)
def handle_stream(self, stream, address):
- conn = HTTPConnection(stream, address, self.no_keep_alive,
- self.protocol)
+ conn = HTTP1Connection(stream, address=address,
+ no_keep_alive=self.no_keep_alive,
+ protocol=self.protocol)
conn.start_serving(self)
def start_request(self, connection):
- return _ServerRequestProcessor(self, connection)
+ return _ServerRequestAdapter(self, connection)
-class _ServerRequestProcessor(httputil.HTTPStreamDelegate):
+class _ServerRequestAdapter(httputil.HTTPMessageDelegate):
+ """Adapts the `HTTPMessageDelegate` interface to the `HTTPServerRequest`
+ interface expected by our clients.
+ """
def __init__(self, server, connection):
self.server = server
self.connection = connection
def headers_received(self, start_line, headers):
- pass
try:
method, uri, version = start_line.split(" ")
except ValueError:
- raise httputil.BadRequestException("Malformed HTTP request line")
+ raise httputil.HTTPMessageException("Malformed HTTP request line")
if not version.startswith("HTTP/"):
- raise httputil.BadRequestException("Malformed HTTP version in HTTP Request-Line")
+ raise httputil.HTTPMessageException(
+ "Malformed HTTP version in HTTP Request-Line")
# HTTPRequest wants an IP, not a full socket address
if self.connection.address_family in (socket.AF_INET, socket.AF_INET6):
remote_ip = self.connection.address[0]
self.server.request_callback(self.request)
-
HTTPRequest = httputil.HTTPServerRequest
-HTTPConnection = http1connection.HTTP1Connection
self.__class__.__name__, args, dict(self.headers))
-class BadRequestException(Exception):
- """Exception class for malformed HTTP requests."""
+class HTTPMessageException(Exception):
+ """Exception class for malformed HTTP requests or responses."""
pass
-class HTTPConnectionDelegate(object):
+class HTTPServerConnectionDelegate(object):
def start_request(self, connection):
raise NotImplementedError()
-class HTTPStreamDelegate(object):
+class HTTPMessageDelegate(object):
def headers_received(self, start_line, headers):
pass
del self.waiting[key]
-class _HTTPConnection(httputil.HTTPStreamDelegate):
+class _HTTPConnection(httputil.HTTPMessageDelegate):
_SUPPORTED_METHODS = set(["GET", "HEAD", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"])
def __init__(self, io_loop, client, request, release_callback,
self.connection = HTTP1Connection(
self.stream, self._sockaddr,
no_keep_alive=True, protocol=self.parsed.scheme)
- # Ensure that any exception raised in process_response ends up in our
+ # Ensure that any exception raised in read_response ends up in our
# stack context.
self.io_loop.add_future(
- self.connection.process_response(self, method=self.request.method),
+ self.connection.read_response(self, method=self.request.method),
lambda f: f.result())
def _release(self):
from __future__ import absolute_import, division, print_function, with_statement
-from tornado import httpclient, simple_httpclient, netutil
+from tornado import netutil
from tornado.escape import json_decode, utf8, _unicode, recursive_unicode, native_str
from tornado.http1connection import HTTP1Connection
from tornado.httpserver import HTTPServer
-from tornado.httputil import HTTPHeaders, HTTPStreamDelegate
+from tornado.httputil import HTTPHeaders, HTTPMessageDelegate
from tornado.iostream import IOStream
from tornado.log import gen_log
-from tornado.netutil import ssl_options_to_context, Resolver
-from tornado.simple_httpclient import SimpleAsyncHTTPClient
+from tornado.netutil import ssl_options_to_context
from tornado.testing import AsyncHTTPTestCase, AsyncHTTPSTestCase, AsyncTestCase, ExpectLog
from tornado.test.util import unittest
from tornado.util import u, bytes_type
b"\r\n" + body)
chunks = []
test = self
- class Delegate(HTTPStreamDelegate):
+ class Delegate(HTTPMessageDelegate):
def data_received(self, chunk):
chunks.append(chunk)
def finish(self):
test.stop()
conn = HTTP1Connection(stream, None)
- conn.process_response(Delegate(), method='GET')
+ conn.read_response(Delegate(), method='GET')
self.wait()
return b''.join(chunks)
def test_unix_socket_bad_request(self):
# Unix sockets don't have remote addresses so they just return an
# empty string.
- with ExpectLog(gen_log, "Malformed HTTP request from"):
+ with ExpectLog(gen_log, "Malformed HTTP message from"):
self.stream.write(b"garbage\r\n\r\n")
self.stream.read_until_close(self.stop)
response = self.wait()