Updated Branches: refs/heads/1.3.x 06c3f351f -> 7648e1537
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/7648e153 Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/7648e153 Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/7648e153 Branch: refs/heads/1.3.x Commit: 7648e1537bccd5eae6a8a6697ce2aa4b0fc32c73 Parents: 06c3f35 Author: Volker Mische <[email protected]> Authored: Sun Mar 10 18:34:59 2013 +0100 Committer: Robert Newson <[email protected]> Committed: Sun Mar 10 17:39:16 2013 -0500 ---------------------------------------------------------------------- CHANGES | 9 +++++++++ src/couchdb/couch_httpd_db.erl | 8 ++++---- test/etap/231-cors.t | 35 ++++++++++++++++++++++++++++++++++- 3 files changed, 47 insertions(+), 5 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/couchdb/blob/7648e153/CHANGES ---------------------------------------------------------------------- diff --git a/CHANGES b/CHANGES index bdfda9d..19f9d19 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,15 @@ Apache CouchDB CHANGES ====================== +Version 1.3.1 +------------- + +This version has not been released yet. + +HTTP Interface: + +* Fix bug in CORS when retrieving attachments. + Version 1.3.0 ------------- http://git-wip-us.apache.org/repos/asf/couchdb/blob/7648e153/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/7648e153/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",
