Anonymous avatar Anonymous committed 263fb4f

url-unquote keys and buckets in jiak_resource and jaywalker resource
Thanks, Jay Doane.

Comments (0)

Files changed (4)

 Christopher Brown
 Tuncer Ayaz
 Rusty Klophaus
+Jay Doane
 

src/jaywalker_resource.erl

      RD, Ctx}.
 
 resource_exists(RD, Ctx=#ctx{jiak_client=JiakClient}) ->
-    Bucket = list_to_atom(wrq:path_info(bucket, RD)),
-    Key = list_to_binary(wrq:path_info(key, RD)),
+    Bucket = list_to_atom(mochiweb_util:unquote(
+                            wrq:path_info(bucket, RD))),
+    Key = list_to_binary(mochiweb_util:unquote(
+                           wrq:path_info(key, RD))),
     case JiakClient:get(Bucket, Key, 2) of
         {ok, Start} ->
             {true, RD, Ctx#ctx{start=Start}};
 parts_to_query([[B,T,A]|Rest], Acc) ->
     parts_to_query(Rest,
                    [{if B == "_" -> '_';
-                        true     -> list_to_atom(B)
+                        true     -> list_to_atom(mochiweb_util:unquote(B))
                      end,
                      if T == "_" -> '_';
-                        true     -> list_to_binary(T)
+                        true     -> list_to_binary(mochiweb_util:unquote(T))
                      end,
                      if A == "1"          -> true;
                         A == "0"          -> false;

src/jiak_resource.erl

     {ServiceAvailable, NewCtx} = 
         case wrq:method(ReqData) of
             'PUT' -> 
-                _ = list_to_atom(wrq:path_info(bucket, ReqData)),
+                _ = list_to_atom(mochiweb_util:unquote(
+                                   wrq:path_info(bucket, ReqData))),
                 Mod = jiak_default:new([]),
                 {true, Context#ctx{module=Mod, key=schema}};
             _ ->
     Key = case Ctx0#ctx.key of
               container -> container;
               schema -> schema;
-              _         -> list_to_binary(wrq:path_info(key, RD))
+              _         -> list_to_binary(mochiweb_util:unquote(
+                                            wrq:path_info(key, RD)))
           end,
     case jiak_util:bucket_from_uri(RD) of
         {ok, Bucket} ->
 
 add_container_link(Bucket,ReqData) ->
     Val = io_lib:format("</~s/~s>; rel=\"up\"",
-                    [riak:get_app_env(jiak_name, "jiak"),Bucket]),
+                    [riak:get_app_env(jiak_name, "jiak"),
+                     mochiweb_util:quote_plus(Bucket)]),
     wrq:merge_resp_headers([{"Link",Val}],ReqData).
 
 add_link_head(Bucket,Key,Tag,ReqData) ->
     Val = io_lib:format("</~s/~s/~s>; riaktag=\"~s\"",
-                    [riak:get_app_env(jiak_name, "jiak"),Bucket, Key, Tag]),
+                    [riak:get_app_env(jiak_name, "jiak")|
+                     [mochiweb_util:quote_plus(E) ||
+                         E <- [Bucket, Key, Tag] ]]),
     wrq:merge_resp_headers([{"Link",Val}],ReqData).
 
 %% @spec full_schema(riak_object:bucket()) ->
 %% @spec make_uri(string(), riak_object:bucket(), string()) -> string()
 %% @doc Get the string-path for the bucket and subpath under jiak.
 make_uri(JiakName,Bucket,Path) ->
-    "/" ++ JiakName ++ "/" ++ atom_to_list(Bucket) ++ "/" ++ Path.
+    "/" ++ JiakName ++ 
+        "/" ++ mochiweb_util:quote_plus(atom_to_list(Bucket)) ++
+        "/" ++ Path.
 
 %% @spec handle_incoming(webmachine:wrq(), context()) ->
 %%          {true, webmachine:wrq(), context()}
                                      make_uri(JiakName,Bucket,
                                               wrq:disp_path(ReqData)),
                                      ReqData),
-                 list_to_binary(wrq:disp_path(ReqData))};
+                 list_to_binary(mochiweb_util:unquote(wrq:disp_path(ReqData)))};
             _ ->
                 {item, ReqData, Key}
         end,
 %%      case of a POST to a bucket, or the path for the given object
 %%      in the case of a POST to a specific object.
 create_path(ReqData, Context=#ctx{key=container}) ->
+    %% riak_util:unique_id_62 produces url-safe strings
     {riak_util:unique_id_62(), ReqData, Context};
 create_path(ReqData, Context=#ctx{key=Key}) ->
-    {Key, ReqData, Context}.
+    {mochiweb_util:quote_plus(Key), ReqData, Context}.
 
 %% @spec delete_resource(webmachine:wrq(), context()) ->
 %%          {boolean(), webmachine:wrq(), context()}

src/jiak_util.erl

 %%      The bucket name must be an existing atom, or this function
 %%      will return {error, no_such_bucket}
 bucket_from_uri(RD) ->
-    try {ok, list_to_existing_atom(wrq:path_info(bucket, RD))}
+    try {ok, list_to_existing_atom(mochiweb_util:unquote(
+                                     wrq:path_info(bucket, RD)))}
     catch _:_ -> {error, no_such_bucket} end.
 
 dynamic_bucket_test() ->
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.