Merge branch 'master' into asgi-refactor-attempt

This commit is contained in:
Adam Hopkins
2019-06-11 11:11:32 +03:00
committed by GitHub
12 changed files with 167 additions and 86 deletions

View File

@@ -37,7 +37,7 @@ class Blueprint:
url_prefix=None,
host=None,
version=None,
strict_slashes=False,
strict_slashes=None,
):
"""
In *Sanic* terminology, a **Blueprint** is a logical collection of

View File

@@ -218,6 +218,11 @@ class ContentRangeError(SanicException):
}
@add_status_code(417)
class HeaderExpectationFailed(SanicException):
pass
@add_status_code(403)
class Forbidden(SanicException):
pass

View File

@@ -29,7 +29,7 @@ except ImportError:
DEFAULT_HTTP_CONTENT_TYPE = "application/octet-stream"
EXPECT_HEADER = "EXPECT"
# HTTP/1.1: https://www.w3.org/Protocols/rfc2616/rfc2616-sec7.html#sec7.2.1
# > If the media type remains unknown, the recipient SHOULD treat it

View File

@@ -15,6 +15,7 @@ from httptools.parser.errors import HttpParserError
from multidict import CIMultiDict
from sanic.exceptions import (
HeaderExpectationFailed,
InvalidUsage,
PayloadTooLarge,
RequestTimeout,
@@ -22,7 +23,7 @@ from sanic.exceptions import (
ServiceUnavailable,
)
from sanic.log import access_logger, logger
from sanic.request import Request, StreamBuffer
from sanic.request import EXPECT_HEADER, Request, StreamBuffer
from sanic.response import HTTPResponse
@@ -314,6 +315,10 @@ class HttpProtocol(asyncio.Protocol):
if self._keep_alive_timeout_handler:
self._keep_alive_timeout_handler.cancel()
self._keep_alive_timeout_handler = None
if self.request.headers.get(EXPECT_HEADER):
self.expect_handler()
if self.is_request_stream:
self._is_stream_handler = self.router.is_stream_handler(
self.request
@@ -324,6 +329,21 @@ class HttpProtocol(asyncio.Protocol):
)
self.execute_request_handler()
def expect_handler(self):
"""
Handler for Expect Header.
"""
expect = self.request.headers.get(EXPECT_HEADER)
if self.request.version == "1.1":
if expect.lower() == "100-continue":
self.transport.write(b"HTTP/1.1 100 Continue\r\n\r\n")
else:
self.write_error(
HeaderExpectationFailed(
"Unknown Expect: {expect}".format(expect=expect)
)
)
def on_body(self, body):
if self.is_request_stream and self._is_stream_handler:
self._request_stream_task = self.loop.create_task(