+/* The users local GNS zone hash */
+static struct GNUNET_CRYPTO_ShortHashCode *local_gns_zone;
+
+/* The users local private zone */
+static struct GNUNET_CRYPTO_ShortHashCode *local_private_zone;
+
+/* The users local shorten zone */
+static struct GNUNET_CRYPTO_ShortHashCode *local_shorten_zone;
+
+/* The CA for SSL certificate generation */
+static struct ProxyCA proxy_ca;
+
+/* UNIX domain socket for mhd */
+struct GNUNET_NETWORK_Handle *mhd_unix_socket;
+
+/* Shorten zone private key */
+struct GNUNET_CRYPTO_RsaPrivateKey *shorten_zonekey;
+
+/**
+ * Checks if name is in tld
+ *
+ * @param name the name to check
+ * @param tld the TLD to check for
+ * @return GNUNET_YES or GNUNET_NO
+ */
+int
+is_tld(const char* name, const char* tld)
+{
+ size_t offset;
+
+ if (strlen(name) <= strlen(tld))
+ return GNUNET_NO;
+
+ offset = strlen(name) - strlen(tld);
+ if (0 != strcmp (name+offset, tld))
+ {
+ GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
+ "%s is not in .%s TLD\n", name, tld);
+ return GNUNET_NO;
+ }
+
+ return GNUNET_YES;
+}
+
+/**
+ * convert integer to string representation
+ *
+ * @param i integer
+ * @return the character
+ */
+char i_to_hexchar (char i)
+{
+ static char hexmap[] = "0123456789abcdef";
+ GNUNET_assert (sizeof (hexmap) > (i & 15));
+ return hexmap[i & 15];
+}
+
+/**
+ * Escape given 0-terminated string
+ *
+ * @param to_esc string to escapse
+ * @return allocated new escaped string (MUST free!)
+ */
+static char*
+escape_to_urlenc (const char *to_esc)
+{
+ char *pos = (char*)to_esc;
+ char *res = GNUNET_malloc (strlen (to_esc) * 3 + 1);
+ char *rpos = res;
+
+ while ('\0' != *pos)
+ {
+ if (isalnum (*pos) ||
+ ('-' == *pos) || ('_' == *pos) ||
+ ('.' == *pos) || ('~' == *pos))
+ *rpos++ = *pos;
+ else if (' ' == *pos)
+ *rpos++ = '+';
+ else
+ {
+ *rpos++ = '%';
+ *rpos++ = i_to_hexchar (*pos >> 4);
+ *rpos++ = i_to_hexchar (*pos >> 15);
+ }
+ pos++;
+ }
+ *rpos = '\0';
+ return res;
+}
+
+static int
+con_post_data_iter (void *cls,
+ enum MHD_ValueKind kind,
+ const char *key,
+ const char *filename,
+ const char *content_type,
+ const char *transfer_encoding,
+ const char *data,
+ uint64_t off,
+ size_t size)
+{
+ struct ProxyCurlTask* ctask = cls;
+ struct ProxyUploadData* pdata;
+ char* enc;
+ char* new_value;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Got POST data: '%s : %s' at offset %llu size %lld\n",
+ key, data, off, size);
+
+ GNUNET_assert (NULL != ctask->post_type);
+
+ if (0 == strcasecmp (MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA,
+ ctask->post_type))
+ {
+ ctask->is_httppost = GNUNET_YES;
+ /* new part */
+ if (0 == off)
+ {
+ pdata = GNUNET_malloc (sizeof (struct ProxyUploadData));
+ pdata->key = strdup (key);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Copied %lld\n");
+
+ if (NULL != filename)
+ {
+ pdata->filename = strdup (filename);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Filename %s\n", filename);
+ }
+
+ if (NULL != content_type)
+ {
+ pdata->content_type = strdup (content_type);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Content-Type %s\n", content_type);
+ }
+
+ pdata->value = GNUNET_malloc (size);
+ pdata->total_bytes = size;
+ memcpy (pdata->value, data, size);
+ GNUNET_CONTAINER_DLL_insert_tail (ctask->upload_data_head,
+ ctask->upload_data_tail,
+ pdata);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Copied %lld bytes of POST Data\n", size);
+ return MHD_YES;
+ }
+
+ pdata = ctask->upload_data_tail;
+ new_value = GNUNET_malloc (size + pdata->total_bytes);
+ memcpy (new_value, pdata->value, pdata->total_bytes);
+ memcpy (new_value+off, data, size);
+ GNUNET_free (pdata->value);
+ pdata->value = new_value;
+ pdata->total_bytes += size;
+
+ return MHD_YES;
+
+ }
+
+ if (0 != strcasecmp (MHD_HTTP_POST_ENCODING_FORM_URLENCODED,
+ ctask->post_type))
+ {
+ return MHD_NO;
+ }
+
+ ctask->is_httppost = GNUNET_NO;
+
+ if (NULL != ctask->curl)
+ curl_easy_pause (ctask->curl, CURLPAUSE_CONT);
+
+ if (0 == off)
+ {
+ /* a key */
+ pdata = GNUNET_malloc (sizeof (struct ProxyUploadData));
+ enc = escape_to_urlenc (key);
+ pdata->value = GNUNET_malloc (strlen (enc) + 3);
+ if (NULL != ctask->upload_data_head)
+ {
+ pdata->value[0] = '&';
+ memcpy (pdata->value+1, enc, strlen (enc));
+ }
+ else
+ memcpy (pdata->value, enc, strlen (enc));
+ pdata->value[strlen (pdata->value)] = '=';
+ pdata->bytes_left = strlen (pdata->value);
+ pdata->total_bytes = pdata->bytes_left;
+ GNUNET_free (enc);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Escaped POST key: '%s'\n",
+ pdata->value);
+
+ GNUNET_CONTAINER_DLL_insert_tail (ctask->upload_data_head,
+ ctask->upload_data_tail,
+ pdata);
+ }
+
+ /* a value */
+ pdata = GNUNET_malloc (sizeof (struct ProxyUploadData));
+ enc = escape_to_urlenc (data);
+ pdata->value = GNUNET_malloc (strlen (enc) + 1);
+ memcpy (pdata->value, enc, strlen (enc));
+ pdata->bytes_left = strlen (pdata->value);
+ pdata->total_bytes = pdata->bytes_left;
+ GNUNET_free (enc);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Escaped POST value: '%s'\n",
+ pdata->value);
+
+ GNUNET_CONTAINER_DLL_insert_tail (ctask->upload_data_head,
+ ctask->upload_data_tail,
+ pdata);
+ return MHD_YES;
+}
+
+