summaryrefslogtreecommitdiff
path: root/src/backend/taler-merchant-httpd_get-orders-ID.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2020-07-26 12:44:53 +0200
committerChristian Grothoff <christian@grothoff.org>2020-07-26 12:44:53 +0200
commit602f5e3e0824d9c2c9dd1fab29342ecbce3b78da (patch)
treeef4d4e6643b3b2556b56245568e83a3d182cc159 /src/backend/taler-merchant-httpd_get-orders-ID.c
parentd78afeb1a0d5c45dcd64e27ff8b7e9ca73bfce21 (diff)
downloadmerchant-602f5e3e0824d9c2c9dd1fab29342ecbce3b78da.tar.gz
merchant-602f5e3e0824d9c2c9dd1fab29342ecbce3b78da.tar.bz2
merchant-602f5e3e0824d9c2c9dd1fab29342ecbce3b78da.zip
first steps towards generating (ugly) HTML replies for /orders/
Diffstat (limited to 'src/backend/taler-merchant-httpd_get-orders-ID.c')
-rw-r--r--src/backend/taler-merchant-httpd_get-orders-ID.c237
1 files changed, 218 insertions, 19 deletions
diff --git a/src/backend/taler-merchant-httpd_get-orders-ID.c b/src/backend/taler-merchant-httpd_get-orders-ID.c
index 21582699..7310483d 100644
--- a/src/backend/taler-merchant-httpd_get-orders-ID.c
+++ b/src/backend/taler-merchant-httpd_get-orders-ID.c
@@ -21,6 +21,7 @@
*/
#include "platform.h"
#include <jansson.h>
+#include <qrencode.h>
#include <taler/taler_signatures.h>
#include <taler/taler_json_lib.h>
#include <taler/taler_exchange_service.h>
@@ -220,6 +221,12 @@ struct GetOrderData
*/
bool refunded;
+ /**
+ * Set to true if the client requested HTML, otherwise
+ * we generate JSON.
+ */
+ bool generate_html;
+
};
@@ -235,6 +242,77 @@ static struct GetOrderData *god_tail;
/**
+ * Create the QR code image for a URI.
+ *
+ * @param uri input string to encode
+ * @return NULL on error, encoded URI otherwise
+ */
+static char *
+create_qrcode (const char *uri)
+{
+ QRinput *qri;
+ QRcode *qrc;
+ struct GNUNET_Buffer buf = { 0 };
+
+ qri = QRinput_new2 (0,
+ QR_ECLEVEL_M);
+ if (NULL == qri)
+ {
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
+ "QRinput_new2");
+ return NULL;
+ }
+ /* first try encoding as uppercase-only alpha-numerical
+ QR code (much smaller encoding); if that fails, also
+ try using binary encoding */
+ if ( (0 !=
+ QRinput_append (qri,
+ QR_MODE_AN,
+ strlen (uri),
+ (unsigned char *) uri)) &&
+ (0 !=
+ QRinput_append (qri,
+ QR_MODE_8,
+ strlen (uri),
+ (unsigned char *) uri)) )
+ {
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
+ "QRinput_append");
+ QRinput_free (qri);
+ return NULL;
+ }
+ qrc = QRcode_encodeInput (qri);
+ if (NULL == qrc)
+ {
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
+ "QRcode_encodeInput");
+ QRinput_free (qri);
+ return NULL;
+ }
+ QRinput_free (qri);
+ /* FIXME-Dold: generate <img> with inline SVG instead of <pre> here! */
+ GNUNET_buffer_write_str (&buf,
+ "<pre>\n\n\n\n ");
+ for (unsigned int y = 0; y<qrc->width; y++)
+ {
+ for (unsigned int x = 0; x<qrc->width; x++)
+ {
+ unsigned int off = x + y * qrc->width;
+ GNUNET_buffer_write_fstr (&buf,
+ "%s",
+ (0 != (qrc->data[off] & 1)) ? "██" : " ");
+ }
+ GNUNET_buffer_write_str (&buf,
+ "\n ");
+ }
+ GNUNET_buffer_write_str (&buf,
+ "\n\n\n\n</pre>");
+ QRcode_free (qrc);
+ return GNUNET_buffer_reap_str (&buf);
+}
+
+
+/**
* Force resuming all suspended order lookups, needed during shutdown.
*/
void
@@ -375,13 +453,54 @@ send_pay_request (struct GetOrderData *god,
god->order_id,
god->session_id,
god->hc->instance->settings.id);
- ret = TALER_MHD_reply_json_pack (god->sc.con,
- MHD_HTTP_OK,
- "{s:s, s:s, s:s?}",
- "taler_pay_uri", taler_pay_uri,
- "order_status", "unpaid",
- "already_paid_order_id",
- already_paid_order_id);
+ if (god->generate_html)
+ {
+ struct MHD_Response *reply;
+ char *qr;
+ char *body;
+
+ qr = create_qrcode (taler_pay_uri);
+ if (NULL == qr)
+ {
+ GNUNET_break (0);
+ return MHD_NO;
+ }
+ GNUNET_asprintf (&body,
+ "<html><body>%s</body></html>",
+ qr);
+ GNUNET_free (qr);
+ reply = MHD_create_response_from_buffer (strlen (body),
+ body,
+ MHD_RESPMEM_MUST_COPY);
+ GNUNET_free (body);
+ if (NULL == reply)
+ {
+ GNUNET_break (0);
+ return MHD_NO;
+ }
+ GNUNET_break (MHD_NO !=
+ MHD_add_response_header (reply,
+ "Taler",
+ taler_pay_uri));
+ GNUNET_break (MHD_NO !=
+ MHD_add_response_header (reply,
+ MHD_HTTP_HEADER_CONTENT_TYPE,
+ "text/html"));
+ ret = MHD_queue_response (god->sc.con,
+ MHD_HTTP_OK,
+ reply);
+ MHD_destroy_response (reply);
+ }
+ else
+ {
+ ret = TALER_MHD_reply_json_pack (god->sc.con,
+ MHD_HTTP_OK,
+ "{s:s, s:s, s:s?}",
+ "taler_pay_uri", taler_pay_uri,
+ "order_status", "unpaid",
+ "already_paid_order_id",
+ already_paid_order_id);
+ }
GNUNET_free (taler_pay_uri);
return ret;
}
@@ -683,6 +802,44 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
}
}
+ { /* check for 'Accept' header */
+ const char *accept;
+
+ accept = MHD_lookup_connection_value (connection,
+ MHD_HEADER_KIND,
+ MHD_HTTP_HEADER_ACCEPT);
+ if (NULL != accept)
+ {
+ char *a = GNUNET_strdup (accept);
+ char *saveptr;
+
+ for (char *t = strtok_r (a, ",", &saveptr);
+ NULL != t;
+ t = strtok_r (NULL, ",", &saveptr))
+ {
+ char *end;
+
+ /* skip leading whitespace */
+ while (isspace ((unsigned char) t[0]))
+ t++;
+ /* trim of ';q=' parameter and everything after space */
+ end = strchr (t, ';');
+ if (NULL != end)
+ *end = '\0';
+ end = strchr (t, ' ');
+ if (NULL != end)
+ *end = '\0';
+ if (0 == strcasecmp ("text/html",
+ t))
+ {
+ god->generate_html = true;
+ break;
+ }
+ }
+ GNUNET_free (a);
+ }
+ } /* end check for 'Accept' header */
+
{
const char *long_poll_timeout_s;
@@ -1058,18 +1215,60 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
refund));
}
- return TALER_MHD_reply_json_pack (
- connection,
- MHD_HTTP_OK,
- "{s:s, s:b, s:o, s:o, s:o}",
- "order_status", "paid",
- "refunded", god->refunded,
- "refund_amount",
- TALER_JSON_from_amount (&god->refund_amount),
- "refunds",
- ra,
- "merchant_pub",
- GNUNET_JSON_from_data_auto (&hc->instance->merchant_pub));
+ if (god->generate_html)
+ {
+ int ret;
+ struct MHD_Response *reply;
+ char *body;
+
+#if 0
+ char *qr;
+
+ qr = create_qrcode (taler_refund_uri);
+ if (NULL == qr)
+ {
+ GNUNET_break (0);
+ return MHD_NO;
+ }
+#endif
+ GNUNET_asprintf (&body,
+ "<html><body>Paid. Refund: %s</body></html>",
+ TALER_amount2s (&god->refund_amount));
+ // GNUNET_free (qr);
+ reply = MHD_create_response_from_buffer (strlen (body),
+ body,
+ MHD_RESPMEM_MUST_COPY);
+ GNUNET_free (body);
+ if (NULL == reply)
+ {
+ GNUNET_break (0);
+ return MHD_NO;
+ }
+ GNUNET_break (MHD_NO !=
+ MHD_add_response_header (reply,
+ MHD_HTTP_HEADER_CONTENT_TYPE,
+ "text/html"));
+ ret = MHD_queue_response (god->sc.con,
+ MHD_HTTP_OK,
+ reply);
+ MHD_destroy_response (reply);
+ return ret;
+ }
+ else
+ {
+ return TALER_MHD_reply_json_pack (
+ connection,
+ MHD_HTTP_OK,
+ "{s:s, s:b, s:o, s:o, s:o}",
+ "order_status", "paid",
+ "refunded", god->refunded,
+ "refund_amount",
+ TALER_JSON_from_amount (&god->refund_amount),
+ "refunds",
+ ra,
+ "merchant_pub",
+ GNUNET_JSON_from_data_auto (&hc->instance->merchant_pub));
+ }
}
}