Skip to content
This repository was archived by the owner on Nov 23, 2021. It is now read-only.

Add optional queue to handler #86

Closed
wants to merge 3 commits into from
Closed
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
26 changes: 16 additions & 10 deletions Sources/HTTP/HTTPCommon.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
// See http://swift.org/LICENSE.txt for license information
//

import Foundation
import Dispatch

/// Typealias for a closure that handles an incoming HTTP request
/// The following is an example of an echo `HTTPRequestHandler` that returns the request it receives as a response:
/// ```swift
/// func echo(request: HTTPRequest, response: HTTPResponseWriter ) -> HTTPBodyProcessing {
/// func echo(request: HTTPRequest, response: HTTPResponseWriter, queue: DispatchQueue? ) -> HTTPBodyProcessing {
/// response.writeHeader(status: .ok)
/// return .processBody { (chunk, stop) in
/// switch chunk {
Expand All @@ -29,20 +29,26 @@ import Foundation
/// }
/// ```
/// This then needs to be registered with the server using `HTTPServer.start(port:handler:)`
/// - Parameter req: the incoming HTTP request.
/// - Parameter res: a writer providing functions to create an HTTP reponse to the request.
/// - Returns HTTPBodyProcessing: a enum that either discards the request data, or provides a closure to process it.
public typealias HTTPRequestHandler = (HTTPRequest, HTTPResponseWriter) -> HTTPBodyProcessing
/// - Parameters:
/// - req: the incoming HTTP request.
/// - res: a writer providing functions to create an HTTP reponse to the request.
/// - queue: optional, if set, dispatch done callbacks back to this queue (if
/// the handler processing escapes the calling queue)
/// - Returns: HTTPBodyProcessing: a enum that either discards the request data, or provides a closure to process it.
public typealias HTTPRequestHandler = (HTTPRequest, HTTPResponseWriter, DispatchQueue?) -> HTTPBodyProcessing
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On Linux you'll need to import Dispatch explicitly to have access to DispatchQueue

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aside: from Swift 4.1 that won't be true, thanks to swiftlang/swift-corelibs-foundation#1206 🙂

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Though importing Foundation is non-sense in the first place, no Foundation is used here ;->


/// Class protocol containing a `handle()` function that implements `HTTPRequestHandler` to respond to incoming HTTP requests.
/// - See: `HTTPRequestHandler` for more information
public protocol HTTPRequestHandling: class {
/// handle: function that implements `HTTPRequestHandler` and is called when a new HTTP request is received by the HTTP server.
/// - Parameter request: the incoming HTTP request.
/// - Parameter response: a writer providing functions to create an HTTP response to the request.
/// - Returns HTTPBodyProcessing: a enum that either discards the request data, or provides a closure to process it.
/// - Parameters:
/// - request: the incoming HTTP request.
/// - response: a writer providing functions to create an HTTP response to the request.
/// - queue: optional, if set, dispatch done callbacks back to this queue (if
/// the handler processing escapes the calling queue)
/// - Returns: HTTPBodyProcessing: a enum that either discards the request data, or provides a closure to process it.
/// - See: `HTTPRequestHandler` for more information
func handle(request: HTTPRequest, response: HTTPResponseWriter) -> HTTPBodyProcessing
func handle(request: HTTPRequest, response: HTTPResponseWriter, queue: DispatchQueue?) -> HTTPBodyProcessing
}

/// The result returned as part of a completion handler
Expand Down
2 changes: 1 addition & 1 deletion Sources/HTTP/HTTPStreamingParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ public class StreamingParser: HTTPResponseWriter {
self.parserBuffer = nil

if !upgradeRequested {
self.httpBodyProcessingCallback = self.handle(self.createRequest(), self)
self.httpBodyProcessingCallback = self.handle(self.createRequest(), self, nil)
}
case .urlReceived:
if let parserBuffer = self.parserBuffer {
Expand Down
4 changes: 2 additions & 2 deletions Tests/HTTPTests/Helpers/AbortAndSendHelloHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// See http://swift.org/LICENSE.txt for license information
//

import Foundation
import Dispatch
import HTTP

/// Simple `HTTPRequestHandler` that prints "Hello, World" as per K&R
Expand All @@ -15,7 +15,7 @@ class AbortAndSendHelloHandler: HTTPRequestHandling {
var chunkCalledCount=0
var chunkLength=0

func handle(request: HTTPRequest, response: HTTPResponseWriter ) -> HTTPBodyProcessing {
func handle(request: HTTPRequest, response: HTTPResponseWriter, queue: DispatchQueue? ) -> HTTPBodyProcessing {
//Assume the router gave us the right request - at least for now
response.writeHeader(status: .ok, headers: [.transferEncoding: "chunked", "X-foo": "bar"])
return .processBody { (chunk, stop) in
Expand Down
4 changes: 2 additions & 2 deletions Tests/HTTPTests/Helpers/EchoHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
// See http://swift.org/LICENSE.txt for license information
//

import Foundation
import Dispatch
import HTTP

/// Simple `HTTPRequestHandler` that just echoes back whatever input it gets
class EchoHandler: HTTPRequestHandling {
func handle(request: HTTPRequest, response: HTTPResponseWriter ) -> HTTPBodyProcessing {
func handle(request: HTTPRequest, response: HTTPResponseWriter, queue: DispatchQueue? ) -> HTTPBodyProcessing {
//Assume the router gave us the right request - at least for now
response.writeHeader(status: .ok, headers: ["Transfer-Encoding": "chunked", "X-foo": "bar"])
return .processBody { (chunk, stop) in
Expand Down
4 changes: 2 additions & 2 deletions Tests/HTTPTests/Helpers/HelloWorldHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
// See http://swift.org/LICENSE.txt for license information
//

import Foundation
import Dispatch
import HTTP

/// Simple `HTTPRequestHandler` that prints "Hello, World" as per K&R
class HelloWorldHandler: HTTPRequestHandling {
func handle(request: HTTPRequest, response: HTTPResponseWriter ) -> HTTPBodyProcessing {
func handle(request: HTTPRequest, response: HTTPResponseWriter, queue: DispatchQueue? ) -> HTTPBodyProcessing {
//Assume the router gave us the right request - at least for now
response.writeHeader(status: .ok, headers: [.transferEncoding: "chunked", "X-foo": "bar"])
return .processBody { (chunk, stop) in
Expand Down
4 changes: 2 additions & 2 deletions Tests/HTTPTests/Helpers/HelloWorldKeepAliveHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
// See http://swift.org/LICENSE.txt for license information
//

import Foundation
import Dispatch
import HTTP

/// `HelloWorldRequestHandler` that sets the keep alive header for XCTest purposes
class HelloWorldKeepAliveHandler: HTTPRequestHandling {
func handle(request: HTTPRequest, response: HTTPResponseWriter ) -> HTTPBodyProcessing {
func handle(request: HTTPRequest, response: HTTPResponseWriter, queue: DispatchQueue? ) -> HTTPBodyProcessing {
//Assume the router gave us the right request - at least for now
response.writeHeader(status: .ok, headers: [
"Transfer-Encoding": "chunked",
Expand Down
4 changes: 2 additions & 2 deletions Tests/HTTPTests/Helpers/OkHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
// See http://swift.org/LICENSE.txt for license information
//

import Foundation
import Dispatch
import HTTP

/// Simple `HTTPRequestHandler` that returns 200: OK without a body
class OkHandler: HTTPRequestHandling {
func handle(request: HTTPRequest, response: HTTPResponseWriter ) -> HTTPBodyProcessing {
func handle(request: HTTPRequest, response: HTTPResponseWriter, queue: DispatchQueue? ) -> HTTPBodyProcessing {
//Assume the router gave us the right request - at least for now
response.writeHeader(status: .ok, headers: ["Transfer-Encoding": "chunked", "X-foo": "bar"])
return .discardBody
Expand Down
3 changes: 2 additions & 1 deletion Tests/HTTPTests/Helpers/SimpleResponseCreator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
*/

import Foundation
import Dispatch
import HTTP

/// Simple block-based wrapper to create a `HTTPRequestHandler`. Normally used during XCTests
Expand All @@ -32,7 +33,7 @@ public class SimpleResponseCreator: HTTPRequestHandling {

var buffer = Data()

public func handle(request: HTTPRequest, response: HTTPResponseWriter ) -> HTTPBodyProcessing {
public func handle(request: HTTPRequest, response: HTTPResponseWriter, queue: DispatchQueue? ) -> HTTPBodyProcessing {
return .processBody { (chunk, stop) in
switch chunk {
case .chunk(let data, let finishedProcessing):
Expand Down
2 changes: 1 addition & 1 deletion Tests/HTTPTests/Helpers/TestResponseResolver.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class TestResponseResolver: HTTPResponseWriter {
}

func resolveHandler(_ handler: HTTPRequestHandler) {
let chunkHandler = handler(request, self)
let chunkHandler = handler(request, self, nil)
if shouldStopProcessingBody {
return
}
Expand Down
4 changes: 2 additions & 2 deletions Tests/HTTPTests/Helpers/UnchunkedHelloWorldHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
// See http://swift.org/LICENSE.txt for license information
//

import Foundation
import Dispatch
import HTTP

/// Simple `HTTPRequestHandler` that prints "Hello, World" as per K&R
class UnchunkedHelloWorldHandler: HTTPRequestHandling {
func handle(request: HTTPRequest, response: HTTPResponseWriter ) -> HTTPBodyProcessing {
func handle(request: HTTPRequest, response: HTTPResponseWriter, queue: DispatchQueue? ) -> HTTPBodyProcessing {
//Assume the router gave us the right request - at least for now
let responseString = "Hello, World!"
response.writeHeader(status: .ok, headers: [.contentLength: "\(responseString.lengthOfBytes(using: .utf8))"])
Expand Down