Skip to content
This repository has been archived by the owner on Apr 7, 2022. It is now read-only.

Commit

Permalink
add support for enabling HTTP pipelining
Browse files Browse the repository at this point in the history
  • Loading branch information
tanner0101 committed Dec 12, 2018
1 parent 6973bf5 commit 939d1f9
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 6 deletions.
11 changes: 10 additions & 1 deletion Sources/HTTP/Responder/HTTPServer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public final class HTTPServer {
/// - reuseAddress: When `true`, can prevent errors re-binding to a socket after successive server restarts.
/// - tcpNoDelay: When `true`, OS will attempt to minimize TCP packet delay.
/// - supportCompression: When `true`, HTTP server will support gzip and deflate compression.
/// - supportPipelining: When `true`, HTTP server will support pipelined HTTP requests.
/// - serverName: If set, this name will be serialized as the `Server` header in outgoing responses.
/// - upgraders: An array of `HTTPProtocolUpgrader` to check for with each request.
/// - worker: `Worker` to perform async work on.
Expand All @@ -36,6 +37,7 @@ public final class HTTPServer {
reuseAddress: Bool = true,
tcpNoDelay: Bool = true,
supportCompression: Bool = false,
supportPipelining: Bool = false,
serverName: String? = nil,
upgraders: [HTTPProtocolUpgrader] = [],
on worker: Worker,
Expand All @@ -59,7 +61,7 @@ public final class HTTPServer {

// configure the pipeline
return channel.pipeline.configureHTTPServerPipeline(
withPipeliningAssistance: false,
withPipeliningAssistance: supportPipelining,
withServerUpgrade: upgrade,
withErrorHandling: false
).then {
Expand Down Expand Up @@ -126,6 +128,9 @@ private final class HTTPServerHandler<R>: ChannelInboundHandler where R: HTTPSer

/// Optional server header.
private let serverHeader: String?

/// If true, we are waiting for a response to be sent.
var awaitingReponse: Bool

/// Current HTTP state.
var state: HTTPServerState
Expand All @@ -137,10 +142,12 @@ private final class HTTPServerHandler<R>: ChannelInboundHandler where R: HTTPSer
self.errorHandler = onError
self.serverHeader = serverHeader
self.state = .ready
self.awaitingReponse = false
}

/// See `ChannelInboundHandler`.
func channelRead(ctx: ChannelHandlerContext, data: NIOAny) {
debugOnly { assert(!self.awaitingReponse, "Pipelined HTTP request detected. Enable pipelining to prevent this error.")}
debugOnly { assert(ctx.channel.eventLoop.inEventLoop) }
switch unwrapInboundIn(data) {
case .head(let head):
Expand Down Expand Up @@ -197,6 +204,7 @@ private final class HTTPServerHandler<R>: ChannelInboundHandler where R: HTTPSer
case .streamingBody(let stream): _ = stream.write(.end)
}
state = .ready
self.awaitingReponse = true
}
}

Expand Down Expand Up @@ -246,6 +254,7 @@ private final class HTTPServerHandler<R>: ChannelInboundHandler where R: HTTPSer
}

// begin serializing
self.awaitingReponse = false
ctx.write(wrapOutboundOut(.head(reshead)), promise: nil)
if reqhead.method == .HEAD || res.status == .noContent {
// skip sending the body for HEAD requests
Expand Down
6 changes: 3 additions & 3 deletions Tests/HTTPTests/HTTPClientTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ class HTTPClientTests: XCTestCase {
try testURL("http://zombo.com", contains: "<title>ZOMBO</title>")
}

func testAmazonWithTLS() throws {
try testURL("https://www.amazon.com", contains: "Amazon.com, Inc.")
func testVaporWithTLS() throws {
try testURL("https://vapor.codes", contains: "Server-side Swift")
}

func testQuery() throws {
Expand All @@ -41,7 +41,7 @@ class HTTPClientTests: XCTestCase {
("testGoogleAPIsFCM", testGoogleAPIsFCM),
("testExampleCom", testExampleCom),
("testZombo", testZombo),
("testAmazonWithTLS", testAmazonWithTLS),
("testVaporWithTLS", testVaporWithTLS),
("testQuery", testQuery),
]
}
Expand Down
2 changes: 0 additions & 2 deletions Tests/HTTPTests/HTTPTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,6 @@ class HTTPTests: XCTestCase {
func upgrade(ctx: ChannelHandlerContext, upgradeResponse: HTTPResponseHead) -> EventLoopFuture<String> {
return ctx.eventLoop.future("hello")
}


}
do {
_ = try HTTPClient.upgrade(hostname: "foo", upgrader: FakeUpgrader(), on: worker).wait()
Expand Down

0 comments on commit 939d1f9

Please sign in to comment.