Comparing version 4.1.1 to 4.1.2
@@ -15,5 +15,4 @@ "use strict"; | ||
var http = require("http"); | ||
var Body_1 = require("../core/Body"); | ||
var Res_1 = require("../core/Res"); | ||
var Headers_1 = require("../core/Headers"); | ||
var Res_1 = require("../core/Res"); | ||
function HttpClient(request) { | ||
@@ -32,3 +31,3 @@ switch (request.method) { | ||
http.request(requestOptions, function (res) { | ||
return resolve(Res_1.ResOf(res.statusCode, Body_1.BodyOf(res), res.headers)); | ||
return resolve(Res_1.ResOf(res.statusCode, res, res.headers)); | ||
}).end(); | ||
@@ -45,3 +44,3 @@ }); | ||
var clientRequest = http.request(requestOptions, function (res) { | ||
return resolve(Res_1.ResOf(res.statusCode, Body_1.BodyOf(res), res.headers)); | ||
return resolve(Res_1.ResOf(res.statusCode, res, res.headers)); | ||
}); | ||
@@ -48,0 +47,0 @@ if (req.bodyStream()) { |
import * as http from "http"; | ||
import {Res} from "../core/Res"; | ||
import {IncomingMessage} from "http"; | ||
import {Res, ResOf} from "../core/Res"; | ||
import {Req} from "../core/Req"; | ||
import {BodyOf} from "../core/Body"; | ||
import {Headers, HeaderValues} from "../core/Headers"; | ||
import {IncomingMessage} from "http"; | ||
import {ResOf} from "../core/Res"; | ||
import {HeadersType} from "../core/HttpMessage"; | ||
@@ -29,3 +27,3 @@ | ||
http.request(requestOptions, (res: IncomingMessage) => { | ||
return resolve(ResOf(res.statusCode, BodyOf(res), res.headers as HeadersType)); | ||
return resolve(ResOf(res.statusCode, res, res.headers as HeadersType)); | ||
}).end(); | ||
@@ -47,4 +45,4 @@ }); | ||
return new Promise(resolve => { | ||
const clientRequest = http.request(requestOptions, (res) => { | ||
return resolve(ResOf(res.statusCode, BodyOf(res), res.headers as HeadersType)); | ||
const clientRequest = http.request(requestOptions, (res: IncomingMessage) => { | ||
return resolve(ResOf(res.statusCode, res, res.headers as HeadersType)); | ||
}); | ||
@@ -51,0 +49,0 @@ if (req.bodyStream()){ |
@@ -17,3 +17,3 @@ /// <reference types="node" /> | ||
private form; | ||
constructor(method: string, uri: Uri | string, body?: Body | string, headers?: {}); | ||
constructor(method: string, uri: Uri | string, body?: Body | Readable | string, headers?: {}); | ||
withUri(uri: Uri | string): Req; | ||
@@ -38,2 +38,2 @@ header(name: string): string; | ||
} | ||
export declare function ReqOf(method: string, uri: Uri | string, body?: Body | string, headers?: {}): Req; | ||
export declare function ReqOf(method: string, uri: Uri | string, body?: Body | Readable | string, headers?: {}): Req; |
@@ -7,2 +7,3 @@ "use strict"; | ||
var Body_1 = require("./Body"); | ||
var stream_1 = require("stream"); | ||
var Req = /** @class */ (function () { | ||
@@ -24,3 +25,8 @@ function Req(method, uri, body, headers) { | ||
} | ||
this.body = typeof body === 'string' ? Body_1.BodyOf(body) : body; | ||
if (typeof body === 'string' || body instanceof stream_1.Readable) { | ||
this.body = Body_1.BodyOf(body); | ||
} | ||
else { | ||
this.body = body; | ||
} | ||
this.headers = headers ? headers : {}; | ||
@@ -27,0 +33,0 @@ this.queries = this.getQueryParams(); |
@@ -23,3 +23,3 @@ import {Uri} from "./Uri"; | ||
uri: Uri | string, | ||
body: Body | string = '', | ||
body: Body | Readable | string = '', | ||
headers = {}) { | ||
@@ -33,3 +33,7 @@ this.method = method.toUpperCase(); | ||
} | ||
this.body = typeof body === 'string' ? BodyOf(body) : body; | ||
if (typeof body === 'string' || body instanceof Readable) { | ||
this.body = BodyOf(body); | ||
} else { | ||
this.body = body; | ||
} | ||
this.headers = headers ? headers : {}; | ||
@@ -195,5 +199,5 @@ this.queries = this.getQueryParams(); | ||
uri: Uri | string, | ||
body: Body | string = '', | ||
body: Body | Readable | string = '', | ||
headers = {}): Req { | ||
return new Req(method, uri, body, headers); | ||
} |
@@ -9,3 +9,3 @@ /// <reference types="node" /> | ||
status: number; | ||
constructor(status?: number, body?: Body | string, headers?: HeadersType); | ||
constructor(status?: number, body?: Body | Readable | string, headers?: HeadersType); | ||
header(name: string): string; | ||
@@ -17,3 +17,3 @@ withHeader(name: string, value: string): Res; | ||
removeHeader(name: string): Res; | ||
withBody(body: Body | string): Res; | ||
withBody(body: Body | Readable | string): Res; | ||
bodyString(): string; | ||
@@ -23,3 +23,3 @@ bodyStream(): Readable | undefined; | ||
} | ||
export declare function ResOf(status?: number, body?: Body | string, headers?: HeadersType): Res; | ||
export declare function ResOf(status?: number, body?: Body | Readable | string, headers?: HeadersType): Res; | ||
export declare function Redirect(status: number | undefined, path: string, headers?: HeadersType): Res; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var Body_1 = require("./Body"); | ||
var stream_1 = require("stream"); | ||
var Res = /** @class */ (function () { | ||
@@ -11,3 +12,8 @@ function Res(status, body, headers) { | ||
this.status = status; | ||
this.body = typeof body === 'string' ? Body_1.BodyOf(body) : body; | ||
if (typeof body === 'string' || body instanceof stream_1.Readable) { | ||
this.body = Body_1.BodyOf(body); | ||
} | ||
else { | ||
this.body = body; | ||
} | ||
this.headers = headers; | ||
@@ -71,4 +77,3 @@ } | ||
if (headers === void 0) { headers = {}; } | ||
var wrappedBody = typeof body === 'string' ? Body_1.BodyOf(body) : body; | ||
return new Res(status, wrappedBody, headers); | ||
return new Res(status, body, headers); | ||
} | ||
@@ -79,4 +84,4 @@ exports.ResOf = ResOf; | ||
if (headers === void 0) { headers = {}; } | ||
return new Res(status, Body_1.BodyOf(''), headers).withHeader("Location", path); | ||
return new Res(status, '', headers).withHeader("Location", path); | ||
} | ||
exports.Redirect = Redirect; |
@@ -11,5 +11,11 @@ import {HttpMessage, HeadersType} from "./HttpMessage"; | ||
constructor(status: number = 200, body: Body | string = '', headers: HeadersType = {}) { | ||
constructor(status: number = 200, | ||
body: Body | Readable | string = '', | ||
headers: HeadersType = {}) { | ||
this.status = status; | ||
this.body = typeof body === 'string' ? BodyOf(body) : body; | ||
if (typeof body === 'string' || body instanceof Readable) { | ||
this.body = BodyOf(body); | ||
} else { | ||
this.body = body; | ||
} | ||
this.headers = headers; | ||
@@ -59,3 +65,3 @@ } | ||
withBody(body: Body | string): Res { | ||
withBody(body: Body | Readable | string): Res { | ||
return ResOf(this.status, body, this.headers); | ||
@@ -78,10 +84,11 @@ } | ||
export function ResOf(status: number = 200, body: Body | string = '', headers: HeadersType = {}): Res { | ||
const wrappedBody = typeof body === 'string' ? BodyOf(body) : body; | ||
return new Res(status, wrappedBody, headers); | ||
export function ResOf(status: number = 200, | ||
body: Body | Readable | string = '', | ||
headers: HeadersType = {}): Res { | ||
return new Res(status, body, headers); | ||
} | ||
export function Redirect(status: number = 301, path: string, headers: HeadersType = {}): Res { | ||
return new Res(status, BodyOf(''), headers).withHeader("Location", path); | ||
return new Res(status, '', headers).withHeader("Location", path); | ||
} | ||
@@ -40,5 +40,5 @@ "use strict"; | ||
var Uri_1 = require("./Uri"); | ||
var NativeHttpServer_1 = require("../servers/NativeHttpServer"); | ||
var Res_2 = require("./Res"); | ||
var HttpClient_1 = require("../client/HttpClient"); | ||
var NativeServer_1 = require("../servers/NativeServer"); | ||
var Routing = /** @class */ (function () { | ||
@@ -93,3 +93,3 @@ function Routing(method, path, headers, handler, name) { | ||
Routing.prototype.asServer = function (server) { | ||
if (server === void 0) { server = new NativeHttpServer_1.NativeHttpServer(3000); } | ||
if (server === void 0) { server = NativeServer_1.HttpServer(3000); } | ||
this.server = server; | ||
@@ -96,0 +96,0 @@ server.registerCatchAllHandler(this); |
@@ -7,5 +7,5 @@ import {Res} from "./Res"; | ||
import {Http4jsServer} from "../servers/Server"; | ||
import {NativeHttpServer} from "../servers/NativeHttpServer"; | ||
import {ResOf} from "./Res"; | ||
import {HttpClient} from "../client/HttpClient"; | ||
import {HttpServer} from "../servers/NativeServer"; | ||
@@ -56,3 +56,3 @@ export type MountedHttpHandler = { path: string, method: string, headers: HeadersType, handler: HttpHandler, name: string } | ||
asServer(server: Http4jsServer = new NativeHttpServer(3000)): Routing { | ||
asServer(server: Http4jsServer = HttpServer(3000)): Routing { | ||
this.server = server; | ||
@@ -59,0 +59,0 @@ server.registerCatchAllHandler(this); |
@@ -11,2 +11,3 @@ export * from "./core/Routing"; | ||
export * from "./servers/Server"; | ||
export * from "./servers/NativeServer"; | ||
export * from "./servers/NativeHttpServer"; | ||
@@ -13,0 +14,0 @@ export * from "./servers/NativeHttpsServer"; |
@@ -14,2 +14,3 @@ "use strict"; | ||
__export(require("./core/Status")); | ||
__export(require("./servers/NativeServer")); | ||
__export(require("./servers/NativeHttpServer")); | ||
@@ -16,0 +17,0 @@ __export(require("./servers/NativeHttpsServer")); |
@@ -12,2 +12,3 @@ export * from "./core/Routing"; | ||
export * from "./servers/Server"; | ||
export * from "./servers/NativeServer"; | ||
export * from "./servers/NativeHttpServer"; | ||
@@ -14,0 +15,0 @@ export * from "./servers/NativeHttpsServer"; |
{ | ||
"name": "http4js", | ||
"version": "4.1.1", | ||
"version": "4.1.2", | ||
"description": "A lightweight HTTP toolkit", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
100
README.md
@@ -5,27 +5,6 @@ # http4js | ||
### *** [read the docs](https://tomshacham.github.io/http4js/) *** | ||
## [read the docs](https://tomshacham.github.io/http4js/) | ||
## Latest features | ||
[Full Release Notes here](https://tomshacham.github.io/http4js/Release-notes/#release-notes) | ||
### 4.1.1: Fix: HttpClient was not streaming out | ||
See [streaming docs](https://tomshacham.github.io/http4js/Request-and-response-api/#streaming) for more info | ||
### 4.1.0: streaming by default | ||
`NativeHttpServer` and `HttpClient` stream in and out by default. A handle on | ||
the stream is provided by `req.bodyStream()` and a `res` is streamed out if | ||
a `Res(200, BodyOf(readable))` is provided, i.e. a `Readable` stream body. | ||
### 4.0.0: ! Breaking change: drop support for Koa and Express backends | ||
In order to evolve the core library faster support for Express and Koa backends | ||
has been dropped. Happy to add back later. | ||
## Use http4js in your project | ||
### To install: | ||
``` | ||
@@ -35,9 +14,12 @@ npm install --save http4js | ||
or | ||
## Contents | ||
``` | ||
yarn add http4js | ||
``` | ||
- [Example](https://github.com/tomshacham/http4js#example) | ||
- [Latest features](https://github.com/tomshacham/http4js#latest-features) | ||
- [Contributing](https://github.com/tomshacham/http4js#contributing) | ||
- [History and Design](https://github.com/tomshacham/http4js#history-and-design) | ||
- [To dos](https://github.com/tomshacham/http4js#to-dos) | ||
- [Running HTTPS Server tests](https://github.com/tomshacham/http4js#running-https-server-tests) | ||
- [Sanity Testing Streaming](https://github.com/tomshacham/http4js#sanity-testing-streaming) | ||
## Example | ||
@@ -48,3 +30,2 @@ | ||
```typescript | ||
//define our routes | ||
@@ -64,38 +45,35 @@ const routing = routes('GET', ".*", async (req: Req) => { | ||
// start routing as a NativeHttpServer on port 3000 | ||
routing | ||
.withFilter(headerFilter) | ||
.asServer() // starts on port 3000 by default | ||
.asServer(HttpServer(3000)) | ||
.start(); | ||
//make an http request to our server and log the response | ||
// make an http request to our server and log the response | ||
HttpClient(ReqOf(Method.GET, "http://localhost:3000/any/path")) | ||
``` | ||
// output | ||
Req { | ||
headers: | ||
{ host: 'localhost:3000', | ||
connection: 'close', | ||
'content-type': 'application/x-www-form-urlencoded', | ||
'x-csrf-token': 0.8369821184747923 }, | ||
queries: {}, | ||
pathParams: {}, | ||
form: {}, | ||
method: 'GET', | ||
uri: | ||
Uri { | ||
matches: {}, | ||
asNativeNodeRequest: | ||
Url { | ||
..., | ||
protocol: 'http:', | ||
host: 'localhost:3000', | ||
port: '3000', | ||
pathname: '/any/path', | ||
path: '/any/path', | ||
href: 'http://localhost:3000/any/path' } }, | ||
body: '' } | ||
## Latest features | ||
[Full Release Notes here](https://tomshacham.github.io/http4js/Release-notes/#release-notes) | ||
``` | ||
### 4.1.2: Convenience methods for starting server | ||
We provide `HttpServer(3000)` and `HttpsServer(3000, certs)` as quick easy ways to provide a server. | ||
### 4.1.1: Fix: HttpClient was not streaming out | ||
See [streaming docs](https://tomshacham.github.io/http4js/Request-and-response-api/#streaming) for more info | ||
### 4.1.0: streaming by default | ||
`NativeHttpServer` and `HttpClient` stream in and out by default. A handle on | ||
the stream is provided by `req.bodyStream()` and a `res` is streamed out if | ||
a `Res(200, readable)` is provided, i.e. a `Readable` stream body. | ||
### 4.0.0: ! Breaking change: drop support for Koa and Express backends | ||
In order to evolve the core library faster support for Express and Koa backends | ||
has been dropped. Happy to add back later. | ||
## Contributing | ||
@@ -110,5 +88,5 @@ | ||
cd http4js && \ | ||
yarn && \ | ||
yarn build && \ | ||
yarn test | ||
npm i --save && \ | ||
./create-ssl-certs.sh && \ | ||
npm test | ||
``` | ||
@@ -128,5 +106,3 @@ | ||
- streaming | ||
- clean up BodyOf leak | ||
- servers, https O | ||
- clients, https O | ||
- check how to stream in req in native server | ||
- refactor req and res to not use clone and instead construct new self | ||
@@ -178,3 +154,3 @@ - extract Form | ||
```typescript | ||
get('/bigfile', async() => ResOf(200, BodyOf(fs.createReadStream('./bigfile.txt')))) | ||
get('/bigfile', async() => ResOf(200, fs.createReadStream('./bigfile.txt'))) | ||
.asServer() | ||
@@ -181,0 +157,0 @@ .start(); |
@@ -1,13 +0,4 @@ | ||
import { Routing } from "../core/Routing"; | ||
import { Http4jsServer } from "./Server"; | ||
export declare class NativeHttpServer implements Http4jsServer { | ||
server: any; | ||
port: number; | ||
routing: Routing; | ||
validHostnameRegex: RegExp; | ||
import { NativeServer } from "./NativeServer"; | ||
export declare class NativeHttpServer extends NativeServer { | ||
constructor(port: number); | ||
registerCatchAllHandler(routing: Routing): void; | ||
private hostnameFrom; | ||
start(): Promise<void>; | ||
stop(): Promise<void>; | ||
} |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
var __extends = (this && this.__extends) || (function () { | ||
var extendStatics = function (d, b) { | ||
extendStatics = Object.setPrototypeOf || | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; | ||
return extendStatics(d, b); | ||
} | ||
}; | ||
return function (d, b) { | ||
extendStatics(d, b); | ||
function __() { this.constructor = d; } | ||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); | ||
}; | ||
})(); | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var http = require("http"); | ||
var stream_1 = require("stream"); | ||
var Body_1 = require("../core/Body"); | ||
var Req_1 = require("../core/Req"); | ||
var NativeHttpServer = /** @class */ (function () { | ||
var NativeServer_1 = require("./NativeServer"); | ||
var NativeHttpServer = /** @class */ (function (_super) { | ||
__extends(NativeHttpServer, _super); | ||
function NativeHttpServer(port) { | ||
this.validHostnameRegex = new RegExp('^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$'); | ||
this.port = port; | ||
this.server = http.createServer(); | ||
return _super.call(this, port) || this; | ||
} | ||
NativeHttpServer.prototype.registerCatchAllHandler = function (routing) { | ||
var _this = this; | ||
this.routing = routing; | ||
this.server.on("request", function (req, res) { | ||
var headers = req.headers, method = req.method, url = req.url; | ||
var inStream = new stream_1.Readable({ read: function () { } }); | ||
var hostname = _this.hostnameFrom(req); | ||
req.on('error', function (err) { | ||
console.error(err); | ||
}).on('data', function (chunk) { | ||
inStream.push(chunk); | ||
}).on('end', function () { | ||
inStream.push(null); // No more data | ||
var req = Req_1.ReqOf(method, "" + hostname + url, Body_1.BodyOf(inStream), headers); | ||
var response = _this.routing.serve(req); | ||
response.then(function (response) { | ||
res.writeHead(response.status, response.headers); | ||
var bodyStream = response.bodyStream(); | ||
if (bodyStream) { | ||
bodyStream.pipe(res); | ||
} | ||
else { | ||
res.write(response.bodyString()); | ||
res.end(); | ||
} | ||
}).catch(function (rej) { return console.log(rej); }); | ||
}); | ||
}); | ||
}; | ||
NativeHttpServer.prototype.hostnameFrom = function (req) { | ||
var hostHeader = req.headers.host; | ||
var isLocalhost = req.socket.localAddress === '::ffff:127.0.0.1'; | ||
return this.validHostnameRegex.test(hostHeader) | ||
? "http://" + hostHeader | ||
: (isLocalhost ? "http://localhost:" + req.socket.localPort : ''); | ||
}; | ||
NativeHttpServer.prototype.start = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
this.server.listen(this.port); | ||
return [2 /*return*/]; | ||
}); | ||
}); | ||
}; | ||
NativeHttpServer.prototype.stop = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
this.server.close(); | ||
return [2 /*return*/]; | ||
}); | ||
}); | ||
}; | ||
return NativeHttpServer; | ||
}()); | ||
}(NativeServer_1.NativeServer)); | ||
exports.NativeHttpServer = NativeHttpServer; |
@@ -1,71 +0,7 @@ | ||
import * as http from "http"; | ||
import {Routing} from "../core/Routing"; | ||
import {Res} from "../core/Res"; | ||
import {Req} from "../core/Req"; | ||
import {Http4jsServer} from "./Server"; | ||
import {HeaderValues} from "../core/Headers"; | ||
import {Form, HeadersType} from "../core/HttpMessage"; | ||
import { Readable } from 'stream'; | ||
import {Stream} from "stream"; | ||
import {BodyOf} from "../core/Body"; | ||
import {ReqOf} from "../core/Req"; | ||
import {NativeServer} from "./NativeServer"; | ||
export class NativeHttpServer implements Http4jsServer { | ||
server: any; | ||
port: number; | ||
routing: Routing; | ||
validHostnameRegex: RegExp = new RegExp('^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$') | ||
export class NativeHttpServer extends NativeServer { | ||
constructor(port: number) { | ||
this.port = port; | ||
this.server = http.createServer(); | ||
super(port); | ||
} | ||
registerCatchAllHandler(routing: Routing): void { | ||
this.routing = routing; | ||
this.server.on("request", (req: any, res: any) => { | ||
const {headers, method, url} = req; | ||
const inStream = new Readable({ read() {} }); | ||
const hostname = this.hostnameFrom(req); | ||
req.on('error', (err: any) => { | ||
console.error(err); | ||
}).on('data', (chunk: Buffer) => { | ||
inStream.push(chunk); | ||
}).on('end', () => { | ||
inStream.push(null); // No more data | ||
const req = ReqOf(method, `${hostname}${url}`, BodyOf(inStream), headers); | ||
const response = this.routing.serve(req); | ||
response.then(response => { | ||
res.writeHead(response.status, response.headers); | ||
const bodyStream = response.bodyStream(); | ||
if (bodyStream){ | ||
bodyStream.pipe(res); | ||
} else { | ||
res.write(response.bodyString()); | ||
res.end(); | ||
} | ||
}).catch(rej => console.log(rej)); | ||
}) | ||
}); | ||
} | ||
private hostnameFrom(req: any) { | ||
const hostHeader = req.headers.host; | ||
const isLocalhost = req.socket.localAddress === '::ffff:127.0.0.1'; | ||
return this.validHostnameRegex.test(hostHeader) | ||
? `http://${hostHeader}` | ||
: (isLocalhost ? `http://localhost:${req.socket.localPort}` : ''); | ||
} | ||
async start(): Promise<void> { | ||
this.server.listen(this.port); | ||
} | ||
async stop(): Promise<void> { | ||
this.server.close(); | ||
} | ||
} | ||
} |
@@ -1,21 +0,4 @@ | ||
/// <reference types="node" /> | ||
import { Http4jsServer } from "./Server"; | ||
import { Routing } from "../"; | ||
declare type Certs = { | ||
key: Buffer; | ||
cert: Buffer; | ||
ca: Buffer; | ||
}; | ||
export declare class NativeHttpsServer implements Http4jsServer { | ||
server: any; | ||
port: number; | ||
options: Certs; | ||
routing: Routing; | ||
validHostnameRegex: RegExp; | ||
constructor(port: number, options?: Certs | undefined); | ||
registerCatchAllHandler(routing: Routing): void; | ||
start(): Promise<void>; | ||
stop(): Promise<void>; | ||
private createInMemResponse; | ||
import { Certs, NativeServer } from "./NativeServer"; | ||
export declare class NativeHttpsServer extends NativeServer { | ||
constructor(port: number, certs: Certs); | ||
} | ||
export {}; |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
var __extends = (this && this.__extends) || (function () { | ||
var extendStatics = function (d, b) { | ||
extendStatics = Object.setPrototypeOf || | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; | ||
return extendStatics(d, b); | ||
} | ||
}; | ||
return function (d, b) { | ||
extendStatics(d, b); | ||
function __() { this.constructor = d; } | ||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); | ||
}; | ||
})(); | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var fs = require("fs"); | ||
var https = require("https"); | ||
var Req_1 = require("../core/Req"); | ||
var Headers_1 = require("../core/Headers"); | ||
var NativeHttpsServer = /** @class */ (function () { | ||
function NativeHttpsServer(port, options) { | ||
if (options === void 0) { options = undefined; } | ||
this.validHostnameRegex = new RegExp('^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$'); | ||
var certs = { | ||
key: fs.readFileSync('src/ssl/key.pem'), | ||
cert: fs.readFileSync('src/ssl/fullchain.pem'), | ||
ca: fs.readFileSync('src/ssl/my-root-ca.cert.pem'), | ||
}; | ||
this.options = options || certs; | ||
this.port = port; | ||
this.server = https.createServer(this.options); | ||
var NativeServer_1 = require("./NativeServer"); | ||
var NativeHttpsServer = /** @class */ (function (_super) { | ||
__extends(NativeHttpsServer, _super); | ||
function NativeHttpsServer(port, certs) { | ||
return _super.call(this, port, certs) || this; | ||
} | ||
NativeHttpsServer.prototype.registerCatchAllHandler = function (routing) { | ||
var _this = this; | ||
this.routing = routing; | ||
this.server.on("request", function (req, res) { | ||
var headers = req.headers, method = req.method, url = req.url; | ||
var hostHeader = req.headers.host; | ||
var isLocalhost = req.socket.localAddress === '::ffff:127.0.0.1'; | ||
var hostname = _this.validHostnameRegex.test(hostHeader) | ||
? "http://" + hostHeader | ||
: (isLocalhost ? "http://localhost:" + req.socket.localPort : ''); | ||
var chunks = []; | ||
req.on('error', function (err) { | ||
console.error(err); | ||
}).on('data', function (chunk) { | ||
chunks.push(chunk); | ||
}).on('end', function () { | ||
var response = _this.createInMemResponse(chunks, method, "" + hostname + url, headers); | ||
response.then(function (response) { | ||
res.writeHead(response.status, response.headers); | ||
res.end(response.bodyString()); | ||
}).catch(function (rej) { return console.log(rej); }); | ||
}); | ||
}); | ||
}; | ||
NativeHttpsServer.prototype.start = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
this.server.listen(this.port); | ||
return [2 /*return*/]; | ||
}); | ||
}); | ||
}; | ||
NativeHttpsServer.prototype.stop = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
this.server.close(); | ||
return [2 /*return*/]; | ||
}); | ||
}); | ||
}; | ||
NativeHttpsServer.prototype.createInMemResponse = function (chunks, method, url, headers) { | ||
var body = Buffer.concat(chunks).toString(); | ||
var form = {}; | ||
if (headers['content-type'] == Headers_1.HeaderValues.FORM) { | ||
body.split("&").map(function (keyvalue) { | ||
var strings = keyvalue.split("="); | ||
var name = strings[0]; | ||
var value = strings[1]; | ||
if (form[name]) { | ||
typeof (form[name]) === "string" | ||
? (form[name]) = [form[name], value] | ||
: form[name].push(value); | ||
} | ||
else { | ||
form[name] = value; | ||
} | ||
}); | ||
} | ||
var inMemRequest = new Req_1.Req(method, url, body, headers).withForm(form); | ||
return this.routing.serve(inMemRequest); | ||
}; | ||
return NativeHttpsServer; | ||
}()); | ||
}(NativeServer_1.NativeServer)); | ||
exports.NativeHttpsServer = NativeHttpsServer; |
@@ -1,83 +0,7 @@ | ||
import * as fs from "fs"; | ||
import * as https from 'https'; | ||
import {Res} from "../core/Res"; | ||
import {Http4jsServer} from "./Server"; | ||
import {Routing} from "../"; | ||
import {Form, HeadersType} from "../core/HttpMessage"; | ||
import {Req} from "../core/Req"; | ||
import {HeaderValues} from "../core/Headers"; | ||
import {Certs, NativeServer} from "./NativeServer"; | ||
type Certs = { key: Buffer; cert: Buffer; ca: Buffer }; | ||
export class NativeHttpsServer implements Http4jsServer { | ||
server: any; | ||
port: number; | ||
options: Certs; | ||
routing: Routing; | ||
validHostnameRegex: RegExp = new RegExp('^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$') | ||
constructor(port: number, options: Certs | undefined = undefined) { | ||
const certs = { | ||
key: fs.readFileSync('src/ssl/key.pem'), | ||
cert: fs.readFileSync('src/ssl/fullchain.pem'), | ||
ca: fs.readFileSync('src/ssl/my-root-ca.cert.pem'), | ||
}; | ||
this.options = options || certs; | ||
this.port = port; | ||
this.server = https.createServer(this.options); | ||
export class NativeHttpsServer extends NativeServer { | ||
constructor(port: number, certs: Certs) { | ||
super(port, certs); | ||
} | ||
registerCatchAllHandler(routing: Routing): void { | ||
this.routing = routing; | ||
this.server.on("request", (req: any, res: any) => { | ||
const {headers, method, url} = req; | ||
const hostHeader = req.headers.host; | ||
const isLocalhost = req.socket.localAddress === '::ffff:127.0.0.1'; | ||
const hostname = this.validHostnameRegex.test(hostHeader) | ||
? `http://${hostHeader}` | ||
: (isLocalhost ? `http://localhost:${req.socket.localPort}` : ''); | ||
const chunks: Buffer[] = []; | ||
req.on('error', (err: any) => { | ||
console.error(err); | ||
}).on('data', (chunk: Buffer) => { | ||
chunks.push(chunk); | ||
}).on('end', () => { | ||
const response = this.createInMemResponse(chunks, method, `${hostname}${url}`, headers); | ||
response.then(response => { | ||
res.writeHead(response.status, response.headers); | ||
res.end(response.bodyString()); | ||
}).catch(rej => console.log(rej)); | ||
}) | ||
}); | ||
} | ||
async start(): Promise<void> { | ||
this.server.listen(this.port); | ||
} | ||
async stop(): Promise<void> { | ||
this.server.close(); | ||
} | ||
private createInMemResponse(chunks: Buffer[], method: string, url: string, headers: HeadersType): Promise<Res> { | ||
const body = Buffer.concat(chunks).toString(); | ||
const form: Form = {}; | ||
if (headers['content-type'] == HeaderValues.FORM) { | ||
body.split("&").map(keyvalue => { | ||
const strings = keyvalue.split("="); | ||
const name = strings[0]; | ||
const value = strings[1]; | ||
if (form[name]) { | ||
typeof (form[name]) === "string" | ||
? (form[name]) = [(form[name] as string), value] | ||
: (form[name] as string[]).push(value); | ||
} else { | ||
form[name] = value; | ||
} | ||
}) | ||
} | ||
const inMemRequest = new Req(method, url, body, headers).withForm(form); | ||
return this.routing.serve(inMemRequest); | ||
} | ||
} |
@@ -0,4 +1,7 @@ | ||
/// <reference types="node" /> | ||
import { Routing } from "../core/Routing"; | ||
import * as http from 'http'; | ||
import * as https from 'https'; | ||
export interface Http4jsServer { | ||
server: any; | ||
server: http.Server | https.Server; | ||
port: number; | ||
@@ -5,0 +8,0 @@ registerCatchAllHandler(routing: Routing): void; |
import {Routing} from "../core/Routing"; | ||
import * as http from 'http'; | ||
import * as https from 'https'; | ||
export interface Http4jsServer { | ||
server: any; | ||
server: http.Server | https.Server; | ||
port: number; | ||
@@ -6,0 +8,0 @@ |
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
63
0
113399
2661
157