summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMax Romanov <max.romanov@nginx.com>2021-01-28 17:13:52 +0300
committerMax Romanov <max.romanov@nginx.com>2021-01-28 17:13:52 +0300
commite4e444b82701de0c984a72eb9c2657f72d7171ae (patch)
tree764370b602b981e3c50af3b1b786321e54c64ac0
parent3855f1c032cb52f4e8f370f639d259b7cc313939 (diff)
downloadunit-e4e444b82701de0c984a72eb9c2657f72d7171ae.tar.gz
unit-e4e444b82701de0c984a72eb9c2657f72d7171ae.tar.bz2
Router: fixing crash after WebSocket processing.
After WebSocket processing, the application port was released with incorrect reason ("got request"), unnecessarily decrementing the active request counter. The assertion was triggered only on application removal; a test was added for this case.
-rw-r--r--docs/changes.xml7
-rw-r--r--src/nxt_router.c5
-rw-r--r--test/test_asgi_websockets.py24
3 files changed, 35 insertions, 1 deletions
diff --git a/docs/changes.xml b/docs/changes.xml
index b97cc823..64adbb46 100644
--- a/docs/changes.xml
+++ b/docs/changes.xml
@@ -97,6 +97,13 @@ a memory leak occurring in the router process when serving a file larger than
</para>
</change>
+<change type="bugfix">
+<para>
+the router process could crash while removing or reconfiguring an application
+that uses WebSocket.
+</para>
+</change>
+
</changes>
diff --git a/src/nxt_router.c b/src/nxt_router.c
index d9c722dd..03fe2a6c 100644
--- a/src/nxt_router.c
+++ b/src/nxt_router.c
@@ -3796,7 +3796,10 @@ nxt_router_response_ready_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg,
nxt_buf_chain_add(&b, nxt_http_buf_last(r));
req_rpc_data->rpc_cancel = 0;
- req_rpc_data->apr_action = NXT_APR_GOT_RESPONSE;
+
+ if (req_rpc_data->apr_action == NXT_APR_REQUEST_FAILED) {
+ req_rpc_data->apr_action = NXT_APR_GOT_RESPONSE;
+ }
nxt_request_rpc_data_unlink(task, req_rpc_data);
diff --git a/test/test_asgi_websockets.py b/test/test_asgi_websockets.py
index 7c9ec555..6121fcc5 100644
--- a/test/test_asgi_websockets.py
+++ b/test/test_asgi_websockets.py
@@ -63,6 +63,9 @@ class TestASGIWebsockets(TestApplicationPython):
key
), 'key'
+ # remove "mirror" application
+ self.load('websockets/subprotocol')
+
def test_asgi_websockets_subprotocol(self):
self.load('websockets/subprotocol')
@@ -92,6 +95,27 @@ class TestASGIWebsockets(TestApplicationPython):
sock.close()
+ def test_asgi_websockets_mirror_app_change(self):
+ self.load('websockets/mirror')
+
+ message = 'blah'
+
+ _, sock, _ = self.ws.upgrade()
+
+ self.ws.frame_write(sock, self.ws.OP_TEXT, message)
+ frame = self.ws.frame_read(sock)
+
+ assert message == frame['data'].decode('utf-8'), 'mirror'
+
+ self.load('websockets/subprotocol')
+
+ self.ws.frame_write(sock, self.ws.OP_TEXT, message)
+ frame = self.ws.frame_read(sock)
+
+ assert message == frame['data'].decode('utf-8'), 'mirror 2'
+
+ sock.close()
+
def test_asgi_websockets_no_mask(self):
self.load('websockets/mirror')