diff options
-rw-r--r-- | apps/couch/THANKS | 1 | ||||
-rw-r--r-- | apps/couch/src/couch_httpd_show.erl | 16 | ||||
-rw-r--r-- | apps/couch/src/couch_rep_changes_feed.erl | 25 | ||||
-rw-r--r-- | apps/couch/src/test_util.erl | 28 | ||||
-rw-r--r-- | rel/overlay/share/www/script/test/update_documents.js | 24 | ||||
-rwxr-xr-x | test/etap/072-cleanup.t | 8 |
6 files changed, 83 insertions, 19 deletions
diff --git a/apps/couch/THANKS b/apps/couch/THANKS index 76a0c19b..470c3937 100644 --- a/apps/couch/THANKS +++ b/apps/couch/THANKS @@ -82,5 +82,6 @@ suggesting improvements or submitting changes. Some of these people are: * Caolan McMahon <caolan.mcmahon@googlemail.com> * Alexander Shorin <kxepal@gmail.com> * Christopher Bonhage <queezey@me.com> + * Christian Carter <cdcarter@gmail.com> For a list of authors see the `AUTHORS` file. diff --git a/apps/couch/src/couch_httpd_show.erl b/apps/couch/src/couch_httpd_show.erl index 742b0f20..58f046e4 100644 --- a/apps/couch/src/couch_httpd_show.erl +++ b/apps/couch/src/couch_httpd_show.erl @@ -127,7 +127,7 @@ handle_doc_update_req(Req, _Db, _DDoc) -> send_doc_update_response(Req, Db, DDoc, UpdateName, Doc, DocId) -> JsonReq = couch_httpd_external:json_req_obj(Req, Db, DocId), JsonDoc = couch_query_servers:json_doc(Doc), - {Code, JsonResp1} = case couch_query_servers:ddoc_prompt(DDoc, + JsonResp1 = case couch_query_servers:ddoc_prompt(DDoc, [<<"updates">>, UpdateName], [JsonDoc, JsonReq]) of [<<"up">>, {NewJsonDoc}, {JsonResp}] -> Options = case couch_httpd:header_value(Req, "X-Couch-Full-Commit", @@ -140,16 +140,14 @@ send_doc_update_response(Req, Db, DDoc, UpdateName, Doc, DocId) -> NewDoc = couch_doc:from_json_obj({NewJsonDoc}), {ok, NewRev} = couch_db:update_doc(Db, NewDoc, Options), NewRevStr = couch_doc:rev_to_str(NewRev), - JsonRespWithRev = {[{<<"headers">>, - {[{<<"X-Couch-Update-NewRev">>, NewRevStr}]}} | JsonResp]}, - {201, JsonRespWithRev}; - [<<"up">>, _Other, JsonResp] -> - {200, JsonResp} + {[{<<"code">>, 201}, {<<"headers">>, + {[{<<"X-Couch-Update-NewRev">>, NewRevStr}]}} | JsonResp]}; + [<<"up">>, _Other, {JsonResp}] -> + {[{<<"code">>, 200} | JsonResp]} end, - - JsonResp2 = couch_util:json_apply_field({<<"code">>, Code}, JsonResp1), + % todo set location field - couch_httpd_external:send_external_response(Req, JsonResp2). + couch_httpd_external:send_external_response(Req, JsonResp1). % view-list request with view and list from same design doc. diff --git a/apps/couch/src/couch_rep_changes_feed.erl b/apps/couch/src/couch_rep_changes_feed.erl index 49edf7cc..7a9573d6 100644 --- a/apps/couch/src/couch_rep_changes_feed.erl +++ b/apps/couch/src/couch_rep_changes_feed.erl @@ -491,13 +491,30 @@ purge_req_messages(ReqId) -> ok end. -queue_changes_row(Row, #state{doc_ids = nil, count = Count, rows = Rows}) -> - {queue:in(Row, Rows), Count + 1}; +queue_changes_row(Row, #state{doc_ids = nil} = State) -> + maybe_queue_row(Row, State); queue_changes_row({RowProps} = Row, - #state{doc_ids = Ids, count = Count, rows = Rows}) -> + #state{doc_ids = Ids, count = Count, rows = Rows} = State) -> case lists:member(get_value(<<"id">>, RowProps), Ids) of true -> - {queue:in(Row, Rows), Count + 1}; + maybe_queue_row(Row, State); false -> {Rows, Count} end. + +maybe_queue_row({Props} = Row, #state{count = Count, rows = Rows} = State) -> + case get_value(<<"id">>, Props) of + <<>> -> + [_, Db | _] = State#state.init_args, + ?LOG_ERROR("Replicator: ignoring document with empty ID in source " + "database `~s` (_changes sequence ~p)", + [dbname(Db), couch_util:get_value(<<"seq">>, Props)]), + {Rows, Count}; + _ -> + {queue:in(Row, Rows), Count + 1} + end. + +dbname(#http_db{url = Url}) -> + couch_util:url_strip_password(Url); +dbname(#db{name = Name}) -> + Name. diff --git a/apps/couch/src/test_util.erl b/apps/couch/src/test_util.erl index 55b95139..f086bf94 100644 --- a/apps/couch/src/test_util.erl +++ b/apps/couch/src/test_util.erl @@ -14,6 +14,7 @@ -export([init_code_path/0]). -export([source_file/1, build_file/1, config_files/0]). +-export([request/3, request/4]). init_code_path() -> code:load_abs("apps/couch/test/etap/etap"). @@ -31,3 +32,30 @@ config_files() -> source_file("test/etap/random_port.ini") ]. +request(Url, Headers, Method) -> + request(Url, Headers, Method, []). + +request(Url, Headers, Method, Body) -> + request(Url, Headers, Method, Body, 3). + +request(_Url, _Headers, _Method, _Body, 0) -> + {error, request_failed}; +request(Url, Headers, Method, Body, N) -> + case code:is_loaded(ibrowse) of + false -> + {ok, _} = ibrowse:start(); + _ -> + ok + end, + case ibrowse:send_req(Url, Headers, Method, Body) of + {ok, Code0, RespHeaders, RespBody0} -> + Code = list_to_integer(Code0), + RespBody = iolist_to_binary(RespBody0), + {ok, Code, RespHeaders, RespBody}; + {error, {'EXIT', {normal, _}}} -> + % Connection closed right after a successful request that + % used the same connection. + request(Url, Headers, Method, Body, N - 1); + Error -> + Error + end. diff --git a/rel/overlay/share/www/script/test/update_documents.js b/rel/overlay/share/www/script/test/update_documents.js index 4d2b29fc..59af4597 100644 --- a/rel/overlay/share/www/script/test/update_documents.js +++ b/rel/overlay/share/www/script/test/update_documents.js @@ -75,6 +75,17 @@ couchTests.update_documents = function(debug) { }), "get-uuid" : stringFun(function(doc, req) { return [null, req.uuid]; + }), + "code-n-bump" : stringFun(function(doc,req) { + if (!doc.counter) doc.counter = 0; + doc.counter += 1; + var message = "<h1>bumped it!</h1>"; + resp = {"code": 302, "body": message} + return [doc, resp]; + }), + "resp-code" : stringFun(function(doc,req) { + resp = {"code": 302} + return [null, resp]; }) } }; @@ -179,4 +190,17 @@ couchTests.update_documents = function(debug) { var doc = db.open("with/slash"); TEquals(2, doc.counter, "counter should be 2"); + + // COUCHDB-648 - the code in the JSON response should be honored + + xhr = CouchDB.request("PUT", "/test_suite_db/_design/update/_update/code-n-bump/"+docid, { + headers : {"X-Couch-Full-Commit":"true"} + }); + T(xhr.status == 302); + T(xhr.responseText == "<h1>bumped it!</h1>"); + doc = db.open(docid); + T(doc.counter == 3); + + xhr = CouchDB.request("POST", "/test_suite_db/_design/update/_update/resp-code/"); + T(xhr.status == 302); }; diff --git a/test/etap/072-cleanup.t b/test/etap/072-cleanup.t index 61790bc6..6f97193d 100755 --- a/test/etap/072-cleanup.t +++ b/test/etap/072-cleanup.t @@ -41,7 +41,6 @@ main(_) -> test() -> {ok, _} = couch_server_sup:start_link(test_util:config_files()), - ok = application:start(inets), couch_server:delete(?TEST_DB, []), timer:sleep(1000), @@ -110,11 +109,8 @@ db_url() -> binary_to_list(?TEST_DB). query_view(DDoc, View) -> - {ok, {{_, Code, _}, _Headers, _Body}} = http:request( - get, - {db_url() ++ "/_design/" ++ DDoc ++ "/_view/" ++ View, []}, - [], - [{sync, true}]), + {ok, Code, _Headers, _Body} = test_util:request( + db_url() ++ "/_design/" ++ DDoc ++ "/_view/" ++ View, [], get), etap:is(Code, 200, "Built view index for " ++ DDoc ++ "."), ok. |