1 module hunt.http.codec.http.model.HttpHeader; 2 3 import hunt.util.traits; 4 5 import std.algorithm; 6 import std.conv; 7 import std.string; 8 9 import hunt.logging; 10 11 bool contains(HttpHeader[] items, ref HttpHeader item) { 12 return items.canFind(item); 13 } 14 15 /** 16 */ 17 struct HttpHeader { 18 enum HttpHeader Null = HttpHeader("Null"); 19 20 /** 21 * General Fields. 22 */ 23 enum HttpHeader CONNECTION = HttpHeader("Connection"); 24 enum HttpHeader CACHE_CONTROL = HttpHeader("Cache-Control"); 25 enum HttpHeader DATE = HttpHeader("Date"); 26 enum HttpHeader PRAGMA = HttpHeader("Pragma"); 27 enum HttpHeader PROXY_CONNECTION = HttpHeader("Proxy-Connection"); 28 enum HttpHeader TRAILER = HttpHeader("Trailer"); 29 enum HttpHeader TRANSFER_ENCODING = HttpHeader("Transfer-Encoding"); 30 enum HttpHeader UPGRADE = HttpHeader("Upgrade"); 31 enum HttpHeader VIA = HttpHeader("Via"); 32 enum HttpHeader WARNING = HttpHeader("Warning"); 33 enum HttpHeader NEGOTIATE = HttpHeader("Negotiate"); 34 35 /** 36 * Entity Fields. 37 */ 38 enum HttpHeader ALLOW = HttpHeader("Allow"); 39 enum HttpHeader CONTENT_DISPOSITION = HttpHeader("Content-Disposition"); 40 enum HttpHeader CONTENT_ENCODING = HttpHeader("Content-Encoding"); 41 enum HttpHeader CONTENT_LANGUAGE = HttpHeader("Content-Language"); 42 enum HttpHeader CONTENT_LENGTH = HttpHeader("Content-Length"); 43 enum HttpHeader CONTENT_LOCATION = HttpHeader("Content-Location"); 44 enum HttpHeader CONTENT_MD5 = HttpHeader("Content-MD5"); 45 enum HttpHeader CONTENT_RANGE = HttpHeader("Content-Range"); 46 enum HttpHeader CONTENT_TYPE = HttpHeader("Content-Type"); 47 enum HttpHeader EXPIRES = HttpHeader("Expires"); 48 enum HttpHeader LAST_MODIFIED = HttpHeader("Last-Modified"); 49 50 /** 51 * Request Fields. 52 */ 53 enum HttpHeader ACCEPT = HttpHeader("Accept"); 54 enum HttpHeader ACCEPT_CHARSET = HttpHeader("Accept-Charset"); 55 enum HttpHeader ACCEPT_ENCODING = HttpHeader("Accept-Encoding"); 56 enum HttpHeader ACCEPT_LANGUAGE = HttpHeader("Accept-Language"); 57 enum HttpHeader AUTHORIZATION = HttpHeader("Authorization"); 58 enum HttpHeader EXPECT = HttpHeader("Expect"); 59 enum HttpHeader FORWARDED = HttpHeader("Forwarded"); 60 enum HttpHeader FROM = HttpHeader("From"); 61 enum HttpHeader HOST = HttpHeader("Host"); 62 enum HttpHeader IF_MATCH = HttpHeader("If-Match"); 63 enum HttpHeader IF_MODIFIED_SINCE = HttpHeader("If-Modified-Since"); 64 enum HttpHeader IF_NONE_MATCH = HttpHeader("If-None-Match"); 65 enum HttpHeader IF_RANGE = HttpHeader("If-Range"); 66 enum HttpHeader IF_UNMODIFIED_SINCE = HttpHeader("If-Unmodified-Since"); 67 enum HttpHeader KEEP_ALIVE = HttpHeader("Keep-Alive"); 68 enum HttpHeader MAX_FORWARDS = HttpHeader("Max-Forwards"); 69 enum HttpHeader PROXY_AUTHORIZATION = HttpHeader("Proxy-Authorization"); 70 enum HttpHeader RANGE = HttpHeader("Range"); 71 enum HttpHeader REQUEST_RANGE = HttpHeader("Request-Range"); 72 enum HttpHeader REFERER = HttpHeader("Referer"); 73 enum HttpHeader TE = HttpHeader("TE"); 74 enum HttpHeader USER_AGENT = HttpHeader("User-Agent"); 75 enum HttpHeader X_FORWARDED_FOR = HttpHeader("X-Forwarded-For"); 76 enum HttpHeader X_FORWARDED_PROTO = HttpHeader("X-Forwarded-Proto"); 77 enum HttpHeader X_FORWARDED_SERVER = HttpHeader("X-Forwarded-Server"); 78 enum HttpHeader X_FORWARDED_HOST = HttpHeader("X-Forwarded-Host"); 79 80 /** 81 * Response Fields. 82 */ 83 enum HttpHeader ACCEPT_RANGES = HttpHeader("Accept-Ranges"); 84 enum HttpHeader AGE = HttpHeader("Age"); 85 enum HttpHeader ETAG = HttpHeader("ETag"); 86 enum HttpHeader LOCATION = HttpHeader("Location"); 87 enum HttpHeader PROXY_AUTHENTICATE = HttpHeader("Proxy-Authenticate"); 88 enum HttpHeader RETRY_AFTER = HttpHeader("Retry-After"); 89 enum HttpHeader SERVER = HttpHeader("Server"); 90 enum HttpHeader SERVLET_ENGINE = HttpHeader("Servlet-Engine"); 91 enum HttpHeader VARY = HttpHeader("Vary"); 92 enum HttpHeader WWW_AUTHENTICATE = HttpHeader("WWW-Authenticate"); 93 94 /** 95 * WebSocket Fields. 96 */ 97 enum HttpHeader ORIGIN = HttpHeader("Origin"); 98 enum HttpHeader SEC_WEBSOCKET_KEY = HttpHeader("Sec-WebSocket-Key"); 99 enum HttpHeader SEC_WEBSOCKET_VERSION = HttpHeader("Sec-WebSocket-Version"); 100 enum HttpHeader SEC_WEBSOCKET_EXTENSIONS = HttpHeader("Sec-WebSocket-Extensions"); 101 enum HttpHeader SEC_WEBSOCKET_SUBPROTOCOL = HttpHeader("Sec-WebSocket-Protocol"); 102 enum HttpHeader SEC_WEBSOCKET_ACCEPT = HttpHeader("Sec-WebSocket-Accept"); 103 104 /** 105 * Other Fields. 106 */ 107 enum HttpHeader COOKIE = HttpHeader("Cookie"); 108 enum HttpHeader SET_COOKIE = HttpHeader("Set-Cookie"); 109 enum HttpHeader SET_COOKIE2 = HttpHeader("Set-Cookie2"); 110 enum HttpHeader MIME_VERSION = HttpHeader("MIME-Version"); 111 enum HttpHeader IDENTITY = HttpHeader("identity"); 112 113 enum HttpHeader X_POWERED_BY = HttpHeader("X-Powered-By"); 114 enum HttpHeader HTTP2_SETTINGS = HttpHeader("HTTP2-Settings"); 115 116 enum HttpHeader STRICT_TRANSPORT_SECURITY = HttpHeader("Strict-Transport-Security"); 117 118 /** 119 * HTTP2 Fields. 120 */ 121 enum HttpHeader C_METHOD = HttpHeader(":method"); 122 enum HttpHeader C_SCHEME = HttpHeader(":scheme"); 123 enum HttpHeader C_AUTHORITY = HttpHeader(":authority"); 124 enum HttpHeader C_PATH = HttpHeader(":path"); 125 enum HttpHeader C_STATUS = HttpHeader(":status"); 126 127 enum HttpHeader UNKNOWN = HttpHeader("::UNKNOWN::"); 128 129 private __gshared HttpHeader[string] CACHE; 130 131 static bool exists(string name) { 132 return (name.toLower() in CACHE) !is null; 133 } 134 135 static HttpHeader get(string name) { 136 return CACHE.get(name.toLower(), HttpHeader.Null); 137 } 138 139 static int getCount() { 140 return cast(int) CACHE.length; 141 } 142 143 shared static this() { 144 int i = 0; 145 foreach (ref HttpHeader header; HttpHeader.values()) { 146 // header._ordinal = i++; 147 if (header != UNKNOWN) 148 CACHE[header.asString().toLower()] = header; 149 } 150 151 // trace(CACHE); 152 // foreach(ref HttpHeader header; HttpHeader.values()) 153 // { 154 // tracef("xx=%d", header._ordinal); 155 // } 156 } 157 158 mixin GetConstantValues!(HttpHeader); 159 160 private int _ordinal; 161 private string _string; 162 private byte[] _bytes; 163 private byte[] _bytesColonSpace; 164 // private ByteBuffer _buffer; 165 166 this(string s) { 167 _string = s; 168 _bytes = cast(byte[]) s.dup; // StringUtils.getBytes(s); 169 _bytesColonSpace = cast(byte[])(s ~ ": ").dup; 170 _ordinal = cast(int) hashOf(s.toLower()); 171 // _buffer = ByteBuffer.wrap(_bytes); 172 } 173 174 // ByteBuffer toBuffer() { 175 // return _buffer.asReadOnlyBuffer(); 176 // } 177 178 byte[] getBytes() { 179 return _bytes; 180 } 181 182 byte[] getBytesColonSpace() { 183 return _bytesColonSpace; 184 } 185 186 bool isSame(string s) const nothrow { 187 return std..string.icmp(_string, s) == 0; 188 } 189 190 string asString() const nothrow { 191 return _string; 192 } 193 194 string toString() { 195 return _string; 196 } 197 198 int ordinal() { 199 return _ordinal; 200 } 201 202 size_t toHash() @trusted nothrow { 203 return hashOf(_string); 204 } 205 206 bool opEquals(const HttpHeader h) nothrow { 207 return std..string.cmp(_string, h._string) == 0; 208 } 209 210 bool opEquals(ref const HttpHeader h) nothrow { 211 return std..string.cmp(_string, h._string) == 0; 212 } 213 214 // bool opEquals(const HttpHeader h) const nothrow{ 215 // return isSame(h.asString()); 216 // } 217 }