Skip to content

[RFC] Add request handlers #17

Open
@codegefluester

Description

@codegefluester

What I liked the most about this (now very dated) server written on Obj-C was how easy it was to extend it.

I propose the same for swift-http, that we add a protocol or base class for request handlers that will then be registered with the main class.

Once a request comes in, the HTTPRequest class will take the request and turn it into an object so that you have easy access to things like the HTTP method, request headers, body, URL parameters etc.

We could then either have the main HTTP class loop through an array of registered handlers and let the first handler that returns true for canHandleRequest handle the request (aka producing a response) or the developer adds an if-statement to the main.swift to figure out which handler should handle the request. Both scenarios might want to either default to a handler that returns the file as plain text or 404.

This is a pseudo-sample of what I am imagine, I am already working on a basic FileRequestHandler that simply returns the contents of a file as well as tries to figure out the proper Content-Type header based on the file extension.

The simple handler protocol

public protocol RequestHandlerProtocol {
  static func canHandleRequest(inout request: HTTPRequest) -> Bool
  static func handleRequest(inout request: HTTPRequest, inout response: HTTPResponse)
}

An example handler

public class DefaultRequestHandler: RequestHandlerProtocol {

  public static func canHandleRequest(inout request: HTTPRequest) -> Bool {
    return true
  }

  public static func handleRequest(inout request: HTTPRequest, inout response: HTTPResponse) {
    response.statusCode = 404
    response.body = "404 Not Found"
    response.addHeader("Content-Type", value: "text/plain")
  }
}

Example of the request handling (in http.swift, start function)*

// ...
let request = HTTPRequest(bytes: bufferRcv)
if DefaultRequestHandler.canHandleRequest(&request) {
    DefaultRequestHandler.handleRequest(&request, response: &response)
}
response.write(clientSocket)
// ...

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions