-
Notifications
You must be signed in to change notification settings - Fork 63
Files
/
Copy pathrequest.js
352 lines (301 loc) · 8.52 KB
1
var capability = require('./capability')
2
var inherits = require('inherits')
3
var response = require('./response')
4
var stream = require('readable-stream')
5
6
7
8
var IncomingMessage = response.IncomingMessage
var rStates = response.readyStates
9
10
function decideMode (preferBinary, useFetch) {
if (capability.fetch && useFetch) {
11
12
13
14
15
16
17
18
19
20
21
22
return 'fetch'
} else if (capability.mozchunkedarraybuffer) {
return 'moz-chunked-arraybuffer'
} else if (capability.msstream) {
return 'ms-stream'
} else if (capability.arraybuffer && preferBinary) {
return 'arraybuffer'
} else {
return 'text'
}
}
23
24
25
26
27
28
var ClientRequest = module.exports = function (opts) {
var self = this
stream.Writable.call(self)
self._opts = opts
self._body = []
29
self._headers = {}
30
if (opts.auth)
31
self.setHeader('Authorization', 'Basic ' + Buffer.from(opts.auth).toString('base64'))
32
Object.keys(opts.headers).forEach(function (name) {
33
34
35
self.setHeader(name, opts.headers[name])
})
36
var preferBinary
37
var useFetch = true
38
if (opts.mode === 'disable-fetch' || ('requestTimeout' in opts && !capability.abortController)) {
39
// If the use of XHR should be preferred. Not typically needed.
40
41
42
useFetch = false
preferBinary = true
} else if (opts.mode === 'prefer-streaming') {
43
44
// If streaming is a high priority but binary compatibility and
// the accuracy of the 'content-type' header aren't
45
preferBinary = false
46
47
} else if (opts.mode === 'allow-wrong-content-type') {
// If streaming is more important than preserving the 'content-type' header
48
preferBinary = !capability.overrideMimeType
49
50
51
} else if (!opts.mode || opts.mode === 'default' || opts.mode === 'prefer-fast') {
// Use binary if text streaming may corrupt data or the content-type header, or for speed
preferBinary = true
52
53
54
} else {
throw new Error('Invalid value for opts.mode')
}
55
self._mode = decideMode(preferBinary, useFetch)
56
self._fetchTimer = null
57
58
self._socketTimeout = null
self._socketTimer = null
59
60
61
62
self.on('finish', function () {
self._onFinish()
})
63
64
}
65
inherits(ClientRequest, stream.Writable)
66
67
68
ClientRequest.prototype.setHeader = function (name, value) {
var self = this
69
70
71
72
var lowerName = name.toLowerCase()
// This check is not necessary, but it prevents warnings from browsers about setting unsafe
// headers. To be honest I'm not entirely sure hiding these warnings is a good thing, but
// http-browserify did it, so I will too.
73
if (unsafeHeaders.indexOf(lowerName) !== -1)
74
75
76
return
self._headers[lowerName] = {
77
78
79
name: name,
value: value
}
80
81
82
}
ClientRequest.prototype.getHeader = function (name) {
83
84
85
86
var header = this._headers[name.toLowerCase()]
if (header)
return header.value
return null
87
88
89
90
}
ClientRequest.prototype.removeHeader = function (name) {
var self = this
91
delete self._headers[name.toLowerCase()]
92
93
94
95
96
}
ClientRequest.prototype._onFinish = function () {
var self = this
97
98
if (self._destroyed)
return
99
100
var opts = self._opts
101
if ('timeout' in opts && opts.timeout !== 0) {