couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kocol...@apache.org
Subject [49/50] git commit: Replicator: don't use chunked encoding for _bulk_docs
Date Wed, 26 Oct 2011 18:05:34 GMT
Replicator: don't use chunked encoding for _bulk_docs

Nginx and a few other servers don't like PUT/POST requests
without a Content-Length header, making it impossible to
do a chunked transfer encoding for these requests.
Issue and patch tested by Dale Harvey, thanks.

Closes COUCHDB-1286.



git-svn-id: https://svn.apache.org/repos/asf/couchdb/trunk@1172388 13f79535-47bb-0310-9956-ffa450edef68


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/06fb18a1
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/06fb18a1
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/06fb18a1

Branch: refs/heads/1319-large-headers-are-corrupted
Commit: 06fb18a149c97b101067258417f0edecb245bcbe
Parents: e71e802
Author: Filipe David Borba Manana <fdmanana@apache.org>
Authored: Sun Sep 18 22:32:10 2011 +0000
Committer: Filipe David Borba Manana <fdmanana@apache.org>
Committed: Sun Sep 18 22:32:10 2011 +0000

----------------------------------------------------------------------
 src/couchdb/couch_api_wrap.erl |   44 ++++++++++++++++++++--------------
 1 files changed, 26 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/06fb18a1/src/couchdb/couch_api_wrap.erl
----------------------------------------------------------------------
diff --git a/src/couchdb/couch_api_wrap.erl b/src/couchdb/couch_api_wrap.erl
index 613d876..19f476a 100644
--- a/src/couchdb/couch_api_wrap.erl
+++ b/src/couchdb/couch_api_wrap.erl
@@ -250,41 +250,49 @@ update_doc(Db, Doc, Options, Type) ->
 update_docs(Db, DocList, Options) ->
     update_docs(Db, DocList, Options, interactive_edit).
 
+update_docs(_Db, [], _Options, _UpdateType) ->
+    {ok, []};
 update_docs(#httpdb{} = HttpDb, DocList, Options, UpdateType) ->
     FullCommit = atom_to_list(not lists:member(delay_commit, Options)),
-    Prefix1 = case UpdateType of
+    Prefix = case UpdateType of
     replicated_changes ->
-        {prefix, <<"{\"new_edits\":false,\"docs\":[">>};
+        <<"{\"new_edits\":false,\"docs\":[">>;
     interactive_edit ->
-        {prefix, <<"{\"docs\":[">>}
+        <<"{\"docs\":[">>
     end,
+    Suffix = <<"]}">>,
+    % Note: nginx and other servers don't like PUT/POST requests without
+    % a Content-Length header, so we can't do a chunked transfer encoding
+    % and JSON encode each doc only before sending it through the socket.
+    {Docs, Len} = lists:mapfoldl(
+        fun(#doc{} = Doc, Acc) ->
+            Json = ?JSON_ENCODE(couch_doc:to_json_obj(Doc, [revs, attachments])),
+            {Json, Acc + iolist_size(Json)};
+        (Doc, Acc) ->
+            {Doc, Acc + iolist_size(Doc)}
+        end,
+        byte_size(Prefix) + byte_size(Suffix) + length(DocList) - 1,
+        DocList),
     BodyFun = fun(eof) ->
             eof;
         ([]) ->
-            {ok, <<"]}">>, eof};
-        ([{prefix, Prefix} | Rest]) ->
+            {ok, Suffix, eof};
+        ([prefix | Rest]) ->
             {ok, Prefix, Rest};
-        ([Doc]) when is_record(Doc, doc) ->
-            DocJson = couch_doc:to_json_obj(Doc, [revs, attachments]),
-            {ok, ?JSON_ENCODE(DocJson), []};
-        ([Doc | RestDocs]) when is_record(Doc, doc) ->
-            DocJson = couch_doc:to_json_obj(Doc, [revs, attachments]),
-            {ok, [?JSON_ENCODE(DocJson), ","], RestDocs};
         ([Doc]) ->
-            % IO list
             {ok, Doc, []};
         ([Doc | RestDocs]) ->
-            % IO list
             {ok, [Doc, ","], RestDocs}
     end,
+    Headers = [
+        {"Content-Length", Len},
+        {"Content-Type", "application/json"},
+        {"X-Couch-Full-Commit", FullCommit}
+    ],
     send_req(
         HttpDb,
         [{method, post}, {path, "_bulk_docs"},
-            {body, {BodyFun, [Prefix1 | DocList]}},
-            {ibrowse_options, [{transfer_encoding, chunked}]},
-            {headers, [
-                {"X-Couch-Full-Commit", FullCommit},
-                {"Content-Type", "application/json"} ]}],
+            {body, {BodyFun, [prefix | Docs]}}, {headers, Headers}],
         fun(201, _, Results) when is_list(Results) ->
                 {ok, bulk_results_to_errors(DocList, Results, remote)};
            (417, _, Results) when is_list(Results) ->


Mime
View raw message