summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Kocoloski <adam@cloudant.com>2014-01-22 09:32:24 -0500
committerAdam Kocoloski <adam@cloudant.com>2014-01-22 09:32:24 -0500
commit37c8459693dbf55cd4683c7e288dcc9ca8899e97 (patch)
treefd2a8108ed4d7d4a4f02e3ab0d7776a16768ab2f
parent15f4fff02882bdfe879ddbbeba447677d1b18fc1 (diff)
parentcb5e7f6a423865d45b134495888d10aa2e8ac474 (diff)
downloadcouchdb-37c8459693dbf55cd4683c7e288dcc9ca8899e97.tar.gz
Merge branch '2031-fix-qs-rewrite'
Closes COUCHDB-2031
-rw-r--r--share/www/script/test/rewrite.js11
-rw-r--r--src/couchdb/couch_httpd_rewrite.erl54
2 files changed, 36 insertions, 29 deletions
diff --git a/share/www/script/test/rewrite.js b/share/www/script/test/rewrite.js
index e88803291..5c56fa503 100644
--- a/share/www/script/test/rewrite.js
+++ b/share/www/script/test/rewrite.js
@@ -182,6 +182,10 @@ couchTests.rewrite = function(debug) {
{
"from": "/",
"to": "_view/basicView",
+ },
+ {
+ "from": "/db/*",
+ "to": "../../*"
}
],
lists: {
@@ -402,6 +406,13 @@ couchTests.rewrite = function(debug) {
var result = JSON.parse(xhr.responseText);
T(typeof(result.rows[0].doc) === "object");
+ // COUCHDB-2031 - path normalization versus qs params
+ xhr = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/db/_design/test?meta=true");
+ T(xhr.status == 200, "path normalization works with qs params");
+ var result = JSON.parse(xhr.responseText);
+ T(result['_id'] == "_design/test");
+ T(typeof(result['_revs_info']) === "object");
+
// test path relative to server
designDoc.rewrites.push({
"from": "uuids",
diff --git a/src/couchdb/couch_httpd_rewrite.erl b/src/couchdb/couch_httpd_rewrite.erl
index 1187397f8..4354215f0 100644
--- a/src/couchdb/couch_httpd_rewrite.erl
+++ b/src/couchdb/couch_httpd_rewrite.erl
@@ -143,36 +143,32 @@ handle_rewrite_req(#httpd{
DispatchList = [make_rule(Rule) || {Rule} <- Rules],
Method1 = couch_util:to_binary(Method),
- %% get raw path by matching url to a rule.
- RawPath = case try_bind_path(DispatchList, Method1,
- PathParts, QueryList) of
- no_dispatch_path ->
- throw(not_found);
- {NewPathParts, Bindings} ->
- Parts = [quote_plus(X) || X <- NewPathParts],
-
- % build new path, reencode query args, eventually convert
- % them to json
- Bindings1 = maybe_encode_bindings(Bindings),
- Path = binary_to_list(
- iolist_to_binary([
- string:join(Parts, [?SEPARATOR]),
- [["?", mochiweb_util:urlencode(Bindings1)]
- || Bindings1 =/= [] ]
- ])),
-
- % if path is relative detect it and rewrite path
- case mochiweb_util:safe_relative_path(Path) of
- undefined ->
- ?b2l(Prefix) ++ "/" ++ Path;
- P1 ->
- ?b2l(Prefix) ++ "/" ++ P1
- end
+ % get raw path by matching url to a rule. Throws not_found.
+ {NewPathParts0, Bindings0} =
+ try_bind_path(DispatchList, Method1, PathParts, QueryList),
+ NewPathParts = [quote_plus(X) || X <- NewPathParts0],
+ Bindings = maybe_encode_bindings(Bindings0),
+
+ Path0 = string:join(NewPathParts, [?SEPARATOR]),
+
+ % if path is relative detect it and rewrite path
+ Path1 = case mochiweb_util:safe_relative_path(Path0) of
+ undefined ->
+ ?b2l(Prefix) ++ "/" ++ Path0;
+ P1 ->
+ ?b2l(Prefix) ++ "/" ++ P1
+ end,
+
+ Path2 = normalize_path(Path1),
- end,
+ Path3 = case Bindings of
+ [] ->
+ Path2;
+ _ ->
+ [Path2, "?", mochiweb_util:urlencode(Bindings)]
+ end,
- % normalize final path (fix levels "." and "..")
- RawPath1 = ?b2l(iolist_to_binary(normalize_path(RawPath))),
+ RawPath1 = ?b2l(iolist_to_binary(Path3)),
% In order to do OAuth correctly, we have to save the
% requested path. We use default so chained rewriting
@@ -216,7 +212,7 @@ quote_plus(X) ->
%% @doc Try to find a rule matching current url. If none is found
%% 404 error not_found is raised
try_bind_path([], _Method, _PathParts, _QueryList) ->
- no_dispatch_path;
+ throw(not_found);
try_bind_path([Dispatch|Rest], Method, PathParts, QueryList) ->
[{PathParts1, Method1}, RedirectPath, QueryArgs, Formats] = Dispatch,
case bind_method(Method1, Method) of