No title Revision 333063613038 (Tue Feb 22 2011 at 12:25) - Diff Link to this snippet: https://friendpaste.com/7mEZ1v1vnq8TZLW55VI892 Embed: manni perldoc borland colorful default murphy trac fruity autumn bw emacs pastie friendly Show line numbers Wrap lines 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162diff --git a/src/couchdb/couch_httpd_rewrite.erl b/src/couchdb/couch_httpd_rewrite.erlindex 6324631..ce44fdd 100644--- a/src/couchdb/couch_httpd_rewrite.erl+++ b/src/couchdb/couch_httpd_rewrite.erl@@ -126,8 +126,7 @@ handle_rewrite_req(#httpd{ % we are in a design handler DesignId = <<"_design/", DesignName/binary>>, Prefix = <<"/", DbName/binary, "/", DesignId/binary>>,- QueryList = couch_httpd:qs(Req),- QueryList1 = [{to_binding(K), V} || {K, V} <- QueryList],+ QueryList = lists:map(fun decode_query_value/1, couch_httpd:qs(Req)), #doc{body={Props}} = DDoc, @@ -145,7 +144,7 @@ handle_rewrite_req(#httpd{ %% get raw path by matching url to a rule. RawPath = case try_bind_path(DispatchList, couch_util:to_binary(Method), PathParts,- QueryList1) of+ QueryList) of no_dispatch_path -> throw(not_found); {NewPathParts, Bindings} ->@@ -153,13 +152,15 @@ handle_rewrite_req(#httpd{ % build new path, reencode query args, eventually convert % them to json- Path = lists:append(- string:join(Parts, [?SEPARATOR]),- case Bindings of- [] -> [];- _ -> [$?, encode_query(Bindings)]- end),- + Bindings1 = maybe_encode_bindings(Bindings),+ ?LOG_INFO("bindings1 ~p~n", [Bindings1]),+ 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 ->@@ -253,44 +254,29 @@ make_query_list([{Key, Value}|Rest], Bindings, Acc) when is_list(Value) -> make_query_list([{Key, Value}|Rest], Bindings, Acc) -> make_query_list(Rest, Bindings, [{to_binding(Key), Value}|Acc]). -replace_var(Key, Value, Bindings) ->- case Value of- <<":", Var/binary>> ->- get_var(Var, Bindings, Value);- <<"*">> ->- get_var(Value, Bindings, Value);- _ when is_list(Value) ->- Value1 = lists:foldr(fun(V, Acc) ->- V1 = case V of- <<":", VName/binary>> ->- case get_var(VName, Bindings, V) of- V2 when is_list(V2) ->- iolist_to_binary(V2);- V2 -> V2- end;- <<"*">> ->- get_var(V, Bindings, V);- _ ->- V- end,- [V1|Acc]- end, [], Value),- to_json(Value1);- _ when is_binary(Value) ->- Value;- _ ->- case Key of- <<"key">> -> to_json(Value);- <<"startkey">> -> to_json(Value);- <<"start_key">> -> to_json(Value);- <<"endkey">> -> to_json(Value);- <<"end_key">> -> to_json(Value);- _ ->- lists:flatten(?JSON_ENCODE(Value))- end+replace_var(Key, <<":", Var/binary>> = Value, Bindings) ->+ get_var(Var, Bindings, Value);+replace_var(_Key, Value, Bindings) when is_binary(Value) ->+ Value;+replace_var(_Key, Value, Bindings) when is_list(Value) ->+ lists:foldl(fun+ (<<":", Var/binary>>=Value1, Acc) ->+ [get_var(Var, Bindings, Value1)|Acc];+ (Value1, Acc) ->+ [Value1|Acc]+ end, [], Value);+replace_var(Key, Value, _Bindings) ->+ Value.+ +maybe_json(Key, Value) ->+ case lists:member(Key, [<<"key">>, <<"startkey">>, <<"start_key">>,+ <<"endkey">>, <<"end_key">>]) of+ true ->+ ?JSON_ENCODE(Value);+ false ->+ Value end. - get_var(VarName, Props, Default) -> VarName1 = to_binding(VarName), couch_util:get_value(VarName1, Props, Default).@@ -309,7 +295,7 @@ make_new_path([?MATCH_ALL|_Rest], _Bindings, Remaining, Acc) -> make_new_path([{bind, P}|Rest], Bindings, Remaining, Acc) -> P2 = case couch_util:get_value({bind, P}, Bindings) of undefined -> << "undefined">>;- P1 -> P1+ P1 -> to_json(P1) end, make_new_path(Rest, Bindings, Remaining, [P2|Acc]); make_new_path([P|Rest], Bindings, Remaining, Acc) ->@@ -437,21 +423,25 @@ path_to_list([P|R], Acc, DotDotCount) -> end, path_to_list(R, [P1|Acc], DotDotCount). -encode_query(Props) -> - Props1 = lists:foldl(fun ({{bind, K}, V}, Acc) ->- case K of- <<"*">> -> Acc;- _ ->- V1 = case is_list(V) orelse is_binary(V) of- true -> V;- false ->- % probably it's a number- quote_plus(V)- end,- [{K, V1} | Acc]- end- end, [], Props),- lists:flatten(mochiweb_util:urlencode(Props1)).+maybe_encode_bindings([]) ->+ [];+maybe_encode_bindings(Props) -> + lists:foldl(fun + ({{bind, <<"*">>}, V}, Acc) ->+ Acc;+ ({{bind, K}, V}, Acc) ->+ V1 = iolist_to_binary(maybe_json(K, V)),+ [{K, V1}|Acc]+ end, [], Props).+ +decode_query_value({K,V}) ->+ case lists:member(K, ["key", "startkey", "start_key",+ "endkey", "end_key"]) of+ true ->+ {to_binding(K), ?JSON_DECODE(V)};+ false ->+ {to_binding(K), ?l2b(V)}+ end. to_binding({bind, V}) -> {bind, V};