summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Lehnardt <jan@apache.org>2009-08-04 17:25:17 +0000
committerJan Lehnardt <jan@apache.org>2009-08-04 17:25:17 +0000
commit251e9ad70c6851023f6765fa5b5a6fdcc8456b2a (patch)
tree3b7190565098706c3e9bae3a30faeab84d3d4c19
parent538cfb0940efaab2729724519b68bee8bdbcfad4 (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.js22
-rw-r--r--src/couchdb/couch_httpd_db.erl2
-rw-r--r--src/couchdb/couch_rep.erl30
-rw-r--r--src/couchdb/couch_util.erl25
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