Added more comments, cleaned up code.
This commit is contained in:
parent
eae8fd6c0e
commit
e411b4d270
|
@ -3,6 +3,10 @@ module handy_http_primitives.handler;
|
||||||
import handy_http_primitives.request;
|
import handy_http_primitives.request;
|
||||||
import handy_http_primitives.response;
|
import handy_http_primitives.response;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the request handler interface, which is called upon to handle an
|
||||||
|
* incoming HTTP request.
|
||||||
|
*/
|
||||||
interface HttpRequestHandler {
|
interface HttpRequestHandler {
|
||||||
void handle(in HttpRequest request, ref HttpResponse response);
|
void handle(ref ServerHttpRequest request, ref ServerHttpResponse response);
|
||||||
}
|
}
|
|
@ -1,2 +1,7 @@
|
||||||
module handy_http_primitives;
|
module handy_http_primitives;
|
||||||
|
|
||||||
|
public import handy_http_primitives.request;
|
||||||
|
public import handy_http_primitives.response;
|
||||||
|
public import handy_http_primitives.handler;
|
||||||
|
public import handy_http_primitives.optional;
|
||||||
|
public import handy_http_primitives.multivalue_map;
|
||||||
|
|
|
@ -1,25 +1,47 @@
|
||||||
module handy_http_primitives.request;
|
module handy_http_primitives.request;
|
||||||
|
|
||||||
import streams;
|
import streams : InputStream;
|
||||||
|
import std.traits : isSomeString, EnumMembers;
|
||||||
|
|
||||||
import handy_http_primitives.multivalue_map;
|
import handy_http_primitives.multivalue_map;
|
||||||
|
import handy_http_primitives.optional;
|
||||||
|
|
||||||
struct HttpRequest {
|
/**
|
||||||
const ubyte httpVersion = 1;
|
* The HTTP request struct which represents the content of an HTTP request as
|
||||||
const Method method = Method.GET;
|
* received by a server.
|
||||||
const string url = "";
|
*/
|
||||||
|
struct ServerHttpRequest {
|
||||||
|
/// The HTTP version of the request.
|
||||||
|
const HttpVersion httpVersion = HttpVersion.V1_1;
|
||||||
|
/// The HTTP verb used in the request.
|
||||||
|
const HttpMethod method = HttpMethod.GET;
|
||||||
|
/// The URL that was requested.
|
||||||
|
const(char[]) url = "";
|
||||||
|
/// A case-insensitive map of all request headers.
|
||||||
const(CaseInsensitiveStringMultiValueMap) headers;
|
const(CaseInsensitiveStringMultiValueMap) headers;
|
||||||
|
/// A case-sensitive map of all URL query parameters.
|
||||||
const(StringMultiValueMap) queryParams;
|
const(StringMultiValueMap) queryParams;
|
||||||
|
/// The underlying stream used to read the body from the request.
|
||||||
InputStream!ubyte inputStream;
|
InputStream!ubyte inputStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enumeration of all possible HTTP request versions, as an unsigned byte for
|
||||||
|
* efficient storage.
|
||||||
|
*/
|
||||||
|
public enum HttpVersion : ubyte {
|
||||||
|
V1_1 = 1 << 1,
|
||||||
|
V2 = 1 << 2,
|
||||||
|
V3 = 1 << 3
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enumeration of all possible HTTP request methods as unsigned integer values
|
* Enumeration of all possible HTTP request methods as unsigned integer values
|
||||||
* for efficient logic.
|
* for efficient logic.
|
||||||
*
|
*
|
||||||
* https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods
|
* https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods
|
||||||
*/
|
*/
|
||||||
public enum Method : ushort {
|
public enum HttpMethod : ushort {
|
||||||
GET = 1 << 0,
|
GET = 1 << 0,
|
||||||
HEAD = 1 << 1,
|
HEAD = 1 << 1,
|
||||||
POST = 1 << 2,
|
POST = 1 << 2,
|
||||||
|
@ -30,3 +52,33 @@ public enum Method : ushort {
|
||||||
TRACE = 1 << 7,
|
TRACE = 1 << 7,
|
||||||
PATCH = 1 << 8
|
PATCH = 1 << 8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to parse an HttpMethod from a string.
|
||||||
|
* Params:
|
||||||
|
* s = The string to parse.
|
||||||
|
* Returns: An optional which may contain an HttpMethod, if one was parsed.
|
||||||
|
*/
|
||||||
|
Optional!HttpMethod parseHttpMethod(S)(S s) if (isSomeString!S) {
|
||||||
|
import std.uni : toUpper;
|
||||||
|
import std.string : strip;
|
||||||
|
import std.conv : to;
|
||||||
|
static foreach (m; EnumMembers!HttpMethod) {
|
||||||
|
if (s == to!string(m)) return Optional!HttpMethod.of(m);
|
||||||
|
}
|
||||||
|
const cleanStr = strip(toUpper(s));
|
||||||
|
static foreach (m; EnumMembers!HttpMethod) {
|
||||||
|
if (cleanStr == to!string(m)) return Optional!HttpMethod.of(m);
|
||||||
|
}
|
||||||
|
return Optional!HttpMethod.empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
unittest {
|
||||||
|
alias R = Optional!HttpMethod;
|
||||||
|
assert(parseHttpMethod("GET") == R.of(HttpMethod.GET));
|
||||||
|
assert(parseHttpMethod("get") == R.of(HttpMethod.GET));
|
||||||
|
assert(parseHttpMethod(" geT ") == R.of(HttpMethod.GET));
|
||||||
|
assert(parseHttpMethod("PATCH") == R.of(HttpMethod.PATCH));
|
||||||
|
assert(parseHttpMethod(" not a method!") == R.empty);
|
||||||
|
assert(parseHttpMethod("") == R.empty);
|
||||||
|
}
|
||||||
|
|
|
@ -4,9 +4,16 @@ import streams;
|
||||||
|
|
||||||
import handy_http_primitives.multivalue_map;
|
import handy_http_primitives.multivalue_map;
|
||||||
|
|
||||||
struct HttpResponse {
|
/**
|
||||||
|
* The response that's sent by a server back to a client after processing the
|
||||||
|
* client's HTTP request.
|
||||||
|
*/
|
||||||
|
struct ServerHttpResponse {
|
||||||
|
/// The response status.
|
||||||
StatusInfo status = HttpStatus.OK;
|
StatusInfo status = HttpStatus.OK;
|
||||||
|
/// A multi-valued map containing all headers.
|
||||||
StringMultiValueMap headers;
|
StringMultiValueMap headers;
|
||||||
|
/// The stream to which the response body is written.
|
||||||
OutputStream!ubyte outputStream;
|
OutputStream!ubyte outputStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue