You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by kl...@apache.org on 2015/11/01 22:47:22 UTC

chttpd commit: updated refs/heads/2859-fix-view-etags to 3ad29dc

Repository: couchdb-chttpd
Updated Branches:
  refs/heads/2859-fix-view-etags [created] 3ad29dc08


Fix view ETag calculation

COUCHDB-2859


Project: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/commit/3ad29dc0
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/tree/3ad29dc0
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/diff/3ad29dc0

Branch: refs/heads/2859-fix-view-etags
Commit: 3ad29dc08aaf048b9836ca8ba14200bd675694c4
Parents: 2147dba
Author: Klaus Trainer <kl...@posteo.de>
Authored: Sun Nov 1 22:43:41 2015 +0100
Committer: Klaus Trainer <kl...@posteo.de>
Committed: Sun Nov 1 22:46:19 2015 +0100

----------------------------------------------------------------------
 src/chttpd_view.erl | 33 +++++++++++++++++++++++++--------
 1 file changed, 25 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/blob/3ad29dc0/src/chttpd_view.erl
----------------------------------------------------------------------
diff --git a/src/chttpd_view.erl b/src/chttpd_view.erl
index 8da557d..4bc736b 100644
--- a/src/chttpd_view.erl
+++ b/src/chttpd_view.erl
@@ -25,13 +25,13 @@ multi_query_view(Req, Db, DDoc, ViewName, Queries) ->
         couch_mrview_util:validate_args(QueryArg)
     end, Queries),
     {ok, Resp2} = couch_httpd:etag_maybe(Req, fun() ->
-        VAcc0 = #vacc{db=Db, req=Req, prepend="\r\n"},
-        %% TODO: proper calculation of etag
-        Etag = [$", couch_uuids:new(), $"],
+        Etag = make_etag(Db, DDoc, ViewName, ArgQueries),
+        ok = check_etag(Etag, Req),
+        VAcc0 = #vacc{db=Db, req=Req, prepend="\r\n", etag=Etag},
         Headers = [{"ETag", Etag}],
         FirstChunk = "{\"results\":[",
         {ok, Resp0} = chttpd:start_delayed_json_response(VAcc0#vacc.req, 200, Headers, FirstChunk),
-        VAcc1 = VAcc0#vacc{resp=Resp0, etag=Etag},
+        VAcc1 = VAcc0#vacc{resp=Resp0},
         VAcc2 = lists:foldl(fun(Args, Acc0) ->
             {ok, Acc1} = fabric:query_view(Db, DDoc, ViewName, fun couch_mrview_http:view_cb/2, Acc0, Args),
             Acc1
@@ -48,12 +48,12 @@ multi_query_view(Req, Db, DDoc, ViewName, Queries) ->
 
 design_doc_view(Req, Db, DDoc, ViewName, Keys) ->
     Args = couch_mrview_http:parse_params(Req, Keys),
-    %% TODO: proper calculation of etag
-    Etag = [$", couch_uuids:new(), $"],
     {ok, Resp} = couch_httpd:etag_maybe(Req, fun() ->
+        Etag = make_etag(Db, DDoc, ViewName, Args),
+        ok = check_etag(Etag, Req),
         Max = chttpd:chunked_response_buffer_size(),
-        VAcc0 = #vacc{db=Db, req=Req, threshold=Max, etag=Etag},
-        fabric:query_view(Db, DDoc, ViewName, fun couch_mrview_http:view_cb/2, VAcc0, Args)
+        VAcc = #vacc{db=Db, req=Req, threshold=Max, etag=Etag},
+        fabric:query_view(Db, DDoc, ViewName, fun couch_mrview_http:view_cb/2, VAcc, Args)
     end),
     case is_record(Resp, vacc) of
         true -> {ok, Resp#vacc.resp};
@@ -94,3 +94,20 @@ handle_view_req(Req, _Db, _DDoc) ->
 handle_temp_view_req(Req, _Db) ->
     Msg = <<"Temporary views are not supported in CouchDB">>,
     chttpd:send_error(Req, 403, forbidden, Msg).
+
+make_etag(Db, DDoc, ViewName, Args) ->
+    DbName = Db#db.name,
+    DDocId = DDoc#doc.id,
+    {ok, ViewGroupInfo} = fabric:get_view_group_info(DbName, DDocId),
+    UpdatesPending = proplists:get_value(updates_pending, ViewGroupInfo),
+    UpdateSeq = proplists:get_value(update_seq, ViewGroupInfo),
+    Signature = proplists:get_value(signature, ViewGroupInfo),
+    PurgeSeq = proplists:get_value(purge_seq, ViewGroupInfo),
+    Term = {DbName, DDocId, ViewName, Args, UpdatesPending, UpdateSeq, Signature, PurgeSeq},
+    chttpd:make_etag(Term).
+
+check_etag(Etag, Req) ->
+    case chttpd:etag_match(Req, Etag) of
+        true -> throw({etag_match, Etag});
+        false -> ok
+    end.