Skip to content

Instantly share code, notes, and snippets.

@soldair
Last active June 30, 2016 13:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save soldair/4aebfddd6ec81ed7d893b7ccffa854b0 to your computer and use it in GitHub Desktop.
Save soldair/4aebfddd6ec81ed7d893b7ccffa854b0 to your computer and use it in GitHub Desktop.
etag halp

im trying to generate the couch etag from the document in node. this might be crazy but i just want to understand it.

there are 2 approaches i see in cthe couch code. one that results in a rev_etag and the other which is make_etag which seems to also use body?

https://github.com/apache/couchdb-couch/blob/04b8c646e39f303b629bd63c0f2f9b2df8320ba6/src/couch_httpd.erl#L609

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)),
    iolist_to_binary([$", io_lib:format("~.36B", [SigInt]), $"]).

now here is where it really gets formatted as the header: https://github.com/apache/couchdb-couch/blob/b4295bfe58680c6a3d332a73ac6b061bd78b4db3/src/couch_httpd_db.erl#L855

        Etag = case Md5 of
            <<>> -> couch_httpd:doc_etag(Doc);
            _ -> "\"" ++ ?b2l(base64:encode(Md5)) ++ "\""
        end,

i have a document https://registry.npmjs.org/walkdir we get an etag of "8ZBQ61DOYOHRHBRGEAJCNUFT3" it has a rev of 28-8f3a8ea6db40d84b9e69865ebe12ec2f

and every way i try to encode it from node i cant reproduce couch etag value. =( advice?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment