From ee4ba41be000abbf4d888d306c72b6e805fdc01b Mon Sep 17 00:00:00 2001 From: John Christopher Anderson Date: Tue, 27 Jan 2009 20:46:39 +0000 Subject: Improved etag handling for show funcs and db_doc requests; main.js cleanup (baby steps); null doc allowed for show funcs git-svn-id: https://svn.apache.org/repos/asf/couchdb/trunk@738237 13f79535-47bb-0310-9956-ffa450edef68 --- src/couchdb/couch_httpd.erl | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'src/couchdb/couch_httpd.erl') diff --git a/src/couchdb/couch_httpd.erl b/src/couchdb/couch_httpd.erl index 996bcf49..acd6af40 100644 --- a/src/couchdb/couch_httpd.erl +++ b/src/couchdb/couch_httpd.erl @@ -17,7 +17,7 @@ -export([header_value/2,header_value/3,qs_value/2,qs_value/3,qs/1,path/1]). -export([verify_is_server_admin/1,unquote/1,quote/1,recv/2]). --export([parse_form/1,json_body/1,body/1,doc_etag/1]). +-export([parse_form/1,json_body/1,body/1,doc_etag/1, make_etag/1, etag_respond/3]). -export([primary_header_value/2,partition/1,serve_file/3]). -export([start_chunked_response/3,send_chunk/2]). -export([start_json_response/2, start_json_response/3, end_json_response/1]). @@ -261,7 +261,29 @@ json_body(#httpd{mochi_req=MochiReq}) -> ?JSON_DECODE(MochiReq:recv_body(?MAX_DOC_SIZE)). doc_etag(#doc{revs=[DiskRev|_]}) -> - "\"" ++ binary_to_list(DiskRev) ++ "\"". + "\"" ++ binary_to_list(DiskRev) ++ "\"". + +make_etag(Term) -> + <> = erlang:md5(term_to_binary(Term)), + list_to_binary("\"" ++ lists:flatten(io_lib:format("~.36B",[SigInt])) ++ "\""). + +etag_match(Req, CurrentEtag) when is_binary(CurrentEtag) -> + etag_match(Req, binary_to_list(CurrentEtag)); + +etag_match(Req, CurrentEtag) -> + EtagsToMatch = string:tokens( + couch_httpd:header_value(Req, "If-None-Match", ""), ", "), + lists:member(CurrentEtag, EtagsToMatch). + +etag_respond(Req, CurrentEtag, RespFun) -> + case etag_match(Req, CurrentEtag) of + true -> + % the client has this in their cache. + couch_httpd:send_response(Req, 304, [{"Etag", CurrentEtag}], <<>>); + false -> + % Run the function. + RespFun() + end. verify_is_server_admin(#httpd{user_ctx=#user_ctx{roles=Roles}}) -> case lists:member(<<"_admin">>, Roles) of -- cgit v1.2.3