You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by fd...@apache.org on 2011/06/12 18:16:30 UTC

svn commit: r1134942 - in /couchdb/branches/1.1.x/src/couchdb: couch_doc.erl couch_httpd_db.erl

Author: fdmanana
Date: Sun Jun 12 16:16:29 2011
New Revision: 1134942

URL: http://svn.apache.org/viewvc?rev=1134942&view=rev
Log:
Backport revision 1129897 from trunk

    Fixes to the doc PUT multipart API
    
    Don't hold the connection forever if the document is rejected
    by a validate_doc_update function. The solution is to discard
    all the attachments' data if the document was rejected.


Modified:
    couchdb/branches/1.1.x/src/couchdb/couch_doc.erl
    couchdb/branches/1.1.x/src/couchdb/couch_httpd_db.erl

Modified: couchdb/branches/1.1.x/src/couchdb/couch_doc.erl
URL: http://svn.apache.org/viewvc/couchdb/branches/1.1.x/src/couchdb/couch_doc.erl?rev=1134942&r1=1134941&r2=1134942&view=diff
==============================================================================
--- couchdb/branches/1.1.x/src/couchdb/couch_doc.erl (original)
+++ couchdb/branches/1.1.x/src/couchdb/couch_doc.erl Sun Jun 12 16:16:29 2011
@@ -18,6 +18,7 @@
 -export([validate_docid/1]).
 -export([doc_from_multi_part_stream/2]).
 -export([doc_to_multi_part_stream/5, len_doc_to_multi_part_stream/4]).
+-export([abort_multi_part_stream/1]).
 
 -include("couch_db.hrl").
 
@@ -501,7 +502,7 @@ doc_from_multi_part_stream(ContentType, 
             receive {Parser, finished} -> ok end,
             erlang:put(mochiweb_request_recv, true)
         end,
-        {ok, Doc#doc{atts=Atts2}, WaitFun}
+        {ok, Doc#doc{atts=Atts2}, WaitFun, Parser}
     end.
 
 mp_parse_doc({headers, H}, []) ->
@@ -542,3 +543,19 @@ mp_parse_atts(body_end) ->
     end.
 
 
+abort_multi_part_stream(Parser) ->
+    abort_multi_part_stream(Parser, erlang:monitor(process, Parser)).
+
+abort_multi_part_stream(Parser, MonRef) ->
+    case is_process_alive(Parser) of
+    true ->
+        Parser ! {get_bytes, self()},
+        receive
+        {bytes, _Bytes} ->
+             abort_multi_part_stream(Parser, MonRef);
+        {'DOWN', MonRef, _, _, _} ->
+             ok
+        end;
+    false ->
+        erlang:demonitor(MonRef, [flush])
+    end.

Modified: couchdb/branches/1.1.x/src/couchdb/couch_httpd_db.erl
URL: http://svn.apache.org/viewvc/couchdb/branches/1.1.x/src/couchdb/couch_httpd_db.erl?rev=1134942&r1=1134941&r2=1134942&view=diff
==============================================================================
--- couchdb/branches/1.1.x/src/couchdb/couch_httpd_db.erl (original)
+++ couchdb/branches/1.1.x/src/couchdb/couch_httpd_db.erl Sun Jun 12 16:16:29 2011
@@ -692,12 +692,18 @@ db_doc_req(#httpd{method='PUT'}=Req, Db,
     RespHeaders = [{"Location", Loc}],
     case couch_util:to_list(couch_httpd:header_value(Req, "Content-Type")) of
     ("multipart/related;" ++ _) = ContentType ->
-        {ok, Doc0, WaitFun} = couch_doc:doc_from_multi_part_stream(
+        {ok, Doc0, WaitFun, Parser} = couch_doc:doc_from_multi_part_stream(
             ContentType, fun() -> receive_request_data(Req) end),
         Doc = couch_doc_from_req(Req, DocId, Doc0),
-        Result = update_doc(Req, Db, DocId, Doc, RespHeaders, UpdateType),
-        WaitFun(),
-        Result;
+        try
+            Result = update_doc(Req, Db, DocId, Doc, RespHeaders, UpdateType),
+            WaitFun(),
+            Result
+        catch throw:Err ->
+            % Document rejected by a validate_doc_update function.
+            couch_doc:abort_multi_part_stream(Parser),
+            throw(Err)
+        end;
     _Else ->
         case couch_httpd:qs_value(Req, "batch") of
         "ok" ->