end to end connect test for websocket
Project: http://git-wip-us.apache.org/repos/asf/couchdb-mochiweb/repo Commit: http://git-wip-us.apache.org/repos/asf/couchdb-mochiweb/commit/ffaa90a1 Tree: http://git-wip-us.apache.org/repos/asf/couchdb-mochiweb/tree/ffaa90a1 Diff: http://git-wip-us.apache.org/repos/asf/couchdb-mochiweb/diff/ffaa90a1 Branch: refs/heads/upstream Commit: ffaa90a107872ffc5ada769cb46c55ae30118448 Parents: 7db3aef Author: Bob Ippolito <[email protected]> Authored: Sun Jan 11 17:10:07 2015 +1300 Committer: Bob Ippolito <[email protected]> Committed: Sun Jan 11 17:11:12 2015 +1300 ---------------------------------------------------------------------- test/mochiweb_test_util.erl | 12 +++--- test/mochiweb_websocket_tests.erl | 67 ++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 5 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/couchdb-mochiweb/blob/ffaa90a1/test/mochiweb_test_util.erl ---------------------------------------------------------------------- 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 @@ with_server(Transport, ServerFun, ClientFun) -> 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 @@ client_request(Transport, Port, Method, TestReqs) -> ({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)}, http://git-wip-us.apache.org/repos/asf/couchdb-mochiweb/blob/ffaa90a1/test/mochiweb_websocket_tests.erl ---------------------------------------------------------------------- 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 @@ hixie_frames_decode_test() -> 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))} + ].
