Implementing error, close, finish, abort events management.

This commit is contained in:
ali.ibrahim 2016-10-04 17:12:17 +02:00
parent bde30b90e8
commit ec1fc5a17b
7 changed files with 391 additions and 117 deletions

View file

@ -50,12 +50,24 @@ class IncomingMessage extends EventEmitter {
}
URLRequest.prototype._emitRequestEvent = function () {
this._request.emit.apply(this._request, arguments)
URLRequest.prototype._emitRequestEvent = function (async, ...rest) {
if (async) {
process.nextTick(() => {
this._request.emit.apply(this._request, rest)
})
} else {
this._request.emit.apply(this._request, rest)
}
}
URLRequest.prototype._emitResponseEvent = function () {
this._response.emit.apply(this._response, arguments)
URLRequest.prototype._emitResponseEvent = function (async, ...rest) {
if (async) {
process.nextTick(() => {
this._request.emit.apply(this._request, rest)
})
} else {
this._response.emit.apply(this._response, rest)
}
}
class ClientRequest extends EventEmitter {
@ -127,16 +139,7 @@ class ClientRequest extends EventEmitter {
}
}
// Flag to prevent request's headers modifications after
// headers flush.
this._started = false
this._aborted = false
// Flag to prevent writings after end.
this._finished = false
// Set when the request uses chuned encoding. Can be switched
// Set when the request uses chunked encoding. Can be switched
// to true only once and never set back to false.
this._chunkedEncoding = false
@ -161,7 +164,7 @@ class ClientRequest extends EventEmitter {
}
set chunkedEncoding (value) {
if (this._started) {
if (!this._url_request.notStarted) {
throw new Error('Can\'t set the transfer encoding, headers have been sent.')
}
this._chunkedEncoding = value
@ -174,7 +177,7 @@ class ClientRequest extends EventEmitter {
if (value === undefined) {
throw new Error('`value` required in setHeader("' + name + '", value).')
}
if (this._started) {
if (!this._url_request.notStarted) {
throw new Error('Can\'t set headers after they are sent.')
}
@ -201,7 +204,7 @@ class ClientRequest extends EventEmitter {
throw new Error('`name` is required for removeHeader(name).')
}
if (this._started) {
if (!this._url_request.notStarted) {
throw new Error('Can\'t remove headers after they are sent.')
}
@ -229,9 +232,8 @@ class ClientRequest extends EventEmitter {
// Since writing to the network is asynchronous, we conservatively
// assume that request headers are written after delivering the first
// buffer to the network IO thread.
if (!this._started) {
if (!this._url_request.notStarted) {
this._url_request.setChunkedUpload(this.chunkedEncoding)
this._started = true
}
// The write callback is fired asynchronously to mimic Node.js.
@ -243,7 +245,7 @@ class ClientRequest extends EventEmitter {
}
write (data, encoding, callback) {
if (this._finished) {
if (this._url_request.finished) {
let error = new Error('Write after end.')
process.nextTick(writeAfterEndNT, this, error, callback)
return true
@ -253,12 +255,10 @@ class ClientRequest extends EventEmitter {
}
end (data, encoding, callback) {
if (this._finished) {
if (this._url_request.finished) {
return false
}
this._finished = true
if (typeof data === 'function') {
callback = data
encoding = null
@ -274,18 +274,7 @@ class ClientRequest extends EventEmitter {
}
abort () {
if (!this._started) {
// Does nothing if stream
return
}
if (!this._aborted) {
this._url_request.abort()
this._aborted = true
process.nextTick(() => {
this.emit('abort')
})
}
this._url_request.cancel()
}
}