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>>).