|
@ -37,6 +37,7 @@ const Buffer = require('buffer').Buffer; |
|
|
const { urlToOptions, searchParamsSymbol } = require('internal/url'); |
|
|
const { urlToOptions, searchParamsSymbol } = require('internal/url'); |
|
|
const outHeadersKey = require('internal/http').outHeadersKey; |
|
|
const outHeadersKey = require('internal/http').outHeadersKey; |
|
|
const nextTick = require('internal/process/next_tick').nextTick; |
|
|
const nextTick = require('internal/process/next_tick').nextTick; |
|
|
|
|
|
const errors = require('internal/errors'); |
|
|
|
|
|
|
|
|
// The actual list of disallowed characters in regexp form is more like:
|
|
|
// The actual list of disallowed characters in regexp form is more like:
|
|
|
// /[^A-Za-z0-9\-._~!$&'()*+,;=/:@]/
|
|
|
// /[^A-Za-z0-9\-._~!$&'()*+,;=/:@]/
|
|
@ -68,8 +69,8 @@ function isInvalidPath(s) { |
|
|
|
|
|
|
|
|
function validateHost(host, name) { |
|
|
function validateHost(host, name) { |
|
|
if (host != null && typeof host !== 'string') { |
|
|
if (host != null && typeof host !== 'string') { |
|
|
throw new TypeError( |
|
|
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', `options.${name}`, |
|
|
`"options.${name}" must either be a string, undefined or null`); |
|
|
['string', 'undefined', 'null'], host); |
|
|
} |
|
|
} |
|
|
return host; |
|
|
return host; |
|
|
} |
|
|
} |
|
@ -80,7 +81,7 @@ function ClientRequest(options, cb) { |
|
|
if (typeof options === 'string') { |
|
|
if (typeof options === 'string') { |
|
|
options = url.parse(options); |
|
|
options = url.parse(options); |
|
|
if (!options.hostname) { |
|
|
if (!options.hostname) { |
|
|
throw new Error('Unable to determine the domain name'); |
|
|
throw new errors.Error('ERR_INVALID_DOMAIN_NAME'); |
|
|
} |
|
|
} |
|
|
} else if (options && options[searchParamsSymbol] && |
|
|
} else if (options && options[searchParamsSymbol] && |
|
|
options[searchParamsSymbol][searchParamsSymbol]) { |
|
|
options[searchParamsSymbol][searchParamsSymbol]) { |
|
@ -101,9 +102,8 @@ function ClientRequest(options, cb) { |
|
|
// Explicitly pass through this statement as agent will not be used
|
|
|
// Explicitly pass through this statement as agent will not be used
|
|
|
// when createConnection is provided.
|
|
|
// when createConnection is provided.
|
|
|
} else if (typeof agent.addRequest !== 'function') { |
|
|
} else if (typeof agent.addRequest !== 'function') { |
|
|
throw new TypeError( |
|
|
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'Agent option', |
|
|
'Agent option must be an Agent-like object, undefined, or false.' |
|
|
['Agent-like object', 'undefined', 'false']); |
|
|
); |
|
|
|
|
|
} |
|
|
} |
|
|
this.agent = agent; |
|
|
this.agent = agent; |
|
|
|
|
|
|
|
@ -122,12 +122,11 @@ function ClientRequest(options, cb) { |
|
|
invalidPath = /[\u0000-\u0020]/.test(path); |
|
|
invalidPath = /[\u0000-\u0020]/.test(path); |
|
|
} |
|
|
} |
|
|
if (invalidPath) |
|
|
if (invalidPath) |
|
|
throw new TypeError('Request path contains unescaped characters'); |
|
|
throw new errors.TypeError('ERR_UNESCAPED_CHARACTERS', 'Request path'); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (protocol !== expectedProtocol) { |
|
|
if (protocol !== expectedProtocol) { |
|
|
throw new Error('Protocol "' + protocol + '" not supported. ' + |
|
|
throw new errors.Error('ERR_INVALID_PROTOCOL', protocol, expectedProtocol); |
|
|
'Expected "' + expectedProtocol + '"'); |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
var defaultPort = options.defaultPort || |
|
|
var defaultPort = options.defaultPort || |
|
@ -145,12 +144,13 @@ function ClientRequest(options, cb) { |
|
|
var method = options.method; |
|
|
var method = options.method; |
|
|
var methodIsString = (typeof method === 'string'); |
|
|
var methodIsString = (typeof method === 'string'); |
|
|
if (method != null && !methodIsString) { |
|
|
if (method != null && !methodIsString) { |
|
|
throw new TypeError('Method must be a string'); |
|
|
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'method', |
|
|
|
|
|
'string', method); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (methodIsString && method) { |
|
|
if (methodIsString && method) { |
|
|
if (!common._checkIsHttpToken(method)) { |
|
|
if (!common._checkIsHttpToken(method)) { |
|
|
throw new TypeError('Method must be a valid HTTP token'); |
|
|
throw new errors.TypeError('ERR_INVALID_HTTP_TOKEN', 'Method'); |
|
|
} |
|
|
} |
|
|
method = this.method = method.toUpperCase(); |
|
|
method = this.method = method.toUpperCase(); |
|
|
} else { |
|
|
} else { |
|
@ -211,8 +211,7 @@ function ClientRequest(options, cb) { |
|
|
options.headers); |
|
|
options.headers); |
|
|
} else if (this.getHeader('expect')) { |
|
|
} else if (this.getHeader('expect')) { |
|
|
if (this._header) { |
|
|
if (this._header) { |
|
|
throw new Error('Can\'t render headers after they are sent to the ' + |
|
|
throw new errors.Error('ERR_HTTP_HEADERS_SENT'); |
|
|
'client'); |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
this._storeHeader(this.method + ' ' + this.path + ' HTTP/1.1\r\n', |
|
|
this._storeHeader(this.method + ' ' + this.path + ' HTTP/1.1\r\n', |
|
@ -303,7 +302,7 @@ ClientRequest.prototype._finish = function _finish() { |
|
|
|
|
|
|
|
|
ClientRequest.prototype._implicitHeader = function _implicitHeader() { |
|
|
ClientRequest.prototype._implicitHeader = function _implicitHeader() { |
|
|
if (this._header) { |
|
|
if (this._header) { |
|
|
throw new Error('Can\'t render headers after they are sent to the client'); |
|
|
throw new errors.Error('ERR_HTTP_HEADERS_SENT'); |
|
|
} |
|
|
} |
|
|
this._storeHeader(this.method + ' ' + this.path + ' HTTP/1.1\r\n', |
|
|
this._storeHeader(this.method + ' ' + this.path + ' HTTP/1.1\r\n', |
|
|
this[outHeadersKey]); |
|
|
this[outHeadersKey]); |
|
|