|
1 | 1 | 'use strict' |
2 | 2 |
|
3 | 3 | constassert=require('node:assert') |
4 | | -const{ kDestroyed, kBodyUsed, kListeners }=require('./symbols') |
| 4 | +const{ kDestroyed, kBodyUsed, kListeners, kBody}=require('./symbols') |
5 | 5 | const{ IncomingMessage }=require('node:http') |
6 | 6 | conststream=require('node:stream') |
7 | 7 | constnet=require('node:net') |
8 | | -const{ InvalidArgumentError }=require('./errors') |
9 | 8 | const{ Blob }=require('node:buffer') |
10 | 9 | constnodeUtil=require('node:util') |
11 | 10 | const{ stringify }=require('node:querystring') |
| 11 | +const{EventEmitter: EE}=require('node:events') |
| 12 | +const{ InvalidArgumentError }=require('./errors') |
12 | 13 | const{ headerNameLowerCasedRecord }=require('./constants') |
13 | 14 | const{ tree }=require('./tree') |
14 | 15 |
|
15 | 16 | const[nodeMajor,nodeMinor]=process.versions.node.split('.').map(v=>Number(v)) |
16 | 17 |
|
| 18 | +classBodyAsyncIterable{ |
| 19 | +constructor(body){ |
| 20 | +this[kBody]=body |
| 21 | +this[kBodyUsed]=false |
| 22 | +} |
| 23 | + |
| 24 | +async*[Symbol.asyncIterator](){ |
| 25 | +assert(!this[kBodyUsed],'disturbed') |
| 26 | +this[kBodyUsed]=true |
| 27 | +yield*this[kBody] |
| 28 | +} |
| 29 | +} |
| 30 | + |
| 31 | +functionwrapRequestBody(body){ |
| 32 | +if(isStream(body)){ |
| 33 | +// TODO (fix): Provide some way for the user to cache the file to e.g. /tmp |
| 34 | +// so that it can be dispatched again? |
| 35 | +// TODO (fix): Do we need 100-expect support to provide a way to do this properly? |
| 36 | +if(bodyLength(body)===0){ |
| 37 | +body |
| 38 | +.on('data',function(){ |
| 39 | +assert(false) |
| 40 | +}) |
| 41 | +} |
| 42 | + |
| 43 | +if(typeofbody.readableDidRead!=='boolean'){ |
| 44 | +body[kBodyUsed]=false |
| 45 | +EE.prototype.on.call(body,'data',function(){ |
| 46 | +this[kBodyUsed]=true |
| 47 | +}) |
| 48 | +} |
| 49 | + |
| 50 | +returnbody |
| 51 | +}elseif(body&&typeofbody.pipeTo==='function'){ |
| 52 | +// TODO (fix): We can't access ReadableStream internal state |
| 53 | +// to determine whether or not it has been disturbed. This is just |
| 54 | +// a workaround. |
| 55 | +returnnewBodyAsyncIterable(body) |
| 56 | +}elseif( |
| 57 | +body&& |
| 58 | +typeofbody!=='string'&& |
| 59 | +!ArrayBuffer.isView(body)&& |
| 60 | +isIterable(body) |
| 61 | +){ |
| 62 | +// TODO: Should we allow re-using iterable if !this.opts.idempotent |
| 63 | +// or through some other flag? |
| 64 | +returnnewBodyAsyncIterable(body) |
| 65 | +}else{ |
| 66 | +returnbody |
| 67 | +} |
| 68 | +} |
| 69 | + |
17 | 70 | functionnop(){} |
18 | 71 |
|
19 | 72 | functionisStream(obj){ |
@@ -634,5 +687,6 @@ module.exports = { |
634 | 687 | isHttpOrHttpsPrefixed, |
635 | 688 | nodeMajor, |
636 | 689 | nodeMinor, |
637 | | -safeHTTPMethods: ['GET','HEAD','OPTIONS','TRACE'] |
| 690 | +safeHTTPMethods: ['GET','HEAD','OPTIONS','TRACE'], |
| 691 | + wrapRequestBody |
638 | 692 | } |
0 commit comments