Updated Branches: refs/heads/1651-fix-reset-rewrite-count 3863eccf2 -> 0c216d163 (forced update)
Reset rewrite counter on new request We were spuriously throwing rewrite limit exceeded for non-looping rewrites. This patch resets the count to zero at the start of a new request and adds a test. COUCHDB-1651 Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/0c216d16 Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/0c216d16 Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/0c216d16 Branch: refs/heads/1651-fix-reset-rewrite-count Commit: 0c216d163155ac27c9d80ce11f3f3816abb3bd14 Parents: 6beb66c Author: Robert Newson <rnew...@apache.org> Authored: Sat Feb 16 11:07:55 2013 +0000 Committer: Jan Lehnardt <j...@apache.org> Committed: Sun Feb 17 20:40:50 2013 +0100 ---------------------------------------------------------------------- CHANGES | 2 ++ share/www/script/test/rewrite.js | 19 ++++++++++++++++++- src/couchdb/couch_db.hrl | 2 ++ src/couchdb/couch_httpd.erl | 2 ++ src/couchdb/couch_httpd_rewrite.erl | 16 +++++++--------- 5 files changed, 31 insertions(+), 10 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/couchdb/blob/0c216d16/CHANGES ---------------------------------------------------------------------- diff --git a/CHANGES b/CHANGES index 3012e3d..743b30a 100644 --- a/CHANGES +++ b/CHANGES @@ -72,6 +72,8 @@ UUID Algorithms: URL Rewriter & Vhosts: * Database name is encoded during rewriting (allowing embedded /'s, etc) + * Reset rewrite counter on new request, avoiding unnecessary request + failures due to bogus rewrite limit reports Log System: http://git-wip-us.apache.org/repos/asf/couchdb/blob/0c216d16/share/www/script/test/rewrite.js ---------------------------------------------------------------------- diff --git a/share/www/script/test/rewrite.js b/share/www/script/test/rewrite.js index ed7d26c..e888032 100644 --- a/share/www/script/test/rewrite.js +++ b/share/www/script/test/rewrite.js @@ -464,6 +464,7 @@ couchTests.rewrite = function(debug) { }; db.save(ddoc_loop); + // Assert loop detection run_on_modified_server( [{section: "httpd", key: "rewrite_limit", @@ -471,7 +472,23 @@ couchTests.rewrite = function(debug) { function(){ var url = "/"+dbName+"/_design/loop/_rewrite/loop"; var xhr = CouchDB.request("GET", url); - T(xhr.status = 400); + TEquals(400, xhr.status); + }); + + // Assert serial execution is not spuriously counted as loop + run_on_modified_server( + [{section: "httpd", + key: "rewrite_limit", + value: "2"}, + {section: "httpd", + key: "secure_rewrites", + value: "false"}], + function(){ + var url = "/"+dbName+"/_design/test/_rewrite/foo"; + for (var i=0; i < 5; i++) { + var xhr = CouchDB.request("GET", url); + TEquals(200, xhr.status); + } }); } } http://git-wip-us.apache.org/repos/asf/couchdb/blob/0c216d16/src/couchdb/couch_db.hrl ---------------------------------------------------------------------- diff --git a/src/couchdb/couch_db.hrl b/src/couchdb/couch_db.hrl index 8d7d020..4036934 100644 --- a/src/couchdb/couch_db.hrl +++ b/src/couchdb/couch_db.hrl @@ -21,6 +21,8 @@ % the lowest possible database sequence number -define(LOWEST_SEQ, 0). +-define(REWRITE_COUNT, couch_rewrite_count). + -define(JSON_ENCODE(V), ejson:encode(V)). -define(JSON_DECODE(V), ejson:decode(V)). http://git-wip-us.apache.org/repos/asf/couchdb/blob/0c216d16/src/couchdb/couch_httpd.erl ---------------------------------------------------------------------- diff --git a/src/couchdb/couch_httpd.erl b/src/couchdb/couch_httpd.erl index 3e3415b..66d28d2 100644 --- a/src/couchdb/couch_httpd.erl +++ b/src/couchdb/couch_httpd.erl @@ -226,6 +226,8 @@ make_fun_spec_strs(SpecStr) -> handle_request(MochiReq, DefaultFun, UrlHandlers, DbUrlHandlers, DesignUrlHandlers) -> + %% reset rewrite count for new request + erlang:put(?REWRITE_COUNT, 0), MochiReq1 = couch_httpd_vhost:dispatch_host(MochiReq), http://git-wip-us.apache.org/repos/asf/couchdb/blob/0c216d16/src/couchdb/couch_httpd_rewrite.erl ---------------------------------------------------------------------- diff --git a/src/couchdb/couch_httpd_rewrite.erl b/src/couchdb/couch_httpd_rewrite.erl index 756cdef..232d2a3 100644 --- a/src/couchdb/couch_httpd_rewrite.erl +++ b/src/couchdb/couch_httpd_rewrite.erl @@ -119,15 +119,13 @@ handle_rewrite_req(#httpd{ Prefix = <<"/", (?l2b(couch_util:url_encode(DbName)))/binary, "/", DesignId/binary>>, QueryList = lists:map(fun decode_query_value/1, couch_httpd:qs(Req)), - MaxRewritesList = couch_config:get("httpd", "rewrite_limit", "100"), - MaxRewrites = list_to_integer(MaxRewritesList), - case get(couch_rewrite_count) of - undefined -> - put(couch_rewrite_count, 1); - NumRewrites when NumRewrites < MaxRewrites -> - put(couch_rewrite_count, NumRewrites + 1); - _ -> - throw({bad_request, <<"Exceeded rewrite recursion limit">>}) + RewritesSoFar = erlang:get(?REWRITE_COUNT), + MaxRewrites = list_to_integer(couch_config:get("httpd", "rewrite_limit", "100")), + case RewritesSoFar >= MaxRewrites of + true -> + throw({bad_request, <<"Exceeded rewrite recursion limit">>}); + false -> + erlang:put(?REWRITE_COUNT, RewritesSoFar + 1) end, #doc{body={Props}} = DDoc,