diff options
author | Adam Kocoloski <adam@cloudant.com> | 2014-01-22 09:32:24 -0500 |
---|---|---|
committer | Adam Kocoloski <adam@cloudant.com> | 2014-01-22 09:32:24 -0500 |
commit | 37c8459693dbf55cd4683c7e288dcc9ca8899e97 (patch) | |
tree | fd2a8108ed4d7d4a4f02e3ab0d7776a16768ab2f | |
parent | 15f4fff02882bdfe879ddbbeba447677d1b18fc1 (diff) | |
parent | cb5e7f6a423865d45b134495888d10aa2e8ac474 (diff) | |
download | couchdb-37c8459693dbf55cd4683c7e288dcc9ca8899e97.tar.gz |
Merge branch '2031-fix-qs-rewrite'
Closes COUCHDB-2031
-rw-r--r-- | share/www/script/test/rewrite.js | 11 | ||||
-rw-r--r-- | src/couchdb/couch_httpd_rewrite.erl | 54 |
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 |