diff options
author | Benoit Chesneau <benoitc@apache.org> | 2010-09-07 21:07:17 +0000 |
---|---|---|
committer | Benoit Chesneau <benoitc@apache.org> | 2010-09-07 21:07:17 +0000 |
commit | c1b74df08076cd850617e500163fdb5fc8d55f3a (patch) | |
tree | 6516b641161c51ac116289468a904ae9951f798c | |
parent | 7d478cf34867e4c5475f907acdd9d4ef283c3db4 (diff) |
improve rewriter. No< it's possible to pass a variable in path as <var>
so you can do /somepath/<var>something or /somepath/<var>.txt ...
git-svn-id: https://svn.apache.org/repos/asf/couchdb/trunk@993532 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | share/www/script/test/rewrite.js | 33 | ||||
-rw-r--r-- | src/couchdb/couch_httpd_rewrite.erl | 27 |
2 files changed, 60 insertions, 0 deletions
diff --git a/share/www/script/test/rewrite.js b/share/www/script/test/rewrite.js index 86905f8f..474abb5e 100644 --- a/share/www/script/test/rewrite.js +++ b/share/www/script/test/rewrite.js @@ -91,6 +91,27 @@ couchTests.rewrite = function(debug) { } }, { + "from": "/type/<type>.json", + "to": "_show/type/:type", + "query": { + "format": "json" + } + }, + { + "from": "/type/<type>.xml", + "to": "_show/type/:type", + "query": { + "format": "xml" + } + }, + { + "from": "/type/<type>", + "to": "_show/type/:type", + "query": { + "format": "html" + } + }, + { "from": "/welcome5/*", "to" : "_show/*", "query": { @@ -193,6 +214,9 @@ couchTests.rewrite = function(debug) { }), "welcome3": stringFun(function(doc,req) { return "Welcome " + req.query["name"]; + }), + "type": stringFun(function(doc, req) { + return req.id + " as " + req.query.format; }) }, updates: { @@ -380,6 +404,15 @@ couchTests.rewrite = function(debug) { xhr = CouchDB.request("GET", "/test_suite_db/_design/test/_rewrite/simpleForm/complexView6?a=test&b=essai"); T(xhr.status == 200, "with query params"); T(/Value: doc 4/.test(xhr.responseText)); + + req = CouchDB.request("GET", "/test_suite_db/_design/test/_rewrite/type/test.json"); + T(req.responseText == "test as json"); + + req = CouchDB.request("GET", "/test_suite_db/_design/test/_rewrite/type/test.xml"); + T(req.responseText == "test as xml"); + + req = CouchDB.request("GET", "/test_suite_db/_design/test/_rewrite/type/test"); + T(req.responseText == "test as html"); // test path relative to server designDoc.rewrites.push({ diff --git a/src/couchdb/couch_httpd_rewrite.erl b/src/couchdb/couch_httpd_rewrite.erl index 391fa016..36b90928 100644 --- a/src/couchdb/couch_httpd_rewrite.erl +++ b/src/couchdb/couch_httpd_rewrite.erl @@ -106,6 +106,15 @@ %% {"from": "/a", /a?foo=b /some/b foo =:= b %% "to": "/some/:foo", %% }} +%% +%% {"from": "/a/<foo>" /a/b /some/b foo =:= b +%% "to": "/a/b", +%% }} +%% +%% {"from": "/a/<foo>.blah" /a/b /some/b foo =:= b +%% "to": "/a/b", +%% }} + @@ -322,6 +331,14 @@ bind_path([?MATCH_ALL], [Match|_RestMatch]=Rest, Bindings) -> {ok, Rest, [{?MATCH_ALL, Match}|Bindings]}; bind_path(_, [], _) -> fail; +bind_path([{bind, {Token, MatchRe}}|RestToken], + [Match|RestMatch],Bindings) -> + case re:run(Match, MatchRe, [{capture, all, binary}]) of + {match, [_, Match1]} -> + bind_path(RestToken, RestMatch, [{{bind, Token}, Match1}|Bindings]); + _ -> + fail + end; bind_path([{bind, Token}|RestToken],[Match|RestMatch],Bindings) -> bind_path(RestToken, RestMatch, [{{bind, Token}, Match}|Bindings]); bind_path([Token|RestToken], [Token|RestMatch], Bindings) -> @@ -399,8 +416,18 @@ path_to_list([<<"..">>|R], Acc, DotDotCount) -> path_to_list(R, [<<"..">>|Acc], DotDotCount+1); path_to_list([P|R], Acc, DotDotCount) -> P1 = case P of + <<"<", _Rest/binary>> -> + {ok, VarRe} = re:compile(<<"<([^>].*)>(.*)">>), + case re:run(P, VarRe, [{capture, all, binary}]) of + {match, [_, Var, Match]} -> + {ok, MatchRe} = re:compile(<<"(.*)", Match/binary>>), + {bind, {Var, MatchRe}}; + _ -> P + end; <<":", Var/binary>> -> to_binding(Var); + + _ -> P end, path_to_list(R, [P1|Acc], DotDotCount). |