diff --git a/source/handy_http_primitives/request.d b/source/handy_http_primitives/request.d index f758c81..c5390a4 100644 --- a/source/handy_http_primitives/request.d +++ b/source/handy_http_primitives/request.d @@ -13,10 +13,12 @@ import handy_http_primitives.optional; struct ServerHttpRequest { /// The HTTP version of the request. const HttpVersion httpVersion = HttpVersion.V1_1; + /// The remote address of the client that sent this request. + const InternetAddress clientAddress; /// The HTTP verb used in the request. - const HttpMethod method = HttpMethod.GET; + const string method = HttpMethod.GET; /// The URL that was requested. - const(char[]) url = ""; + const string url = ""; /// A case-insensitive map of all request headers. const(CaseInsensitiveStringMultiValueMap) headers; /// A case-sensitive map of all URL query parameters. @@ -36,21 +38,20 @@ public enum HttpVersion : ubyte { } /** - * Enumeration of all possible HTTP request methods as unsigned integer values - * for efficient logic. + * Enumeration of all possible HTTP methods, excluding extensions like WebDAV. * * https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods */ -public enum HttpMethod : ushort { - GET = 1 << 0, - HEAD = 1 << 1, - POST = 1 << 2, - PUT = 1 << 3, - DELETE = 1 << 4, - CONNECT = 1 << 5, - OPTIONS = 1 << 6, - TRACE = 1 << 7, - PATCH = 1 << 8 +public enum HttpMethod : string { + GET = "GET", + HEAD = "HEAD", + POST = "POST", + PUT = "PUT", + DELETE = "DELETE", + CONNECT = "CONNECT", + OPTIONS = "OPTIONS", + TRACE = "TRACE", + PATCH = "PATCH" } /** @@ -62,13 +63,12 @@ public enum HttpMethod : ushort { 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); + if (s == 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); + if (cleanStr == m) return Optional!HttpMethod.of(m); } return Optional!HttpMethod.empty; } @@ -82,3 +82,26 @@ unittest { assert(parseHttpMethod(" not a method!") == R.empty); assert(parseHttpMethod("") == R.empty); } + +/// The data representing a remote IPv4 internet address, available as an int or bytes. +union IPv4InternetAddress { + const uint intValue; + const ubyte[4] bytes; +} + +/// The data representing a remote IPv6 internet address. +struct IPv6InternetAddress { + const ubyte[16] bytes; +} + +/// A remote internet address, which is either IPv4 or IPv6. Check `isIPv6`. +struct InternetAddress { + /// True if this address is IPv6. False if this is an IPv4 address. + const bool isIPv6; + /// The port number assigned to the connecting client on this machine. + const ushort port; + union { + IPv4InternetAddress ipv4Address; + IPv6InternetAddress ipv6Address; + } +}