Skip to content

Commit 02be716

Browse files
authored
Merge pull request #27 from jkyberneees/support-transfer-encoding
Support transfer encoding
2 parents 9c966dc + a887b32 commit 02be716

File tree

6 files changed

+1129
-888
lines changed

6 files changed

+1129
-888
lines changed

README.md

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -111,19 +111,40 @@ const pump = require('pump')
111111
const toArray = require('stream-to-array')
112112

113113
const onResponse = async (req, res, stream) => {
114-
if (!res.hasHeader('content-length')) {
114+
const TRANSFER_ENCODING_HEADER_NAME = 'transfer-encoding'
115+
const chunked = stream.headers[TRANSFER_ENCODING_HEADER_NAME]
116+
? stream.headers[TRANSFER_ENCODING_HEADER_NAME].endsWith('chunked')
117+
: false
118+
119+
if (req.headers.connection === 'close' && chunked) {
115120
try {
116-
const resBuffer = Buffer.concat(await toArray(stream))
117-
res.statusCode = stream.statusCode
118-
res.setHeader('content-length', '' + Buffer.byteLength(resBuffer))
119-
res.end(resBuffer)
121+
// remove transfer-encoding header
122+
const transferEncoding = stream.headers[TRANSFER_ENCODING_HEADER_NAME].replace(/(,( )?)?chunked/, '')
123+
if (transferEncoding) {
124+
res.setHeader(TRANSFER_ENCODING_HEADER_NAME, transferEncoding)
125+
} else {
126+
res.removeHeader(TRANSFER_ENCODING_HEADER_NAME)
127+
}
128+
129+
if (!stream.headers['content-length']) {
130+
// pack all pieces into 1 buffer to calculate content length
131+
const resBuffer = Buffer.concat(await toArray(stream))
132+
133+
// add content-length header and send the merged response buffer
134+
res.setHeader('content-length', '' + Buffer.byteLength(resBuffer))
135+
res.statusCode = stream.statusCode
136+
res.end(resBuffer)
137+
138+
return
139+
}
120140
} catch (err) {
121-
res.send(err)
141+
res.statusCode = 500
142+
res.end(err.message)
122143
}
123-
} else {
124-
res.statusCode = stream.statusCode
125-
pump(stream, res)
126144
}
145+
146+
res.statusCode = stream.statusCode
147+
pump(stream, res)
127148
}
128149
```
129150
## The "*GET /services.json*" endpoint

demos/basic.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ gateway({
3131
const service1 = require('restana')({})
3232
service1
3333
.get('/hi', (req, res) => res.send('Hello World!'))
34+
.get('/hi-chunked', (req, res) => {
35+
res.write('Hello ')
36+
res.write('World!')
37+
res.end()
38+
})
3439
.start(3000).then(() => console.log('Public service listening on 3000 port!'))
3540

3641
const service2 = require('restana')({})

index.js

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -103,20 +103,40 @@ const handler = (route, proxy, proxyHandler) => async (req, res, next) => {
103103

104104
const onRequestNoOp = (req, res) => { }
105105
const onResponse = async (req, res, stream) => {
106-
if (!res.hasHeader('content-length')) {
106+
const TRANSFER_ENCODING_HEADER_NAME = 'transfer-encoding'
107+
const chunked = stream.headers[TRANSFER_ENCODING_HEADER_NAME]
108+
? stream.headers[TRANSFER_ENCODING_HEADER_NAME].endsWith('chunked')
109+
: false
110+
111+
if (req.headers.connection === 'close' && chunked) {
107112
try {
108-
const resBuffer = Buffer.concat(await toArray(stream))
109-
res.setHeader('content-length', '' + Buffer.byteLength(resBuffer))
110-
res.statusCode = stream.statusCode
111-
res.end(resBuffer)
113+
// remove transfer-encoding header
114+
const transferEncoding = stream.headers[TRANSFER_ENCODING_HEADER_NAME].replace(/(,( )?)?chunked/, '')
115+
if (transferEncoding) {
116+
res.setHeader(TRANSFER_ENCODING_HEADER_NAME, transferEncoding)
117+
} else {
118+
res.removeHeader(TRANSFER_ENCODING_HEADER_NAME)
119+
}
120+
121+
if (!stream.headers['content-length']) {
122+
// pack all pieces into 1 buffer to calculate content length
123+
const resBuffer = Buffer.concat(await toArray(stream))
124+
125+
// add content-length header and send the merged response buffer
126+
res.setHeader('content-length', '' + Buffer.byteLength(resBuffer))
127+
res.statusCode = stream.statusCode
128+
res.end(resBuffer)
129+
130+
return
131+
}
112132
} catch (err) {
113133
res.statusCode = 500
114134
res.end(err.message)
115135
}
116-
} else {
117-
res.statusCode = stream.statusCode
118-
pump(stream, res)
119136
}
137+
138+
res.statusCode = stream.statusCode
139+
pump(stream, res)
120140
}
121141

122142
module.exports = gateway

0 commit comments

Comments
 (0)