anastasis-httpd.h (8996B)
1 /* 2 This file is part of Anastasis 3 Copyright (C) 2019 Anastasis SARL 4 5 Anastasis is free software; you can redistribute it and/or modify it under the 6 terms of the GNU Affero General Public License as published by the Free Software 7 Foundation; either version 3, or (at your option) any later version. 8 9 Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY 10 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 11 A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 12 13 You should have received a copy of the GNU Affero General Public License along with 14 Anastasis; see the file COPYING. If not, see <http://www.gnu.org/licenses/> 15 */ 16 /** 17 * @file backend/anastasis-httpd.h 18 * @brief HTTP serving layer 19 * @author Christian Grothoff 20 */ 21 #ifndef ANASTASIS_HTTPD_H 22 #define ANASTASIS_HTTPD_H 23 24 #include "platform.h" 25 #include "anastasis_database_lib.h" 26 #include <microhttpd.h> 27 #include <taler/taler_mhd_lib.h> 28 #include <taler/merchant/get-private-orders-ORDER_ID.h> 29 #include <gnunet/gnunet_mhd_compat.h> 30 31 32 /** 33 * For how many years do we allow users to store truth at most? Also 34 * how long we store things if the cost is zero. 35 */ 36 #define ANASTASIS_MAX_YEARS_STORAGE 5 37 38 39 /** 40 * @brief Struct describing an URL and the handler for it. 41 */ 42 struct AH_RequestHandler 43 { 44 45 /** 46 * URL the handler is for. 47 */ 48 const char *url; 49 50 /** 51 * Method the handler is for, NULL for "all". 52 */ 53 const char *method; 54 55 /** 56 * Mime type to use in reply (hint, can be NULL). 57 */ 58 const char *mime_type; 59 60 /** 61 * Raw data for the @e handler 62 */ 63 const void *data; 64 65 /** 66 * Number of bytes in @e data, 0 for 0-terminated. 67 */ 68 size_t data_size; 69 70 71 /** 72 * Function to call to handle the request. 73 * 74 * @param rh this struct 75 * @param connection the MHD connection to handle 76 * @return MHD result code 77 */ 78 enum MHD_Result (*handler)(struct AH_RequestHandler *rh, 79 struct MHD_Connection *connection); 80 81 /** 82 * Default response code. 83 */ 84 unsigned int response_code; 85 }; 86 87 88 /** 89 * Each MHD response handler that sets the "connection_cls" to a 90 * non-NULL value must use a struct that has this struct as its first 91 * member. This struct contains a single callback, which will be 92 * invoked to clean up the memory when the contection is completed. 93 */ 94 struct TM_HandlerContext; 95 96 /** 97 * Signature of a function used to clean up the context 98 * we keep in the "connection_cls" of MHD when handling 99 * a request. 100 * 101 * @param hc header of the context to clean up. 102 */ 103 typedef void 104 (*TM_ContextCleanup)(struct TM_HandlerContext *hc); 105 106 107 /** 108 * Each MHD response handler that sets the "connection_cls" to a 109 * non-NULL value must use a struct that has this struct as its first 110 * member. This struct contains a single callback, which will be 111 * invoked to clean up the memory when the connection is completed. 112 */ 113 struct TM_HandlerContext 114 { 115 116 /** 117 * Function to execute the handler-specific cleanup of the 118 * (typically larger) context. 119 */ 120 TM_ContextCleanup cc; 121 122 /** 123 * Handler-specific context. 124 */ 125 void *ctx; 126 127 /** 128 * Which request handler is handling this request? 129 */ 130 const struct AH_RequestHandler *rh; 131 132 /** 133 * URL requested by the client, for logging. 134 */ 135 const char *url; 136 137 /** 138 * Asynchronous request context id. 139 */ 140 struct GNUNET_AsyncScopeId async_scope_id; 141 }; 142 143 /** 144 * Upload limit to the service, in megabytes. 145 */ 146 extern unsigned long long AH_upload_limit_mb; 147 148 /** 149 * Currencies this provider prices its service in, primary currency 150 * first. From [anastasis] CURRENCIES. Every priced option below offers 151 * exactly these currencies; that is checked at startup. 152 */ 153 extern char **AH_currencies; 154 155 /** 156 * Length of the #AH_currencies array. 157 */ 158 extern unsigned int AH_currencies_len; 159 160 /** 161 * Annual fee for the backup account, per currency. 162 */ 163 extern struct TALER_AmountList AH_annual_fees; 164 165 /** 166 * Fee for a truth upload, per currency. 167 */ 168 extern struct TALER_AmountList AH_truth_upload_fees; 169 170 /** 171 * Amount of insurance, per currency. 172 */ 173 extern struct TALER_AmountList AH_insurance; 174 175 /** 176 * Cost for secure question truth download, per currency. 177 */ 178 extern struct TALER_AmountList AH_question_costs; 179 180 181 /** 182 * Check that @a al is a usable price for a configuration option, and 183 * fail the process if it is not. 184 * 185 * A price must be uniformly free or uniformly priced: offering the same 186 * thing for money in one currency and for nothing in another does not 187 * price the service, it prices the user's choice of currency, and every 188 * wallet would simply pick the free one. A priced option must further 189 * offer exactly the currencies in #AH_currencies, or a user would find 190 * out that some step of recovery is unavailable in their currency only 191 * once the backup exists and the money is spent. 192 * 193 * @param al price list to check 194 * @param section configuration section it came from, for diagnostics 195 * @param option configuration option it came from, for diagnostics 196 * @return #GNUNET_OK if @a al is priced in all of #AH_currencies, 197 * #GNUNET_NO if @a al is free (empty or all zero), 198 * #GNUNET_SYSERR if @a al is unusable; the caller must shut down 199 */ 200 enum GNUNET_GenericReturnValue 201 AH_check_price (const struct TALER_AmountList *al, 202 const char *section, 203 const char *option); 204 205 206 /** 207 * Return the price of @a al in the primary currency, for the scalar 208 * fields that older clients read. 209 * 210 * A free option has no entry for any currency, and reports as zero in 211 * the primary currency --- which is what a single-currency provider 212 * running for free already emitted before there were price lists. 213 * 214 * @param al price list to look in 215 * @return price in the primary currency; the pointer is only valid 216 * until the next call 217 */ 218 const struct TALER_Amount * 219 AH_primary_price (const struct TALER_AmountList *al); 220 221 222 /** 223 * Build the skeleton of a merchant "v1" order that offers every currency 224 * in @a prices as a payable choice, letting the wallet settle in whichever 225 * one it holds. 226 * 227 * Every entry of @a prices becomes a choice: none is dropped and none can 228 * be zero, because #AH_check_price() refused to let the provider start on 229 * a price list that mixes free and non-free currencies. So the order is 230 * either complete and payable in every currency the provider advertises, 231 * or the caller decided the option was free and does not create an order 232 * at all. 233 * 234 * The caller adds whatever else the order needs (products, deadlines, …) 235 * to the returned object. 236 * 237 * @param order_id order ID to use 238 * @param summary human-readable summary of the order 239 * @param prices what the order costs, one entry per currency; must not 240 * be empty and must not contain a zero 241 * @return the order object, caller must `json_decref()` it 242 */ 243 json_t * 244 AH_make_order (const char *order_id, 245 const char *summary, 246 const struct TALER_AmountList *prices); 247 248 249 /** 250 * Extract from a paid order status the amount the wallet actually paid, 251 * in the currency it chose. 252 * 253 * A "v1" order has no top-level amount; the choice that was settled is at 254 * ``choices[choice_index]``. A ``choice_index`` of -1 means the contract 255 * is a legacy "v0" one with a single top-level amount --- which is what 256 * orders created before this provider was upgraded look like, and they 257 * still have to settle. 258 * 259 * @param osr order status to inspect, must be #TALER_MERCHANT_OSC_PAID 260 * @param[out] amount set to the amount that was paid 261 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the contract terms 262 * did not contain a usable amount 263 */ 264 enum GNUNET_GenericReturnValue 265 AH_paid_amount (const struct TALER_MERCHANT_GetPrivateOrderResponse *osr, 266 struct TALER_Amount *amount); 267 268 /** 269 * Our Taler backend to process payments. 270 */ 271 extern char *AH_backend_url; 272 273 /** 274 * Heap for processing timeouts of requests. 275 */ 276 extern struct GNUNET_CONTAINER_Heap *AH_to_heap; 277 278 /** 279 * Our configuration. 280 */ 281 extern const struct GNUNET_CONFIGURATION_Handle *AH_cfg; 282 283 /** 284 * Number of policy uploads permitted per annual fee payment. 285 */ 286 extern unsigned long long AH_post_counter; 287 288 /** 289 * Our fulfillment URL 290 */ 291 extern char *AH_fulfillment_url; 292 293 /** 294 * Our business name. 295 */ 296 extern char *AH_business_name; 297 298 /** 299 * Our provider salt. 300 */ 301 extern struct ANASTASIS_CRYPTO_ProviderSaltP AH_provider_salt; 302 303 /** 304 * Our context for making HTTP requests. 305 */ 306 extern struct GNUNET_CURL_Context *AH_ctx; 307 308 309 /** 310 * Kick MHD to run now, to be called after MHD_resume_connection(). 311 * Basically, we need to explicitly resume MHD's event loop whenever 312 * we made progress serving a request. This function re-schedules 313 * the task processing MHD's activities to run immediately. 314 * 315 * @param cls NULL 316 */ 317 void 318 AH_trigger_daemon (void *cls); 319 320 /** 321 * Kick GNUnet Curl scheduler to begin curl interactions. 322 */ 323 void 324 AH_trigger_curl (void); 325 326 #endif