summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenoit Chesneau <benoitc@apache.org>2010-09-07 21:07:17 +0000
committerBenoit Chesneau <benoitc@apache.org>2010-09-07 21:07:17 +0000
commitc1b74df08076cd850617e500163fdb5fc8d55f3a (patch)
tree6516b641161c51ac116289468a904ae9951f798c
parent7d478cf34867e4c5475f907acdd9d4ef283c3db4 (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.js33
-rw-r--r--src/couchdb/couch_httpd_rewrite.erl27
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).