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/05/31 22:17:49 UTC
svn commit: r1129897 - in /couchdb/trunk/src/couchdb: couch_doc.erl
couch_httpd_db.erl
Author: fdmanana
Date: Tue May 31 20:17:48 2011
New Revision: 1129897
URL: http://svn.apache.org/viewvc?rev=1129897&view=rev
Log:
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/trunk/src/couchdb/couch_doc.erl
couchdb/trunk/src/couchdb/couch_httpd_db.erl
Modified: couchdb/trunk/src/couchdb/couch_doc.erl
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_doc.erl?rev=1129897&r1=1129896&r2=1129897&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/couch_doc.erl (original)
+++ couchdb/trunk/src/couchdb/couch_doc.erl Tue May 31 20:17:48 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]).
-export([to_path/1]).
-export([mp_parse_doc/2]).
-export([with_ejson_body/1, with_bin_body/1]).
@@ -520,7 +521,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}, []) ->
@@ -553,6 +554,24 @@ mp_parse_atts(body_end) ->
fun mp_parse_atts/1.
+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.
+
+
with_bin_body(#doc{body = Json} = Doc) when is_binary(Json) ->
Doc;
with_bin_body(#doc{body = EJson} = Doc) ->
Modified: couchdb/trunk/src/couchdb/couch_httpd_db.erl
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_httpd_db.erl?rev=1129897&r1=1129896&r2=1129897&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/couch_httpd_db.erl (original)
+++ couchdb/trunk/src/couchdb/couch_httpd_db.erl Tue May 31 20:17:48 2011
@@ -696,12 +696,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" ->