Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 386 lines (338 sloc) 13.992 kb
da72255 Initial commit.
Loïc Hoguin authored
1 %% Copyright (c) 2011, Loïc Hoguin <essen@dev-extend.eu>
96a7706 @nox Make HTTP req accessors call themselves with their default default value
nox authored
2 %% Copyright (c) 2011, Anthony Ramine <nox@dev-extend.eu>
da72255 Initial commit.
Loïc Hoguin authored
3 %%
4 %% Permission to use, copy, modify, and/or distribute this software for any
5 %% purpose with or without fee is hereby granted, provided that the above
6 %% copyright notice and this permission notice appear in all copies.
7 %%
8 %% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 %% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 %% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 %% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 %% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 %% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 %% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
16 -module(cowboy_http_req).
408f167 Move the reply function to cowboy_http_req.
Loïc Hoguin authored
17
da72255 Initial commit.
Loïc Hoguin authored
18 -export([
408f167 Move the reply function to cowboy_http_req.
Loïc Hoguin authored
19 method/1, version/1, peer/1,
0ca8f13 @nox Implement path_info feature
nox authored
20 host/1, host_info/1, raw_host/1, port/1,
21 path/1, path_info/1, raw_path/1,
da72255 Initial commit.
Loïc Hoguin authored
22 qs_val/2, qs_val/3, qs_vals/1, raw_qs/1,
23 binding/2, binding/3, bindings/1,
24 header/2, header/3, headers/1
25 %% cookie/2, cookie/3, cookies/1 @todo
408f167 Move the reply function to cowboy_http_req.
Loïc Hoguin authored
26 ]). %% Request API.
27
28 -export([
06274cd Introduce cowboy_http_req:body_qs/1 for automated urlencoded body parsin...
Loïc Hoguin authored
29 body/1, body/2, body_qs/1
8b02992 Skip the request body if it hasn't been read by the handler.
Loïc Hoguin authored
30 ]). %% Request Body API.
31
32 -export([
420f5ba Add chunked reply support.
Loïc Hoguin authored
33 reply/4, chunked_reply/3, chunk/2
408f167 Move the reply function to cowboy_http_req.
Loïc Hoguin authored
34 ]). %% Response API.
da72255 Initial commit.
Loïc Hoguin authored
35
919fa63 Add function cowboy_http_req:compact/1 to regain memory.
Loïc Hoguin authored
36 -export([
37 compact/1
38 ]). %% Misc API.
39
da72255 Initial commit.
Loïc Hoguin authored
40 -include("include/http.hrl").
41 -include_lib("eunit/include/eunit.hrl").
42
408f167 Move the reply function to cowboy_http_req.
Loïc Hoguin authored
43 %% Request API.
da72255 Initial commit.
Loïc Hoguin authored
44
3e55cb6 Refresh the type specifications.
Loïc Hoguin authored
45 -spec method(#http_req{}) -> {http_method(), #http_req{}}.
da72255 Initial commit.
Loïc Hoguin authored
46 method(Req) ->
47 {Req#http_req.method, Req}.
48
3e55cb6 Refresh the type specifications.
Loïc Hoguin authored
49 -spec version(#http_req{}) -> {http_version(), #http_req{}}.
da72255 Initial commit.
Loïc Hoguin authored
50 version(Req) ->
51 {Req#http_req.version, Req}.
52
3e55cb6 Refresh the type specifications.
Loïc Hoguin authored
53 -spec peer(#http_req{}) -> {{inet:ip_address(), inet:ip_port()}, #http_req{}}.
d69d0ad Lazy-retrieve the peer name and port to avoid wasting time each request.
Loïc Hoguin authored
54 peer(Req=#http_req{socket=Socket, transport=Transport, peer=undefined}) ->
55 {ok, Peer} = Transport:peername(Socket),
56 {Peer, Req#http_req{peer=Peer}};
da72255 Initial commit.
Loïc Hoguin authored
57 peer(Req) ->
58 {Req#http_req.peer, Req}.
59
3e55cb6 Refresh the type specifications.
Loïc Hoguin authored
60 -spec host(#http_req{}) -> {cowboy_dispatcher:path_tokens(), #http_req{}}.
da72255 Initial commit.
Loïc Hoguin authored
61 host(Req) ->
62 {Req#http_req.host, Req}.
63
3e55cb6 Refresh the type specifications.
Loïc Hoguin authored
64 -spec host_info(#http_req{})
65 -> {cowboy_dispatcher:path_tokens() | undefined, #http_req{}}.
0ca8f13 @nox Implement path_info feature
nox authored
66 host_info(Req) ->
67 {Req#http_req.host_info, Req}.
68
3e55cb6 Refresh the type specifications.
Loïc Hoguin authored
69 -spec raw_host(#http_req{}) -> {binary(), #http_req{}}.
da72255 Initial commit.
Loïc Hoguin authored
70 raw_host(Req) ->
71 {Req#http_req.raw_host, Req}.
72
3e55cb6 Refresh the type specifications.
Loïc Hoguin authored
73 -spec port(#http_req{}) -> {inet:ip_port(), #http_req{}}.
6c1f73c Add cowboy_http_req:port/1.
Loïc Hoguin authored
74 port(Req) ->
75 {Req#http_req.port, Req}.
76
3e55cb6 Refresh the type specifications.
Loïc Hoguin authored
77 -spec path(#http_req{}) -> {cowboy_dispatcher:path_tokens(), #http_req{}}.
da72255 Initial commit.
Loïc Hoguin authored
78 path(Req) ->
79 {Req#http_req.path, Req}.
80
3e55cb6 Refresh the type specifications.
Loïc Hoguin authored
81 -spec path_info(#http_req{})
82 -> {cowboy_dispatcher:path_tokens() | undefined, #http_req{}}.
0ca8f13 @nox Implement path_info feature
nox authored
83 path_info(Req) ->
84 {Req#http_req.path_info, Req}.
85
3e55cb6 Refresh the type specifications.
Loïc Hoguin authored
86 -spec raw_path(#http_req{}) -> {binary(), #http_req{}}.
da72255 Initial commit.
Loïc Hoguin authored
87 raw_path(Req) ->
88 {Req#http_req.raw_path, Req}.
89
3e55cb6 Refresh the type specifications.
Loïc Hoguin authored
90 -spec qs_val(binary(), #http_req{})
91 -> {binary() | true | undefined, #http_req{}}.
6b1fb5f Fix the @equiv EDoc tags
Loïc Hoguin authored
92 %% @equiv qs_val(Name, Req, undefined)
da72255 Initial commit.
Loïc Hoguin authored
93 qs_val(Name, Req) ->
1010348 @nox Make the default value the last parameter of HTTP req accessors
nox authored
94 qs_val(Name, Req, undefined).
da72255 Initial commit.
Loïc Hoguin authored
95
3e55cb6 Refresh the type specifications.
Loïc Hoguin authored
96 -spec qs_val(binary(), #http_req{}, Default)
97 -> {binary() | true | Default, #http_req{}} when Default::any().
1010348 @nox Make the default value the last parameter of HTTP req accessors
nox authored
98 qs_val(Name, Req=#http_req{raw_qs=RawQs, qs_vals=undefined}, Default) ->
da72255 Initial commit.
Loïc Hoguin authored
99 QsVals = parse_qs(RawQs),
1010348 @nox Make the default value the last parameter of HTTP req accessors
nox authored
100 qs_val(Name, Req#http_req{qs_vals=QsVals}, Default);
101 qs_val(Name, Req, Default) ->
96a7706 @nox Make HTTP req accessors call themselves with their default default value
nox authored
102 case lists:keyfind(Name, 1, Req#http_req.qs_vals) of
103 {Name, Value} -> {Value, Req};
104 false -> {Default, Req}
105 end.
da72255 Initial commit.
Loïc Hoguin authored
106
3e55cb6 Refresh the type specifications.
Loïc Hoguin authored
107 -spec qs_vals(#http_req{}) -> {list({binary(), binary() | true}), #http_req{}}.
da72255 Initial commit.
Loïc Hoguin authored
108 qs_vals(Req=#http_req{raw_qs=RawQs, qs_vals=undefined}) ->
109 QsVals = parse_qs(RawQs),
110 qs_vals(Req#http_req{qs_vals=QsVals});
111 qs_vals(Req=#http_req{qs_vals=QsVals}) ->
112 {QsVals, Req}.
113
3e55cb6 Refresh the type specifications.
Loïc Hoguin authored
114 -spec raw_qs(#http_req{}) -> {binary(), #http_req{}}.
da72255 Initial commit.
Loïc Hoguin authored
115 raw_qs(Req) ->
116 {Req#http_req.raw_qs, Req}.
117
3e55cb6 Refresh the type specifications.
Loïc Hoguin authored
118 -spec binding(atom(), #http_req{}) -> {binary() | undefined, #http_req{}}.
6b1fb5f Fix the @equiv EDoc tags
Loïc Hoguin authored
119 %% @equiv binding(Name, Req, undefined)
da72255 Initial commit.
Loïc Hoguin authored
120 binding(Name, Req) ->
1010348 @nox Make the default value the last parameter of HTTP req accessors
nox authored
121 binding(Name, Req, undefined).
96a7706 @nox Make HTTP req accessors call themselves with their default default value
nox authored
122
3e55cb6 Refresh the type specifications.
Loïc Hoguin authored
123 -spec binding(atom(), #http_req{}, Default)
124 -> {binary() | Default, #http_req{}} when Default::any().
1010348 @nox Make the default value the last parameter of HTTP req accessors
nox authored
125 binding(Name, Req, Default) ->
150723c Return undefined instead of failing or returning "" when a value doesn't...
Loïc Hoguin authored
126 case lists:keyfind(Name, 1, Req#http_req.bindings) of
127 {Name, Value} -> {Value, Req};
96a7706 @nox Make HTTP req accessors call themselves with their default default value
nox authored
128 false -> {Default, Req}
150723c Return undefined instead of failing or returning "" when a value doesn't...
Loïc Hoguin authored
129 end.
da72255 Initial commit.
Loïc Hoguin authored
130
3e55cb6 Refresh the type specifications.
Loïc Hoguin authored
131 -spec bindings(#http_req{}) -> {list({atom(), binary()}), #http_req{}}.
da72255 Initial commit.
Loïc Hoguin authored
132 bindings(Req) ->
133 {Req#http_req.bindings, Req}.
134
3e55cb6 Refresh the type specifications.
Loïc Hoguin authored
135 -spec header(atom() | binary(), #http_req{})
136 -> {binary() | undefined, #http_req{}}.
6b1fb5f Fix the @equiv EDoc tags
Loïc Hoguin authored
137 %% @equiv header(Name, Req, undefined)
da72255 Initial commit.
Loïc Hoguin authored
138 header(Name, Req) ->
1010348 @nox Make the default value the last parameter of HTTP req accessors
nox authored
139 header(Name, Req, undefined).
96a7706 @nox Make HTTP req accessors call themselves with their default default value
nox authored
140
3e55cb6 Refresh the type specifications.
Loïc Hoguin authored
141 -spec header(atom() | binary(), #http_req{}, Default)
142 -> {binary() | Default, #http_req{}} when Default::any().
1010348 @nox Make the default value the last parameter of HTTP req accessors
nox authored
143 header(Name, Req, Default) ->
8b02992 Skip the request body if it hasn't been read by the handler.
Loïc Hoguin authored
144 case lists:keyfind(Name, 1, Req#http_req.headers) of
145 {Name, Value} -> {Value, Req};
96a7706 @nox Make HTTP req accessors call themselves with their default default value
nox authored
146 false -> {Default, Req}
8b02992 Skip the request body if it hasn't been read by the handler.
Loïc Hoguin authored
147 end.
da72255 Initial commit.
Loïc Hoguin authored
148
3e55cb6 Refresh the type specifications.
Loïc Hoguin authored
149 -spec headers(#http_req{}) -> {http_headers(), #http_req{}}.
da72255 Initial commit.
Loïc Hoguin authored
150 headers(Req) ->
151 {Req#http_req.headers, Req}.
152
8b02992 Skip the request body if it hasn't been read by the handler.
Loïc Hoguin authored
153 %% Request Body API.
154
155 %% @todo We probably want to allow a max length.
3e55cb6 Refresh the type specifications.
Loïc Hoguin authored
156 -spec body(#http_req{}) -> {ok, binary(), #http_req{}} | {error, atom()}.
7cacb88 Introduce cowboy_http_req:body/1 to read the full request body.
Loïc Hoguin authored
157 body(Req) ->
158 {Length, Req2} = cowboy_http_req:header('Content-Length', Req),
159 case Length of
4eeabe5 @nox Fix cowboy_http_req:body with regard to the new accessors default value
nox authored
160 undefined -> {error, badarg};
7cacb88 Introduce cowboy_http_req:body/1 to read the full request body.
Loïc Hoguin authored
161 _Any ->
29e71cf Switch the HTTP protocol to use binary packets instead of lists.
Loïc Hoguin authored
162 Length2 = list_to_integer(binary_to_list(Length)),
7cacb88 Introduce cowboy_http_req:body/1 to read the full request body.
Loïc Hoguin authored
163 body(Length2, Req2)
164 end.
165
166 %% @todo We probably want to configure the timeout.
3e55cb6 Refresh the type specifications.
Loïc Hoguin authored
167 -spec body(non_neg_integer(), #http_req{})
168 -> {ok, binary(), #http_req{}} | {error, atom()}.
29e71cf Switch the HTTP protocol to use binary packets instead of lists.
Loïc Hoguin authored
169 body(Length, Req=#http_req{body_state=waiting, buffer=Buffer})
170 when Length =:= byte_size(Buffer) ->
171 {ok, Buffer, Req#http_req{body_state=done, buffer= <<>>}};
3865415 Boring 80-col change.
Loïc Hoguin authored
172 body(Length, Req=#http_req{socket=Socket, transport=Transport,
29e71cf Switch the HTTP protocol to use binary packets instead of lists.
Loïc Hoguin authored
173 body_state=waiting, buffer=Buffer}) when Length > byte_size(Buffer) ->
174 case Transport:recv(Socket, Length - byte_size(Buffer), 5000) of
3e55cb6 Refresh the type specifications.
Loïc Hoguin authored
175 {ok, Body} -> {ok, << Buffer/binary, Body/binary >>,
176 Req#http_req{body_state=done, buffer= <<>>}};
8b02992 Skip the request body if it hasn't been read by the handler.
Loïc Hoguin authored
177 {error, Reason} -> {error, Reason}
178 end.
179
3e55cb6 Refresh the type specifications.
Loïc Hoguin authored
180 -spec body_qs(#http_req{}) -> {list({binary(), binary() | true}), #http_req{}}.
06274cd Introduce cowboy_http_req:body_qs/1 for automated urlencoded body parsin...
Loïc Hoguin authored
181 body_qs(Req) ->
182 {ok, Body, Req2} = body(Req),
29e71cf Switch the HTTP protocol to use binary packets instead of lists.
Loïc Hoguin authored
183 {parse_qs(Body), Req2}.
06274cd Introduce cowboy_http_req:body_qs/1 for automated urlencoded body parsin...
Loïc Hoguin authored
184
408f167 Move the reply function to cowboy_http_req.
Loïc Hoguin authored
185 %% Response API.
186
3e55cb6 Refresh the type specifications.
Loïc Hoguin authored
187 -spec reply(http_status(), http_headers(), iodata(), #http_req{})
188 -> {ok, #http_req{}}.
408f167 Move the reply function to cowboy_http_req.
Loïc Hoguin authored
189 reply(Code, Headers, Body, Req=#http_req{socket=Socket,
71b31ce Make sure we can only reply to an HTTP request inside Handler:handle.
Loïc Hoguin authored
190 transport=Transport, connection=Connection,
191 resp_state=waiting}) ->
18582a7 Separate building the response head from replying.
Loïc Hoguin authored
192 Head = response_head(Code, Headers, [
29e71cf Switch the HTTP protocol to use binary packets instead of lists.
Loïc Hoguin authored
193 {<<"Connection">>, atom_to_connection(Connection)},
48f7cd3 @nox Allow atoms for response header names
nox authored
194 {<<"Content-Length">>,
95006c3 Add the required Date header in the HTTP replies.
Loïc Hoguin authored
195 list_to_binary(integer_to_list(iolist_size(Body)))},
c7069e7 Add the Server header in the HTTP replies.
Loïc Hoguin authored
196 {<<"Date">>, cowboy_clock:rfc1123()},
197 {<<"Server">>, <<"Cowboy">>}
18582a7 Separate building the response head from replying.
Loïc Hoguin authored
198 ]),
199 Transport:send(Socket, [Head, Body]),
71b31ce Make sure we can only reply to an HTTP request inside Handler:handle.
Loïc Hoguin authored
200 {ok, Req#http_req{resp_state=done}}.
408f167 Move the reply function to cowboy_http_req.
Loïc Hoguin authored
201
3e55cb6 Refresh the type specifications.
Loïc Hoguin authored
202 -spec chunked_reply(http_status(), http_headers(), #http_req{})
203 -> {ok, #http_req{}}.
420f5ba Add chunked reply support.
Loïc Hoguin authored
204 chunked_reply(Code, Headers, Req=#http_req{socket=Socket, transport=Transport,
205 resp_state=waiting}) ->
206 Head = response_head(Code, Headers, [
207 {<<"Connection">>, <<"close">>},
95006c3 Add the required Date header in the HTTP replies.
Loïc Hoguin authored
208 {<<"Transfer-Encoding">>, <<"chunked">>},
c7069e7 Add the Server header in the HTTP replies.
Loïc Hoguin authored
209 {<<"Date">>, cowboy_clock:rfc1123()},
210 {<<"Server">>, <<"Cowboy">>}
420f5ba Add chunked reply support.
Loïc Hoguin authored
211 ]),
212 Transport:send(Socket, Head),
213 {ok, Req#http_req{resp_state=chunks}}.
214
3e55cb6 Refresh the type specifications.
Loïc Hoguin authored
215 -spec chunk(iodata(), #http_req{}) -> ok.
420f5ba Add chunked reply support.
Loïc Hoguin authored
216 chunk(Data, #http_req{socket=Socket, transport=Transport, resp_state=chunks}) ->
217 Transport:send(Socket, [integer_to_list(iolist_size(Data), 16),
218 <<"\r\n">>, Data, <<"\r\n">>]).
219
919fa63 Add function cowboy_http_req:compact/1 to regain memory.
Loïc Hoguin authored
220 %% Misc API.
221
222 -spec compact(#http_req{}) -> #http_req{}.
223 compact(Req) ->
224 Req#http_req{host=undefined, host_info=undefined, path=undefined,
225 path_info=undefined, qs_vals=undefined, raw_qs=undefined,
226 bindings=undefined, headers=[]}.
227
da72255 Initial commit.
Loïc Hoguin authored
228 %% Internal.
229
3e55cb6 Refresh the type specifications.
Loïc Hoguin authored
230 -spec parse_qs(binary()) -> list({binary(), binary() | true}).
29e71cf Switch the HTTP protocol to use binary packets instead of lists.
Loïc Hoguin authored
231 parse_qs(<<>>) ->
232 [];
da72255 Initial commit.
Loïc Hoguin authored
233 parse_qs(Qs) ->
29e71cf Switch the HTTP protocol to use binary packets instead of lists.
Loïc Hoguin authored
234 Tokens = binary:split(Qs, <<"&">>, [global, trim]),
235 [case binary:split(Token, <<"=">>) of
236 [Token] -> {Token, true};
237 [Name, Value] -> {Name, Value}
da72255 Initial commit.
Loïc Hoguin authored
238 end || Token <- Tokens].
239
3e55cb6 Refresh the type specifications.
Loïc Hoguin authored
240 -spec response_head(http_status(), http_headers(), http_headers()) -> iolist().
18582a7 Separate building the response head from replying.
Loïc Hoguin authored
241 response_head(Code, Headers, DefaultHeaders) ->
242 StatusLine = <<"HTTP/1.1 ", (status(Code))/binary, "\r\n">>,
243 Headers2 = [{header_to_binary(Key), Value} || {Key, Value} <- Headers],
244 Headers3 = lists:keysort(1, Headers2),
245 Headers4 = lists:ukeymerge(1, Headers3, DefaultHeaders),
246 Headers5 = [<< Key/binary, ": ", Value/binary, "\r\n" >>
247 || {Key, Value} <- Headers4],
248 [StatusLine, Headers5, <<"\r\n">>].
249
3e55cb6 Refresh the type specifications.
Loïc Hoguin authored
250 -spec atom_to_connection(keepalive) -> <<_:80>>;
251 (close) -> <<_:40>>.
408f167 Move the reply function to cowboy_http_req.
Loïc Hoguin authored
252 atom_to_connection(keepalive) ->
29e71cf Switch the HTTP protocol to use binary packets instead of lists.
Loïc Hoguin authored
253 <<"keep-alive">>;
408f167 Move the reply function to cowboy_http_req.
Loïc Hoguin authored
254 atom_to_connection(close) ->
29e71cf Switch the HTTP protocol to use binary packets instead of lists.
Loïc Hoguin authored
255 <<"close">>.
256
3e55cb6 Refresh the type specifications.
Loïc Hoguin authored
257 -spec status(http_status()) -> binary().
29e71cf Switch the HTTP protocol to use binary packets instead of lists.
Loïc Hoguin authored
258 status(100) -> <<"100 Continue">>;
259 status(101) -> <<"101 Switching Protocols">>;
260 status(102) -> <<"102 Processing">>;
261 status(200) -> <<"200 OK">>;
262 status(201) -> <<"201 Created">>;
263 status(202) -> <<"202 Accepted">>;
264 status(203) -> <<"203 Non-Authoritative Information">>;
265 status(204) -> <<"204 No Content">>;
266 status(205) -> <<"205 Reset Content">>;
267 status(206) -> <<"206 Partial Content">>;
268 status(207) -> <<"207 Multi-Status">>;
269 status(226) -> <<"226 IM Used">>;
270 status(300) -> <<"300 Multiple Choices">>;
271 status(301) -> <<"301 Moved Permanently">>;
272 status(302) -> <<"302 Found">>;
273 status(303) -> <<"303 See Other">>;
274 status(304) -> <<"304 Not Modified">>;
275 status(305) -> <<"305 Use Proxy">>;
276 status(306) -> <<"306 Switch Proxy">>;
277 status(307) -> <<"307 Temporary Redirect">>;
278 status(400) -> <<"400 Bad Request">>;
279 status(401) -> <<"401 Unauthorized">>;
280 status(402) -> <<"402 Payment Required">>;
281 status(403) -> <<"403 Forbidden">>;
282 status(404) -> <<"404 Not Found">>;
283 status(405) -> <<"405 Method Not Allowed">>;
284 status(406) -> <<"406 Not Acceptable">>;
285 status(407) -> <<"407 Proxy Authentication Required">>;
286 status(408) -> <<"408 Request Timeout">>;
287 status(409) -> <<"409 Conflict">>;
288 status(410) -> <<"410 Gone">>;
289 status(411) -> <<"411 Length Required">>;
290 status(412) -> <<"412 Precondition Failed">>;
291 status(413) -> <<"413 Request Entity Too Large">>;
292 status(414) -> <<"414 Request-URI Too Long">>;
293 status(415) -> <<"415 Unsupported Media Type">>;
294 status(416) -> <<"416 Requested Range Not Satisfiable">>;
295 status(417) -> <<"417 Expectation Failed">>;
296 status(418) -> <<"418 I'm a teapot">>;
297 status(422) -> <<"422 Unprocessable Entity">>;
298 status(423) -> <<"423 Locked">>;
299 status(424) -> <<"424 Failed Dependency">>;
300 status(425) -> <<"425 Unordered Collection">>;
301 status(426) -> <<"426 Upgrade Required">>;
302 status(500) -> <<"500 Internal Server Error">>;
303 status(501) -> <<"501 Not Implemented">>;
304 status(502) -> <<"502 Bad Gateway">>;
305 status(503) -> <<"503 Service Unavailable">>;
306 status(504) -> <<"504 Gateway Timeout">>;
307 status(505) -> <<"505 HTTP Version Not Supported">>;
308 status(506) -> <<"506 Variant Also Negotiates">>;
309 status(507) -> <<"507 Insufficient Storage">>;
310 status(510) -> <<"510 Not Extended">>;
311 status(B) when is_binary(B) -> B.
408f167 Move the reply function to cowboy_http_req.
Loïc Hoguin authored
312
48f7cd3 @nox Allow atoms for response header names
nox authored
313 -spec header_to_binary(http_header()) -> binary().
314 header_to_binary('Cache-Control') -> <<"Cache-Control">>;
315 header_to_binary('Connection') -> <<"Connection">>;
316 header_to_binary('Date') -> <<"Date">>;
317 header_to_binary('Pragma') -> <<"Pragma">>;
318 header_to_binary('Transfer-Encoding') -> <<"Transfer-Encoding">>;
319 header_to_binary('Upgrade') -> <<"Upgrade">>;
320 header_to_binary('Via') -> <<"Via">>;
321 header_to_binary('Accept') -> <<"Accept">>;
322 header_to_binary('Accept-Charset') -> <<"Accept-Charset">>;
323 header_to_binary('Accept-Encoding') -> <<"Accept-Encoding">>;
324 header_to_binary('Accept-Language') -> <<"Accept-Language">>;
325 header_to_binary('Authorization') -> <<"Authorization">>;
326 header_to_binary('From') -> <<"From">>;
327 header_to_binary('Host') -> <<"Host">>;
328 header_to_binary('If-Modified-Since') -> <<"If-Modified-Since">>;
329 header_to_binary('If-Match') -> <<"If-Match">>;
330 header_to_binary('If-None-Match') -> <<"If-None-Match">>;
331 header_to_binary('If-Range') -> <<"If-Range">>;
332 header_to_binary('If-Unmodified-Since') -> <<"If-Unmodified-Since">>;
333 header_to_binary('Max-Forwards') -> <<"Max-Forwards">>;
334 header_to_binary('Proxy-Authorization') -> <<"Proxy-Authorization">>;
335 header_to_binary('Range') -> <<"Range">>;
336 header_to_binary('Referer') -> <<"Referer">>;
337 header_to_binary('User-Agent') -> <<"User-Agent">>;
338 header_to_binary('Age') -> <<"Age">>;
339 header_to_binary('Location') -> <<"Location">>;
340 header_to_binary('Proxy-Authenticate') -> <<"Proxy-Authenticate">>;
341 header_to_binary('Public') -> <<"Public">>;
342 header_to_binary('Retry-After') -> <<"Retry-After">>;
343 header_to_binary('Server') -> <<"Server">>;
344 header_to_binary('Vary') -> <<"Vary">>;
345 header_to_binary('Warning') -> <<"Warning">>;
346 header_to_binary('Www-Authenticate') -> <<"Www-Authenticate">>;
347 header_to_binary('Allow') -> <<"Allow">>;
348 header_to_binary('Content-Base') -> <<"Content-Base">>;
349 header_to_binary('Content-Encoding') -> <<"Content-Encoding">>;
350 header_to_binary('Content-Language') -> <<"Content-Language">>;
351 header_to_binary('Content-Length') -> <<"Content-Length">>;
352 header_to_binary('Content-Location') -> <<"Content-Location">>;
353 header_to_binary('Content-Md5') -> <<"Content-Md5">>;
354 header_to_binary('Content-Range') -> <<"Content-Range">>;
355 header_to_binary('Content-Type') -> <<"Content-Type">>;
356 header_to_binary('Etag') -> <<"Etag">>;
357 header_to_binary('Expires') -> <<"Expires">>;
358 header_to_binary('Last-Modified') -> <<"Last-Modified">>;
359 header_to_binary('Accept-Ranges') -> <<"Accept-Ranges">>;
360 header_to_binary('Set-Cookie') -> <<"Set-Cookie">>;
361 header_to_binary('Set-Cookie2') -> <<"Set-Cookie2">>;
362 header_to_binary('X-Forwarded-For') -> <<"X-Forwarded-For">>;
363 header_to_binary('Cookie') -> <<"Cookie">>;
364 header_to_binary('Keep-Alive') -> <<"Keep-Alive">>;
365 header_to_binary('Proxy-Connection') -> <<"Proxy-Connection">>;
366 header_to_binary(B) when is_binary(B) -> B.
367
da72255 Initial commit.
Loïc Hoguin authored
368 %% Tests.
369
370 -ifdef(TEST).
371
372 parse_qs_test_() ->
373 %% {Qs, Result}
374 Tests = [
29e71cf Switch the HTTP protocol to use binary packets instead of lists.
Loïc Hoguin authored
375 {<<"">>, []},
376 {<<"a=b">>, [{<<"a">>, <<"b">>}]},
377 {<<"aaa=bbb">>, [{<<"aaa">>, <<"bbb">>}]},
378 {<<"a&b">>, [{<<"a">>, true}, {<<"b">>, true}]},
3e55cb6 Refresh the type specifications.
Loïc Hoguin authored
379 {<<"a=b&c&d=e">>, [{<<"a">>, <<"b">>},
380 {<<"c">>, true}, {<<"d">>, <<"e">>}]},
29e71cf Switch the HTTP protocol to use binary packets instead of lists.
Loïc Hoguin authored
381 {<<"a=b=c=d=e&f=g">>, [{<<"a">>, <<"b=c=d=e">>}, {<<"f">>, <<"g">>}]}
da72255 Initial commit.
Loïc Hoguin authored
382 ],
383 [{Qs, fun() -> R = parse_qs(Qs) end} || {Qs, R} <- Tests].
384
385 -endif.
Something went wrong with that request. Please try again.