koa 3.0.3 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -304,10 +304,18 @@ function respond (ctx) {
304
304
 
305
305
  if (Buffer.isBuffer(body)) return res.end(body)
306
306
  if (typeof body === 'string') return res.end(body)
307
- if (body instanceof Blob) { return Stream.Readable.from(body.stream()).pipe(res) }
308
- if (body instanceof ReadableStream) { return Stream.Readable.from(body).pipe(res) }
309
- if (body instanceof Response) { return Stream.Readable.from(body?.body || '').pipe(res) }
310
- if (isStream(body)) return body.pipe(res)
307
+
308
+ let stream = null
309
+ if (body instanceof Blob) stream = Stream.Readable.from(body.stream())
310
+ else if (body instanceof ReadableStream) stream = Stream.Readable.from(body)
311
+ else if (body instanceof Response) stream = Stream.Readable.from(body?.body || '')
312
+ else if (isStream(body)) stream = body
313
+
314
+ if (stream) {
315
+ return Stream.pipeline(stream, res, err => {
316
+ if (err && ctx.app.listenerCount('error')) ctx.onerror(err)
317
+ })
318
+ }
311
319
 
312
320
  // body: json
313
321
  body = JSON.stringify(body)
package/lib/response.js CHANGED
@@ -135,6 +135,14 @@ module.exports = {
135
135
  set body (val) {
136
136
  const original = this._body
137
137
  this._body = val
138
+
139
+ const cleanupPreviousStream = () => {
140
+ if (original && isStream(original)) {
141
+ original.once('error', () => {})
142
+ destroy(original)
143
+ }
144
+ }
145
+
138
146
  // no content
139
147
 
140
148
  if (val == null) {
@@ -149,6 +157,7 @@ module.exports = {
149
157
  this.remove('Content-Type')
150
158
  this.remove('Content-Length')
151
159
  this.remove('Transfer-Encoding')
160
+ cleanupPreviousStream()
152
161
  return
153
162
  }
154
163
 
@@ -162,6 +171,7 @@ module.exports = {
162
171
  if (typeof val === 'string') {
163
172
  if (setType) this.type = /^\s*</.test(val) ? 'html' : 'text'
164
173
  this.length = Buffer.byteLength(val)
174
+ cleanupPreviousStream()
165
175
  return
166
176
  }
167
177
 
@@ -169,6 +179,7 @@ module.exports = {
169
179
  if (Buffer.isBuffer(val)) {
170
180
  if (setType) this.type = 'bin'
171
181
  this.length = val.length
182
+ cleanupPreviousStream()
172
183
  return
173
184
  }
174
185
 
@@ -176,9 +187,8 @@ module.exports = {
176
187
  if (isStream(val)) {
177
188
  onFinish(this.res, destroy.bind(null, val))
178
189
  if (original !== val) {
179
- val.once('error', err => this.ctx.onerror(err))
180
- // overwriting
181
190
  if (original != null) this.remove('Content-Length')
191
+ cleanupPreviousStream()
182
192
  }
183
193
 
184
194
  if (setType) this.type = 'bin'
@@ -188,6 +198,7 @@ module.exports = {
188
198
  // ReadableStream
189
199
  if (val instanceof ReadableStream) {
190
200
  if (setType) this.type = 'bin'
201
+ cleanupPreviousStream()
191
202
  return
192
203
  }
193
204
 
@@ -195,6 +206,7 @@ module.exports = {
195
206
  if (val instanceof Blob) {
196
207
  if (setType) this.type = 'bin'
197
208
  this.length = val.size
209
+ cleanupPreviousStream()
198
210
  return
199
211
  }
200
212
 
@@ -206,13 +218,14 @@ module.exports = {
206
218
  for (const key of headers.keys()) {
207
219
  this.set(key, headers.get(key))
208
220
  }
209
-
221
+ cleanupPreviousStream()
210
222
  return
211
223
  }
212
224
 
213
225
  // json
214
226
  this.remove('Content-Length')
215
227
  if (!this.type || !/\bjson\b/i.test(this.type)) this.type = 'json'
228
+ cleanupPreviousStream()
216
229
  },
217
230
 
218
231
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "koa",
3
- "version": "3.0.3",
3
+ "version": "3.1.0",
4
4
  "description": "Koa web app framework",
5
5
  "main": "lib/application.js",
6
6
  "exports": {