tsoa
This commit is contained in:
162
node_modules/@hapi/shot/lib/response.js
generated
vendored
Executable file
162
node_modules/@hapi/shot/lib/response.js
generated
vendored
Executable file
@@ -0,0 +1,162 @@
|
||||
'use strict';
|
||||
|
||||
const Http = require('http');
|
||||
const Stream = require('stream');
|
||||
|
||||
const Hoek = require('@hapi/hoek');
|
||||
|
||||
const Symbols = require('./symbols');
|
||||
|
||||
|
||||
const internals = {};
|
||||
|
||||
|
||||
exports = module.exports = internals.Response = class extends Http.ServerResponse {
|
||||
|
||||
constructor(req, onEnd) {
|
||||
|
||||
super({ method: req.method, httpVersionMajor: 1, httpVersionMinor: 1 });
|
||||
this._shot = { headers: null, trailers: {}, payloadChunks: [] };
|
||||
this.assignSocket(internals.nullSocket());
|
||||
|
||||
this.socket.on('error', Hoek.ignore); // The socket can be destroyed with an error
|
||||
|
||||
if (req._shot.simulate.close) {
|
||||
// Ensure premature, manual close is forwarded to res.
|
||||
// In HttpServer the socket closing actually triggers close on both req and res.
|
||||
req.once('close', () => {
|
||||
|
||||
process.nextTick(() => this.destroy());
|
||||
});
|
||||
}
|
||||
|
||||
const finalize = (aborted) => {
|
||||
|
||||
const res = internals.payload(this);
|
||||
res.raw.req = req;
|
||||
if (aborted) {
|
||||
res.aborted = aborted;
|
||||
if (!this.headersSent) {
|
||||
res.statusCode = 499;
|
||||
}
|
||||
}
|
||||
|
||||
this.removeListener('close', abort);
|
||||
|
||||
process.nextTick(() => onEnd(res));
|
||||
};
|
||||
|
||||
const abort = () => finalize(true);
|
||||
|
||||
this.once('finish', finalize);
|
||||
|
||||
// Add fallback listener that will not be called if 'finish' is emitted first
|
||||
|
||||
this.on('close', abort);
|
||||
}
|
||||
|
||||
writeHead(...args) {
|
||||
|
||||
// Find the headers object if one was provided. If a headers object is present, call setHeader()
|
||||
// on the first valid header, and then break out of the loop and call writeHead(). By calling
|
||||
// setHeader(), Node will materialize a headers object.
|
||||
|
||||
const headers = args[args.length - 1];
|
||||
|
||||
if (typeof headers === 'object' && headers !== null) {
|
||||
const headerNames = Object.keys(headers);
|
||||
|
||||
for (let i = 0; i < headerNames.length; ++i) {
|
||||
const name = headerNames[i];
|
||||
|
||||
try {
|
||||
this.setHeader(name, headers[name]);
|
||||
break;
|
||||
}
|
||||
catch (ignoreErr) {} // Let the real writeHead() handle errors.
|
||||
}
|
||||
}
|
||||
|
||||
const result = super.writeHead(...args);
|
||||
|
||||
this._shot.headers = this.getHeaders();
|
||||
|
||||
// Add raw headers
|
||||
|
||||
['Date', 'Connection', 'Transfer-Encoding'].forEach((name) => {
|
||||
|
||||
const regex = new RegExp('\\r\\n' + name + ': ([^\\r]*)\\r\\n');
|
||||
const field = this._header.match(regex);
|
||||
if (field) {
|
||||
this._shot.headers[name.toLowerCase()] = field[1];
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
write(data, encoding, callback) {
|
||||
|
||||
super.write(data, encoding, callback);
|
||||
this._shot.payloadChunks.push(Buffer.from(data, encoding));
|
||||
return true; // Write always returns false when disconnected
|
||||
}
|
||||
|
||||
end(data, encoding, callback) {
|
||||
|
||||
if (data) {
|
||||
this.write(data, encoding);
|
||||
}
|
||||
|
||||
super.end(callback);
|
||||
this.emit('finish');
|
||||
}
|
||||
|
||||
addTrailers(trailers) {
|
||||
|
||||
for (const key in trailers) {
|
||||
this._shot.trailers[key.toLowerCase().trim()] = trailers[key].toString().trim();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
internals.Response.prototype[Symbols.injection] = true;
|
||||
|
||||
|
||||
internals.payload = function (response) {
|
||||
|
||||
// Prepare response object
|
||||
|
||||
const res = {
|
||||
raw: {
|
||||
res: response
|
||||
},
|
||||
headers: response._shot.headers,
|
||||
statusCode: response.statusCode,
|
||||
statusMessage: response.statusMessage,
|
||||
trailers: {}
|
||||
};
|
||||
|
||||
// Prepare payload and trailers
|
||||
|
||||
const rawBuffer = Buffer.concat(response._shot.payloadChunks);
|
||||
res.rawPayload = rawBuffer;
|
||||
res.payload = rawBuffer.toString();
|
||||
res.trailers = response._shot.trailers;
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
|
||||
// Throws away all written data to prevent response from buffering payload
|
||||
|
||||
internals.nullSocket = function () {
|
||||
|
||||
return new Stream.Writable({
|
||||
write(chunk, encoding, callback) {
|
||||
|
||||
setImmediate(callback);
|
||||
}
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user