1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
|
%% This module echoes back the value the test is interested in.
-module(resp_h).
-export([init/2]).
init(Req, Opts) ->
do(cowboy_req:binding(key, Req), Req, Opts).
do(<<"set_resp_cookie3">>, Req0, Opts) ->
Req = case cowboy_req:binding(arg, Req0) of
undefined ->
cowboy_req:set_resp_cookie(<<"mycookie">>, "myvalue", Req0);
<<"multiple">> ->
Req1 = cowboy_req:set_resp_cookie(<<"mycookie">>, "myvalue", Req0),
cowboy_req:set_resp_cookie(<<"yourcookie">>, <<"yourvalue">>, Req1);
<<"overwrite">> ->
Req1 = cowboy_req:set_resp_cookie(<<"mycookie">>, "myvalue", Req0),
cowboy_req:set_resp_cookie(<<"mycookie">>, <<"overwrite">>, Req1)
end,
{ok, cowboy_req:reply(200, #{}, "OK", Req), Opts};
do(<<"set_resp_cookie4">>, Req0, Opts) ->
Req = cowboy_req:set_resp_cookie(<<"mycookie">>, "myvalue", Req0,
#{path => cowboy_req:path(Req0)}),
{ok, cowboy_req:reply(200, #{}, "OK", Req), Opts};
do(<<"set_resp_header">>, Req0, Opts) ->
Req = cowboy_req:set_resp_header(<<"content-type">>, <<"text/plain">>, Req0),
{ok, cowboy_req:reply(200, #{}, "OK", Req), Opts};
do(<<"set_resp_headers">>, Req0, Opts) ->
Req = cowboy_req:set_resp_headers(#{
<<"content-type">> => <<"text/plain">>,
<<"content-encoding">> => <<"compress">>
}, Req0),
{ok, cowboy_req:reply(200, #{}, "OK", Req), Opts};
do(<<"resp_header_defined">>, Req0, Opts) ->
Req1 = cowboy_req:set_resp_header(<<"content-type">>, <<"text/plain">>, Req0),
<<"text/plain">> = cowboy_req:resp_header(<<"content-type">>, Req1),
<<"text/plain">> = cowboy_req:resp_header(<<"content-type">>, Req1, default),
{ok, cowboy_req:reply(200, #{}, "OK", Req0), Opts};
do(<<"resp_header_default">>, Req, Opts) ->
undefined = cowboy_req:resp_header(<<"content-type">>, Req),
default = cowboy_req:resp_header(<<"content-type">>, Req, default),
{ok, cowboy_req:reply(200, #{}, "OK", Req), Opts};
do(<<"resp_headers">>, Req0, Opts) ->
Req1 = cowboy_req:set_resp_header(<<"server">>, <<"nginx">>, Req0),
Req = cowboy_req:set_resp_headers(#{
<<"content-type">> => <<"text/plain">>,
<<"content-encoding">> => <<"compress">>
}, Req1),
Headers = cowboy_req:resp_headers(Req),
true = maps:is_key(<<"server">>, Headers),
true = maps:is_key(<<"content-type">>, Headers),
true = maps:is_key(<<"content-encoding">>, Headers),
{ok, cowboy_req:reply(200, #{}, "OK", Req), Opts};
do(<<"resp_headers_empty">>, Req, Opts) ->
#{} = cowboy_req:resp_headers(Req),
{ok, cowboy_req:reply(200, #{}, "OK", Req), Opts};
do(<<"set_resp_body">>, Req0, Opts) ->
Arg = cowboy_req:binding(arg, Req0),
Req1 = case Arg of
<<"sendfile">> ->
AppFile = code:where_is_file("cowboy.app"),
cowboy_req:set_resp_body({sendfile, 0, filelib:file_size(AppFile), AppFile}, Req0);
_ ->
cowboy_req:set_resp_body(<<"OK">>, Req0)
end,
Req = case Arg of
<<"override">> ->
cowboy_req:reply(200, #{}, <<"OVERRIDE">>, Req1);
_ ->
cowboy_req:reply(200, Req1)
end,
{ok, Req, Opts};
do(<<"has_resp_header">>, Req0, Opts) ->
false = cowboy_req:has_resp_header(<<"content-type">>, Req0),
Req = cowboy_req:set_resp_header(<<"content-type">>, <<"text/plain">>, Req0),
true = cowboy_req:has_resp_header(<<"content-type">>, Req),
{ok, cowboy_req:reply(200, #{}, "OK", Req), Opts};
do(<<"has_resp_body">>, Req0, Opts) ->
case cowboy_req:binding(arg, Req0) of
<<"sendfile">> ->
%% @todo Cases for sendfile. Note that sendfile 0 is unallowed.
false = cowboy_req:has_resp_body(Req0),
Req = cowboy_req:set_resp_body({sendfile, 0, 10, code:where_is_file("cowboy.app")}, Req0),
true = cowboy_req:has_resp_body(Req),
{ok, cowboy_req:reply(200, #{}, <<"OK">>, Req), Opts};
undefined ->
false = cowboy_req:has_resp_body(Req0),
Req = cowboy_req:set_resp_body(<<"OK">>, Req0),
true = cowboy_req:has_resp_body(Req),
{ok, cowboy_req:reply(200, #{}, Req), Opts}
end;
do(<<"delete_resp_header">>, Req0, Opts) ->
false = cowboy_req:has_resp_header(<<"content-type">>, Req0),
Req1 = cowboy_req:set_resp_header(<<"content-type">>, <<"text/plain">>, Req0),
true = cowboy_req:has_resp_header(<<"content-type">>, Req1),
Req = cowboy_req:delete_resp_header(<<"content-type">>, Req1),
false = cowboy_req:has_resp_header(<<"content-type">>, Req),
{ok, cowboy_req:reply(200, #{}, "OK", Req), Opts};
do(<<"reply2">>, Req0, Opts) ->
Req = case cowboy_req:binding(arg, Req0) of
<<"binary">> ->
cowboy_req:reply(<<"200 GOOD">>, Req0);
<<"error">> ->
ct_helper:ignore(cowboy_req, reply, 4),
cowboy_req:reply(ok, Req0);
<<"twice">> ->
ct_helper:ignore(cowboy_req, reply, 4),
Req1 = cowboy_req:reply(200, Req0),
cowboy_req:reply(200, Req1);
Status ->
cowboy_req:reply(binary_to_integer(Status), Req0)
end,
{ok, Req, Opts};
do(<<"reply3">>, Req0, Opts) ->
Req = case cowboy_req:binding(arg, Req0) of
<<"error">> ->
ct_helper:ignore(cowboy_req, reply, 4),
cowboy_req:reply(200, ok, Req0);
Status ->
cowboy_req:reply(binary_to_integer(Status),
#{<<"content-type">> => <<"text/plain">>}, Req0)
end,
{ok, Req, Opts};
do(<<"reply4">>, Req0, Opts) ->
Req = case cowboy_req:binding(arg, Req0) of
<<"error">> ->
ct_helper:ignore(erlang, iolist_size, 1),
cowboy_req:reply(200, #{}, ok, Req0);
Status ->
cowboy_req:reply(binary_to_integer(Status), #{}, <<"OK">>, Req0)
end,
{ok, Req, Opts};
do(<<"stream_reply2">>, Req0, Opts) ->
Req = case cowboy_req:binding(arg, Req0) of
<<"binary">> ->
cowboy_req:stream_reply(<<"200 GOOD">>, Req0);
<<"error">> ->
ct_helper:ignore(cowboy_req, stream_reply, 3),
cowboy_req:stream_reply(ok, Req0);
Status ->
cowboy_req:stream_reply(binary_to_integer(Status), Req0)
end,
stream_body(Req),
{ok, Req, Opts};
do(<<"stream_reply3">>, Req0, Opts) ->
Req = case cowboy_req:binding(arg, Req0) of
<<"error">> ->
ct_helper:ignore(cowboy_req, stream_reply, 3),
cowboy_req:stream_reply(200, ok, Req0);
Status ->
cowboy_req:stream_reply(binary_to_integer(Status),
#{<<"content-type">> => <<"text/plain">>}, Req0)
end,
stream_body(Req),
{ok, Req, Opts};
do(<<"stream_body">>, Req, Opts) ->
%% Call stream_body without initiating streaming.
cowboy_req:stream_body(<<0:800000>>, fin, Req),
{ok, Req, Opts};
do(<<"push">>, Req, Opts) ->
case cowboy_req:binding(arg, Req) of
<<"method">> ->
cowboy_req:push("/static/style.css", #{<<"accept">> => <<"text/css">>}, Req,
#{method => <<"HEAD">>});
<<"origin">> ->
cowboy_req:push("/static/style.css", #{<<"accept">> => <<"text/css">>}, Req,
#{scheme => <<"ftp">>, host => <<"127.0.0.1">>, port => 21});
<<"qs">> ->
cowboy_req:push("/static/style.css", #{<<"accept">> => <<"text/css">>}, Req,
#{qs => <<"server=cowboy&version=2.0">>});
_ ->
cowboy_req:push("/static/style.css", #{<<"accept">> => <<"text/css">>}, Req),
%% The text/plain mime is not defined by default, so a 406 will be returned.
cowboy_req:push("/static/plain.txt", #{<<"accept">> => <<"text/plain">>}, Req)
end,
{ok, cowboy_req:reply(200, Req), Opts}.
stream_body(Req) ->
_ = [cowboy_req:stream_body(<<0:800000>>, nofin, Req) || _ <- lists:seq(1,9)],
cowboy_req:stream_body(<<0:800000>>, fin, Req).
|