Updated Branches: refs/heads/master 6a840a858 -> b0420f900
Fix CORS error with attachments When attachments were returned (?attachments=true) while CORS was enabled and used, an error occured. The reason for this error were headers that were encoded as binaries instead of lists. String operations on binaries throw errors. This commit fixes COUCHDB-1689. Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/b0420f90 Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/b0420f90 Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/b0420f90 Branch: refs/heads/master Commit: b0420f9006915149e81607615720f32f21c76725 Parents: 6a840a8 Author: Volker Mische <[email protected]> Authored: Sun Mar 10 18:34:59 2013 +0100 Committer: Volker Mische <[email protected]> Committed: Sun Mar 10 21:09:53 2013 +0100 ---------------------------------------------------------------------- src/couchdb/couch_httpd_db.erl | 8 ++++---- test/etap/231-cors.t | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 5 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/couchdb/blob/b0420f90/src/couchdb/couch_httpd_db.erl ---------------------------------------------------------------------- diff --git a/src/couchdb/couch_httpd_db.erl b/src/couchdb/couch_httpd_db.erl index 4b345da..f270fef 100644 --- a/src/couchdb/couch_httpd_db.erl +++ b/src/couchdb/couch_httpd_db.erl @@ -627,7 +627,7 @@ send_doc_efficiently(#httpd{mochi_req = MochiReq} = Req, [attachments, follows, att_encoding_info | Options])), {ContentType, Len} = couch_doc:len_doc_to_multi_part_stream( Boundary,JsonBytes, Atts, true), - CType = {<<"Content-Type">>, ContentType}, + CType = {"Content-Type", ?b2l(ContentType)}, {ok, Resp} = start_response_length(Req, 200, [CType|Headers], Len), couch_doc:doc_to_multi_part_stream(Boundary,JsonBytes,Atts, fun(Data) -> couch_httpd:send(Resp, Data) end, true) @@ -673,7 +673,7 @@ send_ranges_multipart(Req, ContentType, Len, Att, Ranges) -> {ok, Resp} = start_chunked_response(Req, 206, [CType]), couch_httpd:send_chunk(Resp, <<"--", Boundary/binary>>), lists:foreach(fun({From, To}) -> - ContentRange = make_content_range(From, To, Len), + ContentRange = ?l2b(make_content_range(From, To, Len)), couch_httpd:send_chunk(Resp, <<"\r\nContent-Type: ", ContentType/binary, "\r\n", "Content-Range: ", ContentRange/binary, "\r\n", @@ -697,7 +697,7 @@ receive_request_data(_Req, _) -> throw(<<"expected more data">>). make_content_range(From, To, Len) -> - ?l2b(io_lib:format("bytes ~B-~B/~B", [From, To, Len])). + io_lib:format("bytes ~B-~B/~B", [From, To, Len]). update_doc_result_to_json({{Id, Rev}, Error}) -> {_Code, Err, Msg} = couch_httpd:error_info(Error), @@ -894,7 +894,7 @@ db_attachment_req(#httpd{method='GET',mochi_req=MochiReq}=Req, Db, DocId, FileNa Ranges = parse_ranges(MochiReq:get(range), Len), case {Enc, Ranges} of {identity, [{From, To}]} -> - Headers1 = [{<<"Content-Range">>, make_content_range(From, To, Len)}] + Headers1 = [{"Content-Range", make_content_range(From, To, Len)}] ++ Headers, {ok, Resp} = start_response_length(Req, 206, Headers1, To - From + 1), couch_doc:range_att_foldl(Att, From, To + 1, http://git-wip-us.apache.org/repos/asf/couchdb/blob/b0420f90/test/etap/231-cors.t ---------------------------------------------------------------------- diff --git a/test/etap/231-cors.t b/test/etap/231-cors.t index ad92ae9..a150867 100644 --- a/test/etap/231-cors.t +++ b/test/etap/231-cors.t @@ -32,7 +32,7 @@ server() -> main(_) -> test_util:init_code_path(), - etap:plan(28), + etap:plan(30), case (catch test()) of ok -> etap:end_tests(); @@ -85,6 +85,8 @@ test() -> test_preflight_request(), test_db_request(), + test_doc_with_attachment_request(), + test_doc_with_attachment_range_request(), test_db_preflight_request(), test_db_origin_request(), test_db1_origin_request(), @@ -223,6 +225,37 @@ test_db_request(VHost) -> etap:is(false, true, "ibrowse failed") end. +% COUCHDB-1689 +test_doc_with_attachment_request() -> + DocUrl = server() ++ "etap-test-db/doc1", + ibrowse:send_req(DocUrl ++ "/attachment.txt", + [{"Content-Type", "text/plain"}], put, "this is a text attachment"), + + Headers = [{"Origin", "http://example.com"}], + Url = DocUrl ++ "?attachments=true", + case ibrowse:send_req(Url, Headers, get, []) of + {ok, Code, _RespHeaders, _Body} -> + etap:is(Code, "200", "Response without errors"); + _ -> + etap:is(false, true, "ibrowse failed") + end. + +% COUCHDB-1689 +test_doc_with_attachment_range_request() -> + AttachmentUrl = server() ++ "etap-test-db/doc2/attachment.bin", + % Use a Content-Type that doesn't get compressed + ibrowse:send_req(AttachmentUrl, + [{"Content-Type", "application/octet-stream"}], put, + "this is an attachment"), + + Headers = [{"Origin", "http://example.com"}, {"Range", "bytes=0-6"}], + case ibrowse:send_req(AttachmentUrl, Headers, get, []) of + {ok, Code, _RespHeaders, _Body} -> + etap:is(Code, "206", "Response without errors"); + _ -> + etap:is(false, true, "ibrowse failed") + end. + test_db_request_credentials_header_off() -> Headers = [{"Origin", "http://example.com"}], Url = server() ++ "etap-test-db",
