#include <gnutls/crypto.h>
#include <time.h>
+#define HAVE_MHD_NO_LISTEN_SOCKET MHD_VERSION >= 0x00091401
+
#define GNUNET_GNS_PROXY_PORT 7777
#define MHD_MAX_CONNECTIONS 300
#define MAX_HTTP_URI_LENGTH 2048
/* DLL for tasks */
struct ProxyCurlTask *next;
+ /* Already accepted */
+ int accepted;
+
/* Handle to cURL */
CURL *curl;
+ /* is curl running? */
+ int curl_running;
+
/* Optional header replacements for curl (LEHO) */
struct curl_slist *headers;
struct MHD_PostProcessor *post_handler;
/* post data */
- struct ProxyPostData *post_data_head;
- struct ProxyPostData *post_data_tail;
+ struct ProxyUploadData *upload_data_head;
+ struct ProxyUploadData *upload_data_tail;
int post_done;
/* the type of POST encoding */
char* post_type;
+
+ struct curl_httppost *httppost;
+
+ struct curl_httppost *httppost_last;
+
+ int is_httppost;
};
/* DLL */
struct ProxyREMatch *prev;
+ /* is SSL */
+ int is_ssl;
+
/* hostname found */
char hostname[255];
/**
* Post data structure
*/
-struct ProxyPostData
+struct ProxyUploadData
{
/* DLL */
- struct ProxyPostData *next;
+ struct ProxyUploadData *next;
/* DLL */
- struct ProxyPostData *prev;
+ struct ProxyUploadData *prev;
+
+ char *key;
+
+ char *filename;
+
+ char *content_type;
+
+ size_t content_length;
/* value */
char *value;
}
/**
- * Escape giben 0-terminated string
+ * Escape given 0-terminated string
*
* @param to_esc string to escapse
* @return allocated new escaped string (MUST free!)
size_t size)
{
struct ProxyCurlTask* ctask = cls;
- struct ProxyPostData* pdata;
+ 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 ProxyPostData));
+ pdata = GNUNET_malloc (sizeof (struct ProxyUploadData));
enc = escape_to_urlenc (key);
pdata->value = GNUNET_malloc (strlen (enc) + 3);
- if (NULL != ctask->post_data_head)
+ if (NULL != ctask->upload_data_head)
{
pdata->value[0] = '&';
memcpy (pdata->value+1, enc, strlen (enc));
"Escaped POST key: '%s'\n",
pdata->value);
- GNUNET_CONTAINER_DLL_insert_tail (ctask->post_data_head,
- ctask->post_data_tail,
+ GNUNET_CONTAINER_DLL_insert_tail (ctask->upload_data_head,
+ ctask->upload_data_tail,
pdata);
}
/* a value */
- pdata = GNUNET_malloc (sizeof (struct ProxyPostData));
+ pdata = GNUNET_malloc (sizeof (struct ProxyUploadData));
enc = escape_to_urlenc (data);
pdata->value = GNUNET_malloc (strlen (enc) + 1);
memcpy (pdata->value, enc, strlen (enc));
"Escaped POST value: '%s'\n",
pdata->value);
- GNUNET_CONTAINER_DLL_insert_tail (ctask->post_data_head,
- ctask->post_data_tail,
+ GNUNET_CONTAINER_DLL_insert_tail (ctask->upload_data_head,
+ ctask->upload_data_tail,
pdata);
return MHD_YES;
}
-static int
-get_uri_val_iter (void *cls,
- enum MHD_ValueKind kind,
- const char *key,
- const char *value)
-{
- char* buf = cls;
-
- if (strlen (buf) + strlen (value) + 3 > MAX_HTTP_URI_LENGTH)
- return MHD_NO;
- sprintf (buf+strlen (buf), "?%s=%s", key, value);
-
- return MHD_YES;
-}
-
/**
* Read HTTP request header field 'Host'
*
else
hdr_val = value;
- if (0 == strcmp (MHD_HTTP_HEADER_CONTENT_TYPE,
+ if (0 == strcasecmp (MHD_HTTP_HEADER_CONTENT_TYPE,
key))
{
- if (0 == strcmp (value,
- MHD_HTTP_POST_ENCODING_FORM_URLENCODED))
+ if (0 == strncasecmp (value,
+ MHD_HTTP_POST_ENCODING_FORM_URLENCODED,
+ strlen (MHD_HTTP_POST_ENCODING_FORM_URLENCODED)))
ctask->post_type = MHD_HTTP_POST_ENCODING_FORM_URLENCODED;
- else if (0 == strcmp (value,
- MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA))
+ else if (0 == strncasecmp (value,
+ MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA,
+ strlen (MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA)))
ctask->post_type = MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA;
else
ctask->post_type = NULL;
char* hdr_val;
int delta_cdomain;
size_t offset = 0;
+ char cors_hdr[strlen (ctask->leho) + strlen ("https://")];
if (NULL == ctask->response)
{
&mhd_content_cb,
ctask,
NULL);
+
+ /* if we have a leho add a CORS header */
+ if (0 != strcmp ("", ctask->leho))
+ {
+ /* We could also allow ssl and http here */
+ if (ctask->mhd->is_ssl)
+ sprintf (cors_hdr, "https://%s", ctask->leho);
+ else
+ sprintf (cors_hdr, "http://%s", ctask->leho);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "MHD: Adding CORS header field %s\n",
+ cors_hdr);
+
+ if (GNUNET_NO == MHD_add_response_header (ctask->response,
+ "Access-Control-Allow-Origin",
+ cors_hdr))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "MHD: Error adding CORS header field %s\n",
+ cors_hdr);
+ }
+ }
ctask->ready_to_queue = GNUNET_YES;
-
}
if (html_mime_len <= bytes)
const struct GNUNET_SCHEDULER_TaskContext *tc)
{
struct ProxyCurlTask *ctask = cls;
- GNUNET_assert (NULL == ctask->pp_match_head);
+ struct ProxyUploadData *pdata;
+ GNUNET_assert (NULL == ctask->pp_match_head);
if (NULL != ctask->headers)
curl_slist_free_all (ctask->headers);
if (NULL != ctask->post_handler)
MHD_destroy_post_processor (ctask->post_handler);
+ if (GNUNET_SCHEDULER_NO_TASK != ctask->pp_task)
+ GNUNET_SCHEDULER_cancel (ctask->pp_task);
+ for (pdata = ctask->upload_data_head; NULL != pdata; pdata = ctask->upload_data_head)
+ {
+ GNUNET_CONTAINER_DLL_remove (ctask->upload_data_head,
+ ctask->upload_data_tail,
+ pdata);
+ GNUNET_free_non_null (pdata->filename);
+ GNUNET_free_non_null (pdata->content_type);
+ GNUNET_free_non_null (pdata->key);
+ GNUNET_free_non_null (pdata->value);
+ GNUNET_free (pdata);
+ }
GNUNET_free (ctask);
}
size_t max)
{
struct ProxyCurlTask *ctask = cls;
- struct ProxyREMatch *re_match = ctask->pp_match_head;
+ struct ProxyREMatch *re_match;
ssize_t copied = 0;
long long int bytes_to_copy = ctask->buffer_write_ptr - ctask->buffer_read_ptr;
return 0;
copied = 0;
- for (; NULL != re_match; re_match = ctask->pp_match_head)
+ for (re_match = ctask->pp_match_head; NULL != re_match; re_match = ctask->pp_match_head)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"MHD: Processing PP %s\n",
return copied;
}
+
/**
* Shorten result callback
*
re_match->hostname,
result);
- if (re_match->ctask->mhd->is_ssl)
+ if (re_match->is_ssl)
sprintf (re_match->result, "href=\"https://%s", result);
else
sprintf (re_match->result, "href=\"http://%s", result);
memset (re_hostname, 0, sizeof (re_hostname));
memcpy (re_hostname, re_ptr+m[1].rm_so, (m[3].rm_eo-m[1].rm_so));
+
re_match = GNUNET_malloc (sizeof (struct ProxyREMatch));
re_match->start = re_ptr + m[0].rm_so;
re_match->end = re_ptr + m[3].rm_eo;
re_match->done = GNUNET_NO;
re_match->ctask = ctask;
+
+ if ('s' == *(re_ptr+m[1].rm_so-strlen("://")-1)) //FIXME strcmp
+ re_match->is_ssl = GNUNET_YES;
+ else
+ re_match->is_ssl = GNUNET_NO;
+
strcpy (re_match->hostname, re_hostname);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"PP: Got hostname %s\n", re_hostname);
"CURL: Got %d. %d free in buffer\n",
total, buf_space);
+ if (BUF_WAIT_FOR_CURL != ctask->buf_status)
+ return CURL_WRITEFUNC_PAUSE;
+
if (total > (buf_space - CURL_BUF_PADDING))
{
if (ctask->buf_status == BUF_WAIT_FOR_CURL)
return total;
}
+
+/**
+ * cURL callback for put data
+ */
+static size_t
+put_read_callback (void *buf, size_t size, size_t nmemb, void *cls)
+{
+ struct ProxyCurlTask *ctask = cls;
+ struct ProxyUploadData *pdata = ctask->upload_data_head;
+ size_t len = size * nmemb;
+ size_t to_copy;
+ char* pos;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "CURL: put read callback\n");
+
+ if (NULL == pdata)
+ return CURL_READFUNC_PAUSE;
+
+ //fin
+ if (NULL == pdata->value)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "CURL: Terminating PUT\n");
+
+ GNUNET_CONTAINER_DLL_remove (ctask->upload_data_head,
+ ctask->upload_data_tail,
+ pdata);
+ GNUNET_free (pdata);
+ return 0;
+ }
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "CURL: read callback value %s\n", pdata->value);
+
+ to_copy = pdata->bytes_left;
+ if (to_copy > len)
+ to_copy = len;
+
+ pos = pdata->value + (pdata->total_bytes - pdata->bytes_left);
+ memcpy (buf, pos, to_copy);
+ pdata->bytes_left -= to_copy;
+ if (pdata->bytes_left <= 0)
+ {
+ GNUNET_free (pdata->value);
+ GNUNET_CONTAINER_DLL_remove (ctask->upload_data_head,
+ ctask->upload_data_tail,
+ pdata);
+ GNUNET_free (pdata);
+ }
+ return to_copy;
+}
+
+
/**
* cURL callback for post data
*/
static size_t
-read_callback (void *buf, size_t size, size_t nmemb, void *cls)
+post_read_callback (void *buf, size_t size, size_t nmemb, void *cls)
{
struct ProxyCurlTask *ctask = cls;
- struct ProxyPostData *pdata = ctask->post_data_head;
+ struct ProxyUploadData *pdata = ctask->upload_data_head;
size_t len = size * nmemb;
size_t to_copy;
char* pos;
"CURL: read callback\n");
if (NULL == pdata)
- return 0;
+ return CURL_READFUNC_PAUSE;
//fin
if (NULL == pdata->value)
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"CURL: Terminating POST data\n");
- GNUNET_CONTAINER_DLL_remove (ctask->post_data_head,
- ctask->post_data_tail,
+ GNUNET_CONTAINER_DLL_remove (ctask->upload_data_head,
+ ctask->upload_data_tail,
pdata);
GNUNET_free (pdata);
return 0;
if (pdata->bytes_left <= 0)
{
GNUNET_free (pdata->value);
- GNUNET_CONTAINER_DLL_remove (ctask->post_data_head,
- ctask->post_data_tail,
+ GNUNET_CONTAINER_DLL_remove (ctask->upload_data_head,
+ ctask->upload_data_tail,
pdata);
GNUNET_free (pdata);
}
else if (NULL != ctasks_head)
{
/* as specified in curl docs */
- curl_download_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
+ curl_download_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MILLISECONDS,
&curl_task_download,
curl_multi);
}
GNUNET_NETWORK_fdset_destroy (gws);
GNUNET_NETWORK_fdset_destroy (grs);
-
}
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Shutdown requested while trying to download\n");
- //TODO cleanup
- return;
+ //TODO cleanup
+ return;
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Ready to dl\n");
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Running curl tasks: %d\n", running);
- ctask = ctasks_head;
- for (; ctask != NULL; ctask = ctask->next)
+ for (ctask = ctasks_head; NULL != ctask; ctask = ctask->next)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"CTask: %s\n", ctask->url);
do
{
- ctask = ctasks_head;
+
msg = curl_multi_info_read (curl_multi, &msgnum);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Messages left: %d\n", msgnum);
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Download curl failed");
- for (; ctask != NULL; ctask = ctask->next)
+ for (ctask = ctasks_head; NULL != ctask; ctask = ctask->next)
{
if (NULL == ctask->curl)
continue;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"CURL: download completed.\n");
- for (; ctask != NULL; ctask = ctask->next)
+ for (ctask = ctasks_head; NULL != ctask; ctask = ctask->next)
{
if (NULL == ctask->curl)
continue;
- if (memcmp (msg->easy_handle, ctask->curl, sizeof (CURL)) != 0)
- continue;
-
- if (ctask->buf_status != BUF_WAIT_FOR_CURL)
+ if (0 != memcmp (msg->easy_handle, ctask->curl, sizeof (CURL)))
continue;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
}
} while (msgnum > 0);
- for (ctask=clean_head; ctask != NULL; ctask = ctask->next)
+ for (ctask=clean_head; NULL != ctask; ctask = ctask->next)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"CURL: Removing task %s.\n", ctask->url);
}
num_ctasks=0;
- for (ctask=ctasks_head; ctask != NULL; ctask = ctask->next)
+ for (ctask=ctasks_head; NULL != ctask; ctask = ctask->next)
{
num_ctasks++;
}
curl_download_prepare();
}
+
/**
* Process LEHO lookup
*
ctask);
}
+static void*
+mhd_log_callback (void* cls, const char* url)
+{
+ struct ProxyCurlTask *ctask;
+
+ ctask = GNUNET_malloc (sizeof (struct ProxyCurlTask));
+ strcpy (ctask->url, url);
+ ctask->accepted = GNUNET_NO;
+ return ctask;
+}
/**
* Main MHD callback for handling requests.
char curlurl[MAX_HTTP_URI_LENGTH]; // buffer overflow!
int ret = MHD_YES;
+ int i;
- struct ProxyCurlTask *ctask;
- struct ProxyPostData *fin_post;
+ struct ProxyCurlTask *ctask = *con_cls;
+ struct ProxyUploadData *fin_post;
+ struct curl_forms forms[5];
+ struct ProxyUploadData *upload_data_iter;
//FIXME handle
if ((0 != strcasecmp (meth, MHD_HTTP_METHOD_GET)) &&
(0 != strcasecmp (meth, MHD_HTTP_METHOD_PUT)) &&
- (0 != strcasecmp (meth, MHD_HTTP_METHOD_POST)))
+ (0 != strcasecmp (meth, MHD_HTTP_METHOD_POST)) &&
+ (0 != strcasecmp (meth, MHD_HTTP_METHOD_HEAD)))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"MHD: %s NOT IMPLEMENTED!\n", meth);
}
- if (NULL == *con_cls)
+ if (GNUNET_NO == ctask->accepted)
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Got %s request for %s\n", meth, url);
- ctask = GNUNET_malloc (sizeof (struct ProxyCurlTask));
ctask->mhd = hd;
- *con_cls = ctask;
-
ctask->curl = curl_easy_init();
+ ctask->curl_running = GNUNET_NO;
if (NULL == ctask->curl)
{
ctask->response = MHD_create_response_from_buffer (strlen (page),
GNUNET_free (ctask);
return ret;
}
-
+
+ if (ctask->mhd->is_ssl)
+ ctask->port = HTTPS_PORT;
+ else
+ ctask->port = HTTP_PORT;
+
+ MHD_get_connection_values (con,
+ MHD_HEADER_KIND,
+ &con_val_iter, ctask);
+
+ curl_easy_setopt (ctask->curl, CURLOPT_HEADERFUNCTION, &curl_check_hdr);
+ curl_easy_setopt (ctask->curl, CURLOPT_HEADERDATA, ctask);
+ curl_easy_setopt (ctask->curl, CURLOPT_WRITEFUNCTION, &curl_download_cb);
+ curl_easy_setopt (ctask->curl, CURLOPT_WRITEDATA, ctask);
+ curl_easy_setopt (ctask->curl, CURLOPT_FOLLOWLOCATION, 0);
+ curl_easy_setopt (ctask->curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
+
+ if (GNUNET_NO == ctask->mhd->is_ssl)
+ {
+ sprintf (curlurl, "http://%s:%d%s", ctask->host, ctask->port, ctask->url);
+ curl_easy_setopt (ctask->curl, CURLOPT_URL, curlurl);
+ }
+
+
+ curl_easy_setopt (ctask->curl, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (ctask->curl, CURLOPT_CONNECTTIMEOUT, 600L);
+ curl_easy_setopt (ctask->curl, CURLOPT_TIMEOUT, 600L);
+
+ /* Add GNS header */
+ ctask->headers = curl_slist_append (ctask->headers,
+ "GNS: YES");
+ ctask->accepted = GNUNET_YES;
ctask->download_in_progress = GNUNET_YES;
ctask->buf_status = BUF_WAIT_FOR_CURL;
ctask->connection = con;
ctask->buffer_read_ptr = ctask->buffer;
ctask->buffer_write_ptr = ctask->buffer;
ctask->pp_task = GNUNET_SCHEDULER_NO_TASK;
- ctask->port = HTTP_PORT;
-
- MHD_get_connection_values (con,
- MHD_HEADER_KIND,
- &con_val_iter, ctask);
+
if (0 == strcasecmp (meth, MHD_HTTP_METHOD_PUT))
{
- if (0 == *upload_data_size)
- {
- curl_easy_cleanup (ctask->curl);
- GNUNET_free (ctask);
- return MHD_NO;
- }
- ctask->put_read_offset = 0;
- ctask->put_read_size = *upload_data_size;
- curl_easy_setopt (ctask->curl, CURLOPT_UPLOAD, 1);
- curl_easy_setopt (ctask->curl, CURLOPT_READDATA, upload_data);
- //curl_easy_setopt (ctask->curl, CURLOPT_READFUNCTION, &curl_read_cb);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Setting up PUT\n");
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Got PUT data: %s\n", upload_data);
- curl_easy_cleanup (ctask->curl);
- GNUNET_free (ctask);
- return MHD_NO;
+ curl_easy_setopt (ctask->curl, CURLOPT_UPLOAD, 1);
+ curl_easy_setopt (ctask->curl, CURLOPT_READDATA, ctask);
+ curl_easy_setopt (ctask->curl, CURLOPT_READFUNCTION, &put_read_callback);
+ ctask->headers = curl_slist_append (ctask->headers,
+ "Transfer-Encoding: chunked");
}
if (0 == strcasecmp (meth, MHD_HTTP_METHOD_POST))
{
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ //FIXME handle multipart
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Setting up POST processor\n");
ctask->post_handler = MHD_create_post_processor (con,
POSTBUFFERSIZE,
&con_post_data_iter,
ctask);
- curl_easy_setopt (ctask->curl, CURLOPT_POST, 1);
- curl_easy_setopt (ctask->curl, CURLOPT_READFUNCTION,
- &read_callback);
- curl_easy_setopt (ctask->curl, CURLOPT_READDATA, ctask);
ctask->headers = curl_slist_append (ctask->headers,
- "Transfer-Encoding: chunked");
- /*curl_easy_setopt (ctask->curl, CURLOPT_POST, 1);
- curl_easy_setopt (ctask->curl, CURLOPT_POSTFIELDSIZE, *upload_data_size);
- curl_easy_setopt (ctask->curl, CURLOPT_COPYPOSTFIELDS, upload_data);
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Got POST data: %s\n", upload_data);
- curl_easy_cleanup (ctask->curl);
- GNUNET_free (ctask);
- return MHD_NO;*/
+ "Transfer-Encoding: chunked");
+ return MHD_YES;
}
- curl_easy_setopt (ctask->curl, CURLOPT_HEADERFUNCTION, &curl_check_hdr);
- curl_easy_setopt (ctask->curl, CURLOPT_HEADERDATA, ctask);
- curl_easy_setopt (ctask->curl, CURLOPT_WRITEFUNCTION, &curl_download_cb);
- curl_easy_setopt (ctask->curl, CURLOPT_WRITEDATA, ctask);
- curl_easy_setopt (ctask->curl, CURLOPT_FOLLOWLOCATION, 0);
- curl_easy_setopt (ctask->curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
-
- if (GNUNET_NO == ctask->mhd->is_ssl)
+ if (0 == strcasecmp (meth, MHD_HTTP_METHOD_HEAD))
{
- sprintf (curlurl, "http://%s:%d%s", ctask->host, ctask->port, url);
- MHD_get_connection_values (con,
- MHD_GET_ARGUMENT_KIND,
- &get_uri_val_iter, curlurl);
- curl_easy_setopt (ctask->curl, CURLOPT_URL, curlurl);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Setting NOBODY\n");
+ curl_easy_setopt (ctask->curl, CURLOPT_NOBODY, 1);
}
- strcpy (ctask->url, url);
+
+
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "MHD: Adding new curl task for %s%s\n", ctask->host, url);
- MHD_get_connection_values (con,
- MHD_GET_ARGUMENT_KIND,
- &get_uri_val_iter, ctask->url);
-
- curl_easy_setopt (ctask->curl, CURLOPT_FAILONERROR, 1);
- curl_easy_setopt (ctask->curl, CURLOPT_CONNECTTIMEOUT, 600L);
- curl_easy_setopt (ctask->curl, CURLOPT_TIMEOUT, 600L);
+ "MHD: Adding new curl task for %s\n", ctask->host);
GNUNET_GNS_get_authority (gns_handle,
ctask->host,
ctask);
ctask->ready_to_queue = GNUNET_NO;
ctask->fin = GNUNET_NO;
+ ctask->curl_running = GNUNET_YES;
return MHD_YES;
}
{
if (0 != *upload_data_size)
{
+
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Invoking POST processor\n");
MHD_post_process (ctask->post_handler,
upload_data, *upload_data_size);
*upload_data_size = 0;
+ if ((GNUNET_NO == ctask->is_httppost) &&
+ (GNUNET_NO == ctask->curl_running))
+ {
+ curl_easy_setopt (ctask->curl, CURLOPT_POST, 1);
+ curl_easy_setopt (ctask->curl, CURLOPT_READFUNCTION,
+ &post_read_callback);
+ curl_easy_setopt (ctask->curl, CURLOPT_READDATA, ctask);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "MHD: Adding new curl task for %s\n", ctask->host);
+
+ GNUNET_GNS_get_authority (gns_handle,
+ ctask->host,
+ &process_get_authority,
+ ctask);
+ ctask->ready_to_queue = GNUNET_NO;
+ ctask->fin = GNUNET_NO;
+ ctask->curl_running = GNUNET_YES;
+ }
return MHD_YES;
}
else if (GNUNET_NO == ctask->post_done)
{
- fin_post = GNUNET_malloc (sizeof (struct ProxyPostData));
- GNUNET_CONTAINER_DLL_insert_tail (ctask->post_data_head,
- ctask->post_data_tail,
+ if (GNUNET_YES == ctask->is_httppost)
+ {
+ for (upload_data_iter = ctask->upload_data_head;
+ NULL != upload_data_iter;
+ upload_data_iter = upload_data_iter->next)
+ {
+ i = 0;
+ if (NULL != upload_data_iter->filename)
+ {
+ forms[i].option = CURLFORM_FILENAME;
+ forms[i].value = upload_data_iter->filename;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Adding filename %s\n",
+ forms[i].value);
+ i++;
+ }
+ if (NULL != upload_data_iter->content_type)
+ {
+ forms[i].option = CURLFORM_CONTENTTYPE;
+ forms[i].value = upload_data_iter->content_type;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Adding content type %s\n",
+ forms[i].value);
+ i++;
+ }
+ forms[i].option = CURLFORM_PTRCONTENTS;
+ forms[i].value = upload_data_iter->value;
+ forms[i+1].option = CURLFORM_END;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Adding formdata for %s (len=%lld)\n",
+ upload_data_iter->key,
+ upload_data_iter->total_bytes);
+
+ curl_formadd(&ctask->httppost, &ctask->httppost_last,
+ CURLFORM_COPYNAME, upload_data_iter->key,
+ CURLFORM_CONTENTSLENGTH, upload_data_iter->total_bytes,
+ CURLFORM_ARRAY, forms,
+ CURLFORM_END);
+ }
+ curl_easy_setopt (ctask->curl, CURLOPT_HTTPPOST,
+ ctask->httppost);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "MHD: Adding new curl task for %s\n", ctask->host);
+
+ GNUNET_GNS_get_authority (gns_handle,
+ ctask->host,
+ &process_get_authority,
+ ctask);
+ ctask->ready_to_queue = GNUNET_YES;
+ ctask->fin = GNUNET_NO;
+ ctask->curl_running = GNUNET_YES;
+ ctask->post_done = GNUNET_YES;
+ return MHD_YES;
+ }
+
+ fin_post = GNUNET_malloc (sizeof (struct ProxyUploadData));
+ GNUNET_CONTAINER_DLL_insert_tail (ctask->upload_data_head,
+ ctask->upload_data_tail,
fin_post);
ctask->post_done = GNUNET_YES;
return MHD_YES;
0, "DE", 2);
gnutls_x509_crt_set_dn_by_oid (request, GNUTLS_OID_X520_ORGANIZATION_NAME,
- 0, "GNUnet", 6);
+ 0, "GADS", 4);
gnutls_x509_crt_set_dn_by_oid (request, GNUTLS_OID_X520_COMMON_NAME,
0, name, strlen (name));
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"No previous SSL instance found... starting new one for %s\n",
domain);
-
- hd->daemon = MHD_start_daemon (MHD_USE_DEBUG | MHD_USE_SSL, 4444,
- &accept_cb, NULL,
- &create_response, hd,
+ hd->daemon = MHD_start_daemon (MHD_USE_DEBUG
+ | MHD_USE_SSL
+#if HAVE_MHD_NO_LISTEN_SOCKET
+ | MHD_USE_NO_LISTEN_SOCKET,
+ 0,
+#else
+ , 4444, //Dummy
+#endif
+ &accept_cb, NULL,
+ &create_response, hd,
+#if !HAVE_MHD_NO_LISTEN_SOCKET
MHD_OPTION_LISTEN_SOCKET, GNUNET_NETWORK_get_fd (mhd_unix_socket),
- MHD_OPTION_CONNECTION_LIMIT, MHD_MAX_CONNECTIONS,
- MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 16,
- MHD_OPTION_NOTIFY_COMPLETED,
- NULL, NULL,
- MHD_OPTION_HTTPS_MEM_KEY, pgc->key,
- MHD_OPTION_HTTPS_MEM_CERT, pgc->cert,
- MHD_OPTION_END);
+#endif
+ MHD_OPTION_CONNECTION_LIMIT,
+ MHD_MAX_CONNECTIONS,
+ MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 16,
+ MHD_OPTION_NOTIFY_COMPLETED, NULL, NULL,
+ MHD_OPTION_HTTPS_MEM_KEY, pgc->key,
+ MHD_OPTION_HTTPS_MEM_CERT, pgc->cert,
+ MHD_OPTION_URI_LOG_CALLBACK, &mhd_log_callback,
+ NULL,
+ MHD_OPTION_END);
GNUNET_assert (hd->daemon != NULL);
hd->httpd_task = GNUNET_SCHEDULER_NO_TASK;
struct NetworkHandleList *tmp_nh;
struct ProxyCurlTask *ctask;
struct ProxyCurlTask *ctask_tmp;
+ struct ProxyUploadData *pdata;
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Shutting down...\n");
if (NULL != ctask->response)
MHD_destroy_response (ctask->response);
+ pdata = ctask->upload_data_head;
+
+ //FIXME free pdata here
+ for (; pdata != NULL; pdata = ctask->upload_data_head)
+ {
+ GNUNET_CONTAINER_DLL_remove (ctask->upload_data_head,
+ ctask->upload_data_tail,
+ pdata);
+ GNUNET_free_non_null (pdata->filename);
+ GNUNET_free_non_null (pdata->content_type);
+ GNUNET_free_non_null (pdata->key);
+ GNUNET_free_non_null (pdata->value);
+ GNUNET_free (pdata);
+ }
GNUNET_free (ctask);
}
{
struct sockaddr_in sa;
struct MhdHttpList *hd;
- struct sockaddr_un mhd_unix_sock_addr;
- size_t len;
- char* proxy_sockfile;
char* cafile_cfg = NULL;
char* cafile;
+#if !HAVE_MHD_NO_LISTEN_SOCKET
+ size_t len;
+ char* proxy_sockfile;
+ struct sockaddr_un mhd_unix_sock_addr;
+#endif
curl_multi = curl_multi_init ();
}
cafile = cafile_cfg;
}
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Using %s as CA\n", cafile);
gnutls_global_init ();
gnutls_x509_crt_init (&proxy_ca.cert);
mhd_httpd_head = NULL;
mhd_httpd_tail = NULL;
total_mhd_connections = 0;
-
+#ifndef HAVE_MHD_NO_LISTEN_SOCKET
if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns-proxy",
"PROXY_UNIXPATH",
&proxy_sockfile))
"Specify PROXY_UNIXPATH in gns-proxy config section!\n");
return;
}
-
+
mhd_unix_socket = GNUNET_NETWORK_socket_create (AF_UNIX,
SOCK_STREAM,
0);
"Unable to listen on unix domain socket!\n");
return;
}
+#endif
hd = GNUNET_malloc (sizeof (struct MhdHttpList));
hd->is_ssl = GNUNET_NO;
strcpy (hd->domain, "");
- httpd = MHD_start_daemon (MHD_USE_DEBUG, 4444, //Dummy port
+ httpd = MHD_start_daemon (MHD_USE_DEBUG
+#if HAVE_MHD_NO_LISTEN_SOCKET
+ | MHD_USE_NO_LISTEN_SOCKET,
+ 0,
+#else
+ , 4444, //Dummy port
+#endif
&accept_cb, NULL,
&create_response, hd,
+#if !HAVE_MHD_NO_LISTEN_SOCKET
MHD_OPTION_LISTEN_SOCKET, GNUNET_NETWORK_get_fd (mhd_unix_socket),
+#endif
MHD_OPTION_CONNECTION_LIMIT, MHD_MAX_CONNECTIONS,
MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 16,
MHD_OPTION_NOTIFY_COMPLETED,
NULL, NULL,
+ MHD_OPTION_URI_LOG_CALLBACK, &mhd_log_callback, NULL,
MHD_OPTION_END);
GNUNET_assert (httpd != NULL);