gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-exchange] branch master updated: add Etag and 'expires' to /wire


From: gnunet
Subject: [taler-exchange] branch master updated: add Etag and 'expires' to /wire
Date: Thu, 12 May 2022 14:15:14 +0200

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository exchange.

The following commit(s) were added to refs/heads/master by this push:
     new 75d9584e add Etag and 'expires' to /wire
     new d0a0bd97 Merge branch 'master' of git+ssh://git.taler.net/exchange
75d9584e is described below

commit 75d9584e280ebfb3fcb400f46942695ac6e2958e
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Thu May 12 14:15:02 2022 +0200

    add Etag and 'expires' to /wire
---
 src/exchange/taler-exchange-httpd_keys.c |  60 +--------------
 src/exchange/taler-exchange-httpd_wire.c | 123 ++++++++++++++++++++-----------
 src/include/taler_mhd_lib.h              |  12 +++
 src/mhd/mhd_legal.c                      |   4 +-
 src/mhd/mhd_responses.c                  |  45 +++++++++++
 5 files changed, 145 insertions(+), 99 deletions(-)

diff --git a/src/exchange/taler-exchange-httpd_keys.c 
b/src/exchange/taler-exchange-httpd_keys.c
index 56fe6412..a8484909 100644
--- a/src/exchange/taler-exchange-httpd_keys.c
+++ b/src/exchange/taler-exchange-httpd_keys.c
@@ -1656,58 +1656,6 @@ add_denom_key_cb (void *cls,
 }
 
 
-/**
- * Produce HTTP "Date:" header.
- *
- * @param at time to write to @a date
- * @param[out] date where to write the header, with
- *        at least 128 bytes available space.
- */
-static void
-get_date_string (struct GNUNET_TIME_Absolute at,
-                 char date[128])
-{
-  static const char *const days[] =
-  { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
-  static const char *const mons[] =
-  { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct",
-    "Nov", "Dec"};
-  struct tm now;
-  time_t t;
-#if ! defined(HAVE_C11_GMTIME_S) && ! defined(HAVE_W32_GMTIME_S) && \
-  ! defined(HAVE_GMTIME_R)
-  struct tm*pNow;
-#endif
-
-  date[0] = 0;
-  t = (time_t) (at.abs_value_us / 1000LL / 1000LL);
-#if defined(HAVE_C11_GMTIME_S)
-  if (NULL == gmtime_s (&t, &now))
-    return;
-#elif defined(HAVE_W32_GMTIME_S)
-  if (0 != gmtime_s (&now, &t))
-    return;
-#elif defined(HAVE_GMTIME_R)
-  if (NULL == gmtime_r (&t, &now))
-    return;
-#else
-  pNow = gmtime (&t);
-  if (NULL == pNow)
-    return;
-  now = *pNow;
-#endif
-  sprintf (date,
-           "%3s, %02u %3s %04u %02u:%02u:%02u GMT",
-           days[now.tm_wday % 7],
-           (unsigned int) now.tm_mday,
-           mons[now.tm_mon % 12],
-           (unsigned int) (1900 + now.tm_year),
-           (unsigned int) now.tm_hour,
-           (unsigned int) now.tm_min,
-           (unsigned int) now.tm_sec);
-}
-
-
 /**
  * Add the headers we want to set for every /keys response.
  *
@@ -1726,8 +1674,8 @@ setup_general_response_headers (struct TEH_KeyStateHandle 
*ksh,
                 MHD_add_response_header (response,
                                          MHD_HTTP_HEADER_CONTENT_TYPE,
                                          "application/json"));
-  get_date_string (ksh->reload_time.abs_time,
-                   dat);
+  TALER_MHD_get_date_string (ksh->reload_time.abs_time,
+                             dat);
   GNUNET_break (MHD_YES ==
                 MHD_add_response_header (response,
                                          MHD_HTTP_HEADER_LAST_MODIFIED,
@@ -1742,8 +1690,8 @@ setup_general_response_headers (struct TEH_KeyStateHandle 
*ksh,
                                   ksh->rekey_frequency);
     a = GNUNET_TIME_relative_to_absolute (r);
     m = GNUNET_TIME_absolute_to_timestamp (a);
-    get_date_string (m.abs_time,
-                     dat);
+    TALER_MHD_get_date_string (m.abs_time,
+                               dat);
     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                 "Setting /keys 'Expires' header to '%s'\n",
                 dat);
diff --git a/src/exchange/taler-exchange-httpd_wire.c 
b/src/exchange/taler-exchange-httpd_wire.c
index 30c281b5..22b4e7cd 100644
--- a/src/exchange/taler-exchange-httpd_wire.c
+++ b/src/exchange/taler-exchange-httpd_wire.c
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  Copyright (C) 2015-2021 Taler Systems SA
+  Copyright (C) 2015-2022 Taler Systems SA
 
   TALER is free software; you can redistribute it and/or modify it under the
   terms of the GNU Affero General Public License as published by the Free 
Software
@@ -72,9 +72,9 @@ struct WireFeeSet
 struct WireStateHandle
 {
   /**
-   * Cached JSON for /wire response.
+   * Cached reply for /wire response.
    */
-  json_t *wire_reply;
+  struct MHD_Response *wire_reply;
 
   /**
    * head of DLL of wire fees.
@@ -136,7 +136,7 @@ destroy_wire_state (struct WireStateHandle *wsh)
     GNUNET_free (wfs->method);
     GNUNET_free (wfs);
   }
-  json_decref (wsh->wire_reply);
+  MHD_destroy_response (wsh->wire_reply);
   GNUNET_free (wsh);
 }
 
@@ -203,28 +203,6 @@ TEH_wire_done ()
 }
 
 
-/**
- * Create standard JSON response format using @a ec and @a detail.
- *
- * @param ec error code to return
- * @param detail optional detail text to return, can be NULL
- * @return JSON response
- */
-static json_t *
-make_ec_reply (enum TALER_ErrorCode ec,
-               const char *detail)
-{
-  return GNUNET_JSON_PACK (
-    GNUNET_JSON_pack_uint64 ("code",
-                             ec),
-    GNUNET_JSON_pack_string ("hint",
-                             TALER_ErrorCode_get_hint (ec)),
-    GNUNET_JSON_pack_allow_null (
-      GNUNET_JSON_pack_string ("detail",
-                               detail)));
-}
-
-
 /**
  * Add information about a wire account to @a cls.
  *
@@ -274,6 +252,18 @@ struct AddContext
    * Array to append the fee to.
    */
   json_t *a;
+
+  /**
+   * Context we hash "everything" we add into. This is used
+   * to compute the etag. Technically, we only hash the
+   * master_sigs, as they imply the rest.
+   */
+  struct GNUNET_HashContext *hc;
+
+  /**
+   * Set to the maximum end-date seen.
+   */
+  struct GNUNET_TIME_Absolute max_seen;
 };
 
 
@@ -297,6 +287,11 @@ add_wire_fee (void *cls,
   struct AddContext *ac = cls;
   struct WireFeeSet *wfs;
 
+  GNUNET_CRYPTO_hash_context_read (ac->hc,
+                                   master_sig,
+                                   sizeof (*master_sig));
+  ac->max_seen = GNUNET_TIME_absolute_max (ac->max_seen,
+                                           end_date.abs_time);
   wfs = GNUNET_new (struct WireFeeSet);
   wfs->start_date = start_date;
   wfs->end_date = end_date;
@@ -341,6 +336,8 @@ build_wire_state (void)
   uint64_t wg = wire_generation; /* must be obtained FIRST */
   enum GNUNET_DB_QueryStatus qs;
   struct WireStateHandle *wsh;
+  struct GNUNET_TIME_Absolute cache_expiration;
+  struct GNUNET_HashContext *hc;
 
   wsh = GNUNET_new (struct WireStateHandle);
   wsh->wire_generation = wg;
@@ -355,8 +352,8 @@ build_wire_state (void)
     json_decref (wire_accounts_array);
     wsh->http_status = MHD_HTTP_INTERNAL_SERVER_ERROR;
     wsh->wire_reply
-      = make_ec_reply (TALER_EC_GENERIC_DB_FETCH_FAILED,
-                       "get_wire_accounts");
+      = TALER_MHD_make_error (TALER_EC_GENERIC_DB_FETCH_FAILED,
+                              "get_wire_accounts");
     return wsh;
   }
   if (0 == json_array_size (wire_accounts_array))
@@ -364,12 +361,14 @@ build_wire_state (void)
     json_decref (wire_accounts_array);
     wsh->http_status = MHD_HTTP_INTERNAL_SERVER_ERROR;
     wsh->wire_reply
-      = make_ec_reply (TALER_EC_EXCHANGE_WIRE_NO_ACCOUNTS_CONFIGURED,
-                       NULL);
+      = TALER_MHD_make_error (TALER_EC_EXCHANGE_WIRE_NO_ACCOUNTS_CONFIGURED,
+                              NULL);
     return wsh;
   }
   wire_fee_object = json_object ();
   GNUNET_assert (NULL != wire_fee_object);
+  cache_expiration = GNUNET_TIME_UNIT_ZERO_ABS;
+  hc = GNUNET_CRYPTO_hash_context_start ();
   {
     json_t *account;
     size_t index;
@@ -385,10 +384,12 @@ build_wire_state (void)
       {
         wsh->http_status = MHD_HTTP_INTERNAL_SERVER_ERROR;
         wsh->wire_reply
-          = make_ec_reply (TALER_EC_EXCHANGE_WIRE_INVALID_PAYTO_CONFIGURED,
-                           payto_uri);
+          = TALER_MHD_make_error (
+              TALER_EC_EXCHANGE_WIRE_INVALID_PAYTO_CONFIGURED,
+              payto_uri);
         json_decref (wire_accounts_array);
         json_decref (wire_fee_object);
+        GNUNET_CRYPTO_hash_context_abort (hc);
         return wsh;
       }
       if (NULL == json_object_get (wire_fee_object,
@@ -397,7 +398,8 @@ build_wire_state (void)
         struct AddContext ac = {
           .wire_method = wire_method,
           .wsh = wsh,
-          .a = json_array ()
+          .a = json_array (),
+          .hc = hc
         };
 
         GNUNET_assert (NULL != ac.a);
@@ -414,8 +416,9 @@ build_wire_state (void)
           GNUNET_free (wire_method);
           wsh->http_status = MHD_HTTP_INTERNAL_SERVER_ERROR;
           wsh->wire_reply
-            = make_ec_reply (TALER_EC_GENERIC_DB_FETCH_FAILED,
-                             "get_wire_fees");
+            = TALER_MHD_make_error (TALER_EC_GENERIC_DB_FETCH_FAILED,
+                                    "get_wire_fees");
+          GNUNET_CRYPTO_hash_context_abort (hc);
           return wsh;
         }
         if (0 == json_array_size (ac.a))
@@ -425,11 +428,14 @@ build_wire_state (void)
           json_decref (wire_fee_object);
           wsh->http_status = MHD_HTTP_INTERNAL_SERVER_ERROR;
           wsh->wire_reply
-            = make_ec_reply (TALER_EC_EXCHANGE_WIRE_FEES_NOT_CONFIGURED,
-                             wire_method);
+            = TALER_MHD_make_error (TALER_EC_EXCHANGE_WIRE_FEES_NOT_CONFIGURED,
+                                    wire_method);
           GNUNET_free (wire_method);
+          GNUNET_CRYPTO_hash_context_abort (hc);
           return wsh;
         }
+        cache_expiration = GNUNET_TIME_absolute_min (ac.max_seen,
+                                                     cache_expiration);
         GNUNET_assert (0 ==
                        json_object_set_new (wire_fee_object,
                                             wire_method,
@@ -438,13 +444,48 @@ build_wire_state (void)
       GNUNET_free (wire_method);
     }
   }
-  wsh->wire_reply = GNUNET_JSON_PACK (
+
+
+  wsh->wire_reply = TALER_MHD_MAKE_JSON_PACK (
     GNUNET_JSON_pack_array_steal ("accounts",
                                   wire_accounts_array),
     GNUNET_JSON_pack_object_steal ("fees",
                                    wire_fee_object),
     GNUNET_JSON_pack_data_auto ("master_public_key",
                                 &TEH_master_public_key));
+  {
+    char dat[128];
+    struct GNUNET_TIME_Timestamp m;
+
+    m = GNUNET_TIME_absolute_to_timestamp (cache_expiration);
+    TALER_MHD_get_date_string (m.abs_time,
+                               dat);
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                "Setting 'Expires' header for '/wire' to '%s'\n",
+                dat);
+    GNUNET_break (MHD_YES ==
+                  MHD_add_response_header (wsh->wire_reply,
+                                           MHD_HTTP_HEADER_EXPIRES,
+                                           dat));
+  }
+  TALER_MHD_add_global_headers (wsh->wire_reply);
+  {
+    struct GNUNET_HashCode h;
+    char etag[sizeof (h) * 2];
+    char *end;
+
+    GNUNET_CRYPTO_hash_context_finish (hc,
+                                       &h);
+    end = GNUNET_STRINGS_data_to_string (&h,
+                                         sizeof (h),
+                                         etag,
+                                         sizeof (etag));
+    *end = '\0';
+    GNUNET_break (MHD_YES ==
+                  MHD_add_response_header (wsh->wire_reply,
+                                           MHD_HTTP_HEADER_ETAG,
+                                           etag));
+  }
   wsh->http_status = MHD_HTTP_OK;
   return wsh;
 }
@@ -509,9 +550,9 @@ TEH_handler_wire (struct TEH_RequestContext *rc,
                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
                                        
TALER_EC_EXCHANGE_GENERIC_BAD_CONFIGURATION,
                                        NULL);
-  return TALER_MHD_reply_json (rc->connection,
-                               wsh->wire_reply,
-                               wsh->http_status);
+  return MHD_queue_response (rc->connection,
+                             wsh->http_status,
+                             wsh->wire_reply);
 }
 
 
diff --git a/src/include/taler_mhd_lib.h b/src/include/taler_mhd_lib.h
index dc68df06..b6423135 100644
--- a/src/include/taler_mhd_lib.h
+++ b/src/include/taler_mhd_lib.h
@@ -207,6 +207,18 @@ TALER_MHD_reply_with_ec (struct MHD_Connection *connection,
                          const char *detail);
 
 
+/**
+ * Produce HTTP "Date:" header.
+ *
+ * @param at time to write to @a date
+ * @param[out] date where to write the header, with
+ *        at least 128 bytes available space.
+ */
+void
+TALER_MHD_get_date_string (struct GNUNET_TIME_Absolute at,
+                           char date[128]);
+
+
 /**
  * Make JSON response object.
  *
diff --git a/src/mhd/mhd_legal.c b/src/mhd/mhd_legal.c
index 64c176a9..bd596862 100644
--- a/src/mhd/mhd_legal.c
+++ b/src/mhd/mhd_legal.c
@@ -178,8 +178,8 @@ TALER_MHD_reply_legal (struct MHD_Connection *conn,
 
   a = GNUNET_TIME_relative_to_absolute (MAX_TERMS_CACHING);
   m = GNUNET_TIME_absolute_to_timestamp (a);
-  get_date_string (m.abs_time,
-                   dat);
+  TALER_MHD_get_date_string (m.abs_time,
+                             dat);
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               "Setting 'Expires' header to '%s'\n",
               dat);
diff --git a/src/mhd/mhd_responses.c b/src/mhd/mhd_responses.c
index a639f405..7dd6824e 100644
--- a/src/mhd/mhd_responses.c
+++ b/src/mhd/mhd_responses.c
@@ -502,4 +502,49 @@ TALER_MHD_reply_static (struct MHD_Connection *connection,
 }
 
 
+void
+TALER_MHD_get_date_string (struct GNUNET_TIME_Absolute at,
+                           char date[128])
+{
+  static const char *const days[] =
+  { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
+  static const char *const mons[] =
+  { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct",
+    "Nov", "Dec"};
+  struct tm now;
+  time_t t;
+#if ! defined(HAVE_C11_GMTIME_S) && ! defined(HAVE_W32_GMTIME_S) && \
+  ! defined(HAVE_GMTIME_R)
+  struct tm*pNow;
+#endif
+
+  date[0] = 0;
+  t = (time_t) (at.abs_value_us / 1000LL / 1000LL);
+#if defined(HAVE_C11_GMTIME_S)
+  if (NULL == gmtime_s (&t, &now))
+    return;
+#elif defined(HAVE_W32_GMTIME_S)
+  if (0 != gmtime_s (&now, &t))
+    return;
+#elif defined(HAVE_GMTIME_R)
+  if (NULL == gmtime_r (&t, &now))
+    return;
+#else
+  pNow = gmtime (&t);
+  if (NULL == pNow)
+    return;
+  now = *pNow;
+#endif
+  sprintf (date,
+           "%3s, %02u %3s %04u %02u:%02u:%02u GMT",
+           days[now.tm_wday % 7],
+           (unsigned int) now.tm_mday,
+           mons[now.tm_mon % 12],
+           (unsigned int) (1900 + now.tm_year),
+           (unsigned int) now.tm_hour,
+           (unsigned int) now.tm_min,
+           (unsigned int) now.tm_sec);
+}
+
+
 /* end of mhd_responses.c */

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]