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",

Reply via email to