+struct _mkq_ {
+ int count;
+ size_t length;
+ size_t alloc;
+ char *text;
+};
+
+static void _mkq_add_(struct _mkq_ *mkq, char value)
+{
+ char *text = mkq->text;
+ if (text != NULL) {
+ if (mkq->length == mkq->alloc) {
+ mkq->alloc += 100;
+ text = realloc(text, mkq->alloc);
+ if (text == NULL) {
+ free(mkq->text);
+ mkq->text = NULL;
+ return;
+ }
+ mkq->text = text;
+ }
+ text[mkq->length++] = value;
+ }
+}
+
+static void _mkq_add_hex_(struct _mkq_ *mkq, char value)
+{
+ _mkq_add_(mkq, (char)(value < 10 ? value + '0' : value + 'A' - 10));
+}
+
+static void _mkq_add_esc_(struct _mkq_ *mkq, char value)
+{
+ _mkq_add_(mkq, '%');
+ _mkq_add_hex_(mkq, (char)((value >> 4) & 15));
+ _mkq_add_hex_(mkq, (char)(value & 15));
+}
+
+static void _mkq_add_char_(struct _mkq_ *mkq, char value)
+{
+ if (value <= ' ' || value >= 127)
+ _mkq_add_esc_(mkq, value);
+ else
+ switch(value) {
+ case '=':
+ case '&':
+ case '%':
+ _mkq_add_esc_(mkq, value);
+ break;
+ default:
+ _mkq_add_(mkq, value);
+ }
+}
+
+static void _mkq_append_(struct _mkq_ *mkq, const char *value)
+{
+ while(*value)
+ _mkq_add_char_(mkq, *value++);
+}
+
+static int _mkquery_(struct _mkq_ *mkq, enum MHD_ValueKind kind, const char *key, const char *value)
+{
+ _mkq_add_(mkq, mkq->count++ ? '&' : '?');
+ _mkq_append_(mkq, key);
+ if (value != NULL) {
+ _mkq_add_(mkq, '=');
+ _mkq_append_(mkq, value);
+ }
+ return 1;
+}
+
+static char *url_with_query(struct afb_hreq *hreq, const char *url)