summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenoit Chesneau <benoitc@apache.org>2010-08-15 14:07:46 +0000
committerBenoit Chesneau <benoitc@apache.org>2010-08-15 14:07:46 +0000
commitb94a613f2cdb3966ab30a8036af41943091f4de4 (patch)
tree0339784c1d57472be8fb0c783fa7bd2d7c62b976
parent9f78585f624d154579cb648d6e7b6298e994fee9 (diff)
add requested_path to the req so we know original path in shows/lists &
updates function. git-svn-id: https://svn.apache.org/repos/asf/couchdb/trunk@985678 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--src/couchdb/couch_db.hrl1
-rw-r--r--src/couchdb/couch_httpd.erl18
-rw-r--r--src/couchdb/couch_httpd_external.erl2
-rwxr-xr-xtest/etap/160-vhosts.t53
4 files changed, 71 insertions, 3 deletions
diff --git a/src/couchdb/couch_db.hrl b/src/couchdb/couch_db.hrl
index 51fb25e2..eb2b6816 100644
--- a/src/couchdb/couch_db.hrl
+++ b/src/couchdb/couch_db.hrl
@@ -72,6 +72,7 @@
{mochi_req,
peer,
method,
+ requested_path_parts,
path_parts,
db_url_handlers,
user_ctx,
diff --git a/src/couchdb/couch_httpd.erl b/src/couchdb/couch_httpd.erl
index 448cd432..b5fe6cce 100644
--- a/src/couchdb/couch_httpd.erl
+++ b/src/couchdb/couch_httpd.erl
@@ -168,12 +168,16 @@ redirect_to_vhost(MochiReq, DefaultFun,
Path = MochiReq:get(raw_path),
Target = VhostTarget ++ Path,
?LOG_DEBUG("Vhost Target: '~p'~n", [Target]),
+
+ Headers = mochiweb_headers:enter("x-couchdb-vhost-path", Path,
+ MochiReq:get(headers)),
+
% build a new mochiweb request
MochiReq1 = mochiweb_request:new(MochiReq:get(socket),
MochiReq:get(method),
Target,
MochiReq:get(version),
- MochiReq:get(headers)),
+ Headers),
% cleanup, It force mochiweb to reparse raw uri.
MochiReq1:cleanup(),
@@ -214,6 +218,14 @@ handle_request_int(MochiReq, DefaultFun,
RawUri = MochiReq:get(raw_path),
{"/" ++ Path, _, _} = mochiweb_util:urlsplit_path(RawUri),
+ Headers = MochiReq:get(headers),
+
+ % get requested path
+ RequestedPath = case MochiReq:get_header_value("x-couchdb-vhost-path") of
+ undefined -> RawUri;
+ P -> P
+ end,
+
HandlerKey =
case mochiweb_util:partition(Path, "/") of
{"", "", ""} ->
@@ -261,10 +273,14 @@ handle_request_int(MochiReq, DefaultFun,
Other -> Other
end,
+
+
HttpReq = #httpd{
mochi_req = MochiReq,
peer = MochiReq:get(peer),
method = Method,
+ requested_path_parts = [list_to_binary(couch_httpd:unquote(Part))
+ || Part <- string:tokens(RequestedPath, "/")],
path_parts = [list_to_binary(couch_httpd:unquote(Part))
|| Part <- string:tokens(Path, "/")],
db_url_handlers = DbUrlHandlers,
diff --git a/src/couchdb/couch_httpd_external.erl b/src/couchdb/couch_httpd_external.erl
index 07202934..84ac44d3 100644
--- a/src/couchdb/couch_httpd_external.erl
+++ b/src/couchdb/couch_httpd_external.erl
@@ -56,6 +56,7 @@ process_external_req(HttpReq, Db, Name) ->
json_req_obj(Req, Db) -> json_req_obj(Req, Db, null).
json_req_obj(#httpd{mochi_req=Req,
method=Method,
+ requested_path_parts=RequestedPath,
path_parts=Path,
req_body=ReqBody
}, Db, DocId) ->
@@ -77,6 +78,7 @@ json_req_obj(#httpd{mochi_req=Req,
{<<"id">>, DocId},
{<<"uuid">>, couch_uuids:new()},
{<<"method">>, Method},
+ {<<"requested_path">>, RequestedPath},
{<<"path">>, Path},
{<<"query">>, json_query_keys(to_json_terms(Req:parse_qs()))},
{<<"headers">>, to_json_terms(Hlist)},
diff --git a/test/etap/160-vhosts.t b/test/etap/160-vhosts.t
index eb704d31..45b3f893 100755
--- a/test/etap/160-vhosts.t
+++ b/test/etap/160-vhosts.t
@@ -54,7 +54,7 @@ config_files() ->
main(_) ->
test_util:init_code_path(),
- etap:plan(4),
+ etap:plan(6),
case (catch test()) of
ok ->
etap:end_tests();
@@ -76,16 +76,41 @@ test() ->
{<<"_id">>, <<"doc1">>},
{<<"value">>, 666}
]}),
- {ok, _} = couch_db:update_docs(Db, [Doc]),
+
+ Doc1 = couch_doc:from_json_obj({[
+ {<<"_id">>, <<"_design/doc1">>},
+ {<<"shows">>, {[
+ {<<"test">>, <<"function(doc, req) {
+ return { json: {
+ requested_path: '/' + req.requested_path.join('/'),
+ path: '/' + req.path.join('/')
+ }};
+}">>}
+ ]}},
+ {<<"rewrites">>, [
+ {[
+ {<<"from">>, <<"/">>},
+ {<<"to">>, <<"_show/test">>}
+ ]}
+ ]}
+ ]}),
+
+ {ok, _} = couch_db:update_docs(Db, [Doc, Doc1]),
+
couch_db:ensure_full_commit(Db),
%% end boilerplate, start test
couch_config:set("vhosts", "example.com", "/etap-test-db", false),
+ couch_config:set("vhosts", "example1.com",
+"/etap-test-db/_design/doc1/_rewrite/", false),
+
test_regular_request(),
test_vhost_request(),
test_vhost_request_with_qs(),
test_vhost_request_with_global(),
+ test_vhost_requested_path(),
+ test_vhost_requested_path_path(),
%% restart boilerplate
couch_db:close(Db),
@@ -129,3 +154,27 @@ test_vhost_request_with_global() ->
etap:is(true, true, "should serve /_utils even inside vhosts");
_Else -> false
end.
+
+test_vhost_requested_path() ->
+ case ibrowse:send_req(server(), [], get, [], [{host_header, "example1.com"}]) of
+ {ok, _, _, Body} ->
+ {Json} = couch_util:json_decode(Body),
+ etap:is(case proplists:get_value(<<"requested_path">>, Json) of
+ <<"/">> -> true;
+ _ -> false
+ end, true, <<"requested path in req ok">>);
+ _Else -> false
+ end.
+
+
+test_vhost_requested_path_path() ->
+ case ibrowse:send_req(server(), [], get, [], [{host_header, "example1.com"}]) of
+ {ok, _, _, Body} ->
+ {Json} = couch_util:json_decode(Body),
+ etap:is(case proplists:get_value(<<"path">>, Json) of
+ <<"/etap-test-db/_design/doc1/_show/test">> -> true;
+ _ -> false
+ end, true, <<"path in req ok">>);
+ _Else -> false
+ end.
+