aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Uzunov <andrey.uzunov@gmail.com>2013-10-10 15:00:39 +0000
committerAndrey Uzunov <andrey.uzunov@gmail.com>2013-10-10 15:00:39 +0000
commit445f5b9ece4be4e2811cf72efc26a5f8a18110b6 (patch)
tree653ad88ce8736725cf8b3702d30384ef6a5f069b
parent0cec4cbb396dedb52e543743058fb8b68b0aaafb (diff)
downloadlibmicrohttpd-445f5b9ece4be4e2811cf72efc26a5f8a18110b6.tar.gz
libmicrohttpd-445f5b9ece4be4e2811cf72efc26a5f8a18110b6.zip
spdy2http: bug fix - wrong usage of destroy functions
-rw-r--r--src/spdy2http/proxy.c78
1 files changed, 56 insertions, 22 deletions
diff --git a/src/spdy2http/proxy.c b/src/spdy2http/proxy.c
index 56c7d929..69a502f4 100644
--- a/src/spdy2http/proxy.c
+++ b/src/spdy2http/proxy.c
@@ -24,14 +24,14 @@
24 * TODO: 24 * TODO:
25 * - test all options! 25 * - test all options!
26 * - don't abort on lack of memory 26 * - don't abort on lack of memory
27 * - Memory leak: in rare cases the proxy object is not freed (and there
28 * is a lot of data pointed from it)
29 * - Correct recapitalizetion of header names before giving the headers 27 * - Correct recapitalizetion of header names before giving the headers
30 * to curl. 28 * to curl.
31 * - curl does not close sockets when connection is closed and no 29 * - curl does not close sockets when connection is closed and no
32 * new sockets are opened (they stay in CLOSE_WAIT) 30 * new sockets are opened (they stay in CLOSE_WAIT)
33 * - add '/' when a user requests http://example.com . Now this is a bad 31 * - add '/' when a user requests http://example.com . Now this is a bad
34 * request 32 * request
33 * - curl returns 0 or 1 ms for timeout even when nothing will be done;
34 * thus the loop uses CPU for nothing
35 * @author Andrey Uzunov 35 * @author Andrey Uzunov
36 */ 36 */
37 37
@@ -173,11 +173,15 @@ struct Proxy
173 size_t received_body_size; 173 size_t received_body_size;
174 //ssize_t length; 174 //ssize_t length;
175 int status; 175 int status;
176 bool done; 176 //bool done;
177 bool receiving_done; 177 bool receiving_done;
178 bool is_curl_read_paused; 178 bool is_curl_read_paused;
179 bool is_with_body_data; 179 bool is_with_body_data;
180 bool error; 180 //bool error;
181 bool curl_done;
182 bool curl_error;
183 bool spdy_done;
184 bool spdy_error;
181}; 185};
182 186
183 187
@@ -444,7 +448,9 @@ response_callback (void *cls,
444 448
445 *more = true; 449 *more = true;
446 450
447 if(proxy->error) 451 assert(!proxy->spdy_error);
452
453 if(proxy->curl_error)
448 { 454 {
449 PRINT_VERBOSE("tell spdy about the error"); 455 PRINT_VERBOSE("tell spdy about the error");
450 return -1; 456 return -1;
@@ -452,8 +458,8 @@ response_callback (void *cls,
452 458
453 if(!proxy->http_body_size)//nothing to write now 459 if(!proxy->http_body_size)//nothing to write now
454 { 460 {
455 PRINT_VERBOSE2("nothing to write now? %i", proxy->done); 461 PRINT_VERBOSE("nothing to write now");
456 if(proxy->done) *more = false; 462 if(proxy->curl_done || proxy->curl_error) *more = false;
457 return 0; 463 return 0;
458 } 464 }
459 465
@@ -461,10 +467,11 @@ response_callback (void *cls,
461 if(ret < 0) 467 if(ret < 0)
462 { 468 {
463 PRINT_INFO("no memory"); 469 PRINT_INFO("no memory");
470 //TODO error?
464 return -1; 471 return -1;
465 } 472 }
466 473
467 if(proxy->done && 0 == proxy->http_body_size) *more = false; 474 if((proxy->curl_done || proxy->curl_error) && 0 == proxy->http_body_size) *more = false;
468 475
469 PRINT_VERBOSE2("given bytes to microspdy: %zd", ret); 476 PRINT_VERBOSE2("given bytes to microspdy: %zd", ret);
470 477
@@ -482,8 +489,11 @@ cleanup(struct Proxy *proxy)
482 if(CURLM_OK != (ret = curl_multi_remove_handle(multi_handle, proxy->curl_handle))) 489 if(CURLM_OK != (ret = curl_multi_remove_handle(multi_handle, proxy->curl_handle)))
483 { 490 {
484 PRINT_INFO2("curl_multi_remove_handle failed (%i)", ret); 491 PRINT_INFO2("curl_multi_remove_handle failed (%i)", ret);
492 DIE("bug in cleanup");
485 } 493 }
486 debug_num_curls--; 494 debug_num_curls--;
495 //TODO bug on ku6.com or amazon.cn
496 // after curl_multi_remove_handle returned CURLM_BAD_EASY_HANDLE
487 curl_slist_free_all(proxy->curl_headers); 497 curl_slist_free_all(proxy->curl_headers);
488 curl_easy_cleanup(proxy->curl_handle); 498 curl_easy_cleanup(proxy->curl_handle);
489 499
@@ -506,6 +516,7 @@ response_done_callback(void *cls,
506 { 516 {
507 free(proxy->http_body); 517 free(proxy->http_body);
508 proxy->http_body = NULL; 518 proxy->http_body = NULL;
519 proxy->spdy_error = true;
509 } 520 }
510 cleanup(proxy); 521 cleanup(proxy);
511 SPDY_destroy_request(request); 522 SPDY_destroy_request(request);
@@ -533,7 +544,8 @@ curl_header_cb(void *ptr, size_t size, size_t nmemb, void *userp)
533 if(!*(proxy->session_alive)) 544 if(!*(proxy->session_alive))
534 { 545 {
535 PRINT_VERBOSE("headers received, but session is dead"); 546 PRINT_VERBOSE("headers received, but session is dead");
536 proxy->error = true; 547 proxy->spdy_error = true;
548 proxy->curl_error = true;
537 return 0; 549 return 0;
538 } 550 }
539 551
@@ -554,8 +566,11 @@ curl_header_cb(void *ptr, size_t size, size_t nmemb, void *userp)
554 DIE("no response"); 566 DIE("no response");
555 567
556 SPDY_name_value_destroy(proxy->headers); 568 SPDY_name_value_destroy(proxy->headers);
569 proxy->headers = NULL;
557 free(proxy->status_msg); 570 free(proxy->status_msg);
571 proxy->status_msg = NULL;
558 free(proxy->version); 572 free(proxy->version);
573 proxy->version = NULL;
559 574
560 if(SPDY_YES != SPDY_queue_response(proxy->request, 575 if(SPDY_YES != SPDY_queue_response(proxy->request,
561 proxy->response, 576 proxy->response,
@@ -566,8 +581,11 @@ curl_header_cb(void *ptr, size_t size, size_t nmemb, void *userp)
566 { 581 {
567 //DIE("no queue"); 582 //DIE("no queue");
568 //TODO right? 583 //TODO right?
569 proxy->error = true; 584 proxy->spdy_error = true;
570 PRINT_VERBOSE2("erorr in curl_header_cb for %s", proxy->url); 585 proxy->curl_error = true;
586 PRINT_VERBOSE2("no queue in curl_header_cb for %s", proxy->url);
587 SPDY_destroy_response(proxy->response);
588 proxy->response = NULL;
571 return 0; 589 return 0;
572 } 590 }
573 591
@@ -671,12 +689,15 @@ curl_write_cb(void *contents, size_t size, size_t nmemb, void *userp)
671 if(!*(proxy->session_alive)) 689 if(!*(proxy->session_alive))
672 { 690 {
673 PRINT_VERBOSE("data received, but session is dead"); 691 PRINT_VERBOSE("data received, but session is dead");
692 proxy->spdy_error = true;
693 proxy->curl_error = true;
674 return 0; 694 return 0;
675 } 695 }
676 696
677 if(!store_in_buffer(contents, realsize, &proxy->http_body, &proxy->http_body_size)) 697 if(!store_in_buffer(contents, realsize, &proxy->http_body, &proxy->http_body_size))
678 { 698 {
679 PRINT_INFO("not enough memory (malloc/realloc returned NULL)"); 699 PRINT_INFO("not enough memory (malloc/realloc returned NULL)");
700 proxy->curl_error = true;
680 return 0; 701 return 0;
681 } 702 }
682 /* 703 /*
@@ -1143,7 +1164,7 @@ run ()
1143 proxy = (struct Proxy *)curl_private; 1164 proxy = (struct Proxy *)curl_private;
1144 if(CURLE_OK == msg->data.result) 1165 if(CURLE_OK == msg->data.result)
1145 { 1166 {
1146 proxy->done = true; 1167 proxy->curl_done = true;
1147 call_spdy_run = true; 1168 call_spdy_run = true;
1148 //TODO what happens with proxy when the client resets a stream 1169 //TODO what happens with proxy when the client resets a stream
1149 //and response_done is not yet set for the last frame? is it 1170 //and response_done is not yet set for the last frame? is it
@@ -1152,27 +1173,40 @@ run ()
1152 else 1173 else
1153 { 1174 {
1154 PRINT_VERBOSE2("bad curl result (%i) for '%s'", msg->data.result, proxy->url); 1175 PRINT_VERBOSE2("bad curl result (%i) for '%s'", msg->data.result, proxy->url);
1155 if(NULL == proxy->response) 1176 if(proxy->spdy_done || proxy->spdy_error || NULL == proxy->response)
1177 {
1178 PRINT_VERBOSE("cleaning");
1179 SPDY_name_value_destroy(proxy->headers);
1180 SPDY_destroy_request(proxy->request);
1181 SPDY_destroy_response(proxy->response);
1182 cleanup(proxy);
1183 }
1184 else
1185 {
1186 proxy->curl_error = true;
1187 }
1188 /*if(NULL == proxy->response)
1156 { 1189 {
1157 SPDY_name_value_destroy(proxy->headers); 1190 SPDY_name_value_destroy(proxy->headers);
1158 /*if(!*(proxy->session_alive)) 1191 *//*if(!*(proxy->session_alive))
1159 { 1192 {
1160 free(proxy->http_body); 1193 free(proxy->http_body);
1161 proxy->http_body = NULL; 1194 proxy->http_body = NULL;
1162*/ 1195*//*
1163 SPDY_destroy_request(proxy->request); 1196 SPDY_destroy_request(proxy->request);
1164 cleanup(proxy); 1197 cleanup(proxy);
1165 /*} 1198 *//*}
1166 else 1199 else
1167 proxy->error = true;*/ 1200 proxy->error = true;*/
1168 } 1201 /* }
1169 else 1202 else
1170 { 1203 {
1171 //proxy->error = true; 1204 //TODO too early to clean them
1172 SPDY_destroy_request(proxy->request); 1205 proxy->error = true;
1173 SPDY_destroy_response(proxy->response); 1206 //SPDY_destroy_request(proxy->request);
1174 cleanup(proxy); 1207 //SPDY_destroy_response(proxy->response);
1175 } 1208 //cleanup(proxy);
1209 }*/
1176 call_spdy_run = true; 1210 call_spdy_run = true;
1177 //TODO spdy should be notified to send RST_STREAM 1211 //TODO spdy should be notified to send RST_STREAM
1178 } 1212 }