You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by cm...@apache.org on 2008/04/01 00:42:48 UTC

svn commit: r643194 - /incubator/couchdb/branches/mochiweb/src/couchdb/couch_httpd.erl

Author: cmlenz
Date: Mon Mar 31 15:42:42 2008
New Revision: 643194

URL: http://svn.apache.org/viewvc?rev=643194&view=rev
Log:
mochiweb branch: more fixes, 13/17 unit tests passing.

Modified:
    incubator/couchdb/branches/mochiweb/src/couchdb/couch_httpd.erl

Modified: incubator/couchdb/branches/mochiweb/src/couchdb/couch_httpd.erl
URL: http://svn.apache.org/viewvc/incubator/couchdb/branches/mochiweb/src/couchdb/couch_httpd.erl?rev=643194&r1=643193&r2=643194&view=diff
==============================================================================
--- incubator/couchdb/branches/mochiweb/src/couchdb/couch_httpd.erl (original)
+++ incubator/couchdb/branches/mochiweb/src/couchdb/couch_httpd.erl Mon Mar 31 15:42:42 2008
@@ -51,9 +51,13 @@
         'HEAD' -> 'GET';
         Other -> Other
     end,
-    Path = Req:get(path),
+
+    % for the path, use the raw path with the query string and fragment
+    % removed, but URL quoting left intact
+    {Path, _, _} = mochiweb_util:urlsplit_path(Req:get(raw_path)),
+
     couch_log:debug("Method:      ~p", [Method]),
-    couch_log:debug("Request URI: ~p", [Req:get(raw_path)]),
+    couch_log:debug("Request URI: ~p", [Path]),
     couch_log:debug("Headers: ~p", [mochiweb_headers:to_list(Req:get(headers))]),
 
     {ok, Resp} = case catch(handle_request(Req, DocumentRoot, Method, Path)) of
@@ -121,7 +125,7 @@
 handle_db_request(Req, Method, {Path}) ->
     UriParts = string:tokens(Path, "/"),
     [DbName|Rest] = UriParts,
-    handle_db_request(Req, Method, {DbName, Rest});
+    handle_db_request(Req, Method, {url_decode(DbName), Rest});
 
 handle_db_request(Req, 'PUT', {DbName, []}) ->
     case couch_server:create(DbName, []) of
@@ -307,7 +311,7 @@
         direction = Dir,
         start_docid = StartDocId
     } = QueryArgs = parse_view_query(Req),
-    View = {DbName, DocId, ViewName},
+    View = {DbName, "_design/" ++ DocId, ViewName},
     Start = {StartKey, StartDocId},
     FoldlFun = make_view_fold_fun(Req, QueryArgs),
     FoldAccInit = {Count, SkipCount, undefined, []},
@@ -354,22 +358,21 @@
 
 % Document request handlers
 
-handle_db_request(Req, Method, {DbName, Db, Resource}) ->
-    handle_doc_request(Req, Method, DbName, Db, Resource).
+handle_db_request(Req, Method, {DbName, Db, [Resource]}) ->
+    DocId = url_decode(Resource),
+    handle_doc_request(Req, Method, DbName, Db, DocId).
 
-handle_doc_request(Req, 'DELETE', _DbName, Db, [DocId]) ->
+handle_doc_request(Req, 'DELETE', _DbName, Db, DocId) ->
     % TODO: Etag handling
     RevToDelete = proplists:get_value("rev", Req:parse_qs()),
-    couch_log:debug("Processing delete doc ~p, rev ~p", [DocId, RevToDelete]),
     {ok, NewRev} = couch_db:delete_doc(Db, DocId, [RevToDelete]),
-    couch_log:debug("Doc ~p deleted, newrev = ~p", [DocId, NewRev]),
     send_json(Req, 202, {obj, [
         {ok, true},
         {id, DocId},
         {rev, NewRev}
     ]});
 
-handle_doc_request(Req, 'GET', _DbName, Db, [DocId]) ->
+handle_doc_request(Req, 'GET', _DbName, Db, DocId) ->
     #doc_query_args{
         rev = Rev,
         open_revs = Revs,
@@ -427,15 +430,14 @@
         end_json_response(Resp)
     end;
 
-handle_doc_request(Req, 'PUT', _DbName, Db, [DocId]) ->
+handle_doc_request(Req, 'PUT', _DbName, Db, DocId) ->
     % TODO: Etag handling
-    {obj, ObjProps} = Json = cjson:decode(Req:recv_body()),
+    Json = {obj, DocProps} = cjson:decode(Req:recv_body()),
     Doc = couch_doc:from_json_obj(Json),
-    DocRev = proplists:get_value("_rev", ObjProps, ""),
+    DocRev = proplists:get_value("_rev", DocProps, ""),
     Revs = if DocRev /= "" -> [DocRev];
         true -> []
     end,
-
     {ok, NewRev} = couch_db:update_doc(Db, Doc#doc{id=DocId, revs=Revs}, []),
     send_json(Req, 201, {obj, [
         {ok, true},
@@ -443,7 +445,7 @@
         {rev, NewRev}
     ]});
 
-handle_doc_request(_Req, _Method, _DbName, _Db, [_DocId]) ->
+handle_doc_request(_Req, _Method, _DbName, _Db, _DocId) ->
     throw({method_not_allowed, "DELETE,GET,HEAD,PUT"}).
 
 % View request handling internals
@@ -681,12 +683,11 @@
 send_error(Req, {method_not_allowed, Methods}) ->
     Req:respond({405, [{"Allow", Methods}], ""});
 send_error(Req, Error) ->
-    couch_log:info("Error: ~p", [Error]),
     {Code, Json} = error_to_json(Error),
+    couch_log:info("HTTP Error (code ~w): ~p", [Code, Error]),
     send_error(Req, Code, Json).
 
 send_error(Req, Code, Json) ->
-    couch_log:info("HTTP Error (code ~w): ~p", [Code, Json]),
     send_json(Req, Code, Json).
 
 send_json(Req, Value) ->
@@ -718,3 +719,11 @@
 end_json_response(Resp) ->
     Resp:write_chunk(""),
     {ok, Resp}.
+
+url_decode([$%, Hi, Lo | Tail]) ->
+    Hex = erlang:list_to_integer([Hi, Lo], 16),
+    xmerl_ucs:to_utf8([Hex]) ++ url_decode(Tail);
+url_decode([H|T]) ->
+    [H |url_decode(T)];
+url_decode([]) ->
+    [].