From b94a613f2cdb3966ab30a8036af41943091f4de4 Mon Sep 17 00:00:00 2001 From: Benoit Chesneau Date: Sun, 15 Aug 2010 14:07:46 +0000 Subject: 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 --- src/couchdb/couch_db.hrl | 1 + src/couchdb/couch_httpd.erl | 18 +++++++++++- src/couchdb/couch_httpd_external.erl | 2 ++ test/etap/160-vhosts.t | 53 ++++++++++++++++++++++++++++++++++-- 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. + -- cgit v1.2.3