Comparing version 0.8.1 to 0.8.2
@@ -8,2 +8,8 @@ # Nodecaf Changelog | ||
## [v0.8.2] - 2020-02-18 | ||
### Added | ||
- WebSocket routes functionality allowing to define ws handlers in given url paths | ||
- missing response log entries when route is not found or an api wasn't defined | ||
## [v0.8.1] - 2020-02-13 | ||
@@ -290,1 +296,2 @@ | ||
[v0.8.1]: https://gitlab.com/GCSBOSS/nodecaf/-/tags/v0.8.1 | ||
[v0.8.2]: https://gitlab.com/GCSBOSS/nodecaf/-/tags/v0.8.2 |
@@ -17,2 +17,3 @@ const | ||
const Logger = require('./logger'); | ||
const WebSocket = require('./ws'); | ||
const HTTP_VERBS = ['get', 'post', 'patch', 'put', 'head']; | ||
@@ -24,2 +25,5 @@ | ||
this.log.req(req); | ||
// Setup server response log | ||
res.on('finish', () => this.log.res(res, req)); | ||
next(); | ||
@@ -36,2 +40,3 @@ } | ||
res.end(); | ||
this.log.res(res, req); | ||
} | ||
@@ -49,3 +54,4 @@ | ||
if(typeof this.buildAPI == 'function') | ||
this.buildAPI({ ...this.routerFuncs, info: noop, conf: this.settings }); | ||
this.buildAPI({ ...this.routerFuncs, info: noop, conf: this.settings, | ||
ws: WebSocket.set.bind(null, this) }); | ||
this.express.use(routeNotFoundHandler); | ||
@@ -64,3 +70,3 @@ this.express.use(defaultErrorHandler.bind(this)); | ||
this.exposed = {}; | ||
this.express = noAPI; | ||
this.express = noAPI.bind(this); | ||
this.name = 'Untitled'; | ||
@@ -157,2 +163,5 @@ this.running = false; | ||
if(this.wsRoutes) | ||
this.wss = WebSocket.start(this); | ||
// Start listening on defined port. | ||
@@ -169,2 +178,5 @@ await new Promise( done => this.server.listen(this.port, done) ); | ||
async stop(){ | ||
if(this.wss) | ||
WebSocket.close(this.wss); | ||
await new Promise(done => this.server.close(done) ); | ||
@@ -171,0 +183,0 @@ this.running = false; |
@@ -76,2 +76,10 @@ const util = require('util'); | ||
ws(client, req, level, message){ | ||
let addr = req.connection.remoteAddress; | ||
return this[level]({ | ||
class: 'websocket', | ||
client: addr | ||
}, message, addr) | ||
} | ||
}; |
@@ -87,5 +87,2 @@ const assert = require('assert'); | ||
// Setup server response log | ||
res.on('finish', () => app.log.res(res, req)); | ||
// Actually run the user handler. | ||
@@ -92,0 +89,0 @@ handler(next, input); |
{ | ||
"name": "nodecaf", | ||
"version": "0.8.1", | ||
"version": "0.8.2", | ||
"description": "Nodecaf is an Express framework for developing REST APIs in a quick and convenient manner.", | ||
@@ -43,3 +43,4 @@ "main": "lib/main.js", | ||
"http-errors": "^1.7.3", | ||
"mime": "^2.4.4" | ||
"mime": "^2.4.4", | ||
"ws": "^7.2.1" | ||
}, | ||
@@ -46,0 +47,0 @@ "devDependencies": { |
@@ -19,2 +19,3 @@ # [Nodecaf](https://gitlab.com/GCSBOSS/nodecaf) | ||
- [HTTPS capability](#https). | ||
- Functions to define [Websocket Routes](#websocket-routes). | ||
- Functions to [describe your API](#api-description) making your code the main | ||
@@ -83,8 +84,8 @@ source of truth. | ||
## Reporting Bugs | ||
If you have found any problems with this module, please: | ||
## Reporting Bugs **or Vulnerabilities** | ||
If you have found any problems with Nodecaf, please: | ||
1. [Open an issue](https://gitlab.com/GCSBOSS/nodecaf/issues/new). | ||
2. Describe what happened and how. | ||
3. Also in the issue text, reference the label `~bug`. | ||
3. Also in the issue text, reference the label `~bug` or `~security`. | ||
@@ -105,2 +106,7 @@ We will make sure to take a look when time allows us. | ||
- For coding style, we provide an [ESLint](https://eslint.org/) configuration | ||
file in the root of the repository. | ||
- All commits are submit to SAST and Dependency Scanning as well as Code Quality | ||
analisys, so expect to be boarded on your MRs. | ||
## Manual | ||
@@ -237,2 +243,5 @@ On top of all the cool features Express offers, check out how to use all | ||
| server | info | The server configuration has been reloaded | | ||
| websocket | info | A new websocket connection happened | | ||
| websocket | debug | A message was received | | ||
| websocket | info | A websocket connection was closed | | ||
@@ -413,2 +422,35 @@ ### Async Handlers | ||
## WebSocket Routes | ||
With nodecaf you can define paths to be accessible as WebSocket endpoints. | ||
In your api file use the `ws(path, events)` method with the folling arguments: | ||
1. `path`: where the websocket will be accessible | ||
2. `events`: object containing any of the following handlers: `connect`, `message`, `close`. | ||
```js | ||
module.exports = function({ post, get, del, head, patch, put, ws }){ | ||
// Regular api routes... | ||
// Websocket routes | ||
ws('/my-path-1', { | ||
connect: (client, req) => console.log('NEW CLIENT'), | ||
message: (message, client, req) => console.log('NEW MESSAGE'), | ||
close: (client, req) => console.log('BYE CLIENT') | ||
}); | ||
ws('/my-path-2', { | ||
connect: (client, req) => console.log('NEW CLIENT 2'), | ||
message: (message, client, req) => console.log('NEW MESSAGE 2'), | ||
close: (client, req) => console.log('BYE CLIENT 2') | ||
}); | ||
}; | ||
``` | ||
All handlers are optional for each websocket endpoint. | ||
### Filter Requests by Mime-type | ||
@@ -415,0 +457,0 @@ |
@@ -896,1 +896,48 @@ const assert = require('assert'); | ||
}); | ||
describe('WebSocket', function(){ | ||
const AppServer = require('../lib/app-server'); | ||
const WebSocket = require('ws'); | ||
it('Should accept websocket connections and messages', function(done){ | ||
let count = 0; | ||
let app = new AppServer(); | ||
app.api(({ ws }) => { | ||
ws('/foo', { | ||
connect: () => count++, | ||
async message(message){ | ||
assert.strictEqual('foobar', message); | ||
await app.stop(); | ||
count++; | ||
}, | ||
close(){ | ||
assert.strictEqual(count, 2); | ||
done(); | ||
} | ||
}); | ||
}); | ||
(async function(){ | ||
await app.start(); | ||
const ws = new WebSocket('ws://localhost/foo'); | ||
ws.on('open', () => { | ||
ws.pong(); | ||
ws.send('foobar'); | ||
}); | ||
})(); | ||
}); | ||
it('Should reject connection to path that is not setup', function(done){ | ||
let app = new AppServer(); | ||
app.api(({ ws }) => ws('/foo', {})); | ||
(async function(){ | ||
await app.start(); | ||
const ws = new WebSocket('ws://localhost/foobar'); | ||
ws.on('error', async () => { | ||
await app.stop(); | ||
done() | ||
}); | ||
})(); | ||
}); | ||
}); |
85407
25
1332
543
9