Skip to content

Commit

Permalink
Fix req/res forceful teardown (#19)
Browse files Browse the repository at this point in the history
Co-authored-by: Yasser Nascimento <[email protected]>
Co-authored-by: Kasper Isager Dalsgarð <[email protected]>
  • Loading branch information
3 people authored Sep 11, 2024
1 parent c90579d commit bb1dad8
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 6 deletions.
18 changes: 13 additions & 5 deletions lib/server-connection.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const tcp = require('bare-tcp')
const { isEnded, isFinished, getStreamError } = require('bare-stream')
const HTTPIncomingMessage = require('./incoming-message')
const HTTPServerResponse = require('./server-response')
const constants = require('./constants')
Expand Down Expand Up @@ -33,13 +34,14 @@ module.exports = class HTTPServerConnection {
this._buffer = null
this._idle = true

this._onerror = this._onerror.bind(this)
this._onclose = this._onclose.bind(this)
this._ondata = this._ondata.bind(this)
this._ondrain = this._ondrain.bind(this)
this._ontimeout = this._ontimeout.bind(this)

socket
.on('error', this._onerror)
.on('error', noop)
.on('close', this._onclose)
.on('data', this._ondata)
.on('drain', this._ondrain)
.on('timeout', this._ontimeout)
Expand All @@ -53,8 +55,11 @@ module.exports = class HTTPServerConnection {
return this._idle
}

_onerror (err) {
this.socket.destroy(err)
_onclose () {
if (this.req && !isEnded(this.req)) this.req.destroy()
if (this.res && !isFinished(this.res)) this.res.destroy()
const err = getStreamError(this.socket)
if (err) this.socket.destroy(err)
}

_ondata (data) {
Expand Down Expand Up @@ -232,11 +237,14 @@ module.exports = class HTTPServerConnection {

_ondetach () {
this.socket
.off('error', this._onerror)
.off('error', noop)
.off('close', this._onclose)
.off('data', this._ondata)
.off('drain', this._ondrain)
.off('timeout', this._ontimeout)

HTTPServerConnection._connections.delete(this.socket)
}
}

function noop () {}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"homepage": "https://github.com/holepunchto/bare-http1#readme",
"dependencies": {
"bare-events": "^2.0.0",
"bare-stream": "^2.0.0",
"bare-stream": "^2.3.0",
"bare-tcp": "^1.8.0"
},
"devDependencies": {
Expand Down
43 changes: 43 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const test = require('brittle')
const tcp = require('bare-tcp')
const http = require('.')

test('basic', async function (t) {
Expand Down Expand Up @@ -325,6 +326,48 @@ test('destroy socket', async function (t) {
server.close()
})

test('close server request/response at premature GET request closure', async function (t) {
const sub = t.test('')
sub.plan(2)

const server = http.createServer((req, res) => {
req.on('close', () => sub.pass('request closed'))
res.on('close', () => sub.pass('response closed'))
}).listen(0)

await waitForServer(server)

const client = tcp.createConnection(server.address().port)
client.write('GET / HTTP/1.1\r\n\r\n')

setTimeout(() => client.destroy(), 300)

await sub

server.close()
})

test('close server request/response at premature POST request closure', async function (t) {
const sub = t.test('')
sub.plan(2)

const server = http.createServer((req, res) => {
req.on('close', () => sub.pass('request closed'))
res.on('close', () => sub.pass('response closed'))
}).listen(0)

await waitForServer(server)

const client = tcp.createConnection(server.address().port)
client.write('POST / HTTP/1.1\r\nContent-Length: 10000000\r\n\r\n')

setTimeout(() => client.destroy(), 300)

await sub

server.close()
})

test('server and client do big writes', async function (t) {
t.plan(8)

Expand Down

0 comments on commit bb1dad8

Please sign in to comment.