You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by be...@apache.org on 2014/02/13 17:06:04 UTC
[09/50] mochiweb commit: updated refs/heads/import-upstream to 8eb1f22
change stop from cast to call
Project: http://git-wip-us.apache.org/repos/asf/couchdb-mochiweb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-mochiweb/commit/8e3f3dd3
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-mochiweb/tree/8e3f3dd3
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-mochiweb/diff/8e3f3dd3
Branch: refs/heads/import-upstream
Commit: 8e3f3dd36b9668d9422f9adef14b509c39f6bb44
Parents: 525d843
Author: Bob Ippolito <bo...@redivi.com>
Authored: Wed May 29 15:24:22 2013 -0700
Committer: Bob Ippolito <bo...@redivi.com>
Committed: Wed May 29 15:24:22 2013 -0700
----------------------------------------------------------------------
CHANGES.md | 2 +
src/mochiweb.erl | 205 ------------------------------------
src/mochiweb_socket_server.erl | 16 ++-
test/mochiweb_tests.erl | 199 ++++++++++++++++++++++++++++++++++
4 files changed, 207 insertions(+), 215 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb-mochiweb/blob/8e3f3dd3/CHANGES.md
----------------------------------------------------------------------
diff --git a/CHANGES.md b/CHANGES.md
index 065f19f..06a8b5f 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,5 +1,7 @@
Version 2.7.0 released XXXX-XX-XX
+* `mochiweb_socket_server:stop/1` is now a synchronous
+ call instead of an asynchronous cast
* `mochiweb_html:parse_tokens/1` (and `parse/1`) will now create a
html element to wrap documents that have a HTML5 doctype
(`<!doctype html>`) but no html element
http://git-wip-us.apache.org/repos/asf/couchdb-mochiweb/blob/8e3f3dd3/src/mochiweb.erl
----------------------------------------------------------------------
diff --git a/src/mochiweb.erl b/src/mochiweb.erl
index 250beb5..f597c73 100644
--- a/src/mochiweb.erl
+++ b/src/mochiweb.erl
@@ -74,208 +74,3 @@ ensure_started(App) ->
{error, {already_started, App}} ->
ok
end.
-
-%%
-%% Tests
-%%
--ifdef(TEST).
--include_lib("eunit/include/eunit.hrl").
-
--record(treq, {path, body= <<>>, xreply= <<>>}).
-
-ssl_cert_opts() ->
- EbinDir = filename:dirname(code:which(?MODULE)),
- CertDir = filename:join([EbinDir, "..", "support", "test-materials"]),
- CertFile = filename:join(CertDir, "test_ssl_cert.pem"),
- KeyFile = filename:join(CertDir, "test_ssl_key.pem"),
- [{certfile, CertFile}, {keyfile, KeyFile}].
-
-with_server(Transport, ServerFun, ClientFun) ->
- ServerOpts0 = [{ip, "127.0.0.1"}, {port, 0}, {loop, ServerFun}],
- ServerOpts = case Transport of
- plain ->
- ServerOpts0;
- ssl ->
- ServerOpts0 ++ [{ssl, true}, {ssl_opts, ssl_cert_opts()}]
- end,
- {ok, Server} = mochiweb_http:start_link(ServerOpts),
- Port = mochiweb_socket_server:get(Server, port),
- Res = (catch ClientFun(Transport, Port)),
- mochiweb_http:stop(Server),
- Res.
-
-request_test() ->
- R = mochiweb_request:new(z, z, "/foo/bar/baz%20wibble+quux?qs=2", z, []),
- "/foo/bar/baz wibble quux" = R:get(path),
- ok.
-
--define(LARGE_TIMEOUT, 60).
-
-single_http_GET_test() ->
- do_GET(plain, 1).
-
-single_https_GET_test() ->
- do_GET(ssl, 1).
-
-multiple_http_GET_test() ->
- do_GET(plain, 3).
-
-multiple_https_GET_test() ->
- do_GET(ssl, 3).
-
-hundred_http_GET_test_() -> % note the underscore
- {timeout, ?LARGE_TIMEOUT,
- fun() -> ?assertEqual(ok, do_GET(plain,100)) end}.
-
-hundred_https_GET_test_() -> % note the underscore
- {timeout, ?LARGE_TIMEOUT,
- fun() -> ?assertEqual(ok, do_GET(ssl,100)) end}.
-
-single_128_http_POST_test() ->
- do_POST(plain, 128, 1).
-
-single_128_https_POST_test() ->
- do_POST(ssl, 128, 1).
-
-single_2k_http_POST_test() ->
- do_POST(plain, 2048, 1).
-
-single_2k_https_POST_test() ->
- do_POST(ssl, 2048, 1).
-
-single_100k_http_POST_test() ->
- do_POST(plain, 102400, 1).
-
-single_100k_https_POST_test() ->
- do_POST(ssl, 102400, 1).
-
-multiple_100k_http_POST_test() ->
- do_POST(plain, 102400, 3).
-
-multiple_100K_https_POST_test() ->
- do_POST(ssl, 102400, 3).
-
-hundred_128_http_POST_test_() -> % note the underscore
- {timeout, ?LARGE_TIMEOUT,
- fun() -> ?assertEqual(ok, do_POST(plain, 128, 100)) end}.
-
-hundred_128_https_POST_test_() -> % note the underscore
- {timeout, ?LARGE_TIMEOUT,
- fun() -> ?assertEqual(ok, do_POST(ssl, 128, 100)) end}.
-
-do_GET(Transport, Times) ->
- PathPrefix = "/whatever/",
- ReplyPrefix = "You requested: ",
- ServerFun = fun (Req) ->
- Reply = ReplyPrefix ++ Req:get(path),
- Req:ok({"text/plain", Reply})
- end,
- TestReqs = [begin
- Path = PathPrefix ++ integer_to_list(N),
- ExpectedReply = list_to_binary(ReplyPrefix ++ Path),
- #treq{path=Path, xreply=ExpectedReply}
- end || N <- lists:seq(1, Times)],
- ClientFun = new_client_fun('GET', TestReqs),
- ok = with_server(Transport, ServerFun, ClientFun),
- ok.
-
-do_POST(Transport, Size, Times) ->
- ServerFun = fun (Req) ->
- Body = Req:recv_body(),
- Headers = [{"Content-Type", "application/octet-stream"}],
- Req:respond({201, Headers, Body})
- end,
- TestReqs = [begin
- Path = "/stuff/" ++ integer_to_list(N),
- Body = crypto:rand_bytes(Size),
- #treq{path=Path, body=Body, xreply=Body}
- end || N <- lists:seq(1, Times)],
- ClientFun = new_client_fun('POST', TestReqs),
- ok = with_server(Transport, ServerFun, ClientFun),
- ok.
-
-new_client_fun(Method, TestReqs) ->
- fun (Transport, Port) ->
- client_request(Transport, Port, Method, TestReqs)
- end.
-
-client_request(Transport, Port, Method, TestReqs) ->
- Opts = [binary, {active, false}, {packet, http}],
- SockFun = case Transport of
- plain ->
- {ok, Socket} = gen_tcp:connect("127.0.0.1", Port, Opts),
- fun (recv) ->
- gen_tcp:recv(Socket, 0);
- ({recv, Length}) ->
- gen_tcp:recv(Socket, Length);
- ({send, Data}) ->
- gen_tcp:send(Socket, Data);
- ({setopts, L}) ->
- inet:setopts(Socket, L)
- end;
- ssl ->
- {ok, Socket} = ssl:connect("127.0.0.1", Port, [{ssl_imp, new} | Opts]),
- fun (recv) ->
- ssl:recv(Socket, 0);
- ({recv, Length}) ->
- ssl:recv(Socket, Length);
- ({send, Data}) ->
- ssl:send(Socket, Data);
- ({setopts, L}) ->
- ssl:setopts(Socket, L)
- end
- end,
- client_request(SockFun, Method, TestReqs).
-
-client_request(SockFun, _Method, []) ->
- {the_end, {error, closed}} = {the_end, SockFun(recv)},
- ok;
-client_request(SockFun, Method,
- [#treq{path=Path, body=Body, xreply=ExReply} | Rest]) ->
- Request = [atom_to_list(Method), " ", Path, " HTTP/1.1\r\n",
- client_headers(Body, Rest =:= []),
- "\r\n",
- Body],
- ok = SockFun({send, Request}),
- case Method of
- 'GET' ->
- {ok, {http_response, {1,1}, 200, "OK"}} = SockFun(recv);
- 'POST' ->
- {ok, {http_response, {1,1}, 201, "Created"}} = SockFun(recv)
- end,
- ok = SockFun({setopts, [{packet, httph}]}),
- {ok, {http_header, _, 'Server', _, "MochiWeb" ++ _}} = SockFun(recv),
- {ok, {http_header, _, 'Date', _, _}} = SockFun(recv),
- {ok, {http_header, _, 'Content-Type', _, _}} = SockFun(recv),
- {ok, {http_header, _, 'Content-Length', _, ConLenStr}} = SockFun(recv),
- ContentLength = list_to_integer(ConLenStr),
- {ok, http_eoh} = SockFun(recv),
- ok = SockFun({setopts, [{packet, raw}]}),
- {payload, ExReply} = {payload, drain_reply(SockFun, ContentLength, <<>>)},
- ok = SockFun({setopts, [{packet, http}]}),
- client_request(SockFun, Method, Rest).
-
-client_headers(Body, IsLastRequest) ->
- ["Host: localhost\r\n",
- case Body of
- <<>> ->
- "";
- _ ->
- ["Content-Type: application/octet-stream\r\n",
- "Content-Length: ", integer_to_list(byte_size(Body)), "\r\n"]
- end,
- case IsLastRequest of
- true ->
- "Connection: close\r\n";
- false ->
- ""
- end].
-
-drain_reply(_SockFun, 0, Acc) ->
- Acc;
-drain_reply(SockFun, Length, Acc) ->
- Sz = erlang:min(Length, 1024),
- {ok, B} = SockFun({recv, Sz}),
- drain_reply(SockFun, Length - Sz, <<Acc/bytes, B/bytes>>).
-
--endif.
http://git-wip-us.apache.org/repos/asf/couchdb-mochiweb/blob/8e3f3dd3/src/mochiweb_socket_server.erl
----------------------------------------------------------------------
diff --git a/src/mochiweb_socket_server.erl b/src/mochiweb_socket_server.erl
index e6e9fc9..3c8a8b1 100644
--- a/src/mochiweb_socket_server.erl
+++ b/src/mochiweb_socket_server.erl
@@ -59,13 +59,9 @@ set(Name, Property, _Value) ->
error_logger:info_msg("?MODULE:set for ~p with ~p not implemented~n",
[Name, Property]).
-stop(Name) when is_atom(Name) ->
- gen_server:cast(Name, stop);
-stop(Pid) when is_pid(Pid) ->
- gen_server:cast(Pid, stop);
-stop({local, Name}) ->
- stop(Name);
-stop({global, Name}) ->
+stop(Name) when is_atom(Name) orelse is_pid(Name) ->
+ gen_server:call(Name, stop);
+stop({Scope, Name}) when Scope =:= local orelse Scope =:= global ->
stop(Name);
stop(Options) ->
State = parse_options(Options),
@@ -235,6 +231,8 @@ handle_call(Req, From, State) when ?is_old_state(State) ->
handle_call({get, Property}, _From, State) ->
Res = do_get(Property, State),
{reply, Res, State};
+handle_call(stop, _From, State) ->
+ {stop, normal, ok, State};
handle_call(_Message, _From, State) ->
Res = error,
{reply, Res, State}.
@@ -259,9 +257,7 @@ handle_cast({set, profile_fun, ProfileFun}, State) ->
_ ->
State
end,
- {noreply, State1};
-handle_cast(stop, State) ->
- {stop, normal, State}.
+ {noreply, State1}.
terminate(Reason, State) when ?is_old_state(State) ->
http://git-wip-us.apache.org/repos/asf/couchdb-mochiweb/blob/8e3f3dd3/test/mochiweb_tests.erl
----------------------------------------------------------------------
diff --git a/test/mochiweb_tests.erl b/test/mochiweb_tests.erl
new file mode 100644
index 0000000..15cb06a
--- /dev/null
+++ b/test/mochiweb_tests.erl
@@ -0,0 +1,199 @@
+-module(mochiweb_tests).
+-include_lib("eunit/include/eunit.hrl").
+
+-record(treq, {path, body= <<>>, xreply= <<>>}).
+
+ssl_cert_opts() ->
+ EbinDir = filename:dirname(code:which(?MODULE)),
+ CertDir = filename:join([EbinDir, "..", "support", "test-materials"]),
+ CertFile = filename:join(CertDir, "test_ssl_cert.pem"),
+ KeyFile = filename:join(CertDir, "test_ssl_key.pem"),
+ [{certfile, CertFile}, {keyfile, KeyFile}].
+
+with_server(Transport, ServerFun, ClientFun) ->
+ ServerOpts0 = [{ip, "127.0.0.1"}, {port, 0}, {loop, ServerFun}],
+ ServerOpts = case Transport of
+ plain ->
+ ServerOpts0;
+ ssl ->
+ ServerOpts0 ++ [{ssl, true}, {ssl_opts, ssl_cert_opts()}]
+ end,
+ {ok, Server} = mochiweb_http:start_link(ServerOpts),
+ Port = mochiweb_socket_server:get(Server, port),
+ Res = (catch ClientFun(Transport, Port)),
+ mochiweb_http:stop(Server),
+ Res.
+
+request_test() ->
+ R = mochiweb_request:new(z, z, "/foo/bar/baz%20wibble+quux?qs=2", z, []),
+ "/foo/bar/baz wibble quux" = R:get(path),
+ ok.
+
+-define(LARGE_TIMEOUT, 60).
+
+single_http_GET_test() ->
+ do_GET(plain, 1).
+
+single_https_GET_test() ->
+ do_GET(ssl, 1).
+
+multiple_http_GET_test() ->
+ do_GET(plain, 3).
+
+multiple_https_GET_test() ->
+ do_GET(ssl, 3).
+
+hundred_http_GET_test_() -> % note the underscore
+ {timeout, ?LARGE_TIMEOUT,
+ fun() -> ?assertEqual(ok, do_GET(plain,100)) end}.
+
+hundred_https_GET_test_() -> % note the underscore
+ {timeout, ?LARGE_TIMEOUT,
+ fun() -> ?assertEqual(ok, do_GET(ssl,100)) end}.
+
+single_128_http_POST_test() ->
+ do_POST(plain, 128, 1).
+
+single_128_https_POST_test() ->
+ do_POST(ssl, 128, 1).
+
+single_2k_http_POST_test() ->
+ do_POST(plain, 2048, 1).
+
+single_2k_https_POST_test() ->
+ do_POST(ssl, 2048, 1).
+
+single_100k_http_POST_test() ->
+ do_POST(plain, 102400, 1).
+
+single_100k_https_POST_test() ->
+ do_POST(ssl, 102400, 1).
+
+multiple_100k_http_POST_test() ->
+ do_POST(plain, 102400, 3).
+
+multiple_100K_https_POST_test() ->
+ do_POST(ssl, 102400, 3).
+
+hundred_128_http_POST_test_() -> % note the underscore
+ {timeout, ?LARGE_TIMEOUT,
+ fun() -> ?assertEqual(ok, do_POST(plain, 128, 100)) end}.
+
+hundred_128_https_POST_test_() -> % note the underscore
+ {timeout, ?LARGE_TIMEOUT,
+ fun() -> ?assertEqual(ok, do_POST(ssl, 128, 100)) end}.
+
+do_GET(Transport, Times) ->
+ PathPrefix = "/whatever/",
+ ReplyPrefix = "You requested: ",
+ ServerFun = fun (Req) ->
+ Reply = ReplyPrefix ++ Req:get(path),
+ Req:ok({"text/plain", Reply})
+ end,
+ TestReqs = [begin
+ Path = PathPrefix ++ integer_to_list(N),
+ ExpectedReply = list_to_binary(ReplyPrefix ++ Path),
+ #treq{path=Path, xreply=ExpectedReply}
+ end || N <- lists:seq(1, Times)],
+ ClientFun = new_client_fun('GET', TestReqs),
+ ok = with_server(Transport, ServerFun, ClientFun),
+ ok.
+
+do_POST(Transport, Size, Times) ->
+ ServerFun = fun (Req) ->
+ Body = Req:recv_body(),
+ Headers = [{"Content-Type", "application/octet-stream"}],
+ Req:respond({201, Headers, Body})
+ end,
+ TestReqs = [begin
+ Path = "/stuff/" ++ integer_to_list(N),
+ Body = crypto:rand_bytes(Size),
+ #treq{path=Path, body=Body, xreply=Body}
+ end || N <- lists:seq(1, Times)],
+ ClientFun = new_client_fun('POST', TestReqs),
+ ok = with_server(Transport, ServerFun, ClientFun),
+ ok.
+
+new_client_fun(Method, TestReqs) ->
+ fun (Transport, Port) ->
+ client_request(Transport, Port, Method, TestReqs)
+ end.
+
+client_request(Transport, Port, Method, TestReqs) ->
+ Opts = [binary, {active, false}, {packet, http}],
+ SockFun = case Transport of
+ plain ->
+ {ok, Socket} = gen_tcp:connect("127.0.0.1", Port, Opts),
+ fun (recv) ->
+ gen_tcp:recv(Socket, 0);
+ ({recv, Length}) ->
+ gen_tcp:recv(Socket, Length);
+ ({send, Data}) ->
+ gen_tcp:send(Socket, Data);
+ ({setopts, L}) ->
+ inet:setopts(Socket, L)
+ end;
+ ssl ->
+ {ok, Socket} = ssl:connect("127.0.0.1", Port, [{ssl_imp, new} | Opts]),
+ fun (recv) ->
+ ssl:recv(Socket, 0);
+ ({recv, Length}) ->
+ ssl:recv(Socket, Length);
+ ({send, Data}) ->
+ ssl:send(Socket, Data);
+ ({setopts, L}) ->
+ ssl:setopts(Socket, L)
+ end
+ end,
+ client_request(SockFun, Method, TestReqs).
+
+client_request(SockFun, _Method, []) ->
+ {the_end, {error, closed}} = {the_end, SockFun(recv)},
+ ok;
+client_request(SockFun, Method,
+ [#treq{path=Path, body=Body, xreply=ExReply} | Rest]) ->
+ Request = [atom_to_list(Method), " ", Path, " HTTP/1.1\r\n",
+ client_headers(Body, Rest =:= []),
+ "\r\n",
+ Body],
+ ok = SockFun({send, Request}),
+ case Method of
+ 'GET' ->
+ {ok, {http_response, {1,1}, 200, "OK"}} = SockFun(recv);
+ 'POST' ->
+ {ok, {http_response, {1,1}, 201, "Created"}} = SockFun(recv)
+ end,
+ ok = SockFun({setopts, [{packet, httph}]}),
+ {ok, {http_header, _, 'Server', _, "MochiWeb" ++ _}} = SockFun(recv),
+ {ok, {http_header, _, 'Date', _, _}} = SockFun(recv),
+ {ok, {http_header, _, 'Content-Type', _, _}} = SockFun(recv),
+ {ok, {http_header, _, 'Content-Length', _, ConLenStr}} = SockFun(recv),
+ ContentLength = list_to_integer(ConLenStr),
+ {ok, http_eoh} = SockFun(recv),
+ ok = SockFun({setopts, [{packet, raw}]}),
+ {payload, ExReply} = {payload, drain_reply(SockFun, ContentLength, <<>>)},
+ ok = SockFun({setopts, [{packet, http}]}),
+ client_request(SockFun, Method, Rest).
+
+client_headers(Body, IsLastRequest) ->
+ ["Host: localhost\r\n",
+ case Body of
+ <<>> ->
+ "";
+ _ ->
+ ["Content-Type: application/octet-stream\r\n",
+ "Content-Length: ", integer_to_list(byte_size(Body)), "\r\n"]
+ end,
+ case IsLastRequest of
+ true ->
+ "Connection: close\r\n";
+ false ->
+ ""
+ end].
+
+drain_reply(_SockFun, 0, Acc) ->
+ Acc;
+drain_reply(SockFun, Length, Acc) ->
+ Sz = erlang:min(Length, 1024),
+ {ok, B} = SockFun({recv, Sz}),
+ drain_reply(SockFun, Length - Sz, <<Acc/bytes, B/bytes>>).