summaryrefslogtreecommitdiff
path: root/src/couchdb/couch_httpd_form.erl
diff options
context:
space:
mode:
authorJohn Christopher Anderson <jchris@apache.org>2009-01-12 01:48:36 +0000
committerJohn Christopher Anderson <jchris@apache.org>2009-01-12 01:48:36 +0000
commitf5e38acc625d4bb73934e121a9d6abb75e507460 (patch)
tree41e03518ee8bfa43c1226629d265ae66299ab444 /src/couchdb/couch_httpd_form.erl
parent2417e37a68178c3212c9374d73bea5a2522ab418 (diff)
rename _form to _show and move the funcs in the design doc to design.show.docs
git-svn-id: https://svn.apache.org/repos/asf/couchdb/trunk@733576 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/couchdb/couch_httpd_form.erl')
-rw-r--r--src/couchdb/couch_httpd_form.erl114
1 files changed, 0 insertions, 114 deletions
diff --git a/src/couchdb/couch_httpd_form.erl b/src/couchdb/couch_httpd_form.erl
deleted file mode 100644
index f4fa2c18..00000000
--- a/src/couchdb/couch_httpd_form.erl
+++ /dev/null
@@ -1,114 +0,0 @@
-% Licensed under the Apache License, Version 2.0 (the "License"); you may not
-% use this file except in compliance with the License. You may obtain a copy of
-% the License at
-%
-% http://www.apache.org/licenses/LICENSE-2.0
-%
-% Unless required by applicable law or agreed to in writing, software
-% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-% License for the specific language governing permissions and limitations under
-% the License.
-
--module(couch_httpd_form).
-
--export([handle_form_req/2]).
-
-
--include("couch_db.hrl").
-
--import(couch_httpd,
- [send_json/2,send_json/3,send_json/4,send_method_not_allowed/2,
- start_json_response/2,send_chunk/2,end_json_response/1,
- start_chunked_response/3, send_error/4]).
-
-handle_form_req(#httpd{method='GET',path_parts=[_, _, DesignName, FormName, Docid]}=Req, Db) ->
- DesignId = <<"_design/", DesignName/binary>>,
- % Anyway we can dry up this error handling?
- case (catch couch_httpd_db:couch_doc_open(Db, DesignId, [], [])) of
- {not_found, missing} ->
- throw({not_found, missing_design_doc});
- {not_found, deleted} ->
- throw({not_found, deleted_design_doc});
- DesignDoc ->
- #doc{body={Props}} = DesignDoc,
- Lang = proplists:get_value(<<"language">>, Props, <<"javascript">>),
- case proplists:get_value(<<"forms">>, Props, nil) of
- {Forms} ->
- case proplists:get_value(FormName, Forms, nil) of
- nil ->
- throw({not_found, missing_form});
- FormSrc ->
- case (catch couch_httpd_db:couch_doc_open(Db, Docid, [], [])) of
- {not_found, missing} ->
- throw({not_found, missing});
- {not_found, deleted} ->
- throw({not_found, deleted});
- Doc ->
- % ok we have everythign we need. let's make it happen.
- send_form_response(Lang, FormSrc, Doc, Req, Db)
- end
- end;
- nil ->
- throw({not_found, missing_form})
- end
- end;
-
-handle_form_req(#httpd{method='GET'}=Req, _Db) ->
- send_error(Req, 404, <<"form_error">>, <<"Invalid path.">>);
-
-handle_form_req(Req, _Db) ->
- send_method_not_allowed(Req, "GET,HEAD").
-
-
-send_form_response(Lang, FormSrc, #doc{revs=[DocRev|_]}=Doc, #httpd{mochi_req=MReq}=Req, Db) ->
- % make a term with etag-effecting Req components, but not always changing ones.
- Headers = MReq:get(headers),
- Hlist = mochiweb_headers:to_list(Headers),
- Accept = proplists:get_value('Accept', Hlist),
- <<SigInt:128/integer>> = erlang:md5(term_to_binary({Lang, FormSrc, DocRev, Accept})),
- CurrentEtag = list_to_binary("\"" ++ lists:flatten(io_lib:format("form_~.36B",[SigInt])) ++ "\""),
- EtagsToMatch = string:tokens(
- couch_httpd:header_value(Req, "If-None-Match", ""), ", "),
- % We know our etag now
- case lists:member(binary_to_list(CurrentEtag), EtagsToMatch) of
- true ->
- % the client has this in their cache.
- couch_httpd:send_response(Req, 304, [{"Etag", CurrentEtag}], <<>>);
- false ->
- % Run the external form renderer.
- {JsonResponse} = couch_query_servers:render_doc_form(Lang, FormSrc, Doc, Req, Db),
- % Here we embark on the delicate task of replacing or creating the
- % headers on the JsonResponse object. We need to control the Etag and
- % Vary headers. If the external function controls the Etag, we'd have to
- % run it to check for a match, which sort of defeats the purpose.
- JsonResponse2 = case proplists:get_value(<<"headers">>, JsonResponse, nil) of
- nil ->
- % no JSON headers
- % add our Etag and Vary headers to the response
- [{<<"headers">>, {[{<<"Etag">>, CurrentEtag}, {<<"Vary">>, <<"Accept">>}]}} | JsonResponse];
- {JsonHeaders} ->
- [case Field of
- {<<"headers">>, {JsonHeaders}} -> % add our headers
- JsonHeadersEtagged = set_or_replace_header({<<"Etag">>, CurrentEtag}, JsonHeaders),
- JsonHeadersVaried = set_or_replace_header({<<"Vary">>, <<"Accept">>}, JsonHeadersEtagged),
- {<<"headers">>, {JsonHeadersVaried}};
- _ -> % skip non-header fields
- Field
- end || Field <- JsonResponse]
- end,
- couch_httpd_external:send_external_response(Req, {JsonResponse2})
- end.
-
-set_or_replace_header(H, L) ->
- set_or_replace_header(H, L, []).
-
-set_or_replace_header({Key, NewValue}, [{Key, _OldVal} | Headers], Acc) ->
- % drop matching keys
- set_or_replace_header({Key, NewValue}, Headers, Acc);
-set_or_replace_header({Key, NewValue}, [{OtherKey, OtherVal} | Headers], Acc) ->
- % something else is next, leave it alone.
- set_or_replace_header({Key, NewValue}, Headers, [{OtherKey, OtherVal} | Acc]);
-set_or_replace_header({Key, NewValue}, [], Acc) ->
- % end of list, add ours
- [{Key, NewValue}|Acc]. \ No newline at end of file