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

feat: Ability to limit request size and connection count #1481

Merged
merged 19 commits into from Oct 9, 2019

Conversation

@djones6
Copy link
Member

djones6 commented Aug 16, 2019

Description

This PR allows a requestSizeLimit (maximum bytes for the request body) and connectionLimit (on total number of concurrent connections) to be configured when registering a server.

Example usage from Kitura is as follows:

let options = ServerOptions(requestSizeLimit: 100, connectionLimit: 3)
Kitura.addHTTPServer(onPort: port, with: router, options: options)

If you do not specify either of the parameters, or do not specify a ServerOptions at all, then default values are used. The defaults are defined as constants ServerOptions.defaultRequestSizeLimit and ServerOptions.defaultConnectionLimit.

  • These have been given conservative defaults of 100mb and 10,000 connections, so as to not break existing deployments.

If a client sends a request that exceeds the limit, then they are immediately sent an HTTP/1.1 413 Request Entity Too Large and the connection is closed.
If a client attempts to connect, but we are already at the connection limit, they are immediately sent an HTTP/1.1 503 Service Unavailable and the connection is closed.

These responses can be further customized by supplying requestSizeResponseGenerator and connectionResponseGenerator closures, which are passed an Int (the limit that was exceeded) and a String (the hostname and port of the socket), and return an HTTPStatusCode and a String that is a plaintext message to be returned to the client. The default responses are again defined as constants defaultRequestSizeResponseGenerator and defaultConnectionResponseGenerator.

This does not provide a means to set a limit on the request headers (more specifically, all data up to the point where the HTTP parser determines that headers are complete). Both the HTTPParser in Kitura-net and Swift-NIO set a limit of 80kb on the size of the headers, and it seems unlikely in practice that this would need to be modified.

Some issues I'm aware of:

  • There are already parameters keepAlive and allowPortReuse on Kitura.addHTTPServer which could be rolled into this new options struct.

Depends on IBM-Swift/Kitura-net#307 and IBM-Swift/Kitura-NIO#221

Motivation and Context

Resolves #1384

How Has This Been Tested?

Tests have been added for:

  • a POST request that is (exactly) within the limit is successful,
  • an oversized POST request is rejected,
  • a request with oversized headers is rejected,
  • connections above the configured limit are rejected,
  • custom responses for oversized requests and excess connections.

Checklist:

  • If applicable, I have updated the documentation accordingly.
  • If applicable, I have added tests to cover my changes.
@djones6 djones6 force-pushed the requestLimit branch from 65c9e2b to ef435df Oct 7, 2019
djones6 added 4 commits Oct 7, 2019
@djones6 djones6 changed the title [WIP] feat: Ability to limit request size and connection count feat: Ability to limit request size and connection count Oct 8, 2019
@djones6 djones6 requested a review from ianpartridge Oct 8, 2019
@djones6 djones6 merged commit 728acab into master Oct 9, 2019
2 checks passed
2 checks passed
continuous-integration/travis-ci/pr The Travis CI build passed
Details
license/cla Contributor License Agreement is signed.
Details
@djones6 djones6 deleted the requestLimit branch Oct 9, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.