Skip to content

Commit 8e3f3dd

Browse files
committed
change stop from cast to call
1 parent 525d843 commit 8e3f3dd

File tree

4 files changed

+207
-215
lines changed

4 files changed

+207
-215
lines changed

CHANGES.md

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
Version 2.7.0 released XXXX-XX-XX
22

3+
* `mochiweb_socket_server:stop/1` is now a synchronous
4+
call instead of an asynchronous cast
35
* `mochiweb_html:parse_tokens/1` (and `parse/1`) will now create a
46
html element to wrap documents that have a HTML5 doctype
57
(`<!doctype html>`) but no html element

src/mochiweb.erl

-205
Original file line numberDiff line numberDiff line change
@@ -74,208 +74,3 @@ ensure_started(App) ->
7474
{error, {already_started, App}} ->
7575
ok
7676
end.
77-
78-
%%
79-
%% Tests
80-
%%
81-
-ifdef(TEST).
82-
-include_lib("eunit/include/eunit.hrl").
83-
84-
-record(treq, {path, body= <<>>, xreply= <<>>}).
85-
86-
ssl_cert_opts() ->
87-
EbinDir = filename:dirname(code:which(?MODULE)),
88-
CertDir = filename:join([EbinDir, "..", "support", "test-materials"]),
89-
CertFile = filename:join(CertDir, "test_ssl_cert.pem"),
90-
KeyFile = filename:join(CertDir, "test_ssl_key.pem"),
91-
[{certfile, CertFile}, {keyfile, KeyFile}].
92-
93-
with_server(Transport, ServerFun, ClientFun) ->
94-
ServerOpts0 = [{ip, "127.0.0.1"}, {port, 0}, {loop, ServerFun}],
95-
ServerOpts = case Transport of
96-
plain ->
97-
ServerOpts0;
98-
ssl ->
99-
ServerOpts0 ++ [{ssl, true}, {ssl_opts, ssl_cert_opts()}]
100-
end,
101-
{ok, Server} = mochiweb_http:start_link(ServerOpts),
102-
Port = mochiweb_socket_server:get(Server, port),
103-
Res = (catch ClientFun(Transport, Port)),
104-
mochiweb_http:stop(Server),
105-
Res.
106-
107-
request_test() ->
108-
R = mochiweb_request:new(z, z, "/foo/bar/baz%20wibble+quux?qs=2", z, []),
109-
"/foo/bar/baz wibble quux" = R:get(path),
110-
ok.
111-
112-
-define(LARGE_TIMEOUT, 60).
113-
114-
single_http_GET_test() ->
115-
do_GET(plain, 1).
116-
117-
single_https_GET_test() ->
118-
do_GET(ssl, 1).
119-
120-
multiple_http_GET_test() ->
121-
do_GET(plain, 3).
122-
123-
multiple_https_GET_test() ->
124-
do_GET(ssl, 3).
125-
126-
hundred_http_GET_test_() -> % note the underscore
127-
{timeout, ?LARGE_TIMEOUT,
128-
fun() -> ?assertEqual(ok, do_GET(plain,100)) end}.
129-
130-
hundred_https_GET_test_() -> % note the underscore
131-
{timeout, ?LARGE_TIMEOUT,
132-
fun() -> ?assertEqual(ok, do_GET(ssl,100)) end}.
133-
134-
single_128_http_POST_test() ->
135-
do_POST(plain, 128, 1).
136-
137-
single_128_https_POST_test() ->
138-
do_POST(ssl, 128, 1).
139-
140-
single_2k_http_POST_test() ->
141-
do_POST(plain, 2048, 1).
142-
143-
single_2k_https_POST_test() ->
144-
do_POST(ssl, 2048, 1).
145-
146-
single_100k_http_POST_test() ->
147-
do_POST(plain, 102400, 1).
148-
149-
single_100k_https_POST_test() ->
150-
do_POST(ssl, 102400, 1).
151-
152-
multiple_100k_http_POST_test() ->
153-
do_POST(plain, 102400, 3).
154-
155-
multiple_100K_https_POST_test() ->
156-
do_POST(ssl, 102400, 3).
157-
158-
hundred_128_http_POST_test_() -> % note the underscore
159-
{timeout, ?LARGE_TIMEOUT,
160-
fun() -> ?assertEqual(ok, do_POST(plain, 128, 100)) end}.
161-
162-
hundred_128_https_POST_test_() -> % note the underscore
163-
{timeout, ?LARGE_TIMEOUT,
164-
fun() -> ?assertEqual(ok, do_POST(ssl, 128, 100)) end}.
165-
166-
do_GET(Transport, Times) ->
167-
PathPrefix = "/whatever/",
168-
ReplyPrefix = "You requested: ",
169-
ServerFun = fun (Req) ->
170-
Reply = ReplyPrefix ++ Req:get(path),
171-
Req:ok({"text/plain", Reply})
172-
end,
173-
TestReqs = [begin
174-
Path = PathPrefix ++ integer_to_list(N),
175-
ExpectedReply = list_to_binary(ReplyPrefix ++ Path),
176-
#treq{path=Path, xreply=ExpectedReply}
177-
end || N <- lists:seq(1, Times)],
178-
ClientFun = new_client_fun('GET', TestReqs),
179-
ok = with_server(Transport, ServerFun, ClientFun),
180-
ok.
181-
182-
do_POST(Transport, Size, Times) ->
183-
ServerFun = fun (Req) ->
184-
Body = Req:recv_body(),
185-
Headers = [{"Content-Type", "application/octet-stream"}],
186-
Req:respond({201, Headers, Body})
187-
end,
188-
TestReqs = [begin
189-
Path = "/stuff/" ++ integer_to_list(N),
190-
Body = crypto:rand_bytes(Size),
191-
#treq{path=Path, body=Body, xreply=Body}
192-
end || N <- lists:seq(1, Times)],
193-
ClientFun = new_client_fun('POST', TestReqs),
194-
ok = with_server(Transport, ServerFun, ClientFun),
195-
ok.
196-
197-
new_client_fun(Method, TestReqs) ->
198-
fun (Transport, Port) ->
199-
client_request(Transport, Port, Method, TestReqs)
200-
end.
201-
202-
client_request(Transport, Port, Method, TestReqs) ->
203-
Opts = [binary, {active, false}, {packet, http}],
204-
SockFun = case Transport of
205-
plain ->
206-
{ok, Socket} = gen_tcp:connect("127.0.0.1", Port, Opts),
207-
fun (recv) ->
208-
gen_tcp:recv(Socket, 0);
209-
({recv, Length}) ->
210-
gen_tcp:recv(Socket, Length);
211-
({send, Data}) ->
212-
gen_tcp:send(Socket, Data);
213-
({setopts, L}) ->
214-
inet:setopts(Socket, L)
215-
end;
216-
ssl ->
217-
{ok, Socket} = ssl:connect("127.0.0.1", Port, [{ssl_imp, new} | Opts]),
218-
fun (recv) ->
219-
ssl:recv(Socket, 0);
220-
({recv, Length}) ->
221-
ssl:recv(Socket, Length);
222-
({send, Data}) ->
223-
ssl:send(Socket, Data);
224-
({setopts, L}) ->
225-
ssl:setopts(Socket, L)
226-
end
227-
end,
228-
client_request(SockFun, Method, TestReqs).
229-
230-
client_request(SockFun, _Method, []) ->
231-
{the_end, {error, closed}} = {the_end, SockFun(recv)},
232-
ok;
233-
client_request(SockFun, Method,
234-
[#treq{path=Path, body=Body, xreply=ExReply} | Rest]) ->
235-
Request = [atom_to_list(Method), " ", Path, " HTTP/1.1\r\n",
236-
client_headers(Body, Rest =:= []),
237-
"\r\n",
238-
Body],
239-
ok = SockFun({send, Request}),
240-
case Method of
241-
'GET' ->
242-
{ok, {http_response, {1,1}, 200, "OK"}} = SockFun(recv);
243-
'POST' ->
244-
{ok, {http_response, {1,1}, 201, "Created"}} = SockFun(recv)
245-
end,
246-
ok = SockFun({setopts, [{packet, httph}]}),
247-
{ok, {http_header, _, 'Server', _, "MochiWeb" ++ _}} = SockFun(recv),
248-
{ok, {http_header, _, 'Date', _, _}} = SockFun(recv),
249-
{ok, {http_header, _, 'Content-Type', _, _}} = SockFun(recv),
250-
{ok, {http_header, _, 'Content-Length', _, ConLenStr}} = SockFun(recv),
251-
ContentLength = list_to_integer(ConLenStr),
252-
{ok, http_eoh} = SockFun(recv),
253-
ok = SockFun({setopts, [{packet, raw}]}),
254-
{payload, ExReply} = {payload, drain_reply(SockFun, ContentLength, <<>>)},
255-
ok = SockFun({setopts, [{packet, http}]}),
256-
client_request(SockFun, Method, Rest).
257-
258-
client_headers(Body, IsLastRequest) ->
259-
["Host: localhost\r\n",
260-
case Body of
261-
<<>> ->
262-
"";
263-
_ ->
264-
["Content-Type: application/octet-stream\r\n",
265-
"Content-Length: ", integer_to_list(byte_size(Body)), "\r\n"]
266-
end,
267-
case IsLastRequest of
268-
true ->
269-
"Connection: close\r\n";
270-
false ->
271-
""
272-
end].
273-
274-
drain_reply(_SockFun, 0, Acc) ->
275-
Acc;
276-
drain_reply(SockFun, Length, Acc) ->
277-
Sz = erlang:min(Length, 1024),
278-
{ok, B} = SockFun({recv, Sz}),
279-
drain_reply(SockFun, Length - Sz, <<Acc/bytes, B/bytes>>).
280-
281-
-endif.

src/mochiweb_socket_server.erl

+6-10
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,9 @@ set(Name, Property, _Value) ->
5959
error_logger:info_msg("?MODULE:set for ~p with ~p not implemented~n",
6060
[Name, Property]).
6161

62-
stop(Name) when is_atom(Name) ->
63-
gen_server:cast(Name, stop);
64-
stop(Pid) when is_pid(Pid) ->
65-
gen_server:cast(Pid, stop);
66-
stop({local, Name}) ->
67-
stop(Name);
68-
stop({global, Name}) ->
62+
stop(Name) when is_atom(Name) orelse is_pid(Name) ->
63+
gen_server:call(Name, stop);
64+
stop({Scope, Name}) when Scope =:= local orelse Scope =:= global ->
6965
stop(Name);
7066
stop(Options) ->
7167
State = parse_options(Options),
@@ -235,6 +231,8 @@ handle_call(Req, From, State) when ?is_old_state(State) ->
235231
handle_call({get, Property}, _From, State) ->
236232
Res = do_get(Property, State),
237233
{reply, Res, State};
234+
handle_call(stop, _From, State) ->
235+
{stop, normal, ok, State};
238236
handle_call(_Message, _From, State) ->
239237
Res = error,
240238
{reply, Res, State}.
@@ -259,9 +257,7 @@ handle_cast({set, profile_fun, ProfileFun}, State) ->
259257
_ ->
260258
State
261259
end,
262-
{noreply, State1};
263-
handle_cast(stop, State) ->
264-
{stop, normal, State}.
260+
{noreply, State1}.
265261

266262

267263
terminate(Reason, State) when ?is_old_state(State) ->

0 commit comments

Comments
 (0)