Skip to content

Commit

Permalink
Fix an issue with a failed websocket handshake leaving connection han…
Browse files Browse the repository at this point in the history
  • Loading branch information
Gustavo J. A. M. Carneiro authored and asvetlov committed Aug 31, 2019
1 parent 010caab commit e7c9ef0
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGES/3380.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix failed websocket handshake leaving connection hanging.
3 changes: 3 additions & 0 deletions aiohttp/_http_parser.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,9 @@ cdef class HttpParser:
else:
return messages, False, b''

def set_upgraded(self, val):
self._upgraded = val


cdef class HttpRequestParser(HttpParser):

Expand Down
7 changes: 7 additions & 0 deletions aiohttp/http_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,13 @@ def parse_headers(

return (headers, raw_headers, close_conn, encoding, upgrade, chunked)

def set_upgraded(self, val: bool) -> None:
"""Set connection upgraded (to websocket) mode.
:param bool val: new state.
"""
self._upgraded = val


class HttpRequestParser(HttpParser):
"""Read request status line. Exception .http_exceptions.BadStatusLine
Expand Down
6 changes: 6 additions & 0 deletions aiohttp/web_protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,12 @@ async def finish_response(self,
can get exception information. Returns True if the client disconnects
prematurely.
"""
if self._request_parser is not None:
self._request_parser.set_upgraded(False)
self._upgrade = False
if self._message_tail:
self._request_parser.feed_data(self._message_tail)
self._message_tail = b''
try:
prepare_meth = resp.prepare
except AttributeError:
Expand Down
28 changes: 27 additions & 1 deletion tests/test_web_websocket_functional.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import pytest

import aiohttp
from aiohttp import web
from aiohttp import WSServerHandshakeError, web
from aiohttp.http import WSMsgType


Expand Down Expand Up @@ -827,3 +827,29 @@ async def handler(request):
ws = await client.ws_connect('/')
with pytest.raises(TypeError):
await ws.receive_bytes()


async def test_bug3380(loop, aiohttp_client) -> None:

async def handle_null(request):
return aiohttp.web.json_response({'err': None})

async def ws_handler(request):
return web.Response(status=401)

app = web.Application()
app.router.add_route('GET', '/ws', ws_handler)
app.router.add_route('GET', '/api/null', handle_null)

client = await aiohttp_client(app)

resp = await client.get('/api/null')
assert (await resp.json()) == {'err': None}
resp.close()

with pytest.raises(WSServerHandshakeError):
await client.ws_connect('/ws')

resp = await client.get('/api/null', timeout=1)
assert (await resp.json()) == {'err': None}
resp.close()

0 comments on commit e7c9ef0

Please sign in to comment.