Implementing abort workflow, emitting error events.

This commit is contained in:
ali.ibrahim 2016-09-28 15:07:54 +02:00
parent cbbc4376ca
commit 08947682b0
5 changed files with 84 additions and 46 deletions

View file

@ -130,6 +130,12 @@ 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;
@ -137,10 +143,6 @@ class ClientRequest extends EventEmitter {
// to true only once and never set back to false.
this._chunkedEncoding = false;
// Flag to prevent request's headers modifications after
// headers flush.
this._headersSent = false;
// This is a copy of the extra headers structure held by the native
// net::URLRequest. The main reason is to keep the getHeader API synchronous
// after the request starts.
@ -162,7 +164,7 @@ class ClientRequest extends EventEmitter {
}
set chunkedEncoding(value) {
if (this._headersSent) {
if (this._started) {
throw new Error('Can\'t set the transfer encoding, headers have been sent.');
}
this._chunkedEncoding = value;
@ -174,7 +176,7 @@ class ClientRequest extends EventEmitter {
throw new TypeError('`name` should be a string in setHeader(name, value).');
if (value === undefined)
throw new Error('`value` required in setHeader("' + name + '", value).');
if (this._headersSent)
if (this._started)
throw new Error('Can\'t set headers after they are sent.');
let key = name.toLowerCase();
@ -202,7 +204,7 @@ class ClientRequest extends EventEmitter {
throw new Error('`name` is required for removeHeader(name).');
}
if (this._headersSent) {
if (this._started) {
throw new Error('Can\'t remove headers after they are sent.');
}
@ -227,14 +229,14 @@ class ClientRequest extends EventEmitter {
// Headers are assumed to be sent on first call to _writeBuffer,
// i.e. after the first call to write or end.
let result = this._url_request.writeBuffer(chunk, is_last);
let result = this._url_request.write(chunk, is_last);
// 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._headersSent) {
if (!this._started) {
this._url_request.setChunkedUpload(this.chunkedEncoding);
this._headersSent = true;
this._started = true;
}
// The write callback is fired asynchronously to mimic Node.js.
@ -278,6 +280,21 @@ class ClientRequest extends EventEmitter {
return this._write(data, encoding, callback, true);
}
abort() {
if (!this._started) {
// Does nothing if stream
return;
}
if (!this._aborted) {
this._url_request.abort();
this._aborted = true;
process.nextTick( ()=>{
this.emit('abort');
} );
}
}
}
function writeAfterEndNT(self, error, callback) {