ensure correct ordering of Set-Cookie output headers #162
Project: http://git-wip-us.apache.org/repos/asf/couchdb-mochiweb/repo Commit: http://git-wip-us.apache.org/repos/asf/couchdb-mochiweb/commit/952087ef Tree: http://git-wip-us.apache.org/repos/asf/couchdb-mochiweb/tree/952087ef Diff: http://git-wip-us.apache.org/repos/asf/couchdb-mochiweb/diff/952087ef Branch: refs/heads/master Commit: 952087ef7a2ce73b8c2d666de13adf138d913d77 Parents: 419ba96 Author: Bob Ippolito <b...@redivi.com> Authored: Mon Aug 31 08:30:40 2015 -0700 Committer: Bob Ippolito <b...@redivi.com> Committed: Mon Aug 31 08:30:40 2015 -0700 ---------------------------------------------------------------------- CHANGES.md | 2 ++ src/mochiweb_request.erl | 8 +++----- test/mochiweb_test_util.erl | 10 +++++++++- test/mochiweb_test_util.hrl | 2 +- test/mochiweb_tests.erl | 17 +++++++++++++++++ 5 files changed, 32 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/couchdb-mochiweb/blob/952087ef/CHANGES.md ---------------------------------------------------------------------- diff --git a/CHANGES.md b/CHANGES.md index 7102a6f..b7f6c4b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,7 @@ Version 2.13.0 released XXXX-XX-XX +* Ensure correct ordering of Set-Cookie headers, first in first out. + https://github.com/mochi/mochiweb/issues/162 * Improve response times by caching a formatted date once per second for the response headers with a mochiweb_clock service https://github.com/mochi/mochiweb/pull/158 http://git-wip-us.apache.org/repos/asf/couchdb-mochiweb/blob/952087ef/src/mochiweb_request.erl ---------------------------------------------------------------------- diff --git a/src/mochiweb_request.erl b/src/mochiweb_request.erl index 093d9ba..39890ce 100644 --- a/src/mochiweb_request.erl +++ b/src/mochiweb_request.erl @@ -326,12 +326,10 @@ format_response_header({Code, ResponseHeaders}, {?MODULE, [_Socket, _Opts, _Meth false -> HResponse1 end, - F = fun ({K, V}, Acc) -> - [mochiweb_util:make_io(K), <<": ">>, V, <<"\r\n">> | Acc] - end, - End = lists:foldl(F, [<<"\r\n">>], mochiweb_headers:to_list(HResponse2)), + End = [[mochiweb_util:make_io(K), <<": ">>, V, <<"\r\n">>] + || {K, V} <- mochiweb_headers:to_list(HResponse2)], Response = mochiweb:new_response({THIS, Code, HResponse2}), - {[make_version(Version), make_code(Code), <<"\r\n">> | End], Response}; + {[make_version(Version), make_code(Code), <<"\r\n">> | [End, <<"\r\n">>]], Response}; format_response_header({Code, ResponseHeaders, Length}, {?MODULE, [_Socket, _Opts, _Method, _RawPath, _Version, _Headers]}=THIS) -> HResponse = mochiweb_headers:make(ResponseHeaders), http://git-wip-us.apache.org/repos/asf/couchdb-mochiweb/blob/952087ef/test/mochiweb_test_util.erl ---------------------------------------------------------------------- diff --git a/test/mochiweb_test_util.erl b/test/mochiweb_test_util.erl index 2fbf14f..a0bf11a 100644 --- a/test/mochiweb_test_util.erl +++ b/test/mochiweb_test_util.erl @@ -63,7 +63,7 @@ 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]) -> + [#treq{path=Path, body=Body, xreply=ExReply, xheaders=ExHeaders} | Rest]) -> Request = [atom_to_list(Method), " ", Path, " HTTP/1.1\r\n", client_headers(Body, Rest =:= []), "\r\n", @@ -83,6 +83,14 @@ client_request(SockFun, Method, ?assert(mochiweb_headers:get_value("Date", Headers) =/= undefined), ?assert(mochiweb_headers:get_value("Content-Type", Headers) =/= undefined), ContentLength = list_to_integer(mochiweb_headers:get_value("Content-Length", Headers)), + EHeaders = mochiweb_headers:make(ExHeaders), + lists:foreach( + fun (K) -> + ?assertEqual(mochiweb_headers:get_value(K, EHeaders), + mochiweb_headers:get_value(K, Headers)) + end, + %% Assumes implementation details of the headers + gb_trees:keys(EHeaders)), {payload, ExReply} = {payload, drain_reply(SockFun, ContentLength, <<>>)}, client_request(SockFun, Method, Rest). http://git-wip-us.apache.org/repos/asf/couchdb-mochiweb/blob/952087ef/test/mochiweb_test_util.hrl ---------------------------------------------------------------------- diff --git a/test/mochiweb_test_util.hrl b/test/mochiweb_test_util.hrl index 99fdc4e..503be98 100644 --- a/test/mochiweb_test_util.hrl +++ b/test/mochiweb_test_util.hrl @@ -1 +1 @@ --record(treq, {path, body= <<>>, xreply= <<>>}). +-record(treq, {path, body= <<>>, xreply= <<>>, xheaders= []}). http://git-wip-us.apache.org/repos/asf/couchdb-mochiweb/blob/952087ef/test/mochiweb_tests.erl ---------------------------------------------------------------------- diff --git a/test/mochiweb_tests.erl b/test/mochiweb_tests.erl index 209971b..0b558ac 100644 --- a/test/mochiweb_tests.erl +++ b/test/mochiweb_tests.erl @@ -96,6 +96,23 @@ single_GET_any_test_() -> ?_assertEqual(ok, with_server(Transport, ServerFun, ClientFun))} || Transport <- [ssl, plain]]. + +cookie_header_test() -> + ReplyPrefix = "You requested: ", + ExHeaders = [{"Set-Cookie", "foo=bar"}, + {"Set-Cookie", "foo=baz"}], + ServerFun = fun (Req) -> + Reply = ReplyPrefix ++ Req:get(path), + Req:ok({"text/plain", ExHeaders, Reply}) + end, + Path = "cookie_header", + ExpectedReply = list_to_binary(ReplyPrefix ++ Path), + TestReqs = [#treq{path=Path, xreply=ExpectedReply, xheaders=ExHeaders}], + ClientFun = new_client_fun('GET', TestReqs), + ok = with_server(plain, ServerFun, ClientFun), + ok. + + do_CONNECT(Transport, Times) -> PathPrefix = "example.com:", ReplyPrefix = "You requested: ",