koa 3.0.3 → 3.1.1

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,17 @@ 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
+ // Only destroy if the new value is not a stream
143
+ if (!isStream(val)) {
144
+ destroy(original)
145
+ }
146
+ }
147
+ }
148
+
138
149
  // no content
139
150
 
140
151
  if (val == null) {
@@ -149,6 +160,7 @@ module.exports = {
149
160
  this.remove('Content-Type')
150
161
  this.remove('Content-Length')
151
162
  this.remove('Transfer-Encoding')
163
+ cleanupPreviousStream()
152
164
  return
153
165
  }
154
166
 
@@ -162,6 +174,7 @@ module.exports = {
162
174
  if (typeof val === 'string') {
163
175
  if (setType) this.type = /^\s*</.test(val) ? 'html' : 'text'
164
176
  this.length = Buffer.byteLength(val)
177
+ cleanupPreviousStream()
165
178
  return
166
179
  }
167
180
 
@@ -169,6 +182,7 @@ module.exports = {
169
182
  if (Buffer.isBuffer(val)) {
170
183
  if (setType) this.type = 'bin'
171
184
  this.length = val.length
185
+ cleanupPreviousStream()
172
186
  return
173
187
  }
174
188
 
@@ -176,9 +190,8 @@ module.exports = {
176
190
  if (isStream(val)) {
177
191
  onFinish(this.res, destroy.bind(null, val))
178
192
  if (original !== val) {
179
- val.once('error', err => this.ctx.onerror(err))
180
- // overwriting
181
193
  if (original != null) this.remove('Content-Length')
194
+ cleanupPreviousStream()
182
195
  }
183
196
 
184
197
  if (setType) this.type = 'bin'
@@ -188,6 +201,7 @@ module.exports = {
188
201
  // ReadableStream
189
202
  if (val instanceof ReadableStream) {
190
203
  if (setType) this.type = 'bin'
204
+ cleanupPreviousStream()
191
205
  return
192
206
  }
193
207
 
@@ -195,6 +209,7 @@ module.exports = {
195
209
  if (val instanceof Blob) {
196
210
  if (setType) this.type = 'bin'
197
211
  this.length = val.size
212
+ cleanupPreviousStream()
198
213
  return
199
214
  }
200
215
 
@@ -206,13 +221,14 @@ module.exports = {
206
221
  for (const key of headers.keys()) {
207
222
  this.set(key, headers.get(key))
208
223
  }
209
-
224
+ cleanupPreviousStream()
210
225
  return
211
226
  }
212
227
 
213
228
  // json
214
229
  this.remove('Content-Length')
215
230
  if (!this.type || !/\bjson\b/i.test(this.type)) this.type = 'json'
231
+ cleanupPreviousStream()
216
232
  },
217
233
 
218
234
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "koa",
3
- "version": "3.0.3",
3
+ "version": "3.1.1",
4
4
  "description": "Koa web app framework",
5
5
  "main": "lib/application.js",
6
6
  "exports": {