aboutsummaryrefslogtreecommitdiff
path: root/src/transport
diff options
context:
space:
mode:
authorDavid Barksdale <amatus.amongus@gmail.com>2014-06-01 21:35:18 +0000
committerDavid Barksdale <amatus.amongus@gmail.com>2014-06-01 21:35:18 +0000
commitda3d84fb0f3e5a681976b53d43275b2d9b401886 (patch)
tree2c1b067aa7c4e20c57e8f5a362ca1aa3ce231d16 /src/transport
parentef94867ca20a89d62f741f32f0a5b17a2fcfbe76 (diff)
downloadgnunet-da3d84fb0f3e5a681976b53d43275b2d9b401886.tar.gz
gnunet-da3d84fb0f3e5a681976b53d43275b2d9b401886.zip
Support a wider range of http transport clients.
Specifically web clients which cannot maintain permanent GET and PUT connections.
Diffstat (limited to 'src/transport')
-rw-r--r--src/transport/plugin_transport_http_server.c253
1 files changed, 127 insertions, 126 deletions
diff --git a/src/transport/plugin_transport_http_server.c b/src/transport/plugin_transport_http_server.c
index 950f02f8f..29ae6224e 100644
--- a/src/transport/plugin_transport_http_server.c
+++ b/src/transport/plugin_transport_http_server.c
@@ -31,6 +31,7 @@
31#include "gnunet_nat_lib.h" 31#include "gnunet_nat_lib.h"
32#include "plugin_transport_http_common.h" 32#include "plugin_transport_http_common.h"
33#include <microhttpd.h> 33#include <microhttpd.h>
34#include <regex.h>
34 35
35 36
36 37
@@ -50,17 +51,6 @@
50 51
51 52
52/** 53/**
53 * Enable output for debbuging URL's of incoming requests
54 */
55#define DEBUG_URL_PARSE GNUNET_NO
56
57
58/**
59 * Encapsulation of all of the state of the plugin.
60 */
61struct Plugin;
62
63/**
64 * Session handle for connections. 54 * Session handle for connections.
65 */ 55 */
66struct Session 56struct Session
@@ -137,11 +127,6 @@ struct Session
137 int session_ended; 127 int session_ended;
138 128
139 /** 129 /**
140 * Are incoming connection established at the moment
141 */
142 int connect_in_progress;
143
144 /**
145 * Absolute time when to receive data again 130 * Absolute time when to receive data again
146 * Used for receive throttling 131 * Used for receive throttling
147 */ 132 */
@@ -151,6 +136,11 @@ struct Session
151 * Session timeout task 136 * Session timeout task
152 */ 137 */
153 GNUNET_SCHEDULER_TaskIdentifier timeout_task; 138 GNUNET_SCHEDULER_TaskIdentifier timeout_task;
139
140 /**
141 * Should this session get disconnected? GNUNET_YES/NO
142 */
143 int disconnect;
154}; 144};
155 145
156 146
@@ -162,12 +152,8 @@ struct ServerConnection
162 int direction; 152 int direction;
163 153
164 /** 154 /**
165 * Should this connection get disconnected? GNUNET_YES/NO
166 */
167 int disconnect;
168
169 /**
170 * For PUT connections: Is this the first or last callback with size 0 155 * For PUT connections: Is this the first or last callback with size 0
156 * For GET connections: Have we sent a message
171 */ 157 */
172 int connected; 158 int connected;
173 159
@@ -185,6 +171,12 @@ struct ServerConnection
185 * The MHD daemon 171 * The MHD daemon
186 */ 172 */
187 struct MHD_Daemon *mhd_daemon; 173 struct MHD_Daemon *mhd_daemon;
174
175 /**
176 * Options requested by peer
177 */
178 uint32_t options;
179#define OPTION_LONG_POLL 1 /* GET request wants long-poll semantics */
188}; 180};
189 181
190 182
@@ -345,6 +337,11 @@ struct HTTP_Server_Plugin
345 */ 337 */
346 struct MHD_Daemon *server_v6; 338 struct MHD_Daemon *server_v6;
347 339
340 /**
341 * Regex for parsing URLs
342 */
343 regex_t url_regex;
344
348#if BUILD_HTTPS 345#if BUILD_HTTPS
349 /** 346 /**
350 * Crypto related 347 * Crypto related
@@ -549,23 +546,8 @@ http_server_plugin_send (void *cls,
549 GNUNET_break (0); 546 GNUNET_break (0);
550 return GNUNET_SYSERR; 547 return GNUNET_SYSERR;
551 } 548 }
552 if (NULL == session->server_send) 549 if (session->disconnect)
553 { 550 return GNUNET_SYSERR;
554 if (GNUNET_NO == session->connect_in_progress)
555 {
556 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, session->plugin->name,
557 "Session %p/connection %p: Sending message with %u bytes to peer `%s' with FAILED\n",
558 session, session->server_send,
559 msgbuf_size, GNUNET_i2s (&session->target));
560 GNUNET_break (0);
561 return GNUNET_SYSERR;
562 }
563 }
564 else
565 {
566 if (GNUNET_YES == session->server_send->disconnect)
567 return GNUNET_SYSERR;
568 }
569 551
570 552
571 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, session->plugin->name, 553 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, session->plugin->name,
@@ -844,15 +826,14 @@ http_server_plugin_disconnect_session (void *cls,
844 GNUNET_break (0); 826 GNUNET_break (0);
845 return GNUNET_SYSERR; 827 return GNUNET_SYSERR;
846 } 828 }
847 829 s->disconnect = GNUNET_YES;
848 send = (struct ServerConnection *) s->server_send; 830 send = (struct ServerConnection *) s->server_send;
849 if (s->server_send != NULL) 831 if (send != NULL)
850 { 832 {
851 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, s->plugin->name, 833 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, s->plugin->name,
852 "Server: %p / %p Terminating inbound PUT session to peer `%s'\n", 834 "Server: %p / %p Terminating inbound PUT session to peer `%s'\n",
853 s, s->server_send, GNUNET_i2s (&s->target)); 835 s, send, GNUNET_i2s (&s->target));
854 836
855 send->disconnect = GNUNET_YES;
856 MHD_set_connection_option (send->mhd_conn, 837 MHD_set_connection_option (send->mhd_conn,
857 MHD_CONNECTION_OPTION_TIMEOUT, 838 MHD_CONNECTION_OPTION_TIMEOUT,
858 1); 839 1);
@@ -864,9 +845,8 @@ http_server_plugin_disconnect_session (void *cls,
864 { 845 {
865 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, s->plugin->name, 846 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, s->plugin->name,
866 "Server: %p / %p Terminating inbound GET session to peer `%s'\n", 847 "Server: %p / %p Terminating inbound GET session to peer `%s'\n",
867 s, s->server_recv, GNUNET_i2s (&s->target)); 848 s, recv, GNUNET_i2s (&s->target));
868 849
869 recv->disconnect = GNUNET_YES;
870 MHD_set_connection_option (recv->mhd_conn, 850 MHD_set_connection_option (recv->mhd_conn,
871 MHD_CONNECTION_OPTION_TIMEOUT, 851 MHD_CONNECTION_OPTION_TIMEOUT,
872 1); 852 1);
@@ -881,7 +861,7 @@ http_server_plugin_disconnect_session (void *cls,
881 * GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT is divided by this number to 861 * GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT is divided by this number to
882 * calculate the interval between keepalive packets. 862 * calculate the interval between keepalive packets.
883 * 863 *
884 * @param cls closure with the `struct Plugin` 864 * @param cls closure with the `struct HTTP_Server_Plugin`
885 * @return keepalive factor 865 * @return keepalive factor
886 */ 866 */
887static unsigned int 867static unsigned int
@@ -947,111 +927,124 @@ server_mhd_connection_timeout (struct HTTP_Server_Plugin *plugin,
947 * @param url incoming url 927 * @param url incoming url
948 * @param target where to store the target 928 * @param target where to store the target
949 * @param tag where to store the tag 929 * @param tag where to store the tag
930 * @param options where to store the options
950 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 931 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
951 */ 932 */
952static int 933static int
953server_parse_url (struct HTTP_Server_Plugin *plugin, 934server_parse_url (struct HTTP_Server_Plugin *plugin,
954 const char *url, 935 const char *url,
955 struct GNUNET_PeerIdentity *target, 936 struct GNUNET_PeerIdentity *target,
956 uint32_t *tag) 937 uint32_t *tag,
938 uint32_t *options)
957{ 939{
958 char * tag_start = NULL; 940 regmatch_t matches[4];
959 char * tag_end = NULL; 941 const char *tag_start;
960 char * target_start = NULL; 942 const char *target_start;
961 char * separator = NULL; 943 char *tag_end;
962 unsigned int hash_length; 944 char *options_end;
963 unsigned long int ctag; 945 size_t hash_length;
964 946 unsigned long int rc;
965 /* URL parsing 947
966 * URL is valid if it is in the form [prefix with (multiple) '/'][peerid[103];tag]*/ 948 /* URL parsing */
949#define URL_REGEX \
950 ("^.*/([0-9A-V]+);([0-9]+)(,[0-9]+)?$")
967 951
968 if (NULL == url) 952 if (NULL == url)
969 { 953 {
970 GNUNET_break (0); 954 GNUNET_break (0);
971 return GNUNET_SYSERR; 955 return GNUNET_SYSERR;
972 } 956 }
973 /* convert tag */
974 957
975 /* find separator */ 958 if (regexec(&plugin->url_regex, url, 4, matches, 0))
976 separator = strrchr (url, ';');
977
978 if (NULL == separator)
979 { 959 {
980 if (DEBUG_URL_PARSE) GNUNET_break (0); 960 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
981 return GNUNET_SYSERR; 961 "URL `%s' did not match regex\n", url);
962 return GNUNET_SYSERR;
982 } 963 }
983 tag_start = separator + 1;
984 964
985 if (strlen (tag_start) == 0) 965 target_start = &url[matches[1].rm_so];
966 tag_start = &url[matches[2].rm_so];
967
968 /* convert tag */
969 rc = strtoul (tag_start, &tag_end, 10);
970 if (&url[matches[2].rm_eo] != tag_end)
986 { 971 {
987 /* No tag after separator */ 972 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
988 if (DEBUG_URL_PARSE) GNUNET_break (0); 973 "URL tag did not line up with submatch\n");
989 return GNUNET_SYSERR; 974 return GNUNET_SYSERR;
990 } 975 }
991 ctag = strtoul (tag_start, &tag_end, 10); 976 if (rc == 0)
992 if (ctag == 0)
993 { 977 {
994 /* tag == 0 , invalid */ 978 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
995 if (DEBUG_URL_PARSE) GNUNET_break (0); 979 "URL tag is zero\n");
996 return GNUNET_SYSERR; 980 return GNUNET_SYSERR;
997 } 981 }
998 if ((ctag == ULONG_MAX) && (ERANGE == errno)) 982 if ((rc == ULONG_MAX) && (ERANGE == errno))
999 { 983 {
1000 /* out of range: > ULONG_MAX */ 984 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
1001 if (DEBUG_URL_PARSE) GNUNET_break (0); 985 "URL tag > ULONG_MAX\n");
1002 return GNUNET_SYSERR; 986 return GNUNET_SYSERR;
1003 } 987 }
1004 if (ctag > UINT32_MAX) 988 if (rc > UINT32_MAX)
1005 { 989 {
1006 /* out of range: > UINT32_MAX */ 990 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
1007 if (DEBUG_URL_PARSE) GNUNET_break (0); 991 "URL tag > UINT32_MAX\n");
1008 return GNUNET_SYSERR; 992 return GNUNET_SYSERR;
1009 } 993 }
1010 (*tag) = (uint32_t) ctag; 994 (*tag) = (uint32_t)rc;
1011 if (NULL == tag_end) 995 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
1012 { 996 "Found tag `%u' in url\n", *tag);
1013 /* no char after tag */
1014 if (DEBUG_URL_PARSE) GNUNET_break (0);
1015 return GNUNET_SYSERR;
1016 }
1017 if (url[strlen(url)] != tag_end[0])
1018 {
1019 /* there are more not converted chars after tag */
1020 if (DEBUG_URL_PARSE) GNUNET_break (0);
1021 return GNUNET_SYSERR;
1022 }
1023 if (DEBUG_URL_PARSE)
1024 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
1025 "Found tag `%u' in url\n", (*tag));
1026 997
1027 /* convert peer id */ 998 /* convert peer id */
1028 target_start = strrchr (url, '/'); 999 hash_length = matches[1].rm_eo - matches[1].rm_so;
1029 if (NULL == target_start)
1030 {
1031 /* no leading '/' */
1032 target_start = (char *) url;
1033 }
1034 target_start++;
1035 hash_length = separator - target_start;
1036 if (hash_length != plugin->peer_id_length) 1000 if (hash_length != plugin->peer_id_length)
1037 { 1001 {
1038 /* no char after tag */ 1002 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
1039 if (DEBUG_URL_PARSE) GNUNET_break (0); 1003 "URL target is %u bytes, expecting %u\n",
1040 return GNUNET_SYSERR; 1004 hash_length, plugin->peer_id_length);
1005 return GNUNET_SYSERR;
1041 } 1006 }
1042 if (GNUNET_OK != 1007 if (GNUNET_OK !=
1043 GNUNET_CRYPTO_eddsa_public_key_from_string (target_start, 1008 GNUNET_CRYPTO_eddsa_public_key_from_string (target_start,
1044 hash_length, 1009 hash_length,
1045 &target->public_key)) 1010 &target->public_key))
1046 { 1011 {
1047 /* hash conversion failed */ 1012 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
1048 if (DEBUG_URL_PARSE) GNUNET_break (0); 1013 "URL target conversion failed\n");
1049 return GNUNET_SYSERR; 1014 return GNUNET_SYSERR;
1050 } 1015 }
1051 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 1016 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1052 plugin->name, 1017 plugin->name,
1053 "Found target `%s' in URL\n", 1018 "Found target `%s' in URL\n",
1054 GNUNET_i2s_full (target)); 1019 GNUNET_i2s_full (target));
1020
1021 /* convert options */
1022 if (-1 == matches[3].rm_so) {
1023 *options = 0;
1024 } else {
1025 rc = strtoul (&url[matches[3].rm_so + 1], &options_end, 10);
1026 if (&url[matches[3].rm_eo] != options_end)
1027 {
1028 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
1029 "URL options did not line up with submatch\n");
1030 return GNUNET_SYSERR;
1031 }
1032 if ((rc == ULONG_MAX) && (ERANGE == errno))
1033 {
1034 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
1035 "URL options > ULONG_MAX\n");
1036 return GNUNET_SYSERR;
1037 }
1038 if (rc > UINT32_MAX)
1039 {
1040 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
1041 "URL options > UINT32_MAX\n");
1042 return GNUNET_SYSERR;
1043 }
1044 (*options) = (uint32_t)rc;
1045 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
1046 "Found options `%u' in url\n", *options);
1047 }
1055 return GNUNET_OK; 1048 return GNUNET_OK;
1056} 1049}
1057 1050
@@ -1079,6 +1072,7 @@ server_lookup_connection (struct HTTP_Server_Plugin *plugin,
1079 struct GNUNET_PeerIdentity target; 1072 struct GNUNET_PeerIdentity target;
1080 size_t addr_len; 1073 size_t addr_len;
1081 uint32_t tag = 0; 1074 uint32_t tag = 0;
1075 uint32_t options;
1082 int direction = GNUNET_SYSERR; 1076 int direction = GNUNET_SYSERR;
1083 unsigned int to; 1077 unsigned int to;
1084 1078
@@ -1090,7 +1084,7 @@ server_lookup_connection (struct HTTP_Server_Plugin *plugin,
1090 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, 1084 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
1091 "New %s connection from %s\n", method, url); 1085 "New %s connection from %s\n", method, url);
1092 1086
1093 if (GNUNET_SYSERR == server_parse_url (plugin, url, &target, &tag)) 1087 if (GNUNET_SYSERR == server_parse_url (plugin, url, &target, &tag, &options))
1094 { 1088 {
1095 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, 1089 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
1096 "Invalid url %s\n", url); 1090 "Invalid url %s\n", url);
@@ -1177,7 +1171,6 @@ server_lookup_connection (struct HTTP_Server_Plugin *plugin,
1177 s->server_send = NULL; 1171 s->server_send = NULL;
1178 s->session_passed = GNUNET_NO; 1172 s->session_passed = GNUNET_NO;
1179 s->session_ended = GNUNET_NO; 1173 s->session_ended = GNUNET_NO;
1180 s->connect_in_progress = GNUNET_YES;
1181 server_start_session_timeout(s); 1174 server_start_session_timeout(s);
1182 GNUNET_CONTAINER_DLL_insert (plugin->head, plugin->tail, s); 1175 GNUNET_CONTAINER_DLL_insert (plugin->head, plugin->tail, s);
1183 1176
@@ -1198,6 +1191,7 @@ server_lookup_connection (struct HTTP_Server_Plugin *plugin,
1198 sc->direction = direction; 1191 sc->direction = direction;
1199 sc->connected = GNUNET_NO; 1192 sc->connected = GNUNET_NO;
1200 sc->session = s; 1193 sc->session = s;
1194 sc->options = options;
1201 if (direction == _SEND) 1195 if (direction == _SEND)
1202 s->server_send = sc; 1196 s->server_send = sc;
1203 if (direction == _RECEIVE) 1197 if (direction == _RECEIVE)
@@ -1205,7 +1199,6 @@ server_lookup_connection (struct HTTP_Server_Plugin *plugin,
1205 1199
1206 if ((NULL != s->server_send) && (NULL != s->server_recv)) 1200 if ((NULL != s->server_send) && (NULL != s->server_recv))
1207 { 1201 {
1208 s->connect_in_progress = GNUNET_NO; /* PUT and GET are connected */
1209 plugin->env->session_start (NULL, s->address ,s, NULL, 0); 1202 plugin->env->session_start (NULL, s->address ,s, NULL, 0);
1210 } 1203 }
1211 1204
@@ -1277,12 +1270,16 @@ static ssize_t
1277server_send_callback (void *cls, uint64_t pos, char *buf, size_t max) 1270server_send_callback (void *cls, uint64_t pos, char *buf, size_t max)
1278{ 1271{
1279 struct Session *s = cls; 1272 struct Session *s = cls;
1273 struct ServerConnection *sc;
1280 ssize_t bytes_read = 0; 1274 ssize_t bytes_read = 0;
1281 struct HTTP_Message *msg; 1275 struct HTTP_Message *msg;
1282 char *stat_txt; 1276 char *stat_txt;
1283 1277
1284 if (GNUNET_NO == server_exist_session (s->plugin, s)) 1278 if (GNUNET_NO == server_exist_session (s->plugin, s))
1285 return 0; 1279 return 0;
1280 sc = s->server_send;
1281 if (NULL == sc)
1282 return 0;
1286 msg = s->msg_head; 1283 msg = s->msg_head;
1287 if (NULL != msg) 1284 if (NULL != msg)
1288 { 1285 {
@@ -1304,6 +1301,7 @@ server_send_callback (void *cls, uint64_t pos, char *buf, size_t max)
1304 } 1301 }
1305 if (0 < bytes_read) 1302 if (0 < bytes_read)
1306 { 1303 {
1304 sc->connected = GNUNET_YES;
1307 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, s->plugin->name, 1305 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, s->plugin->name,
1308 "Sent %u bytes to peer `%s' with session %p \n", bytes_read, GNUNET_i2s (&s->target), s); 1306 "Sent %u bytes to peer `%s' with session %p \n", bytes_read, GNUNET_i2s (&s->target), s);
1309 GNUNET_asprintf (&stat_txt, "# bytes currently in %s_server buffers", 1307 GNUNET_asprintf (&stat_txt, "# bytes currently in %s_server buffers",
@@ -1316,6 +1314,11 @@ server_send_callback (void *cls, uint64_t pos, char *buf, size_t max)
1316 GNUNET_STATISTICS_update (s->plugin->env->stats, 1314 GNUNET_STATISTICS_update (s->plugin->env->stats,
1317 stat_txt, bytes_read, GNUNET_NO); 1315 stat_txt, bytes_read, GNUNET_NO);
1318 GNUNET_free (stat_txt); 1316 GNUNET_free (stat_txt);
1317 } else if ((sc->options & OPTION_LONG_POLL) && sc->connected) {
1318 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, s->plugin->name,
1319 "Completing GET response to peer `%s' with session %p \n",
1320 GNUNET_i2s (&s->target), s);
1321 return MHD_CONTENT_READER_END_OF_STREAM;
1319 } 1322 }
1320 return bytes_read; 1323 return bytes_read;
1321} 1324}
@@ -1468,7 +1471,7 @@ server_access_cb (void *cls, struct MHD_Connection *mhd_connection,
1468 s = sc->session; 1471 s = sc->session;
1469 GNUNET_assert (NULL != s); 1472 GNUNET_assert (NULL != s);
1470 /* connection is to be disconnected */ 1473 /* connection is to be disconnected */
1471 if (sc->disconnect == GNUNET_YES) 1474 if (s->disconnect == GNUNET_YES)
1472 { 1475 {
1473 /* Sent HTTP/1.1: 200 OK as response */ 1476 /* Sent HTTP/1.1: 200 OK as response */
1474 response = MHD_create_response_from_data (strlen ("Thank you!"), 1477 response = MHD_create_response_from_data (strlen ("Thank you!"),
@@ -1615,9 +1618,9 @@ server_disconnect_cb (void *cls, struct MHD_Connection *connection,
1615 plugin->protocol, s->address->address, 1618 plugin->protocol, s->address->address,
1616 s->address->address_length)); 1619 s->address->address_length));
1617 s->server_send = NULL; 1620 s->server_send = NULL;
1618 if (NULL != (s->server_recv)) 1621 if (!(sc->options & OPTION_LONG_POLL) && NULL != (s->server_recv))
1619 { 1622 {
1620 s->server_recv->disconnect = GNUNET_YES; 1623 s->disconnect = GNUNET_YES;
1621 GNUNET_assert (NULL != s->server_recv->mhd_conn); 1624 GNUNET_assert (NULL != s->server_recv->mhd_conn);
1622#if MHD_VERSION >= 0x00090E00 1625#if MHD_VERSION >= 0x00090E00
1623 MHD_set_connection_option (s->server_recv->mhd_conn, MHD_CONNECTION_OPTION_TIMEOUT, 1626 MHD_set_connection_option (s->server_recv->mhd_conn, MHD_CONNECTION_OPTION_TIMEOUT,
@@ -1635,17 +1638,6 @@ server_disconnect_cb (void *cls, struct MHD_Connection *connection,
1635 plugin->protocol, s->address->address, 1638 plugin->protocol, s->address->address,
1636 s->address->address_length)); 1639 s->address->address_length));
1637 s->server_recv = NULL; 1640 s->server_recv = NULL;
1638 /* Do not terminate session when PUT disconnects
1639 if (NULL != (s->server_send))
1640 {
1641 s->server_send->disconnect = GNUNET_YES;
1642 GNUNET_assert (NULL != s->server_send->mhd_conn);
1643#if MHD_VERSION >= 0x00090E00
1644 MHD_set_connection_option (s->server_send->mhd_conn, MHD_CONNECTION_OPTION_TIMEOUT,
1645 1);
1646#endif
1647 server_reschedule (plugin, s->server_send->mhd_daemon, GNUNET_NO);
1648 }*/
1649 if (s->msg_tk != NULL) 1641 if (s->msg_tk != NULL)
1650 { 1642 {
1651 GNUNET_SERVER_mst_destroy (s->msg_tk); 1643 GNUNET_SERVER_mst_destroy (s->msg_tk);
@@ -1656,7 +1648,7 @@ server_disconnect_cb (void *cls, struct MHD_Connection *connection,
1656 GNUNET_free (sc); 1648 GNUNET_free (sc);
1657 plugin->cur_connections--; 1649 plugin->cur_connections--;
1658 1650
1659 if ((s->server_send == NULL) && (s->server_recv == NULL)) 1651 if (s->disconnect && (s->server_send == NULL) && (s->server_recv == NULL))
1660 { 1652 {
1661 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, 1653 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
1662 "Peer `%s' on address `%s' disconnected\n", 1654 "Peer `%s' on address `%s' disconnected\n",
@@ -3090,6 +3082,7 @@ LIBGNUNET_PLUGIN_TRANSPORT_DONE (void *cls)
3090 GNUNET_free_non_null (plugin->ext_addr); 3082 GNUNET_free_non_null (plugin->ext_addr);
3091 GNUNET_free_non_null (plugin->server_addr_v4); 3083 GNUNET_free_non_null (plugin->server_addr_v4);
3092 GNUNET_free_non_null (plugin->server_addr_v6); 3084 GNUNET_free_non_null (plugin->server_addr_v6);
3085 regfree(&plugin->url_regex);
3093 3086
3094 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, 3087 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
3095 _("Shutdown for plugin `%s' complete\n"), 3088 _("Shutdown for plugin `%s' complete\n"),
@@ -3117,7 +3110,7 @@ http_plugin_address_to_string (void *cls,
3117/** 3110/**
3118 * Function obtain the network type for a session 3111 * Function obtain the network type for a session
3119 * 3112 *
3120 * @param cls closure ('struct Plugin*') 3113 * @param cls closure ('struct HTTP_Server_Plugin*')
3121 * @param session the session 3114 * @param session the session
3122 * @return the network type in HBO or GNUNET_SYSERR 3115 * @return the network type in HBO or GNUNET_SYSERR
3123 */ 3116 */
@@ -3178,6 +3171,14 @@ LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls)
3178 plugin->protocol = "http"; 3171 plugin->protocol = "http";
3179#endif 3172#endif
3180 3173
3174 /* Compile URL regex */
3175 if (regcomp(&plugin->url_regex, URL_REGEX, REG_EXTENDED)) {
3176 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name,
3177 _("Unable to compile URL regex\n"));
3178 LIBGNUNET_PLUGIN_TRANSPORT_DONE (api);
3179 return NULL;
3180 }
3181
3181 /* Configure plugin */ 3182 /* Configure plugin */
3182 if (GNUNET_SYSERR == server_configure_plugin (plugin)) 3183 if (GNUNET_SYSERR == server_configure_plugin (plugin))
3183 { 3184 {