diff options
author | Jan Lehnardt <jan@apache.org> | 2009-08-04 17:25:17 +0000 |
---|---|---|
committer | Jan Lehnardt <jan@apache.org> | 2009-08-04 17:25:17 +0000 |
commit | 251e9ad70c6851023f6765fa5b5a6fdcc8456b2a (patch) | |
tree | 3b7190565098706c3e9bae3a30faeab84d3d4c19 | |
parent | 538cfb0940efaab2729724519b68bee8bdbcfad4 (diff) |
encode slashes in db names in Location response header after database creation, move couch_rep:url_encode/1 to couch_util:url_encode/1, closes COUCHDB-411
git-svn-id: https://svn.apache.org/repos/asf/couchdb/trunk@800883 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | share/www/script/test/basics.js | 22 | ||||
-rw-r--r-- | src/couchdb/couch_httpd_db.erl | 2 | ||||
-rw-r--r-- | src/couchdb/couch_rep.erl | 30 | ||||
-rw-r--r-- | src/couchdb/couch_util.erl | 25 |
4 files changed, 42 insertions, 37 deletions
diff --git a/share/www/script/test/basics.js b/share/www/script/test/basics.js index 5e26360f..3979d860 100644 --- a/share/www/script/test/basics.js +++ b/share/www/script/test/basics.js @@ -29,15 +29,19 @@ couchTests.basics = function(debug) { if (debug) debugger; // creating a new DB should return Location header - xhr = CouchDB.request("DELETE", "/test_suite_db"); - xhr = CouchDB.request("PUT", "/test_suite_db"); - TEquals("/test_suite_db", - xhr.getResponseHeader("Location").substr(-14), - "should return Location header to newly created document"); - - TEquals("http://", - xhr.getResponseHeader("Location").substr(0, 7), - "should return absolute Location header to newly created document"); + // and it should work for dbs with slashes (COUCHDB-411) + var dbnames = ["test_suite_db", "test_suite_db%2Fwith_slashes"]; + dbnames.forEach(function(dbname) { + xhr = CouchDB.request("DELETE", "/" + dbname); + xhr = CouchDB.request("PUT", "/" + dbname); + TEquals(dbname, + xhr.getResponseHeader("Location").substr(-dbname.length), + "should return Location header to newly created document"); + + TEquals("http://", + xhr.getResponseHeader("Location").substr(0, 7), + "should return absolute Location header to newly created document"); + }); // Get the database info, check the db_name T(db.info().db_name == "test_suite_db"); diff --git a/src/couchdb/couch_httpd_db.erl b/src/couchdb/couch_httpd_db.erl index 63ae5563..119182af 100644 --- a/src/couchdb/couch_httpd_db.erl +++ b/src/couchdb/couch_httpd_db.erl @@ -237,7 +237,7 @@ create_db_req(#httpd{user_ctx=UserCtx}=Req, DbName) -> case couch_server:create(DbName, [{user_ctx, UserCtx}]) of {ok, Db} -> couch_db:close(Db), - DocUrl = absolute_uri(Req, "/" ++ DbName), + DocUrl = absolute_uri(Req, "/" ++ couch_util:url_encode(DbName)), send_json(Req, 201, [{"Location", DocUrl}], {[{ok, true}]}); Error -> throw(Error) diff --git a/src/couchdb/couch_rep.erl b/src/couchdb/couch_rep.erl index 3cb90347..71aa0693 100644 --- a/src/couchdb/couch_rep.erl +++ b/src/couchdb/couch_rep.erl @@ -392,7 +392,7 @@ att_stub_converter(DbS, Id, Rev, #att{name=Name,data=stub,type=Type,len=Length}=Att) -> #http_db{uri=DbUrl, headers=Headers} = DbS, {Pos, [RevId|_]} = Rev, - Url = lists:flatten([DbUrl, url_encode(Id), "/", url_encode(?b2l(Name)), + Url = lists:flatten([DbUrl, couch_util:url_encode(Id), "/", couch_util:url_encode(?b2l(Name)), "?rev=", ?b2l(couch_doc:rev_to_str({Pos,RevId}))]), ?LOG_DEBUG("Attachment URL ~s", [Url]), {ok, RcvFun} = make_att_stub_receiver(Url, Headers, Name, @@ -732,7 +732,7 @@ get_missing_revs(Db, DocId) -> open_doc(#http_db{uri=DbUrl, headers=Headers}, DocId, Options) -> [] = Options, - case do_http_request(DbUrl ++ url_encode(DocId), get, Headers) of + case do_http_request(DbUrl ++ couch_util:url_encode(DocId), get, Headers) of {[{<<"error">>, ErrId}, {<<"reason">>, Reason}]} -> {couch_util:to_existing_atom(ErrId), Reason}; Doc -> @@ -744,7 +744,7 @@ open_doc(Db, DocId, Options) -> open_doc_revs(#http_db{uri=DbUrl, headers=Headers} = DbS, DocId, Revs0, [latest]) -> Revs = couch_doc:rev_to_strs(Revs0), - BaseUrl = DbUrl ++ url_encode(DocId) ++ "?revs=true&latest=true", + BaseUrl = DbUrl ++ couch_util:url_encode(DocId) ++ "?revs=true&latest=true", %% MochiWeb expects URLs < 8KB long, so maybe split into multiple requests MaxN = trunc((8192 - length(BaseUrl))/14), @@ -827,7 +827,7 @@ binary_memory(Pid) -> update_doc(#http_db{uri=DbUrl, headers=Headers}, #doc{id=DocId}=Doc, Options) -> [] = Options, - Url = DbUrl ++ url_encode(DocId), + Url = DbUrl ++ couch_util:url_encode(DocId), {ResponseMembers} = do_http_request(Url, put, Headers, couch_doc:to_json_obj(Doc, [attachments])), Rev = proplists:get_value(<<"rev">>, ResponseMembers), @@ -865,25 +865,3 @@ up_to_date(Source, Seq) -> couch_db:close(NewDb), T. -url_encode(Bin) when is_binary(Bin) -> - url_encode(binary_to_list(Bin)); -url_encode([H|T]) -> - if - H >= $a, $z >= H -> - [H|url_encode(T)]; - H >= $A, $Z >= H -> - [H|url_encode(T)]; - H >= $0, $9 >= H -> - [H|url_encode(T)]; - H == $_; H == $.; H == $-; H == $: -> - [H|url_encode(T)]; - true -> - case lists:flatten(io_lib:format("~.16.0B", [H])) of - [X, Y] -> - [$%, X, Y | url_encode(T)]; - [X] -> - [$%, $0, X | url_encode(T)] - end - end; -url_encode([]) -> - []. diff --git a/src/couchdb/couch_util.erl b/src/couchdb/couch_util.erl index db9f937c..71c6aea9 100644 --- a/src/couchdb/couch_util.erl +++ b/src/couchdb/couch_util.erl @@ -18,7 +18,7 @@ -export([abs_pathname/1,abs_pathname/2, trim/1, ascii_lower/1]). -export([encodeBase64/1, decodeBase64/1, to_hex/1,parse_term/1,dict_find/3]). -export([file_read_size/1, get_nested_json_value/2, json_user_ctx/1]). --export([to_binary/1, to_list/1]). +-export([to_binary/1, to_list/1, url_encode/1]). -include("couch_db.hrl"). -include_lib("kernel/include/file.hrl"). @@ -328,3 +328,26 @@ to_list(V) when is_atom(V) -> atom_to_list(V); to_list(V) -> lists:flatten(io_lib:format("~p", [V])). + +url_encode(Bin) when is_binary(Bin) -> + url_encode(binary_to_list(Bin)); +url_encode([H|T]) -> + if + H >= $a, $z >= H -> + [H|url_encode(T)]; + H >= $A, $Z >= H -> + [H|url_encode(T)]; + H >= $0, $9 >= H -> + [H|url_encode(T)]; + H == $_; H == $.; H == $-; H == $: -> + [H|url_encode(T)]; + true -> + case lists:flatten(io_lib:format("~.16.0B", [H])) of + [X, Y] -> + [$%, X, Y | url_encode(T)]; + [X] -> + [$%, $0, X | url_encode(T)] + end + end; +url_encode([]) -> + [].
\ No newline at end of file |