Skip to content

Commit

Permalink
Merge pull request #725 from frsechet/websocket-fixes
Browse files Browse the repository at this point in the history
Add DELETE route to close a websocket connection
  • Loading branch information
dherault committed Jul 2, 2019
2 parents 1ba79f2 + e70db4b commit 28266f2
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 0 deletions.
24 changes: 24 additions & 0 deletions manual_test_websocket/main/test/e2e/ws.e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -370,5 +370,29 @@ describe('serverless', () => {

expect(res).to.have.status(410);
}).timeout(timeout);

it('should be able to close connections via REST API', async () => {
await createClient();
const c2 = await createClient();
const url = new URL(endpoint);
const signature = { service: 'execute-api', host: url.host, path: `${url.pathname}/@connections/${c2.id}`, method: 'DELETE', body: 'Hello World!', headers: { 'Content-Type': 'text/plain'/* 'application/text' */ } };
aws4.sign(signature, { accessKeyId: cred.accessKeyId, secretAccessKey: cred.secretAccessKey });
const res = await req.del(signature.path.replace(url.pathname, '')).set('X-Amz-Date', signature.headers['X-Amz-Date']).set('Authorization', signature.headers.Authorization).set('Content-Type', signature.headers['Content-Type']);

expect(res).to.have.status(200);
}).timeout(timeout);

it('should receive error code when deleting a previously closed client via REST API', async () => {
const c = await createClient();
const cId = c.id;
c.ws.close();
const url = new URL(endpoint);
const signature = { service: 'execute-api', host: url.host, path: `${url.pathname}/@connections/${cId}`, method: 'DELETE', body: 'Hello World!', headers: { 'Content-Type': 'text/plain'/* 'application/text' */ } };
aws4.sign(signature, { accessKeyId: cred.accessKeyId, secretAccessKey: cred.secretAccessKey });
const res = await req.del(signature.path.replace(url.pathname, '')).set('X-Amz-Date', signature.headers['X-Amz-Date']).set('Authorization', signature.headers.Authorization).set('Content-Type', signature.headers['Content-Type']);

expect(res).to.have.status(410);
}).timeout(timeout);

});
});
31 changes: 31 additions & 0 deletions src/ApiGatewayWebSocket.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ module.exports = class ApiGatewayWebSocket {
this.websocketsApiRouteSelectionExpression = serverless.service.provider.websocketsApiRouteSelectionExpression || '$request.body.action';
}

printBlankLine() {
console.log();
}

_createWebSocket() {
// start COPY PASTE FROM HTTP SERVER CODE
const serverOptions = {
Expand Down Expand Up @@ -248,6 +252,33 @@ module.exports = class ApiGatewayWebSocket {
return '';
},
});

this.wsServer.route({
method: 'DELETE',
path: '/@connections/{connectionId}',
config: { payload: { parse: false } },
handler: (request, h) => {
debugLog(`got DELETE to ${request.url}`);

const getByConnectionId = (map, searchValue) => {
for (const [key, connection] of map.entries()) {
if (connection.connectionId === searchValue) return key;
}

return undefined;
};

const ws = getByConnectionId(this.clients, request.params.connectionId);

if (!ws) return h.response().code(410);

ws.close();

debugLog(`closed connection:${request.params.connectionId}`);

return '';
},
});
}

_createWsAction(fun, funName, servicePath, funOptions, event) {
Expand Down

0 comments on commit 28266f2

Please sign in to comment.