end to end connect test for websocket
diff --git a/test/mochiweb_test_util.erl b/test/mochiweb_test_util.erl
index ccfc611..690f134 100644
--- a/test/mochiweb_test_util.erl
+++ b/test/mochiweb_test_util.erl
@@ -1,5 +1,5 @@
-module(mochiweb_test_util).
--export([with_server/3, client_request/4]).
+-export([with_server/3, client_request/4, sock_fun/2]).
-include("mochiweb_test_util.hrl").
ssl_cert_opts() ->
@@ -23,9 +23,9 @@
mochiweb_http:stop(Server),
Res.
-client_request(Transport, Port, Method, TestReqs) ->
+sock_fun(Transport, Port) ->
Opts = [binary, {active, false}, {packet, http}],
- SockFun = case Transport of
+ case Transport of
plain ->
{ok, Socket} = gen_tcp:connect("127.0.0.1", Port, Opts),
fun (recv) ->
@@ -48,8 +48,10 @@
({setopts, L}) ->
ssl:setopts(Socket, L)
end
- end,
- client_request(SockFun, Method, TestReqs).
+ end.
+
+client_request(Transport, Port, Method, TestReqs) ->
+ client_request(sock_fun(Transport, Port), Method, TestReqs).
client_request(SockFun, _Method, []) ->
{the_end, {error, closed}} = {the_end, SockFun(recv)},
diff --git a/test/mochiweb_websocket_tests.erl b/test/mochiweb_websocket_tests.erl
index 890aa17..20967fb 100644
--- a/test/mochiweb_websocket_tests.erl
+++ b/test/mochiweb_websocket_tests.erl
@@ -82,3 +82,70 @@
mochiweb_websocket:parse_hixie_frames(
<<0,102,111,111,255,0,98,97,114,255>>,
[])).
+
+end_to_end_test_factory(ServerTransport) ->
+ mochiweb_test_util:with_server(
+ ServerTransport,
+ fun end_to_end_server/1,
+ fun (Transport, Port) ->
+ end_to_end_client(mochiweb_test_util:sock_fun(Transport, Port))
+ end).
+
+end_to_end_server(Req) ->
+ ?assertEqual("Upgrade", Req:get_header_value("connection")),
+ ?assertEqual("websocket", Req:get_header_value("upgrade")),
+ {ReentryWs, _ReplyChannel} = mochiweb_websocket:upgrade_connection(
+ Req,
+ fun end_to_end_ws_loop/3),
+ ReentryWs(ok).
+
+end_to_end_ws_loop(_Payload, State, _ReplyChannel) ->
+ State.
+
+end_to_end_client(S) ->
+ UpgradeReq = string:join(
+ ["GET / HTTP/1.1",
+ "Host: localhost",
+ "Upgrade: websocket",
+ "Connection: Upgrade",
+ "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==",
+ "",
+ ""], "\r\n"),
+ ok = S({send, UpgradeReq}),
+ {ok, {http_response, {1,1}, 101, _}} = S(recv),
+ ok = S({setopts, [{packet, httph}]}),
+ D = read_expected_headers(
+ S,
+ gb_from_list(
+ [{'Upgrade', "websocket"},
+ {'Connection', "Upgrade"},
+ {'Content-Length', "0"},
+ {"Sec-Websocket-Accept", "s3pPLMBiTxaQ9kYGzzhZRbK+xOo="}])),
+ ?assertEqual([], gb_trees:to_list(D)),
+ ok = S({setopts, [{packet, raw}]}),
+ ok.
+
+gb_from_list(L) ->
+ lists:foldl(
+ fun ({K, V}, D) -> gb_trees:insert(K, V, D) end,
+ gb_trees:empty(),
+ L).
+
+read_expected_headers(S, D) ->
+ case S(recv) of
+ {ok, http_eoh} ->
+ D;
+ {ok, {http_header, _, K, _, V}} ->
+ case gb_trees:lookup(K, D) of
+ {value, V1} ->
+ ?assertEqual({K, V}, {K, V1}),
+ read_expected_headers(S, gb_trees:delete(K, D));
+ none ->
+ read_expected_headers(S, D)
+ end
+ end.
+
+end_to_end_test_() ->
+ [{"http", ?_assertEqual(ok, end_to_end_test_factory(plain))}
+ ,{"https", ?_assertEqual(ok, end_to_end_test_factory(ssl))}
+ ].