diff options
author | David Barksdale <amatus.amongus@gmail.com> | 2014-06-01 21:35:18 +0000 |
---|---|---|
committer | David Barksdale <amatus.amongus@gmail.com> | 2014-06-01 21:35:18 +0000 |
commit | da3d84fb0f3e5a681976b53d43275b2d9b401886 (patch) | |
tree | 2c1b067aa7c4e20c57e8f5a362ca1aa3ce231d16 /src/transport | |
parent | ef94867ca20a89d62f741f32f0a5b17a2fcfbe76 (diff) | |
download | gnunet-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.c | 253 |
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 | */ | ||
61 | struct Plugin; | ||
62 | |||
63 | /** | ||
64 | * Session handle for connections. | 54 | * Session handle for connections. |
65 | */ | 55 | */ |
66 | struct Session | 56 | struct 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 | */ |
887 | static unsigned int | 867 | static 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 | */ |
952 | static int | 933 | static int |
953 | server_parse_url (struct HTTP_Server_Plugin *plugin, | 934 | server_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 | |||
1277 | server_send_callback (void *cls, uint64_t pos, char *buf, size_t max) | 1270 | server_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 | { |