diff --git a/gunicorn/asgi/message.py b/gunicorn/asgi/message.py index b73e1b0b..76569579 100644 --- a/gunicorn/asgi/message.py +++ b/gunicorn/asgi/message.py @@ -83,6 +83,7 @@ class AsyncRequest: self.trailers = [] self.scheme = "https" if cfg.is_ssl else "http" self.must_close = False + self._expected_100_continue = False self.proxy_protocol_info = None @@ -474,6 +475,21 @@ class AsyncRequest: if header_length > self.limit_request_field_size > 0: raise LimitRequestHeaders("limit request headers fields size") + if not from_trailer and name == "EXPECT": + # https://datatracker.ietf.org/doc/html/rfc9110#section-10.1.1 + # "The Expect field value is case-insensitive." + if value.lower() == "100-continue": + if self.version < (1, 1): + # https://datatracker.ietf.org/doc/html/rfc9110#section-10.1.1-12 + # "A server that receives a 100-continue expectation + # in an HTTP/1.0 request MUST ignore that expectation." + pass + else: + self._expected_100_continue = True + # N.B. understood but ignored expect header does not return 417 + else: + raise ExpectationFailed(value) + if name in secure_scheme_headers: secure = value == secure_scheme_headers[name] scheme = "https" if secure else "http"