diff options
Diffstat (limited to 'src/backend/taler-merchant-httpd_get-orders-ID.c')
-rw-r--r-- | src/backend/taler-merchant-httpd_get-orders-ID.c | 237 |
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)); + } } } |