UNPKG

httpao

Version:

Simple, lighweight http server module

106 lines (92 loc) 3.03 kB
const dir = __dirname; const {Socket} = require('net'), InComing = require(`${dir}/incoming.js`), Codes = require(`${dir}/codes.js`); const validheader = (o) => { if (typeof o != 'object') throw new TypeError('The headers type must be a object'); }; const validheadername = (k) => { if (typeof k != 'string') throw new TypeError(`Header name must be a valid HTTP token ["${String(k)}"]`); }; const validheadervalue = (k, v) => { if (typeof v == 'undefined') throw new TypeError(`Invalid value "${String(v)}" for header "${k}"`); } const validstatuscode = (c) => { if (typeof c != 'number' || c < 100 || c > 999) throw new Error(`Invalid status code: ${c}`); }; const ksocket = Symbol('socket'); const kheadersSent = Symbol('headersSent'); const knoBody = Symbol('noBody'); const kheaders = Symbol('headers'); const kEnded = Symbol('Ended'); class OutGoing { constructor (socket, req) { if (!(socket instanceof Socket)) throw new TypeError('socket not a Socket instance'); if (!(req instanceof InComing)) throw new TypeError('req not a InComing instance'); this[ksocket] = socket; this[kheadersSent] = false; this[knoBody] = false; this[kheaders] = {}; this[kEnded] = false; } write (d, e) { if (!this[kheadersSent]) { this._sendHeaders(); } this[ksocket].write(d, e); } end (d, e) { this.write(d, e); this[ksocket].end(); this[kEnded] = true; } setHeader (k, v) { if (this[kheadersSent]) throw new Error('Cannot set headers after they are sent to the client'); validheadername(k); validheadervalue(k, v); this[kheaders][k] = String(v); } setHeaders (o) { validheaders(o); Object.keys(o).forEach(k => { this.setHeader(k, o[k]); }); } writeHead (c, m, h) { validstatuscode(c); this.statusCode = c; if (m) { if (typeof m == 'string') { this.statusMessage = m; } else if (typeof m == 'object') { this.setHeaders(m); return; } else { throw new TypeError('The status message type must be a string'); } } if (h) { this.setHeaders(h); } this._sendHeaders(); } _sendHeaders () { this[kheadersSent] = true; this.statusCode = this.statusCode || 200; this.statusMessage = this.statusMessage ? this.statusMessage : (Codes[this.statusCode] ? Codes[this.statusCode] : this.statusCode); this[ksocket].write(`HTTP/1.1 ${this.statusCode} ${this.statusMessage}\r\n`); this[kheaders]['Date'] = new Date().toString(); this[kheaders]['X-Powered-By'] = 'HTTPAO'; Object.keys(this[kheaders]).forEach(k => { this[ksocket].write(`${k}: ${this[kheaders][k]}\r\n`); }); this[ksocket].write(`\r\n`); } get headersSent () { return this[kheadersSent]; } get Ended () { return this[kEnded]; } } module.exports = OutGoing;