Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support setting http.Server properties through config. #3

Merged
merged 1 commit into from
Apr 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "koa-simple-web",
"version": "1.3.0",
"version": "1.4.0",
"description": "A simple web server using Koa",
"main": "src/simple-web.js",
"scripts": {
Expand Down
21 changes: 21 additions & 0 deletions src/simple-web.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,23 @@

const Koa = require("koa");

const PASSTHROUGH_CONFIG_KEYS = [
"maxHeadersCount",
"headersTimeout",
"timeout",
"keepAliveTimeout"
];

/**
* @typedef {Object} SimpleWebServerConfig
*
* See this bug related to the timeouts: https://github.com/nodejs/node/issues/27363
*
* @property {number} port The port to listen on
* @property [number] maxHeadersCount {@link https://nodejs.org/docs/latest/api/http.html#http_server_maxheaderscount}
* @property [number] headersTimeout {@link https://nodejs.org/docs/latest/api/http.html#http_server_headerstimeout}
* @property [number] timeout {@link https://nodejs.org/docs/latest/api/http.html#http_server_timeout}
* @property [number] keepAliveTimeout {@link https://nodejs.org/docs/latest/api/http.html#http_server_keepalivetimeout}
*/

/**
Expand All @@ -27,6 +41,13 @@ class SimpleWeb {
return new Promise((resolve, reject) => {
if (!this._server) {
this._server = this._web.listen(this._config.port);

PASSTHROUGH_CONFIG_KEYS.forEach((key) => {
if (typeof this._config[key] !== 'undefined') {
this._server[key] = this._config[key];
}
});

this._server.on("listening", resolve);
}
else {
Expand Down
73 changes: 66 additions & 7 deletions test/simple-web-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,30 @@
const Router = require("koa-router");
const superagent = require("superagent");

const { assertThat, equalTo, is } = require("hamjest");
const { assertThat, equalTo, is, not, defined } = require("hamjest");
const { hasHeader, hasStatusCode } = require("superjest");

const SimpleWeb = require("../src/simple-web");

const port = process.env.PORT || 8080;
const PORT = process.env.PORT || 8080;
const MAX_HEADERS_COUNT = 1111;
const HEADERS_TIMEOUT = 2222;
const TIMEOUT = 3333;
const KEEP_ALIVE_TIMEOUT = 4444;

const config = {
port: PORT,
maxHeadersCount: MAX_HEADERS_COUNT,
headersTimeout: HEADERS_TIMEOUT,
timeout: TIMEOUT,
keepAliveTimeout: KEEP_ALIVE_TIMEOUT
};

describe("simple web", function() {
let web;

beforeEach(async function() {
web = new SimpleWeb({ port: port });
web = new SimpleWeb(config);
});

afterEach(async function() {
Expand Down Expand Up @@ -50,6 +62,53 @@ describe("simple web", function() {
})
});

describe("config", function() {
["maxHeadersCount", "headersTimeout", "timeout", "keepAliveTimeout"].forEach((key) => {
it(`should set ${key}`, async function() {
// Configuration should be synchronous, not wait for the promise to settle
const promise = web.start();

try {
assertThat(web._server[key], is(config[key]));
}
finally {
await promise;
}
});

it(`should set ${key} to zero`, async function() {
const alteredConfig = Object.assign({}, config);
alteredConfig[key] = 0;

web = new SimpleWeb(alteredConfig);
const promise = web.start();

try {
assertThat(web._server[key], is(0));
}
finally {
await promise;
}
});

it(`should not set ${key} if undefined`, async function() {
const alteredConfig = Object.assign({}, config);
delete alteredConfig[key];

web = new SimpleWeb(alteredConfig);
const promise = web.start();

try {
assertThat(web._server[key], defined());
assertThat(web._server[key], not(config[key]));
}
finally {
await promise;
}
});
});
});

describe("routes", function() {
beforeEach(async function() {
web.route(givenRootRoute());
Expand All @@ -58,7 +117,7 @@ describe("simple web", function() {
});

it("should mount routes", function(done) {
superagent.get(`http://localhost:${port}`)
superagent.get(`http://localhost:${PORT}`)
.end((error, response) => {
assertThat(response, hasStatusCode(200));
assertThat(response.text, is("OK"));
Expand All @@ -68,7 +127,7 @@ describe("simple web", function() {
});

it("should only allow defined methods", function(done) {
superagent.post(`http://localhost:${port}`)
superagent.post(`http://localhost:${PORT}`)
.end((error, response) => {
assertThat(response, hasStatusCode(405));

Expand Down Expand Up @@ -97,7 +156,7 @@ describe("simple web", function() {
});

it("should allow arbitrary middleware", function(done) {
superagent.get(`http://localhost:${port}`)
superagent.get(`http://localhost:${PORT}`)
.end((error, response) => {
assertThat(response, hasStatusCode(200));
assertThat(response, hasHeader("x-foo", equalTo("bar")));
Expand Down Expand Up @@ -127,7 +186,7 @@ describe("simple web", function() {
return name;
});

superagent.get(`http://localhost:${port}/name`)
superagent.get(`http://localhost:${PORT}/name`)
.end((error, response) => {
assertThat(response, hasStatusCode(200));
assertThat(response.text, is(name));
Expand Down