diff options
author | Martin Schanzenbach <mschanzenbach@posteo.de> | 2016-08-31 09:53:47 +0000 |
---|---|---|
committer | Martin Schanzenbach <mschanzenbach@posteo.de> | 2016-08-31 09:53:47 +0000 |
commit | 16f176f0ff371539c270b95a9b6d333a39f26ede (patch) | |
tree | 65a59fb6f9e2940e56d17201ea0f29945aa120c5 /src/gns | |
parent | 7284d5df365298347caca546fd91a010d0af3719 (diff) | |
download | gnunet-16f176f0ff371539c270b95a9b6d333a39f26ede.tar.gz gnunet-16f176f0ff371539c270b95a9b6d333a39f26ede.zip |
- fixing a variety of bugs including POSTing data, content-length handling and improving connection handling
Diffstat (limited to 'src/gns')
-rw-r--r-- | src/gns/gnunet-gns-proxy.c | 362 |
1 files changed, 226 insertions, 136 deletions
diff --git a/src/gns/gnunet-gns-proxy.c b/src/gns/gnunet-gns-proxy.c index c02247988..36b21365e 100644 --- a/src/gns/gnunet-gns-proxy.c +++ b/src/gns/gnunet-gns-proxy.c | |||
@@ -430,6 +430,31 @@ enum SocksPhase | |||
430 | }; | 430 | }; |
431 | 431 | ||
432 | 432 | ||
433 | /** | ||
434 | * A header list | ||
435 | */ | ||
436 | struct HttpResponseHeader | ||
437 | { | ||
438 | /** | ||
439 | * DLL | ||
440 | */ | ||
441 | struct HttpResponseHeader *next; | ||
442 | |||
443 | /** | ||
444 | * DLL | ||
445 | */ | ||
446 | struct HttpResponseHeader *prev; | ||
447 | |||
448 | /** | ||
449 | * Header type | ||
450 | */ | ||
451 | char *type; | ||
452 | |||
453 | /** | ||
454 | * Header value | ||
455 | */ | ||
456 | char *value; | ||
457 | }; | ||
433 | 458 | ||
434 | /** | 459 | /** |
435 | * A structure for socks requests | 460 | * A structure for socks requests |
@@ -572,6 +597,16 @@ struct Socks5Request | |||
572 | */ | 597 | */ |
573 | uint16_t port; | 598 | uint16_t port; |
574 | 599 | ||
600 | /** | ||
601 | * Headers from response | ||
602 | */ | ||
603 | struct HttpResponseHeader *header_head; | ||
604 | |||
605 | /** | ||
606 | * Headers from response | ||
607 | */ | ||
608 | struct HttpResponseHeader *header_tail; | ||
609 | |||
575 | }; | 610 | }; |
576 | 611 | ||
577 | 612 | ||
@@ -986,12 +1021,12 @@ static size_t | |||
986 | curl_check_hdr (void *buffer, size_t size, size_t nmemb, void *cls) | 1021 | curl_check_hdr (void *buffer, size_t size, size_t nmemb, void *cls) |
987 | { | 1022 | { |
988 | struct Socks5Request *s5r = cls; | 1023 | struct Socks5Request *s5r = cls; |
1024 | struct HttpResponseHeader *header; | ||
989 | size_t bytes = size * nmemb; | 1025 | size_t bytes = size * nmemb; |
990 | char *ndup; | 1026 | char *ndup; |
991 | const char *hdr_type; | 1027 | const char *hdr_type; |
992 | const char *cookie_domain; | 1028 | const char *cookie_domain; |
993 | char *hdr_val; | 1029 | char *hdr_val; |
994 | long resp_code; | ||
995 | char *new_cookie_hdr; | 1030 | char *new_cookie_hdr; |
996 | char *new_location; | 1031 | char *new_location; |
997 | size_t offset; | 1032 | size_t offset; |
@@ -999,49 +1034,11 @@ curl_check_hdr (void *buffer, size_t size, size_t nmemb, void *cls) | |||
999 | int domain_matched; | 1034 | int domain_matched; |
1000 | char *tok; | 1035 | char *tok; |
1001 | 1036 | ||
1002 | if (NULL == s5r->response) | 1037 | /* first, check SSL certificate */ |
1003 | { | 1038 | if ( (HTTPS_PORT == s5r->port) && |
1004 | /* first, check SSL certificate */ | 1039 | (GNUNET_OK != check_ssl_certificate (s5r)) ) |
1005 | if ( (HTTPS_PORT == s5r->port) && | 1040 | return GNUNET_SYSERR; |
1006 | (GNUNET_OK != check_ssl_certificate (s5r)) ) | ||
1007 | return 0; | ||
1008 | 1041 | ||
1009 | GNUNET_break (CURLE_OK == | ||
1010 | curl_easy_getinfo (s5r->curl, | ||
1011 | CURLINFO_RESPONSE_CODE, | ||
1012 | &resp_code)); | ||
1013 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1014 | "Creating MHD response with code %d\n", | ||
1015 | (int) resp_code); | ||
1016 | s5r->response_code = resp_code; | ||
1017 | s5r->response = MHD_create_response_from_callback (MHD_SIZE_UNKNOWN, | ||
1018 | IO_BUFFERSIZE, | ||
1019 | &mhd_content_cb, | ||
1020 | s5r, | ||
1021 | NULL); | ||
1022 | if (NULL != s5r->leho) | ||
1023 | { | ||
1024 | char *cors_hdr; | ||
1025 | |||
1026 | GNUNET_asprintf (&cors_hdr, | ||
1027 | (HTTPS_PORT == s5r->port) | ||
1028 | ? "https://%s" | ||
1029 | : "http://%s", | ||
1030 | s5r->leho); | ||
1031 | |||
1032 | GNUNET_break (MHD_YES == | ||
1033 | MHD_add_response_header (s5r->response, | ||
1034 | MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN, | ||
1035 | cors_hdr)); | ||
1036 | GNUNET_free (cors_hdr); | ||
1037 | } | ||
1038 | /* force connection to be closed after each request, as we | ||
1039 | do not support HTTP pipelining (yet, FIXME!) */ | ||
1040 | /*GNUNET_break (MHD_YES == | ||
1041 | MHD_add_response_header (s5r->response, | ||
1042 | MHD_HTTP_HEADER_CONNECTION, | ||
1043 | "close"));*/ | ||
1044 | } | ||
1045 | 1042 | ||
1046 | ndup = GNUNET_strndup (buffer, bytes); | 1043 | ndup = GNUNET_strndup (buffer, bytes); |
1047 | hdr_type = strtok (ndup, ":"); | 1044 | hdr_type = strtok (ndup, ":"); |
@@ -1063,41 +1060,41 @@ curl_check_hdr (void *buffer, size_t size, size_t nmemb, void *cls) | |||
1063 | new_cookie_hdr = NULL; | 1060 | new_cookie_hdr = NULL; |
1064 | if ( (NULL != s5r->leho) && | 1061 | if ( (NULL != s5r->leho) && |
1065 | (0 == strcasecmp (hdr_type, | 1062 | (0 == strcasecmp (hdr_type, |
1066 | MHD_HTTP_HEADER_SET_COOKIE)) ) | 1063 | MHD_HTTP_HEADER_SET_COOKIE)) ) |
1067 | 1064 | ||
1068 | { | 1065 | { |
1069 | new_cookie_hdr = GNUNET_malloc (strlen (hdr_val) + | 1066 | new_cookie_hdr = GNUNET_malloc (strlen (hdr_val) + |
1070 | strlen (s5r->domain) + 1); | 1067 | strlen (s5r->domain) + 1); |
1071 | offset = 0; | 1068 | offset = 0; |
1072 | domain_matched = GNUNET_NO; /* make sure we match domain at most once */ | 1069 | domain_matched = GNUNET_NO; /* make sure we match domain at most once */ |
1073 | for (tok = strtok (hdr_val, ";"); NULL != tok; tok = strtok (NULL, ";")) | 1070 | for (tok = strtok (hdr_val, ";"); NULL != tok; tok = strtok (NULL, ";")) |
1074 | { | 1071 | { |
1075 | if ( (0 == strncasecmp (tok, " domain", strlen (" domain"))) && | 1072 | if ( (0 == strncasecmp (tok, " domain", strlen (" domain"))) && |
1076 | (GNUNET_NO == domain_matched) ) | 1073 | (GNUNET_NO == domain_matched) ) |
1077 | { | 1074 | { |
1078 | domain_matched = GNUNET_YES; | 1075 | domain_matched = GNUNET_YES; |
1079 | cookie_domain = tok + strlen (" domain") + 1; | 1076 | cookie_domain = tok + strlen (" domain") + 1; |
1080 | if (strlen (cookie_domain) < strlen (s5r->leho)) | 1077 | if (strlen (cookie_domain) < strlen (s5r->leho)) |
1081 | { | 1078 | { |
1082 | delta_cdomain = strlen (s5r->leho) - strlen (cookie_domain); | 1079 | delta_cdomain = strlen (s5r->leho) - strlen (cookie_domain); |
1083 | if (0 == strcasecmp (cookie_domain, s5r->leho + delta_cdomain)) | 1080 | if (0 == strcasecmp (cookie_domain, s5r->leho + delta_cdomain)) |
1084 | { | 1081 | { |
1085 | offset += sprintf (new_cookie_hdr + offset, | 1082 | offset += sprintf (new_cookie_hdr + offset, |
1086 | " domain=%s;", | 1083 | " domain=%s;", |
1087 | s5r->domain); | 1084 | s5r->domain); |
1088 | continue; | 1085 | continue; |
1089 | } | 1086 | } |
1090 | } | 1087 | } |
1091 | else if (0 == strcmp (cookie_domain, s5r->leho)) | 1088 | else if (0 == strcmp (cookie_domain, s5r->leho)) |
1092 | { | 1089 | { |
1093 | offset += sprintf (new_cookie_hdr + offset, | 1090 | offset += sprintf (new_cookie_hdr + offset, |
1094 | " domain=%s;", | 1091 | " domain=%s;", |
1095 | s5r->domain); | 1092 | s5r->domain); |
1096 | continue; | 1093 | continue; |
1097 | } | 1094 | } |
1098 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1095 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
1099 | _("Cookie domain `%s' supplied by server is invalid\n"), | 1096 | _("Cookie domain `%s' supplied by server is invalid\n"), |
1100 | tok); | 1097 | tok); |
1101 | } | 1098 | } |
1102 | GNUNET_memcpy (new_cookie_hdr + offset, tok, strlen (tok)); | 1099 | GNUNET_memcpy (new_cookie_hdr + offset, tok, strlen (tok)); |
1103 | offset += strlen (tok); | 1100 | offset += strlen (tok); |
@@ -1112,21 +1109,21 @@ curl_check_hdr (void *buffer, size_t size, size_t nmemb, void *cls) | |||
1112 | char *leho_host; | 1109 | char *leho_host; |
1113 | 1110 | ||
1114 | GNUNET_asprintf (&leho_host, | 1111 | GNUNET_asprintf (&leho_host, |
1115 | (HTTPS_PORT != s5r->port) | 1112 | (HTTPS_PORT != s5r->port) |
1116 | ? "http://%s" | 1113 | ? "http://%s" |
1117 | : "https://%s", | 1114 | : "https://%s", |
1118 | s5r->leho); | 1115 | s5r->leho); |
1119 | if (0 == strncmp (leho_host, | 1116 | if (0 == strncmp (leho_host, |
1120 | hdr_val, | 1117 | hdr_val, |
1121 | strlen (leho_host))) | 1118 | strlen (leho_host))) |
1122 | { | 1119 | { |
1123 | GNUNET_asprintf (&new_location, | 1120 | GNUNET_asprintf (&new_location, |
1124 | "%s%s%s", | 1121 | "%s%s%s", |
1125 | (HTTPS_PORT != s5r->port) | 1122 | (HTTPS_PORT != s5r->port) |
1126 | ? "http://" | 1123 | ? "http://" |
1127 | : "https://", | 1124 | : "https://", |
1128 | s5r->domain, | 1125 | s5r->domain, |
1129 | hdr_val + strlen (leho_host)); | 1126 | hdr_val + strlen (leho_host)); |
1130 | hdr_val = new_location; | 1127 | hdr_val = new_location; |
1131 | } | 1128 | } |
1132 | GNUNET_free (leho_host); | 1129 | GNUNET_free (leho_host); |
@@ -1138,17 +1135,18 @@ curl_check_hdr (void *buffer, size_t size, size_t nmemb, void *cls) | |||
1138 | *tok = '\0'; | 1135 | *tok = '\0'; |
1139 | if (NULL != (tok = strchr (hdr_val, '\t'))) | 1136 | if (NULL != (tok = strchr (hdr_val, '\t'))) |
1140 | *tok = '\0'; | 1137 | *tok = '\0'; |
1141 | if ((0 != strlen (hdr_val) ) && | 1138 | if (0 != strlen (hdr_val)) /* Rely in MHD to set those */ |
1142 | (0 != strcasecmp (MHD_HTTP_HEADER_CONTENT_LENGTH, hdr_type))) | ||
1143 | { | 1139 | { |
1144 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1140 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1145 | "Adding header %s: %s to MHD response\n", | 1141 | "Adding header %s: %s to MHD response\n", |
1146 | hdr_type, | 1142 | hdr_type, |
1147 | hdr_val); | 1143 | hdr_val); |
1148 | GNUNET_break (MHD_YES == | 1144 | header = GNUNET_new (struct HttpResponseHeader); |
1149 | MHD_add_response_header (s5r->response, | 1145 | header->type = GNUNET_strndup (hdr_type, strlen (hdr_type)); |
1150 | hdr_type, | 1146 | header->value = GNUNET_strndup (hdr_val, strlen (hdr_val)); |
1151 | hdr_val)); | 1147 | GNUNET_CONTAINER_DLL_insert (s5r->header_head, |
1148 | s5r->header_tail, | ||
1149 | header); | ||
1152 | } | 1150 | } |
1153 | GNUNET_free (ndup); | 1151 | GNUNET_free (ndup); |
1154 | GNUNET_free_non_null (new_cookie_hdr); | 1152 | GNUNET_free_non_null (new_cookie_hdr); |
@@ -1156,6 +1154,69 @@ curl_check_hdr (void *buffer, size_t size, size_t nmemb, void *cls) | |||
1156 | return bytes; | 1154 | return bytes; |
1157 | } | 1155 | } |
1158 | 1156 | ||
1157 | static int | ||
1158 | create_mhd_response_from_s5r (struct Socks5Request *s5r) | ||
1159 | { | ||
1160 | long resp_code; | ||
1161 | double content_length; | ||
1162 | struct HttpResponseHeader *header; | ||
1163 | |||
1164 | if (NULL != s5r->response) | ||
1165 | { | ||
1166 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1167 | "Response already set!\n"); | ||
1168 | return GNUNET_SYSERR; | ||
1169 | } | ||
1170 | |||
1171 | GNUNET_break (CURLE_OK == | ||
1172 | curl_easy_getinfo (s5r->curl, | ||
1173 | CURLINFO_RESPONSE_CODE, | ||
1174 | &resp_code)); | ||
1175 | GNUNET_break (CURLE_OK == | ||
1176 | curl_easy_getinfo (s5r->curl, | ||
1177 | CURLINFO_CONTENT_LENGTH_DOWNLOAD, | ||
1178 | &content_length)); | ||
1179 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1180 | "Creating MHD response with code %d and size %d\n", | ||
1181 | (int) resp_code, (int) content_length); | ||
1182 | s5r->response_code = resp_code; | ||
1183 | s5r->response = MHD_create_response_from_callback ((-1 == content_length) ? MHD_SIZE_UNKNOWN : content_length, | ||
1184 | IO_BUFFERSIZE, | ||
1185 | &mhd_content_cb, | ||
1186 | s5r, | ||
1187 | NULL); | ||
1188 | for (header = s5r->header_head; NULL != header; header = header->next) | ||
1189 | { | ||
1190 | GNUNET_break (MHD_YES == | ||
1191 | MHD_add_response_header (s5r->response, | ||
1192 | header->type, | ||
1193 | header->value)); | ||
1194 | |||
1195 | } | ||
1196 | if (NULL != s5r->leho) | ||
1197 | { | ||
1198 | char *cors_hdr; | ||
1199 | |||
1200 | GNUNET_asprintf (&cors_hdr, | ||
1201 | (HTTPS_PORT == s5r->port) | ||
1202 | ? "https://%s" | ||
1203 | : "http://%s", | ||
1204 | s5r->leho); | ||
1205 | |||
1206 | GNUNET_break (MHD_YES == | ||
1207 | MHD_add_response_header (s5r->response, | ||
1208 | MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN, | ||
1209 | cors_hdr)); | ||
1210 | GNUNET_free (cors_hdr); | ||
1211 | } | ||
1212 | /* force connection to be closed after each request, as we | ||
1213 | do not support HTTP pipelining (yet, FIXME!) */ | ||
1214 | /*GNUNET_break (MHD_YES == | ||
1215 | MHD_add_response_header (s5r->response, | ||
1216 | MHD_HTTP_HEADER_CONNECTION, | ||
1217 | "close"));*/ | ||
1218 | return GNUNET_OK; | ||
1219 | } | ||
1159 | 1220 | ||
1160 | /** | 1221 | /** |
1161 | * Handle response payload data from cURL. Copies it into our `io_buf` to make | 1222 | * Handle response payload data from cURL. Copies it into our `io_buf` to make |
@@ -1173,6 +1234,9 @@ curl_download_cb (void *ptr, size_t size, size_t nmemb, void* ctx) | |||
1173 | struct Socks5Request *s5r = ctx; | 1234 | struct Socks5Request *s5r = ctx; |
1174 | size_t total = size * nmemb; | 1235 | size_t total = size * nmemb; |
1175 | 1236 | ||
1237 | if (NULL == s5r->response) | ||
1238 | GNUNET_assert (GNUNET_OK == create_mhd_response_from_s5r (s5r)); | ||
1239 | |||
1176 | if ( (SOCKS5_SOCKET_UPLOAD_STARTED == s5r->state) || | 1240 | if ( (SOCKS5_SOCKET_UPLOAD_STARTED == s5r->state) || |
1177 | (SOCKS5_SOCKET_UPLOAD_DONE == s5r->state) ) | 1241 | (SOCKS5_SOCKET_UPLOAD_DONE == s5r->state) ) |
1178 | { | 1242 | { |
@@ -1180,18 +1244,18 @@ curl_download_cb (void *ptr, size_t size, size_t nmemb, void* ctx) | |||
1180 | start the download, the IO buffer is still full | 1244 | start the download, the IO buffer is still full |
1181 | with upload data. */ | 1245 | with upload data. */ |
1182 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1246 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1183 | "Pausing CURL download, waiting for UPLOAD to finish\n"); | 1247 | "Pausing CURL download, waiting for UPLOAD to finish\n"); |
1184 | return CURL_WRITEFUNC_PAUSE; /* not yet ready for data download */ | 1248 | return CURL_WRITEFUNC_PAUSE; /* not yet ready for data download */ |
1185 | } | 1249 | } |
1186 | if (sizeof (s5r->io_buf) - s5r->io_len < total) | 1250 | if (sizeof (s5r->io_buf) - s5r->io_len < total) |
1187 | { | 1251 | { |
1188 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1252 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1189 | "Pausing CURL download, not enough space\n"); | 1253 | "Pausing CURL download, not enough space\n"); |
1190 | return CURL_WRITEFUNC_PAUSE; /* not enough space */ | 1254 | return CURL_WRITEFUNC_PAUSE; /* not enough space */ |
1191 | } | 1255 | } |
1192 | GNUNET_memcpy (&s5r->io_buf[s5r->io_len], | 1256 | GNUNET_memcpy (&s5r->io_buf[s5r->io_len], |
1193 | ptr, | 1257 | ptr, |
1194 | total); | 1258 | total); |
1195 | s5r->io_len += total; | 1259 | s5r->io_len += total; |
1196 | if (s5r->io_len == total) | 1260 | if (s5r->io_len == total) |
1197 | run_mhd_now (s5r->hd); | 1261 | run_mhd_now (s5r->hd); |
@@ -1215,12 +1279,12 @@ curl_upload_cb (void *buf, size_t size, size_t nmemb, void *cls) | |||
1215 | struct Socks5Request *s5r = cls; | 1279 | struct Socks5Request *s5r = cls; |
1216 | size_t len = size * nmemb; | 1280 | size_t len = size * nmemb; |
1217 | size_t to_copy; | 1281 | size_t to_copy; |
1218 | 1282 | ||
1219 | if ( (0 == s5r->io_len) && | 1283 | if ( (0 == s5r->io_len) && |
1220 | (SOCKS5_SOCKET_UPLOAD_DONE != s5r->state) ) | 1284 | (SOCKS5_SOCKET_UPLOAD_DONE != s5r->state) ) |
1221 | { | 1285 | { |
1222 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1286 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1223 | "Pausing CURL UPLOAD, need more data\n"); | 1287 | "Pausing CURL UPLOAD, need more data\n"); |
1224 | return CURL_READFUNC_PAUSE; | 1288 | return CURL_READFUNC_PAUSE; |
1225 | } | 1289 | } |
1226 | if ( (0 == s5r->io_len) && | 1290 | if ( (0 == s5r->io_len) && |
@@ -1228,7 +1292,7 @@ curl_upload_cb (void *buf, size_t size, size_t nmemb, void *cls) | |||
1228 | { | 1292 | { |
1229 | s5r->state = SOCKS5_SOCKET_DOWNLOAD_STARTED; | 1293 | s5r->state = SOCKS5_SOCKET_DOWNLOAD_STARTED; |
1230 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1294 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1231 | "Completed CURL UPLOAD\n"); | 1295 | "Completed CURL UPLOAD\n"); |
1232 | return 0; /* upload finished, can now download */ | 1296 | return 0; /* upload finished, can now download */ |
1233 | } | 1297 | } |
1234 | if ( (SOCKS5_SOCKET_UPLOAD_STARTED != s5r->state) && | 1298 | if ( (SOCKS5_SOCKET_UPLOAD_STARTED != s5r->state) && |
@@ -1238,11 +1302,11 @@ curl_upload_cb (void *buf, size_t size, size_t nmemb, void *cls) | |||
1238 | return CURL_READFUNC_ABORT; | 1302 | return CURL_READFUNC_ABORT; |
1239 | } | 1303 | } |
1240 | to_copy = GNUNET_MIN (s5r->io_len, | 1304 | to_copy = GNUNET_MIN (s5r->io_len, |
1241 | len); | 1305 | len); |
1242 | GNUNET_memcpy (buf, s5r->io_buf, to_copy); | 1306 | GNUNET_memcpy (buf, s5r->io_buf, to_copy); |
1243 | memmove (s5r->io_buf, | 1307 | memmove (s5r->io_buf, |
1244 | &s5r->io_buf[to_copy], | 1308 | &s5r->io_buf[to_copy], |
1245 | s5r->io_len - to_copy); | 1309 | s5r->io_len - to_copy); |
1246 | s5r->io_len -= to_copy; | 1310 | s5r->io_len -= to_copy; |
1247 | if (s5r->io_len + to_copy == sizeof (s5r->io_buf)) | 1311 | if (s5r->io_len + to_copy == sizeof (s5r->io_buf)) |
1248 | run_mhd_now (s5r->hd); /* got more space for upload now */ | 1312 | run_mhd_now (s5r->hd); /* got more space for upload now */ |
@@ -1309,9 +1373,9 @@ curl_download_prepare () | |||
1309 | GNUNET_NETWORK_fdset_copy_native (grs, &rs, max + 1); | 1373 | GNUNET_NETWORK_fdset_copy_native (grs, &rs, max + 1); |
1310 | GNUNET_NETWORK_fdset_copy_native (gws, &ws, max + 1); | 1374 | GNUNET_NETWORK_fdset_copy_native (gws, &ws, max + 1); |
1311 | curl_download_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, | 1375 | curl_download_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, |
1312 | rtime, | 1376 | rtime, |
1313 | grs, gws, | 1377 | grs, gws, |
1314 | &curl_task_download, curl_multi); | 1378 | &curl_task_download, curl_multi); |
1315 | GNUNET_NETWORK_fdset_destroy (gws); | 1379 | GNUNET_NETWORK_fdset_destroy (gws); |
1316 | GNUNET_NETWORK_fdset_destroy (grs); | 1380 | GNUNET_NETWORK_fdset_destroy (grs); |
1317 | } | 1381 | } |
@@ -1367,6 +1431,8 @@ curl_task_download (void *cls) | |||
1367 | case CURLE_GOT_NOTHING: | 1431 | case CURLE_GOT_NOTHING: |
1368 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1432 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1369 | "CURL download completed.\n"); | 1433 | "CURL download completed.\n"); |
1434 | if (NULL == s5r->response) | ||
1435 | GNUNET_assert (GNUNET_OK == create_mhd_response_from_s5r (s5r)); | ||
1370 | s5r->state = SOCKS5_SOCKET_DOWNLOAD_DONE; | 1436 | s5r->state = SOCKS5_SOCKET_DOWNLOAD_DONE; |
1371 | run_mhd_now (s5r->hd); | 1437 | run_mhd_now (s5r->hd); |
1372 | break; | 1438 | break; |
@@ -1605,8 +1671,8 @@ create_response (void *cls, | |||
1605 | else if (0 == strcasecmp (meth, MHD_HTTP_METHOD_POST)) | 1671 | else if (0 == strcasecmp (meth, MHD_HTTP_METHOD_POST)) |
1606 | { | 1672 | { |
1607 | s5r->state = SOCKS5_SOCKET_UPLOAD_STARTED; | 1673 | s5r->state = SOCKS5_SOCKET_UPLOAD_STARTED; |
1608 | curl_easy_setopt (s5r->curl, CURLOPT_POST, 1); | 1674 | curl_easy_setopt (s5r->curl, CURLOPT_POST, 1L); |
1609 | curl_easy_setopt (s5r->curl, CURLOPT_WRITEFUNCTION, &curl_download_cb); | 1675 | curl_easy_setopt (s5r->curl, CURLOPT_WRITEFUNCTION, &curl_download_cb); |
1610 | curl_easy_setopt (s5r->curl, CURLOPT_WRITEDATA, s5r); | 1676 | curl_easy_setopt (s5r->curl, CURLOPT_WRITEDATA, s5r); |
1611 | curl_easy_setopt (s5r->curl, CURLOPT_READFUNCTION, &curl_upload_cb); | 1677 | curl_easy_setopt (s5r->curl, CURLOPT_READFUNCTION, &curl_upload_cb); |
1612 | curl_easy_setopt (s5r->curl, CURLOPT_READDATA, s5r); | 1678 | curl_easy_setopt (s5r->curl, CURLOPT_READDATA, s5r); |
@@ -1654,7 +1720,10 @@ create_response (void *cls, | |||
1654 | if (HTTPS_PORT == s5r->port) | 1720 | if (HTTPS_PORT == s5r->port) |
1655 | { | 1721 | { |
1656 | curl_easy_setopt (s5r->curl, CURLOPT_USE_SSL, CURLUSESSL_ALL); | 1722 | curl_easy_setopt (s5r->curl, CURLOPT_USE_SSL, CURLUSESSL_ALL); |
1657 | curl_easy_setopt (s5r->curl, CURLOPT_SSL_VERIFYPEER, 1L); | 1723 | if (NULL != s5r->dane_data) |
1724 | curl_easy_setopt (s5r->curl, CURLOPT_SSL_VERIFYPEER, 0L); | ||
1725 | else | ||
1726 | curl_easy_setopt (s5r->curl, CURLOPT_SSL_VERIFYPEER, 1L); | ||
1658 | /* Disable cURL checking the hostname, as we will check ourselves | 1727 | /* Disable cURL checking the hostname, as we will check ourselves |
1659 | as only we have the domain name or the LEHO or the DANE record */ | 1728 | as only we have the domain name or the LEHO or the DANE record */ |
1660 | curl_easy_setopt (s5r->curl, CURLOPT_SSL_VERIFYHOST, 0L); | 1729 | curl_easy_setopt (s5r->curl, CURLOPT_SSL_VERIFYHOST, 0L); |
@@ -1686,8 +1755,15 @@ create_response (void *cls, | |||
1686 | /* continuing to process request */ | 1755 | /* continuing to process request */ |
1687 | if (0 != *upload_data_size) | 1756 | if (0 != *upload_data_size) |
1688 | { | 1757 | { |
1758 | |||
1689 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1759 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1690 | "Processing %lu bytes UPLOAD\n", *upload_data_size); | 1760 | "Processing %lu bytes UPLOAD\n", *upload_data_size); |
1761 | |||
1762 | /* FIXME: This must be set or a header with Transfer-Encoding: chunked. Else | ||
1763 | * upload callback is not called! | ||
1764 | */ | ||
1765 | curl_easy_setopt (s5r->curl, CURLOPT_POSTFIELDSIZE, *upload_data_size); | ||
1766 | |||
1691 | left = GNUNET_MIN (*upload_data_size, | 1767 | left = GNUNET_MIN (*upload_data_size, |
1692 | sizeof (s5r->io_buf) - s5r->io_len); | 1768 | sizeof (s5r->io_buf) - s5r->io_len); |
1693 | GNUNET_memcpy (&s5r->io_buf[s5r->io_len], | 1769 | GNUNET_memcpy (&s5r->io_buf[s5r->io_len], |
@@ -1705,6 +1781,7 @@ create_response (void *cls, | |||
1705 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1781 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1706 | "Finished processing UPLOAD\n"); | 1782 | "Finished processing UPLOAD\n"); |
1707 | s5r->state = SOCKS5_SOCKET_UPLOAD_DONE; | 1783 | s5r->state = SOCKS5_SOCKET_UPLOAD_DONE; |
1784 | curl_download_prepare (); | ||
1708 | } | 1785 | } |
1709 | if (NULL == s5r->response) | 1786 | if (NULL == s5r->response) |
1710 | return MHD_YES; /* too early to queue response, did not yet get headers from cURL */ | 1787 | return MHD_YES; /* too early to queue response, did not yet get headers from cURL */ |
@@ -1736,6 +1813,7 @@ mhd_completed_cb (void *cls, | |||
1736 | enum MHD_RequestTerminationCode toe) | 1813 | enum MHD_RequestTerminationCode toe) |
1737 | { | 1814 | { |
1738 | struct Socks5Request *s5r = *con_cls; | 1815 | struct Socks5Request *s5r = *con_cls; |
1816 | struct HttpResponseHeader *header; | ||
1739 | 1817 | ||
1740 | if (NULL == s5r) | 1818 | if (NULL == s5r) |
1741 | return; | 1819 | return; |
@@ -1758,6 +1836,15 @@ mhd_completed_cb (void *cls, | |||
1758 | if ( (NULL != s5r->response) && | 1836 | if ( (NULL != s5r->response) && |
1759 | (curl_failure_response != s5r->response) ) | 1837 | (curl_failure_response != s5r->response) ) |
1760 | MHD_destroy_response (s5r->response); | 1838 | MHD_destroy_response (s5r->response); |
1839 | for (header = s5r->header_head; header != NULL; header = s5r->header_head) | ||
1840 | { | ||
1841 | GNUNET_CONTAINER_DLL_remove (s5r->header_head, | ||
1842 | s5r->header_head, | ||
1843 | header); | ||
1844 | GNUNET_free (header->type); | ||
1845 | GNUNET_free (header->value); | ||
1846 | GNUNET_free (header); | ||
1847 | } | ||
1761 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Finished request for %s\n", s5r->url); | 1848 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Finished request for %s\n", s5r->url); |
1762 | GNUNET_free (s5r->url); | 1849 | GNUNET_free (s5r->url); |
1763 | s5r->state = SOCKS5_SOCKET_WITH_MHD; | 1850 | s5r->state = SOCKS5_SOCKET_WITH_MHD; |
@@ -1786,34 +1873,46 @@ mhd_connection_cb (void *cls, | |||
1786 | const union MHD_ConnectionInfo *ci; | 1873 | const union MHD_ConnectionInfo *ci; |
1787 | int sock; | 1874 | int sock; |
1788 | 1875 | ||
1789 | if (MHD_CONNECTION_NOTIFY_STARTED == cnc) | 1876 | switch (cnc) |
1790 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connection started...\n"); | ||
1791 | |||
1792 | if (MHD_CONNECTION_NOTIFY_CLOSED != cnc) | ||
1793 | return; //Ignore | ||
1794 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connection closed... cleaning up\n"); | ||
1795 | |||
1796 | ci = MHD_get_connection_info (connection, | ||
1797 | MHD_CONNECTION_INFO_CONNECTION_FD); | ||
1798 | if (NULL == ci) | ||
1799 | { | 1877 | { |
1800 | GNUNET_break (0); | 1878 | case MHD_CONNECTION_NOTIFY_STARTED: |
1801 | return; | 1879 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connection started...\n"); |
1802 | } | 1880 | ci = MHD_get_connection_info (connection, |
1881 | MHD_CONNECTION_INFO_CONNECTION_FD); | ||
1882 | if (NULL == ci) | ||
1883 | { | ||
1884 | GNUNET_break (0); | ||
1885 | return; | ||
1886 | } | ||
1803 | 1887 | ||
1804 | sock = ci->connect_fd; | 1888 | sock = ci->connect_fd; |
1805 | for (s5r = s5r_head; NULL != s5r; s5r = s5r->next) | 1889 | for (s5r = s5r_head; NULL != s5r; s5r = s5r->next) |
1806 | if (GNUNET_NETWORK_get_fd (s5r->sock) == sock) | 1890 | { |
1891 | if (GNUNET_NETWORK_get_fd (s5r->sock) == sock) | ||
1892 | { | ||
1893 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Context set...\n"); | ||
1894 | *con_cls = s5r; | ||
1895 | break; | ||
1896 | } | ||
1897 | } | ||
1898 | if (NULL == s5r) | ||
1899 | GNUNET_break (0); | ||
1807 | break; | 1900 | break; |
1808 | 1901 | case MHD_CONNECTION_NOTIFY_CLOSED: | |
1809 | if (NULL == s5r) | 1902 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connection closed... cleaning up\n"); |
1810 | { | 1903 | s5r = *con_cls; |
1811 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Connection stale!\n"); | 1904 | if (NULL == s5r) |
1812 | return; | 1905 | { |
1906 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Connection stale!\n"); | ||
1907 | return; | ||
1908 | } | ||
1909 | cleanup_s5r (s5r); | ||
1910 | curl_download_prepare (); | ||
1911 | *con_cls = NULL; | ||
1912 | break; | ||
1913 | default: | ||
1914 | GNUNET_break (0); | ||
1813 | } | 1915 | } |
1814 | cleanup_s5r (s5r); | ||
1815 | curl_download_prepare (); | ||
1816 | *con_cls = NULL; | ||
1817 | } | 1916 | } |
1818 | 1917 | ||
1819 | /** | 1918 | /** |
@@ -1836,36 +1935,27 @@ mhd_log_callback (void *cls, | |||
1836 | { | 1935 | { |
1837 | struct Socks5Request *s5r; | 1936 | struct Socks5Request *s5r; |
1838 | const union MHD_ConnectionInfo *ci; | 1937 | const union MHD_ConnectionInfo *ci; |
1839 | int sock; | ||
1840 | 1938 | ||
1841 | ci = MHD_get_connection_info (connection, | 1939 | ci = MHD_get_connection_info (connection, |
1842 | MHD_CONNECTION_INFO_CONNECTION_FD); | 1940 | MHD_CONNECTION_INFO_SOCKET_CONTEXT); |
1843 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing %s\n", url); | 1941 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing %s\n", url); |
1844 | if (NULL == ci) | 1942 | if (NULL == ci) |
1845 | { | 1943 | { |
1846 | GNUNET_break (0); | 1944 | GNUNET_break (0); |
1847 | return NULL; | 1945 | return NULL; |
1848 | } | 1946 | } |
1849 | sock = ci->connect_fd; | 1947 | s5r = ci->socket_context; |
1850 | for (s5r = s5r_head; NULL != s5r; s5r = s5r->next) | 1948 | if (NULL != s5r->url) |
1851 | { | 1949 | { |
1852 | if (GNUNET_NETWORK_get_fd (s5r->sock) == sock) | 1950 | GNUNET_break (0); |
1853 | { | 1951 | return NULL; |
1854 | if (NULL != s5r->url) | ||
1855 | { | ||
1856 | GNUNET_break (0); | ||
1857 | return NULL; | ||
1858 | } | ||
1859 | s5r->url = GNUNET_strdup (url); | ||
1860 | if (NULL != s5r->timeout_task) | ||
1861 | GNUNET_SCHEDULER_cancel (s5r->timeout_task); | ||
1862 | s5r->timeout_task = NULL; | ||
1863 | GNUNET_assert (s5r->state == SOCKS5_SOCKET_WITH_MHD); | ||
1864 | return s5r; | ||
1865 | } | ||
1866 | } | 1952 | } |
1867 | GNUNET_break (0); | 1953 | s5r->url = GNUNET_strdup (url); |
1868 | return NULL; | 1954 | if (NULL != s5r->timeout_task) |
1955 | GNUNET_SCHEDULER_cancel (s5r->timeout_task); | ||
1956 | s5r->timeout_task = NULL; | ||
1957 | GNUNET_assert (s5r->state == SOCKS5_SOCKET_WITH_MHD); | ||
1958 | return s5r; | ||
1869 | } | 1959 | } |
1870 | 1960 | ||
1871 | 1961 | ||