Skip to content
This repository has been archived by the owner on May 25, 2021. It is now read-only.

Commit

Permalink
Create md5 etag for _local docs
Browse files Browse the repository at this point in the history
This makes a unique ETAG for _local docs, so that they are cached
correctly, and fetched again when the document changes.

fixes COUCHDB-2978
  • Loading branch information
garrensmith committed Apr 12, 2016
1 parent 79c98d8 commit bf9cd2b
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 3 deletions.
15 changes: 12 additions & 3 deletions src/couch_httpd.erl
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
-export([make_fun_spec_strs/1]).
-export([make_arity_1_fun/1, make_arity_2_fun/1, make_arity_3_fun/1]).
-export([parse_form/1,json_body/1,json_body_obj/1,body/1]).
-export([doc_etag/1, make_etag/1, etag_match/2, etag_respond/3, etag_maybe/2]).
-export([doc_etag/1, doc_etag/3, make_etag/1, etag_match/2, etag_respond/3, etag_maybe/2]).
-export([primary_header_value/2,partition/1,serve_file/3,serve_file/4, server_header/0]).
-export([start_chunked_response/3,send_chunk/2,log_request/2]).
-export([start_response_length/4, start_response/3, send/2]).
Expand Down Expand Up @@ -594,8 +594,17 @@ maybe_decompress(Httpd, Body) ->
throw({bad_ctype, [Else, " is not a supported content encoding."]})
end.

doc_etag(#doc{revs={Start, [DiskRev|_]}}) ->
"\"" ++ ?b2l(couch_doc:rev_to_str({Start, DiskRev})) ++ "\"".
doc_etag(#doc{id=Id, body=Body, revs={Start, [DiskRev|_]}}) ->
doc_etag(Id, Body, {Start, DiskRev}).

doc_etag(<<"_local/", _/binary>>, Body, {Start, DiskRev}) ->
make_etag({Start, DiskRev, Body});
doc_etag(_Id, _Body, {Start, DiskRev}) ->
rev_etag({Start, DiskRev}).

rev_etag({Start, DiskRev}) ->
Rev = couch_doc:rev_to_str({Start, DiskRev}),
<<$", Rev/binary, $">>.

make_etag(Term) ->
<<SigInt:128/integer>> = couch_crypto:hash(md5, term_to_binary(Term)),
Expand Down
30 changes: 30 additions & 0 deletions test/couch_etag_tests.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
% 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_etag_tests).

-include_lib("eunit/include/eunit.hrl").

local_with_empty_body_test() ->
Etag = couch_httpd:doc_etag(<<"_local/local-and-empty">>, {[]}, {0, <<"1">>}),
?assertEqual(Etag, <<"\"5ZVXQYO7VLEOU0TL9VXDNP5PV\"">>).


local_with_body_test() ->
DocBody = {[{<<"hello">>,<<"world">>},{<<"relax">>,true}]},
Etag = couch_httpd:doc_etag(<<"_local/local-with-body">>, DocBody, {0, <<"1">>}),
?assertEqual(Etag, <<"\"CEFXP6WH8OKYIWO1GLGBHKCCA\"">>).

normal_doc_uses_rev_test() ->
DocBody = {[{<<"hello">>,<<"world">>},{<<"relax">>,true}]},
Etag = couch_httpd:doc_etag(<<"nomal-doc">>, DocBody, {1, <<"efda11e34e88ebe31a2f83e84a0435b6">>}),
?assertEqual(Etag, <<"\"1-efda11e34e88ebe31a2f83e84a0435b6\"">>).

0 comments on commit bf9cd2b

Please sign in to comment.