1 /******************************************************************************
2 
3     HTTP method name constants and enumerator
4 
5     TODO: add support for extension methods (when needed)
6 
7     Copyright:
8         Copyright (c) 2009-2016 dunnhumby Germany GmbH.
9         All rights reserved.
10 
11     License:
12         Boost Software License Version 1.0. See LICENSE_BOOST.txt for details.
13         Alternatively, this file may be distributed under the terms of the Tango
14         3-Clause BSD License (see LICENSE_BSD.txt for details).
15 
16  ******************************************************************************/
17 
18 module ocean.net.http.consts.HttpMethod;
19 
20 
21 import ocean.meta.types.Qualifiers;
22 
23 version (unittest) import ocean.core.Test;
24 
25 /******************************************************************************
26 
27     HTTP method enumerator
28 
29  ******************************************************************************/
30 
31 enum HttpMethod : ubyte
32 {
33     Undefined = 0,
34     Get,
35     Head,
36     Post,
37     Put,
38     Delete,
39     Trace,
40     Connect,
41     Options
42 }
43 
44 /******************************************************************************
45 
46     HTTP method name string constants and enumerator value association
47 
48  ******************************************************************************/
49 
50 struct HttpMethodNames
51 {
52     /**************************************************************************
53 
54         HTTP method name string constants
55 
56         @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.1.1
57 
58      **************************************************************************/
59 
60     enum istring[HttpMethod.max + 1] List =
61     [
62         HttpMethod.Undefined:  "",
63         HttpMethod.Get:        "GET",
64         HttpMethod.Head:       "HEAD",
65         HttpMethod.Post:       "POST",
66         HttpMethod.Put:        "PUT",
67         HttpMethod.Delete:     "DELETE",
68         HttpMethod.Trace:      "TRACE",
69         HttpMethod.Connect:    "CONNECT",
70         HttpMethod.Options:    "OPTIONS"
71     ];
72 
73     /**************************************************************************
74 
75         HTTP method enumerator value by name string
76 
77      **************************************************************************/
78 
79     private static HttpMethod[istring] methods_by_name;
80 
81     /**************************************************************************
82 
83         Obtains the HTTP method enumerator value by name string. Does not throw
84         an exception.
85 
86         Params:
87             name = HTTP method name string
88 
89          Returns:
90              HTTP method enumerator value corresponding to name string or
91              HttpMethod.Undefined if the name string is unknown.
92 
93      **************************************************************************/
94 
95     static HttpMethod opIndex ( cstring name )
96     {
97         HttpMethod* method = name? name in methods_by_name : null;
98 
99         return method? *method : HttpMethod.init;
100     }
101 
102     /**************************************************************************
103 
104         Obtains the HTTP method name string by enumerator value. Does not throw
105         an exception.
106 
107         Params:
108             method = HTTP method enumerator value
109 
110          Returns:
111              HTTP method name string corresponding to name method or null on
112              invalid value.
113 
114      **************************************************************************/
115 
116     static istring opIndex ( HttpMethod method )
117     {
118         static assert (method.max < List.length);
119         return (method <= method.max)? List[method] : null;
120     }
121 
122     /**************************************************************************
123 
124         Static constructor; populates the association map
125 
126      **************************************************************************/
127 
128     static this ( )
129     {
130         foreach (method, name; List)
131         {
132             methods_by_name[name] = cast (HttpMethod) method;
133         }
134 
135         methods_by_name.rehash;
136     }
137 }
138 
139 
140 unittest
141 {
142     static assert(HttpMethodNames.List[HttpMethod.Get]     == "GET");
143     static assert(HttpMethodNames.List[HttpMethod.Head]    == "HEAD");
144     static assert(HttpMethodNames.List[HttpMethod.Post]    == "POST");
145     static assert(HttpMethodNames.List[HttpMethod.Put]     == "PUT");
146     static assert(HttpMethodNames.List[HttpMethod.Delete]  == "DELETE");
147     static assert(HttpMethodNames.List[HttpMethod.Trace]   == "TRACE");
148     static assert(HttpMethodNames.List[HttpMethod.Connect] == "CONNECT");
149     static assert(HttpMethodNames.List[HttpMethod.Options] == "OPTIONS");
150 
151     static assert(!HttpMethodNames.List[HttpMethod.Undefined].length);
152 
153     test(HttpMethodNames[HttpMethod.Get]     == "GET");
154     test(HttpMethodNames[HttpMethod.Head]    == "HEAD");
155     test(HttpMethodNames[HttpMethod.Post]    == "POST");
156     test(HttpMethodNames[HttpMethod.Put]     == "PUT");
157     test(HttpMethodNames[HttpMethod.Delete]  == "DELETE");
158     test(HttpMethodNames[HttpMethod.Trace]   == "TRACE");
159     test(HttpMethodNames[HttpMethod.Connect] == "CONNECT");
160     test(HttpMethodNames[HttpMethod.Options] == "OPTIONS");
161 
162     test(!HttpMethodNames[HttpMethod.Undefined].length);
163 
164     test(HttpMethodNames[cast(HttpMethod)(HttpMethod.max + 1)] is null);
165 
166     test(HttpMethodNames["GET"]     == HttpMethod.Get);
167     test(HttpMethodNames["HEAD"]    == HttpMethod.Head);
168     test(HttpMethodNames["POST"]    == HttpMethod.Post);
169     test(HttpMethodNames["PUT"]     == HttpMethod.Put);
170     test(HttpMethodNames["DELETE"]  == HttpMethod.Delete);
171     test(HttpMethodNames["TRACE"]   == HttpMethod.Trace);
172     test(HttpMethodNames["CONNECT"] == HttpMethod.Connect);
173     test(HttpMethodNames["OPTIONS"] == HttpMethod.Options);
174 
175     test(HttpMethodNames["SPAM"]    == HttpMethod.Undefined);
176     test(HttpMethodNames[""]        == HttpMethod.Undefined);
177     test(HttpMethodNames[null]      == HttpMethod.Undefined);
178 }