@nodefony/http-bundle
Version:
Nodefony Framework Bundle HTTP
306 lines (271 loc) • 7.87 kB
JavaScript
const http = require("http");
const mime = require('mime');
const ansiRegex= function ({onlyFirst = false} = {}){
const pattern = [
'[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)',
'(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))'
].join('|');
return new RegExp(pattern, onlyFirst ? undefined : 'g');
};
const stripAinsi = function(val){
return ( typeof val === 'string') ? val.replace(ansiRegex(), '') : val;
};
module.exports = nodefony.register("Response", function () {
const Response = class httpResponse {
constructor(response, container) {
//if (response instanceof http.ServerResponse || response instanceof http2.Http2ServerResponse) {
this.response = response;
//}
this.context = container.get('context');
this.container = container;
//BODY
this.body = "";
this.encoding = this.setEncoding('utf8');
//cookies
this.cookies = {};
// struct headers
this.headers = {};
this.statusCode = 200;
this.statusMessage = null;
this.ended = false;
this.streamFile = null;
// default http code
//this.setStatusCode(200, null);
//timeout default
this.timeout = this.context.kernelHttp.responseTimeout[this.context.type];
this.contentType = null;
}
clean() {
this.response = null;
delete this.response;
this.cookies = null;
delete this.cookies;
this.headers = null;
delete this.headers;
this.body = null;
delete this.body;
//this.streamFile = null;
//delete this.streamFile;
}
isHtml() {
return (mime.getExtension(this.getHeader("Content-Type")) === "html");
}
setTimeout(ms) {
this.timeout = ms;
}
addCookie(cookie) {
if (cookie instanceof nodefony.cookies.cookie) {
return this.cookies[cookie.name] = cookie;
} else {
throw new Error("Response addCookies not valid cookies");
}
}
setCookies() {
for (let cook in this.cookies) {
this.setCookie(this.cookies[cook]);
}
}
setCookie(cookie) {
let serialize = cookie.serialize();
this.log("ADD COOKIE ==> " + serialize, "DEBUG");
return this.setHeader('Set-Cookie', serialize);
}
log(pci, severity, msgid, msg) {
if (!msgid) {
msgid = this.context.type + " RESPONSE ";
}
return this.context.log(pci, severity, msgid, msg);
}
//ADD INPLICIT HEADER
setHeader(name, value) {
if (this.response) {
if (this.flushing) {
let obj = {};
obj[name] = value;
return this.addTrailers(obj);
}
return this.response.setHeader(name, value);
}
}
setHeaders(obj) {
if (obj instanceof Object) {
for (let head in obj) {
this.setHeader(head, obj[head]);
}
}
return this.headers = this.response.getHeaders();
}
getHeader(name) {
return this.response.getHeader(name);
}
getHeaders() {
return this.response.getHeaders();
}
setContentType(type, encoding) {
let myType = this.getMimeType(type);
if (!myType) {
this.log("Content-Type not valid !!! : " + type, "WARNING");
myType = "application/octet-stream";
}
this.contentType = myType;
return this.setHeader("Content-Type", myType + " ; charset=" + (encoding || this.encoding));
}
getMimeType(name) {
return mime.getType(name);
}
setEncoding(encoding) {
return this.encoding = encoding;
}
setStatusCode(status, message) {
if (status && typeof status !== "number") {
status = parseInt(status, 10);
if (isNaN(status)) {
status = 500;
}
}
this.statusCode = status || this.statusCode;
if (message) {
this.statusMessage = stripAinsi(message);
} else {
if (!this.statusMessage) {
if (http.STATUS_CODES[this.statusCode]) {
this.statusMessage = http.STATUS_CODES[this.statusCode];
} else {
this.statusMessage = http.STATUS_CODES[500];
}
}
}
return {
code: this.statusCode,
message: this.statusMessage
};
}
getStatus() {
return {
code: this.getStatusCode(),
message: this.getStatusMessage()
};
}
getStatusCode() {
return this.statusCode;
}
getStatusMessage(code) {
if (code) {
return http.STATUS_CODES[code] || this.statusMessage || this.response.statusMessage;
}
if (this.response) {
return this.statusMessage || this.response.statusMessage || http.STATUS_CODES[this.statusCode];
} else {
return this.statusMessage || http.STATUS_CODES[this.statusCode];
}
}
setBody(ele, encoding = null) {
//console.trace("setBody : ", ele.length)
return this.body = Buffer.from(ele, encoding || this.encoding);
}
getLength(ele) {
return Buffer.byteLength(ele || this.body);
}
writeHead(statusCode, headers) {
if (statusCode) {
this.setStatusCode(statusCode);
}
if (!this.response.headersSent) {
//this.response.statusMessage = this.statusMessage;
try {
if (this.context.method === "HEAD" || this.context.contentLength) {
this.setHeader('Content-Length', this.getLength());
}
return this.response.writeHead(
this.statusCode,
this.statusMessage,
headers
);
} catch (e) {
throw e;
}
} else {
this.log("Headers already sent !!", "WARNING");
}
}
flushHeaders() {
try {
return this.response.flushHeaders();
} catch (e) {
throw e;
}
}
addTrailers(headers) {
try {
return this.response.addTrailers(headers);
} catch (e) {
throw e;
}
}
flush(data, encoding) {
this.flushing = true;
this.setHeader("Transfer-Encoding", 'chunked');
return this.send(data, encoding, true);
}
send(data, encoding, flush = false) {
try {
if (this.context.isRedirect) {
if (!this.stream.headersSent) {
this.writeHead();
return this.end();
}
return this.end();
}
if (data) {
this.setBody(data);
}
if (!flush) {
this.context.displayDebugBar();
}
return this.response.write(this.body, (encoding || this.encoding));
} catch (e) {
throw e;
}
}
write(data, encoding) {
return this.send(data, encoding);
}
writeContinue() {
return this.response.writeContinue();
}
end(data, encoding) {
if (this.response) {
this.ended = true;
return Promise.resolve(this.response.end(data, (encoding || this.encoding)));
}
return Promise.resolve(null);
}
redirect(url, status, headers) {
this.context.isRedirect = true;
status = parseInt(status, 10);
if (status === 302) {
this.setStatusCode(status);
} else {
status = 301;
this.setStatusCode(301);
}
if (headers) {
switch (nodefony.typeOf(headers)) {
case "object":
this.setHeaders(headers);
break;
case "boolean":
this.setHeaders({
"Cache-Control": "no-store, no-cache, must-revalidate",
"Expires": "Thu, 01 Jan 1970 00:00:00 GMT"
});
break;
}
}
this.setHeader("Location", url);
this.log(`REDIRECT ${status} : ${url} `, "DEBUG");
return this;
}
};
return Response;
});