@@ -47,6 +47,7 @@ include "_headers.pxi"
4747
4848from aiohttp cimport _find_header
4949
50+ ALLOWED_UPGRADES = frozenset ({" websocket" })
5051DEF DEFAULT_FREELIST_SIZE = 250
5152
5253cdef extern from " Python.h" :
@@ -417,16 +418,20 @@ cdef class HttpParser:
417418 cdef _on_headers_complete(self ):
418419 self ._process_header()
419420
420- method = http_method_str(self ._cparser.method)
421421 should_close = not cparser.llhttp_should_keep_alive(self ._cparser)
422422 upgrade = self ._cparser.upgrade
423423 chunked = self ._cparser.flags & cparser.F_CHUNKED
424424
425425 raw_headers = tuple (self ._raw_headers)
426426 headers = CIMultiDictProxy(self ._headers)
427427
428- if upgrade or self ._cparser.method == cparser.HTTP_CONNECT:
429- self ._upgraded = True
428+ if self ._cparser.type == cparser.HTTP_REQUEST:
429+ allowed = upgrade and headers.get(" upgrade" , " " ).lower() in ALLOWED_UPGRADES
430+ if allowed or self ._cparser.method == cparser.HTTP_CONNECT:
431+ self ._upgraded = True
432+ else :
433+ if upgrade and self ._cparser.status_code == 101 :
434+ self ._upgraded = True
430435
431436 # do not support old websocket spec
432437 if SEC_WEBSOCKET_KEY1 in headers:
@@ -441,6 +446,7 @@ cdef class HttpParser:
441446 encoding = enc
442447
443448 if self ._cparser.type == cparser.HTTP_REQUEST:
449+ method = http_method_str(self ._cparser.method)
444450 msg = _new_request_message(
445451 method, self ._path,
446452 self .http_version(), headers, raw_headers,
@@ -565,7 +571,7 @@ cdef class HttpParser:
565571 if self ._upgraded:
566572 return messages, True , data[nb:]
567573 else :
568- return messages, False , b' '
574+ return messages, False , b" "
569575
570576 def set_upgraded (self , val ):
571577 self ._upgraded = val
@@ -748,10 +754,7 @@ cdef int cb_on_headers_complete(cparser.llhttp_t* parser) except -1:
748754 pyparser._last_error = exc
749755 return - 1
750756 else :
751- if (
752- pyparser._cparser.upgrade or
753- pyparser._cparser.method == cparser.HTTP_CONNECT
754- ):
757+ if pyparser._upgraded or pyparser._cparser.method == cparser.HTTP_CONNECT:
755758 return 2
756759 else :
757760 return 0
0 commit comments