aboutsummaryrefslogtreecommitdiff
path: root/src/spdy2http/proxy.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/spdy2http/proxy.c')
-rw-r--r--src/spdy2http/proxy.c311
1 files changed, 156 insertions, 155 deletions
diff --git a/src/spdy2http/proxy.c b/src/spdy2http/proxy.c
index c317588a..b089084c 100644
--- a/src/spdy2http/proxy.c
+++ b/src/spdy2http/proxy.c
@@ -34,7 +34,7 @@
34 * thus the loop uses CPU for nothing 34 * thus the loop uses CPU for nothing
35 * @author Andrey Uzunov 35 * @author Andrey Uzunov
36 */ 36 */
37 37
38#include "platform.h" 38#include "platform.h"
39#include <unistd.h> 39#include <unistd.h>
40#include <stdlib.h> 40#include <stdlib.h>
@@ -132,7 +132,7 @@ struct URI
132 } \ 132 } \
133 }\ 133 }\
134 while(0) 134 while(0)
135 135
136 136
137#define DIE(msg) do{\ 137#define DIE(msg) do{\
138 printf("FATAL ERROR (line %i): %s\n", __LINE__, msg);\ 138 printf("FATAL ERROR (line %i): %s\n", __LINE__, msg);\
@@ -217,7 +217,7 @@ init_parse_uri(regex_t * preg)
217 query = $7 217 query = $7
218 fragment = $9 218 fragment = $9
219 */ 219 */
220 220
221 return regcomp(preg, "^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?", REG_EXTENDED); 221 return regcomp(preg, "^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?", REG_EXTENDED);
222} 222}
223 223
@@ -227,7 +227,7 @@ deinit_parse_uri(regex_t * preg)
227{ 227{
228 regfree(preg); 228 regfree(preg);
229} 229}
230 230
231 231
232static int 232static int
233parse_uri(regex_t * preg, const char * full_uri, struct URI ** uri) 233parse_uri(regex_t * preg, const char * full_uri, struct URI ** uri)
@@ -241,37 +241,37 @@ parse_uri(regex_t * preg, const char * full_uri, struct URI ** uri)
241 241
242 if (0 != (ret = regexec(preg, full_uri, nmatch, pmatch, 0))) 242 if (0 != (ret = regexec(preg, full_uri, nmatch, pmatch, 0)))
243 return ret; 243 return ret;
244 244
245 *uri = malloc(sizeof(struct URI)); 245 *uri = malloc(sizeof(struct URI));
246 if(NULL == *uri) 246 if(NULL == *uri)
247 return -200; 247 return -200;
248 248
249 (*uri)->full_uri = strdup(full_uri); 249 (*uri)->full_uri = strdup(full_uri);
250 250
251 asprintf(&((*uri)->scheme), 251 asprintf(&((*uri)->scheme),
252 "%.*s", 252 "%.*s",
253 (int) (pmatch[2].rm_eo - pmatch[2].rm_so), 253 (int) (pmatch[2].rm_eo - pmatch[2].rm_so),
254 &full_uri[pmatch[2].rm_so]); 254 &full_uri[pmatch[2].rm_so]);
255 asprintf(&((*uri)->host_and_port), "%.*s", 255 asprintf(&((*uri)->host_and_port), "%.*s",
256 (int) (pmatch[4].rm_eo - pmatch[4].rm_so), 256 (int) (pmatch[4].rm_eo - pmatch[4].rm_so),
257 &full_uri[pmatch[4].rm_so]); 257 &full_uri[pmatch[4].rm_so]);
258 asprintf(&((*uri)->path), 258 asprintf(&((*uri)->path),
259 "%.*s", 259 "%.*s",
260 (int) (pmatch[5].rm_eo - pmatch[5].rm_so), 260 (int) (pmatch[5].rm_eo - pmatch[5].rm_so),
261 &full_uri[pmatch[5].rm_so]); 261 &full_uri[pmatch[5].rm_so]);
262 asprintf(&((*uri)->path_and_more), 262 asprintf(&((*uri)->path_and_more),
263 "%.*s", 263 "%.*s",
264 (int) (pmatch[9].rm_eo - pmatch[5].rm_so), 264 (int) (pmatch[9].rm_eo - pmatch[5].rm_so),
265 &full_uri[pmatch[5].rm_so]); 265 &full_uri[pmatch[5].rm_so]);
266 asprintf(&((*uri)->query), 266 asprintf(&((*uri)->query),
267 "%.*s", 267 "%.*s",
268 (int) (pmatch[7].rm_eo - pmatch[7].rm_so), 268 (int) (pmatch[7].rm_eo - pmatch[7].rm_so),
269 &full_uri[pmatch[7].rm_so]); 269 &full_uri[pmatch[7].rm_so]);
270 asprintf(&((*uri)->fragment), 270 asprintf(&((*uri)->fragment),
271 "%.*s", 271 "%.*s",
272 (int) (pmatch[9].rm_eo - pmatch[9].rm_so), 272 (int) (pmatch[9].rm_eo - pmatch[9].rm_so),
273 &full_uri[pmatch[9].rm_so]); 273 &full_uri[pmatch[9].rm_so]);
274 274
275 colon = strrchr((*uri)->host_and_port, ':'); 275 colon = strrchr((*uri)->host_and_port, ':');
276 if(NULL == colon) 276 if(NULL == colon)
277 { 277 {
@@ -294,7 +294,7 @@ parse_uri(regex_t * preg, const char * full_uri, struct URI ** uri)
294 }*/ 294 }*/
295 return 0; 295 return 0;
296 } 296 }
297 297
298 port = atoi(colon + 1); 298 port = atoi(colon + 1);
299 if(port<1 || port >= 256 * 256) 299 if(port<1 || port >= 256 * 256)
300 { 300 {
@@ -303,7 +303,7 @@ parse_uri(regex_t * preg, const char * full_uri, struct URI ** uri)
303 } 303 }
304 (*uri)->port = port; 304 (*uri)->port = port;
305 asprintf(&((*uri)->host), "%.*s", (int)(colon - (*uri)->host_and_port), (*uri)->host_and_port); 305 asprintf(&((*uri)->host), "%.*s", (int)(colon - (*uri)->host_and_port), (*uri)->host_and_port);
306 306
307 return 0; 307 return 0;
308} 308}
309 309
@@ -313,7 +313,7 @@ store_in_buffer(const void *src, size_t src_size, void **dst, size_t *dst_size)
313{ 313{
314 if(0 == src_size) 314 if(0 == src_size)
315 return true; 315 return true;
316 316
317 if(NULL == *dst) 317 if(NULL == *dst)
318 *dst = malloc(src_size); 318 *dst = malloc(src_size);
319 else 319 else
@@ -323,7 +323,7 @@ store_in_buffer(const void *src, size_t src_size, void **dst, size_t *dst_size)
323 323
324 memcpy(*dst + *dst_size, src, src_size); 324 memcpy(*dst + *dst_size, src, src_size);
325 *dst_size += src_size; 325 *dst_size += src_size;
326 326
327 return true; 327 return true;
328} 328}
329 329
@@ -333,7 +333,7 @@ get_from_buffer(void **src, size_t *src_size, void *dst, size_t max_size)
333{ 333{
334 size_t ret; 334 size_t ret;
335 void *newbody; 335 void *newbody;
336 336
337 if(max_size >= *src_size) 337 if(max_size >= *src_size)
338 { 338 {
339 ret = *src_size; 339 ret = *src_size;
@@ -350,7 +350,7 @@ get_from_buffer(void **src, size_t *src_size, void *dst, size_t max_size)
350 free(*src); 350 free(*src);
351 *src = newbody; 351 *src = newbody;
352 *src_size -= ret; 352 *src_size -= ret;
353 353
354 return ret; 354 return ret;
355} 355}
356 356
@@ -359,7 +359,7 @@ static void
359catch_signal(int signal) 359catch_signal(int signal)
360{ 360{
361 (void)signal; 361 (void)signal;
362 362
363 loop = 0; 363 loop = 0;
364} 364}
365 365
@@ -368,9 +368,9 @@ new_session_cb (void * cls,
368 struct SPDY_Session * session) 368 struct SPDY_Session * session)
369{ 369{
370 (void)cls; 370 (void)cls;
371 371
372 bool *session_alive; 372 bool *session_alive;
373 373
374 PRINT_VERBOSE("new session"); 374 PRINT_VERBOSE("new session");
375 //TODO clean this memory 375 //TODO clean this memory
376 if(NULL == (session_alive = malloc(sizeof(bool)))) 376 if(NULL == (session_alive = malloc(sizeof(bool))))
@@ -388,17 +388,17 @@ session_closed_cb (void * cls,
388 int by_client) 388 int by_client)
389{ 389{
390 (void)cls; 390 (void)cls;
391 391
392 bool *session_alive; 392 bool *session_alive;
393 393
394 PRINT_VERBOSE2("session closed; by client: %i", by_client); 394 PRINT_VERBOSE2("session closed; by client: %i", by_client);
395 395
396 session_alive = SPDY_get_cls_from_session(session); 396 session_alive = SPDY_get_cls_from_session(session);
397 assert(NULL != session_alive); 397 assert(NULL != session_alive);
398 398
399 *session_alive = false; 399 *session_alive = false;
400} 400}
401 401
402 402
403static int 403static int
404spdy_post_data_cb (void * cls, 404spdy_post_data_cb (void * cls,
@@ -410,19 +410,19 @@ spdy_post_data_cb (void * cls,
410 (void)cls; 410 (void)cls;
411 int ret; 411 int ret;
412 struct Proxy *proxy = (struct Proxy *)SPDY_get_cls_from_request(request); 412 struct Proxy *proxy = (struct Proxy *)SPDY_get_cls_from_request(request);
413 413
414 if(!store_in_buffer(buf, size, &proxy->received_body, &proxy->received_body_size)) 414 if(!store_in_buffer(buf, size, &proxy->received_body, &proxy->received_body_size))
415 { 415 {
416 PRINT_INFO("not enough memory (malloc/realloc returned NULL)"); 416 PRINT_INFO("not enough memory (malloc/realloc returned NULL)");
417 return 0; 417 return 0;
418 } 418 }
419 419
420 proxy->receiving_done = !more; 420 proxy->receiving_done = !more;
421 421
422 PRINT_VERBOSE2("POST bytes from SPDY: %zu", size); 422 PRINT_VERBOSE2("POST bytes from SPDY: %zu", size);
423 423
424 call_curl_run = true; 424 call_curl_run = true;
425 425
426 if(proxy->is_curl_read_paused) 426 if(proxy->is_curl_read_paused)
427 { 427 {
428 if(CURLE_OK != (ret = curl_easy_pause(proxy->curl_handle, CURLPAUSE_CONT))) 428 if(CURLE_OK != (ret = curl_easy_pause(proxy->curl_handle, CURLPAUSE_CONT)))
@@ -432,11 +432,11 @@ spdy_post_data_cb (void * cls,
432 } 432 }
433 PRINT_VERBOSE("curl_read_cb pause resumed"); 433 PRINT_VERBOSE("curl_read_cb pause resumed");
434 } 434 }
435 435
436 return SPDY_YES; 436 return SPDY_YES;
437} 437}
438 438
439 439
440ssize_t 440ssize_t
441response_callback (void *cls, 441response_callback (void *cls,
442 void *buffer, 442 void *buffer,
@@ -445,24 +445,24 @@ response_callback (void *cls,
445{ 445{
446 ssize_t ret; 446 ssize_t ret;
447 struct Proxy *proxy = (struct Proxy *)cls; 447 struct Proxy *proxy = (struct Proxy *)cls;
448 448
449 *more = true; 449 *more = true;
450 450
451 assert(!proxy->spdy_error); 451 assert(!proxy->spdy_error);
452 452
453 if(proxy->curl_error) 453 if(proxy->curl_error)
454 { 454 {
455 PRINT_VERBOSE("tell spdy about the error"); 455 PRINT_VERBOSE("tell spdy about the error");
456 return -1; 456 return -1;
457 } 457 }
458 458
459 if(!proxy->http_body_size)//nothing to write now 459 if(!proxy->http_body_size)//nothing to write now
460 { 460 {
461 PRINT_VERBOSE("nothing to write now"); 461 PRINT_VERBOSE("nothing to write now");
462 if(proxy->curl_done || proxy->curl_error) *more = false; 462 if(proxy->curl_done || proxy->curl_error) *more = false;
463 return 0; 463 return 0;
464 } 464 }
465 465
466 ret = get_from_buffer(&(proxy->http_body), &(proxy->http_body_size), buffer, max); 466 ret = get_from_buffer(&(proxy->http_body), &(proxy->http_body_size), buffer, max);
467 if(ret < 0) 467 if(ret < 0)
468 { 468 {
@@ -470,11 +470,11 @@ response_callback (void *cls,
470 //TODO error? 470 //TODO error?
471 return -1; 471 return -1;
472 } 472 }
473 473
474 if((proxy->curl_done || proxy->curl_error) && 0 == proxy->http_body_size) *more = false; 474 if((proxy->curl_done || proxy->curl_error) && 0 == proxy->http_body_size) *more = false;
475 475
476 PRINT_VERBOSE2("given bytes to microspdy: %zd", ret); 476 PRINT_VERBOSE2("given bytes to microspdy: %zd", ret);
477 477
478 return ret; 478 return ret;
479} 479}
480 480
@@ -483,9 +483,9 @@ static void
483cleanup(struct Proxy *proxy) 483cleanup(struct Proxy *proxy)
484{ 484{
485 int ret; 485 int ret;
486 486
487 //fprintf(stderr, "free proxy for %s\n", proxy->url); 487 //fprintf(stderr, "free proxy for %s\n", proxy->url);
488 488
489 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)))
490 { 490 {
491 PRINT_INFO2("curl_multi_remove_handle failed (%i)", ret); 491 PRINT_INFO2("curl_multi_remove_handle failed (%i)", ret);
@@ -496,7 +496,7 @@ cleanup(struct Proxy *proxy)
496 // after curl_multi_remove_handle returned CURLM_BAD_EASY_HANDLE 496 // after curl_multi_remove_handle returned CURLM_BAD_EASY_HANDLE
497 curl_slist_free_all(proxy->curl_headers); 497 curl_slist_free_all(proxy->curl_headers);
498 curl_easy_cleanup(proxy->curl_handle); 498 curl_easy_cleanup(proxy->curl_handle);
499 499
500 free(proxy->url); 500 free(proxy->url);
501 free(proxy); 501 free(proxy);
502} 502}
@@ -511,7 +511,7 @@ response_done_callback(void *cls,
511{ 511{
512 (void)streamopened; 512 (void)streamopened;
513 struct Proxy *proxy = (struct Proxy *)cls; 513 struct Proxy *proxy = (struct Proxy *)cls;
514 514
515 if(SPDY_RESPONSE_RESULT_SUCCESS != status) 515 if(SPDY_RESPONSE_RESULT_SUCCESS != status)
516 { 516 {
517 free(proxy->http_body); 517 free(proxy->http_body);
@@ -539,7 +539,7 @@ curl_header_cb(void *ptr, size_t size, size_t nmemb, void *userp)
539 int num_values; 539 int num_values;
540 const char * const * values; 540 const char * const * values;
541 bool abort_it; 541 bool abort_it;
542 542
543 //printf("curl_header_cb %s\n", line); 543 //printf("curl_header_cb %s\n", line);
544 if(!*(proxy->session_alive)) 544 if(!*(proxy->session_alive))
545 { 545 {
@@ -548,7 +548,7 @@ curl_header_cb(void *ptr, size_t size, size_t nmemb, void *userp)
548 proxy->curl_error = true; 548 proxy->curl_error = true;
549 return 0; 549 return 0;
550 } 550 }
551 551
552 //trailer 552 //trailer
553 if(NULL != proxy->response) return 0; 553 if(NULL != proxy->response) return 0;
554 554
@@ -564,14 +564,14 @@ curl_header_cb(void *ptr, size_t size, size_t nmemb, void *userp)
564 0))) 564 0)))
565 //256))) 565 //256)))
566 DIE("no response"); 566 DIE("no response");
567 567
568 SPDY_name_value_destroy(proxy->headers); 568 SPDY_name_value_destroy(proxy->headers);
569 proxy->headers = NULL; 569 proxy->headers = NULL;
570 free(proxy->status_msg); 570 free(proxy->status_msg);
571 proxy->status_msg = NULL; 571 proxy->status_msg = NULL;
572 free(proxy->version); 572 free(proxy->version);
573 proxy->version = NULL; 573 proxy->version = NULL;
574 574
575 if(SPDY_YES != SPDY_queue_response(proxy->request, 575 if(SPDY_YES != SPDY_queue_response(proxy->request,
576 proxy->response, 576 proxy->response,
577 true, 577 true,
@@ -588,12 +588,12 @@ curl_header_cb(void *ptr, size_t size, size_t nmemb, void *userp)
588 proxy->response = NULL; 588 proxy->response = NULL;
589 return 0; 589 return 0;
590 } 590 }
591 591
592 call_spdy_run = true; 592 call_spdy_run = true;
593 593
594 return realsize; 594 return realsize;
595 } 595 }
596 596
597 pos = 0; 597 pos = 0;
598 if(NULL == proxy->version) 598 if(NULL == proxy->version)
599 { 599 {
@@ -605,7 +605,7 @@ curl_header_cb(void *ptr, size_t size, size_t nmemb, void *userp)
605 if(NULL == (proxy->version = strndup(line, i - pos))) 605 if(NULL == (proxy->version = strndup(line, i - pos)))
606 DIE("No memory"); 606 DIE("No memory");
607 pos = i+1; 607 pos = i+1;
608 608
609 //status (number) 609 //status (number)
610 for(i=pos; i<realsize && ' '!=line[i] && '\r'!=line[i] && '\n'!=line[i]; ++i); 610 for(i=pos; i<realsize && ' '!=line[i] && '\r'!=line[i] && '\n'!=line[i]; ++i);
611 if(NULL == (status = strndup(&(line[pos]), i - pos))) 611 if(NULL == (status = strndup(&(line[pos]), i - pos)))
@@ -623,7 +623,7 @@ curl_header_cb(void *ptr, size_t size, size_t nmemb, void *userp)
623 PRINT_VERBOSE2("Header line received '%s' '%i' '%s' ", proxy->version, proxy->status, proxy->status_msg); 623 PRINT_VERBOSE2("Header line received '%s' '%i' '%s' ", proxy->version, proxy->status, proxy->status_msg);
624 return realsize; 624 return realsize;
625 } 625 }
626 626
627 //other lines 627 //other lines
628 //header name 628 //header name
629 for(i=pos; i<realsize && ':'!=line[i] && '\r'!=line[i] && '\n'!=line[i]; ++i) 629 for(i=pos; i<realsize && ':'!=line[i] && '\r'!=line[i] && '\n'!=line[i]; ++i)
@@ -646,7 +646,7 @@ curl_header_cb(void *ptr, size_t size, size_t nmemb, void *userp)
646 DIE("SPDY_name_value_add failed"); 646 DIE("SPDY_name_value_add failed");
647 return realsize; 647 return realsize;
648 } 648 }
649 649
650 //header value 650 //header value
651 pos = i+1; 651 pos = i+1;
652 while(pos<realsize && isspace(line[pos])) ++pos; //remove leading space 652 while(pos<realsize && isspace(line[pos])) ++pos; //remove leading space
@@ -665,7 +665,7 @@ curl_header_cb(void *ptr, size_t size, size_t nmemb, void *userp)
665 PRINT_VERBOSE2("header appears more than once with same value '%s: %s'", name, value); 665 PRINT_VERBOSE2("header appears more than once with same value '%s: %s'", name, value);
666 break; 666 break;
667 } 667 }
668 668
669 if(abort_it) 669 if(abort_it)
670 { 670 {
671 PRINT_INFO2("SPDY_name_value_add failed (%i) for '%s'", ret, name); 671 PRINT_INFO2("SPDY_name_value_add failed (%i) for '%s'", ret, name);
@@ -684,7 +684,7 @@ curl_write_cb(void *contents, size_t size, size_t nmemb, void *userp)
684{ 684{
685 size_t realsize = size * nmemb; 685 size_t realsize = size * nmemb;
686 struct Proxy *proxy = (struct Proxy *)userp; 686 struct Proxy *proxy = (struct Proxy *)userp;
687 687
688 //printf("curl_write_cb %i\n", realsize); 688 //printf("curl_write_cb %i\n", realsize);
689 if(!*(proxy->session_alive)) 689 if(!*(proxy->session_alive))
690 { 690 {
@@ -693,7 +693,7 @@ curl_write_cb(void *contents, size_t size, size_t nmemb, void *userp)
693 proxy->curl_error = true; 693 proxy->curl_error = true;
694 return 0; 694 return 0;
695 } 695 }
696 696
697 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))
698 { 698 {
699 PRINT_INFO("not enough memory (malloc/realloc returned NULL)"); 699 PRINT_INFO("not enough memory (malloc/realloc returned NULL)");
@@ -713,12 +713,12 @@ curl_write_cb(void *contents, size_t size, size_t nmemb, void *userp)
713 713
714 memcpy(proxy->http_body + proxy->http_body_size, contents, realsize); 714 memcpy(proxy->http_body + proxy->http_body_size, contents, realsize);
715 proxy->http_body_size += realsize; 715 proxy->http_body_size += realsize;
716 */ 716 */
717 717
718 PRINT_VERBOSE2("received bytes from curl: %zu", realsize); 718 PRINT_VERBOSE2("received bytes from curl: %zu", realsize);
719 719
720 call_spdy_run = true; 720 call_spdy_run = true;
721 721
722 return realsize; 722 return realsize;
723} 723}
724 724
@@ -730,34 +730,34 @@ curl_read_cb(void *ptr, size_t size, size_t nmemb, void *userp)
730 size_t max = size * nmemb; 730 size_t max = size * nmemb;
731 struct Proxy *proxy = (struct Proxy *)userp; 731 struct Proxy *proxy = (struct Proxy *)userp;
732 //void *newbody; 732 //void *newbody;
733 733
734 734
735 if((proxy->receiving_done && !proxy->received_body_size) || !proxy->is_with_body_data || max < 1) 735 if((proxy->receiving_done && !proxy->received_body_size) || !proxy->is_with_body_data || max < 1)
736 { 736 {
737 PRINT_VERBOSE("curl_read_cb last call"); 737 PRINT_VERBOSE("curl_read_cb last call");
738 return 0; 738 return 0;
739 } 739 }
740 740
741 if(!*(proxy->session_alive)) 741 if(!*(proxy->session_alive))
742 { 742 {
743 PRINT_VERBOSE("POST is still being sent, but session is dead"); 743 PRINT_VERBOSE("POST is still being sent, but session is dead");
744 return CURL_READFUNC_ABORT; 744 return CURL_READFUNC_ABORT;
745 } 745 }
746 746
747 if(!proxy->received_body_size)//nothing to write now 747 if(!proxy->received_body_size)//nothing to write now
748 { 748 {
749 PRINT_VERBOSE("curl_read_cb called paused"); 749 PRINT_VERBOSE("curl_read_cb called paused");
750 proxy->is_curl_read_paused = true; 750 proxy->is_curl_read_paused = true;
751 return CURL_READFUNC_PAUSE;//TODO curl pause should be used 751 return CURL_READFUNC_PAUSE;//TODO curl pause should be used
752 } 752 }
753 753
754 ret = get_from_buffer(&(proxy->received_body), &(proxy->received_body_size), ptr, max); 754 ret = get_from_buffer(&(proxy->received_body), &(proxy->received_body_size), ptr, max);
755 if(ret < 0) 755 if(ret < 0)
756 { 756 {
757 PRINT_INFO("no memory"); 757 PRINT_INFO("no memory");
758 return CURL_READFUNC_ABORT; 758 return CURL_READFUNC_ABORT;
759 } 759 }
760 760
761 /* 761 /*
762 if(max >= proxy->received_body_size) 762 if(max >= proxy->received_body_size)
763 { 763 {
@@ -779,9 +779,9 @@ curl_read_cb(void *ptr, size_t size, size_t nmemb, void *userp)
779 proxy->received_body = newbody; 779 proxy->received_body = newbody;
780 proxy->received_body_size -= ret; 780 proxy->received_body_size -= ret;
781 * */ 781 * */
782 782
783 PRINT_VERBOSE2("given POST bytes to curl: %zd", ret); 783 PRINT_VERBOSE2("given POST bytes to curl: %zd", ret);
784 784
785 return ret; 785 return ret;
786} 786}
787 787
@@ -794,23 +794,23 @@ iterate_cb (void *cls, const char *name, const char * const * value, int num_val
794 char *line; 794 char *line;
795 int line_len = strlen(name) + 3; //+ ": \0" 795 int line_len = strlen(name) + 3; //+ ": \0"
796 int i; 796 int i;
797 797
798 for(i=0; i<num_values; ++i) 798 for(i=0; i<num_values; ++i)
799 { 799 {
800 if(i) line_len += 2; //", " 800 if(i) line_len += 2; //", "
801 line_len += strlen(value[i]); 801 line_len += strlen(value[i]);
802 } 802 }
803 803
804 if(NULL == (line = malloc(line_len)))//no recovery 804 if(NULL == (line = malloc(line_len)))//no recovery
805 DIE("No memory"); 805 DIE("No memory");
806 line[0] = 0; 806 line[0] = 0;
807 807
808 strcat(line, name); 808 strcat(line, name);
809 strcat(line, ": "); 809 strcat(line, ": ");
810 //all spdy header names are lower case; 810 //all spdy header names are lower case;
811 //for simplicity here we just capitalize the first letter 811 //for simplicity here we just capitalize the first letter
812 line[0] = toupper(line[0]); 812 line[0] = toupper(line[0]);
813 813
814 for(i=0; i<num_values; ++i) 814 for(i=0; i<num_values; ++i)
815 { 815 {
816 if(i) strcat(line, ", "); 816 if(i) strcat(line, ", ");
@@ -821,7 +821,7 @@ iterate_cb (void *cls, const char *name, const char * const * value, int num_val
821 if(NULL == (*curl_headers = curl_slist_append(*curl_headers, line))) 821 if(NULL == (*curl_headers = curl_slist_append(*curl_headers, line)))
822 DIE("curl_slist_append failed"); 822 DIE("curl_slist_append failed");
823 free(line); 823 free(line);
824 824
825 return SPDY_YES; 825 return SPDY_YES;
826} 826}
827 827
@@ -842,40 +842,40 @@ standard_request_handler(void *cls,
842 (void)priority; 842 (void)priority;
843 (void)host; 843 (void)host;
844 (void)scheme; 844 (void)scheme;
845 845
846 struct Proxy *proxy; 846 struct Proxy *proxy;
847 int ret; 847 int ret;
848 struct URI *uri; 848 struct URI *uri;
849 struct SPDY_Session *session; 849 struct SPDY_Session *session;
850 850
851 proxy = SPDY_get_cls_from_request(request); 851 proxy = SPDY_get_cls_from_request(request);
852 if(NULL != proxy) 852 if(NULL != proxy)
853 { 853 {
854 //ignore trailers or more headers 854 //ignore trailers or more headers
855 return; 855 return;
856 } 856 }
857 857
858 PRINT_VERBOSE2("received request for '%s %s %s'\n", method, path, version); 858 PRINT_VERBOSE2("received request for '%s %s %s'\n", method, path, version);
859 859
860 //TODO not freed once in a while 860 //TODO not freed once in a while
861 if(NULL == (proxy = malloc(sizeof(struct Proxy)))) 861 if(NULL == (proxy = malloc(sizeof(struct Proxy))))
862 DIE("No memory"); 862 DIE("No memory");
863 memset(proxy, 0, sizeof(struct Proxy)); 863 memset(proxy, 0, sizeof(struct Proxy));
864 864
865 //fprintf(stderr, "new proxy for %s\n", path); 865 //fprintf(stderr, "new proxy for %s\n", path);
866 866
867 session = SPDY_get_session_for_request(request); 867 session = SPDY_get_session_for_request(request);
868 assert(NULL != session); 868 assert(NULL != session);
869 proxy->session_alive = SPDY_get_cls_from_session(session); 869 proxy->session_alive = SPDY_get_cls_from_session(session);
870 assert(NULL != proxy->session_alive); 870 assert(NULL != proxy->session_alive);
871 871
872 SPDY_set_cls_to_request(request, proxy); 872 SPDY_set_cls_to_request(request, proxy);
873 873
874 proxy->request = request; 874 proxy->request = request;
875 proxy->is_with_body_data = more; 875 proxy->is_with_body_data = more;
876 if(NULL == (proxy->headers = SPDY_name_value_create())) 876 if(NULL == (proxy->headers = SPDY_name_value_create()))
877 DIE("No memory"); 877 DIE("No memory");
878 878
879 if(glob_opt.transparent) 879 if(glob_opt.transparent)
880 { 880 {
881 if(NULL != glob_opt.http_backend) //use always same host 881 if(NULL != glob_opt.http_backend) //use always same host
@@ -884,7 +884,7 @@ standard_request_handler(void *cls,
884 ret = asprintf(&(proxy->url),"%s://%s%s", scheme, host, path); 884 ret = asprintf(&(proxy->url),"%s://%s%s", scheme, host, path);
885 if(-1 == ret) 885 if(-1 == ret)
886 DIE("No memory"); 886 DIE("No memory");
887 887
888 ret = parse_uri(&uri_preg, proxy->url, &uri); 888 ret = parse_uri(&uri_preg, proxy->url, &uri);
889 if(ret != 0) 889 if(ret != 0)
890 DIE("parsing built uri failed"); 890 DIE("parsing built uri failed");
@@ -895,7 +895,7 @@ standard_request_handler(void *cls,
895 PRINT_INFO2("path %s '%s' '%s'", path, uri->scheme, uri->host); 895 PRINT_INFO2("path %s '%s' '%s'", path, uri->scheme, uri->host);
896 if(ret != 0 || !strlen(uri->scheme) || !strlen(uri->host)) 896 if(ret != 0 || !strlen(uri->scheme) || !strlen(uri->host))
897 DIE("parsing received uri failed"); 897 DIE("parsing received uri failed");
898 898
899 if(NULL != glob_opt.http_backend) //use backend host 899 if(NULL != glob_opt.http_backend) //use backend host
900 { 900 {
901 ret = asprintf(&(proxy->url),"%s://%s%s", uri->scheme, glob_opt.http_backend, uri->path_and_more); 901 ret = asprintf(&(proxy->url),"%s://%s%s", uri->scheme, glob_opt.http_backend, uri->path_and_more);
@@ -906,22 +906,22 @@ standard_request_handler(void *cls,
906 if(NULL == (proxy->url = strdup(path))) 906 if(NULL == (proxy->url = strdup(path)))
907 DIE("No memory"); 907 DIE("No memory");
908 } 908 }
909 909
910 free_uri(uri); 910 free_uri(uri);
911 911
912 PRINT_VERBOSE2("curl will request '%s'", proxy->url); 912 PRINT_VERBOSE2("curl will request '%s'", proxy->url);
913 913
914 SPDY_name_value_iterate(headers, &iterate_cb, proxy); 914 SPDY_name_value_iterate(headers, &iterate_cb, proxy);
915 915
916 if(NULL == (proxy->curl_handle = curl_easy_init())) 916 if(NULL == (proxy->curl_handle = curl_easy_init()))
917 { 917 {
918 PRINT_INFO("curl_easy_init failed"); 918 PRINT_INFO("curl_easy_init failed");
919 abort(); 919 abort();
920 } 920 }
921 921
922 if(glob_opt.curl_verbose) 922 if(glob_opt.curl_verbose)
923 CURL_SETOPT(proxy->curl_handle, CURLOPT_VERBOSE, 1); 923 CURL_SETOPT(proxy->curl_handle, CURLOPT_VERBOSE, 1);
924 924
925 if(0 == strcmp(SPDY_HTTP_METHOD_POST,method)) 925 if(0 == strcmp(SPDY_HTTP_METHOD_POST,method))
926 { 926 {
927 if(NULL == (proxy->curl_headers = curl_slist_append(proxy->curl_headers, "Expect:"))) 927 if(NULL == (proxy->curl_headers = curl_slist_append(proxy->curl_headers, "Expect:")))
@@ -930,7 +930,7 @@ standard_request_handler(void *cls,
930 CURL_SETOPT(proxy->curl_handle, CURLOPT_READFUNCTION, curl_read_cb); 930 CURL_SETOPT(proxy->curl_handle, CURLOPT_READFUNCTION, curl_read_cb);
931 CURL_SETOPT(proxy->curl_handle, CURLOPT_READDATA, proxy); 931 CURL_SETOPT(proxy->curl_handle, CURLOPT_READDATA, proxy);
932 } 932 }
933 933
934 if(glob_opt.timeout) 934 if(glob_opt.timeout)
935 CURL_SETOPT(proxy->curl_handle, CURLOPT_TIMEOUT, glob_opt.timeout); 935 CURL_SETOPT(proxy->curl_handle, CURLOPT_TIMEOUT, glob_opt.timeout);
936 CURL_SETOPT(proxy->curl_handle, CURLOPT_URL, proxy->url); 936 CURL_SETOPT(proxy->curl_handle, CURLOPT_URL, proxy->url);
@@ -948,14 +948,14 @@ standard_request_handler(void *cls,
948 CURL_SETOPT(proxy->curl_handle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); 948 CURL_SETOPT(proxy->curl_handle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
949 else if(glob_opt.ipv6 && !glob_opt.ipv4) 949 else if(glob_opt.ipv6 && !glob_opt.ipv4)
950 CURL_SETOPT(proxy->curl_handle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V6); 950 CURL_SETOPT(proxy->curl_handle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V6);
951 951
952 if(CURLM_OK != (ret = curl_multi_add_handle(multi_handle, proxy->curl_handle))) 952 if(CURLM_OK != (ret = curl_multi_add_handle(multi_handle, proxy->curl_handle)))
953 { 953 {
954 PRINT_INFO2("curl_multi_add_handle failed (%i)", ret); 954 PRINT_INFO2("curl_multi_add_handle failed (%i)", ret);
955 abort(); 955 abort();
956 } 956 }
957 debug_num_curls++; 957 debug_num_curls++;
958 958
959 //~5ms additional latency for calling this 959 //~5ms additional latency for calling this
960 if(CURLM_OK != (ret = curl_multi_perform(multi_handle, &still_running)) 960 if(CURLM_OK != (ret = curl_multi_perform(multi_handle, &still_running))
961 && CURLM_CALL_MULTI_PERFORM != ret) 961 && CURLM_CALL_MULTI_PERFORM != ret)
@@ -963,7 +963,7 @@ standard_request_handler(void *cls,
963 PRINT_INFO2("curl_multi_perform failed (%i)", ret); 963 PRINT_INFO2("curl_multi_perform failed (%i)", ret);
964 abort(); 964 abort();
965 } 965 }
966 966
967 call_curl_run = true; 967 call_curl_run = true;
968} 968}
969 969
@@ -995,21 +995,21 @@ run ()
995 enum SPDY_DAEMON_FLAG flags = SPDY_DAEMON_FLAG_NO; 995 enum SPDY_DAEMON_FLAG flags = SPDY_DAEMON_FLAG_NO;
996 //struct SPDY_Response *error_response; 996 //struct SPDY_Response *error_response;
997 char *curl_private; 997 char *curl_private;
998 998
999 signal(SIGPIPE, SIG_IGN); 999 signal(SIGPIPE, SIG_IGN);
1000 1000
1001 if (signal(SIGINT, catch_signal) == SIG_ERR) 1001 if (signal(SIGINT, catch_signal) == SIG_ERR)
1002 PRINT_VERBOSE("signal failed"); 1002 PRINT_VERBOSE("signal failed");
1003 1003
1004 srand(time(NULL)); 1004 srand(time(NULL));
1005 if(init_parse_uri(&uri_preg)) 1005 if(init_parse_uri(&uri_preg))
1006 DIE("Regexp compilation failed"); 1006 DIE("Regexp compilation failed");
1007 1007
1008 SPDY_init(); 1008 SPDY_init();
1009 1009
1010 if(glob_opt.nodelay) 1010 if(glob_opt.nodelay)
1011 flags |= SPDY_DAEMON_FLAG_NO_DELAY; 1011 flags |= SPDY_DAEMON_FLAG_NO_DELAY;
1012 1012
1013 if(NULL == glob_opt.listen_host) 1013 if(NULL == glob_opt.listen_host)
1014 { 1014 {
1015 daemon = SPDY_start_daemon(glob_opt.listen_port, 1015 daemon = SPDY_start_daemon(glob_opt.listen_port,
@@ -1034,13 +1034,13 @@ run ()
1034 memset (&hints, 0, sizeof(struct addrinfo)); 1034 memset (&hints, 0, sizeof(struct addrinfo));
1035 hints.ai_family = AF_INET; 1035 hints.ai_family = AF_INET;
1036 hints.ai_socktype = SOCK_STREAM; 1036 hints.ai_socktype = SOCK_STREAM;
1037 1037
1038 ret = getaddrinfo(glob_opt.listen_host, service, &hints, &gai); 1038 ret = getaddrinfo(glob_opt.listen_host, service, &hints, &gai);
1039 if(ret != 0) 1039 if(ret != 0)
1040 DIE("problem with specified host"); 1040 DIE("problem with specified host");
1041 1041
1042 addr = (struct sockaddr_in *) gai->ai_addr; 1042 addr = (struct sockaddr_in *) gai->ai_addr;
1043 1043
1044 daemon = SPDY_start_daemon(0, 1044 daemon = SPDY_start_daemon(0,
1045 glob_opt.cert, 1045 glob_opt.cert,
1046 glob_opt.cert_key, 1046 glob_opt.cert_key,
@@ -1061,16 +1061,16 @@ run ()
1061 //1, 1061 //1,
1062 SPDY_DAEMON_OPTION_END); 1062 SPDY_DAEMON_OPTION_END);
1063 } 1063 }
1064 1064
1065 if(NULL==daemon){ 1065 if(NULL==daemon){
1066 printf("no daemon\n"); 1066 printf("no daemon\n");
1067 return 1; 1067 return 1;
1068 } 1068 }
1069 1069
1070 multi_handle = curl_multi_init(); 1070 multi_handle = curl_multi_init();
1071 if(NULL==multi_handle) 1071 if(NULL==multi_handle)
1072 DIE("no multi_handle"); 1072 DIE("no multi_handle");
1073 1073
1074 timeout.tv_usec = 0; 1074 timeout.tv_usec = 0;
1075 1075
1076 do 1076 do
@@ -1078,16 +1078,16 @@ run ()
1078 FD_ZERO(&rs); 1078 FD_ZERO(&rs);
1079 FD_ZERO(&ws); 1079 FD_ZERO(&ws);
1080 FD_ZERO(&es); 1080 FD_ZERO(&es);
1081 1081
1082 PRINT_VERBOSE2("num curls %i", debug_num_curls); 1082 PRINT_VERBOSE2("num curls %i", debug_num_curls);
1083 1083
1084 ret_spdy = SPDY_get_timeout(daemon, &timeout_spdy); 1084 ret_spdy = SPDY_get_timeout(daemon, &timeout_spdy);
1085 if(SPDY_NO == ret_spdy || timeout_spdy > 5000) 1085 if(SPDY_NO == ret_spdy || timeout_spdy > 5000)
1086 timeoutlong = 5000; 1086 timeoutlong = 5000;
1087 else 1087 else
1088 timeoutlong = timeout_spdy; 1088 timeoutlong = timeout_spdy;
1089 PRINT_VERBOSE2("SPDY timeout %lld; %i", timeout_spdy, ret_spdy); 1089 PRINT_VERBOSE2("SPDY timeout %lld; %i", timeout_spdy, ret_spdy);
1090 1090
1091 if(CURLM_OK != (ret_curl = curl_multi_timeout(multi_handle, &timeout_curl))) 1091 if(CURLM_OK != (ret_curl = curl_multi_timeout(multi_handle, &timeout_curl)))
1092 { 1092 {
1093 PRINT_VERBOSE2("curl_multi_timeout failed (%i)", ret_curl); 1093 PRINT_VERBOSE2("curl_multi_timeout failed (%i)", ret_curl);
@@ -1095,33 +1095,33 @@ run ()
1095 } 1095 }
1096 else if(timeout_curl >= 0 && timeoutlong > (unsigned long)timeout_curl) 1096 else if(timeout_curl >= 0 && timeoutlong > (unsigned long)timeout_curl)
1097 timeoutlong = (unsigned long)timeout_curl; 1097 timeoutlong = (unsigned long)timeout_curl;
1098 1098
1099 PRINT_VERBOSE2("curl timeout %ld", timeout_curl); 1099 PRINT_VERBOSE2("curl timeout %ld", timeout_curl);
1100 1100
1101 timeout.tv_sec = timeoutlong / 1000; 1101 timeout.tv_sec = timeoutlong / 1000;
1102 timeout.tv_usec = (timeoutlong % 1000) * 1000; 1102 timeout.tv_usec = (timeoutlong % 1000) * 1000;
1103 1103
1104 maxfd = SPDY_get_fdset (daemon, 1104 maxfd = SPDY_get_fdset (daemon,
1105 &rs, 1105 &rs,
1106 &ws, 1106 &ws,
1107 &es); 1107 &es);
1108 assert(-1 != maxfd); 1108 assert(-1 != maxfd);
1109 1109
1110 if(CURLM_OK != (ret = curl_multi_fdset(multi_handle, &rs, 1110 if(CURLM_OK != (ret = curl_multi_fdset(multi_handle, &rs,
1111 &ws, 1111 &ws,
1112 &es, &maxfd_curl))) 1112 &es, &maxfd_curl)))
1113 { 1113 {
1114 PRINT_INFO2("curl_multi_fdset failed (%i)", ret); 1114 PRINT_INFO2("curl_multi_fdset failed (%i)", ret);
1115 abort(); 1115 abort();
1116 } 1116 }
1117 1117
1118 if(maxfd_curl > maxfd) 1118 if(maxfd_curl > maxfd)
1119 maxfd = maxfd_curl; 1119 maxfd = maxfd_curl;
1120 1120
1121 PRINT_VERBOSE2("timeout before %lld %lld", (unsigned long long)timeout.tv_sec, (unsigned long long)timeout.tv_usec); 1121 PRINT_VERBOSE2("timeout before %lld %lld", (unsigned long long)timeout.tv_sec, (unsigned long long)timeout.tv_usec);
1122 ret = select(maxfd+1, &rs, &ws, &es, &timeout); 1122 ret = select(maxfd+1, &rs, &ws, &es, &timeout);
1123 PRINT_VERBOSE2("timeout after %lld %lld; ret is %i", (unsigned long long)timeout.tv_sec, (unsigned long long)timeout.tv_usec, ret); 1123 PRINT_VERBOSE2("timeout after %lld %lld; ret is %i", (unsigned long long)timeout.tv_sec, (unsigned long long)timeout.tv_usec, ret);
1124 1124
1125 /*switch(ret) { 1125 /*switch(ret) {
1126 case -1: 1126 case -1:
1127 PRINT_INFO2("select error: %i", errno); 1127 PRINT_INFO2("select error: %i", errno);
@@ -1129,7 +1129,7 @@ run ()
1129 case 0: 1129 case 0:
1130 break; 1130 break;
1131 default:*/ 1131 default:*/
1132 1132
1133 //the second part should not happen with current implementation 1133 //the second part should not happen with current implementation
1134 if(ret > 0 || (SPDY_YES == ret_spdy && 0 == timeout_spdy)) 1134 if(ret > 0 || (SPDY_YES == ret_spdy && 0 == timeout_spdy))
1135 { 1135 {
@@ -1137,7 +1137,7 @@ run ()
1137 SPDY_run(daemon); 1137 SPDY_run(daemon);
1138 call_spdy_run = false; 1138 call_spdy_run = false;
1139 } 1139 }
1140 1140
1141 //if(ret > 0 || (CURLM_OK == ret_curl && 0 == timeout_curl) || call_curl_run) 1141 //if(ret > 0 || (CURLM_OK == ret_curl && 0 == timeout_curl) || call_curl_run)
1142 { 1142 {
1143 PRINT_VERBOSE("run curl"); 1143 PRINT_VERBOSE("run curl");
@@ -1151,7 +1151,7 @@ run ()
1151 } 1151 }
1152 /*break; 1152 /*break;
1153 }*/ 1153 }*/
1154 1154
1155 while ((msg = curl_multi_info_read(multi_handle, &msgs_left))) { 1155 while ((msg = curl_multi_info_read(multi_handle, &msgs_left))) {
1156 if (msg->msg == CURLMSG_DONE) { 1156 if (msg->msg == CURLMSG_DONE) {
1157 PRINT_VERBOSE("A curl handler is done"); 1157 PRINT_VERBOSE("A curl handler is done");
@@ -1218,39 +1218,40 @@ run ()
1218 } 1218 }
1219 else PRINT_INFO("shouldn't happen"); 1219 else PRINT_INFO("shouldn't happen");
1220 } 1220 }
1221 1221
1222 if(call_spdy_run) 1222 if(call_spdy_run)
1223 { 1223 {
1224 PRINT_VERBOSE("second call to SPDY_run"); 1224 PRINT_VERBOSE("second call to SPDY_run");
1225 SPDY_run(daemon); 1225 SPDY_run(daemon);
1226 call_spdy_run = false; 1226 call_spdy_run = false;
1227 } 1227 }
1228 1228
1229 if(glob_opt.verbose) 1229 if(glob_opt.verbose)
1230 { 1230 {
1231 1231
1232#ifdef HAVE_CLOCK_GETTIME 1232#ifdef HAVE_CLOCK_GETTIME
1233#ifdef CLOCK_MONOTONIC 1233#ifdef CLOCK_MONOTONIC
1234 struct timespec ts; 1234 struct timespec ts;
1235 1235
1236 if (0 == clock_gettime(CLOCK_MONOTONIC, &ts)) 1236 if (0 == clock_gettime(CLOCK_MONOTONIC, &ts))
1237 PRINT_VERBOSE2 ("time now %lld %lld", 1237 PRINT_VERBOSE2 ("time now %lld %lld",
1238 (unsigned long long) ts.tv_sec, 1238 (unsigned long long) ts.tv_sec,
1239 (unsigned long long) ts.tv_nsec); 1239 (unsigned long long) ts.tv_nsec);
1240 }
1241#endif 1240#endif
1242#endif 1241#endif
1242 }
1243
1243 } 1244 }
1244 while(loop); 1245 while(loop);
1245 1246
1246 SPDY_stop_daemon(daemon); 1247 SPDY_stop_daemon(daemon);
1247 1248
1248 curl_multi_cleanup(multi_handle); 1249 curl_multi_cleanup(multi_handle);
1249 1250
1250 SPDY_deinit(); 1251 SPDY_deinit();
1251 1252
1252 deinit_parse_uri(&uri_preg); 1253 deinit_parse_uri(&uri_preg);
1253 1254
1254 return 0; 1255 return 0;
1255} 1256}
1256 1257
@@ -1293,8 +1294,8 @@ display_usage()
1293 1294
1294int 1295int
1295main (int argc, char *const *argv) 1296main (int argc, char *const *argv)
1296{ 1297{
1297 1298
1298 int getopt_ret; 1299 int getopt_ret;
1299 int option_index; 1300 int option_index;
1300 struct option long_options[] = { 1301 struct option long_options[] = {
@@ -1313,7 +1314,7 @@ main (int argc, char *const *argv)
1313 {"timeout", required_argument, 0, 'T'}, 1314 {"timeout", required_argument, 0, 'T'},
1314 {0, 0, 0, 0} 1315 {0, 0, 0, 0}
1315 }; 1316 };
1316 1317
1317 while (1) 1318 while (1)
1318 { 1319 {
1319 getopt_ret = getopt_long( argc, argv, "p:l:c:k:b:rv0Dth46T:", long_options, &option_index); 1320 getopt_ret = getopt_long( argc, argv, "p:l:c:k:b:rv0Dth46T:", long_options, &option_index);
@@ -1325,76 +1326,76 @@ main (int argc, char *const *argv)
1325 case 'p': 1326 case 'p':
1326 glob_opt.listen_port = atoi(optarg); 1327 glob_opt.listen_port = atoi(optarg);
1327 break; 1328 break;
1328 1329
1329 case 'l': 1330 case 'l':
1330 glob_opt.listen_host= strdup(optarg); 1331 glob_opt.listen_host= strdup(optarg);
1331 if(NULL == glob_opt.listen_host) 1332 if(NULL == glob_opt.listen_host)
1332 return 1; 1333 return 1;
1333 break; 1334 break;
1334 1335
1335 case 'c': 1336 case 'c':
1336 glob_opt.cert = strdup(optarg); 1337 glob_opt.cert = strdup(optarg);
1337 break; 1338 break;
1338 1339
1339 case 'k': 1340 case 'k':
1340 glob_opt.cert_key = strdup(optarg); 1341 glob_opt.cert_key = strdup(optarg);
1341 break; 1342 break;
1342 1343
1343 case 'b': 1344 case 'b':
1344 glob_opt.http_backend = strdup(optarg); 1345 glob_opt.http_backend = strdup(optarg);
1345 if(NULL == glob_opt.http_backend) 1346 if(NULL == glob_opt.http_backend)
1346 return 1; 1347 return 1;
1347 break; 1348 break;
1348 1349
1349 case 'r': 1350 case 'r':
1350 glob_opt.notls = true; 1351 glob_opt.notls = true;
1351 break; 1352 break;
1352 1353
1353 case 'v': 1354 case 'v':
1354 glob_opt.verbose = true; 1355 glob_opt.verbose = true;
1355 break; 1356 break;
1356 1357
1357 case 'h': 1358 case 'h':
1358 glob_opt.curl_verbose = true; 1359 glob_opt.curl_verbose = true;
1359 break; 1360 break;
1360 1361
1361 case '0': 1362 case '0':
1362 glob_opt.http10 = true; 1363 glob_opt.http10 = true;
1363 break; 1364 break;
1364 1365
1365 case 'D': 1366 case 'D':
1366 glob_opt.nodelay = true; 1367 glob_opt.nodelay = true;
1367 break; 1368 break;
1368 1369
1369 case 't': 1370 case 't':
1370 glob_opt.transparent = true; 1371 glob_opt.transparent = true;
1371 break; 1372 break;
1372 1373
1373 case '4': 1374 case '4':
1374 glob_opt.ipv4 = true; 1375 glob_opt.ipv4 = true;
1375 break; 1376 break;
1376 1377
1377 case '6': 1378 case '6':
1378 glob_opt.ipv6 = true; 1379 glob_opt.ipv6 = true;
1379 break; 1380 break;
1380 1381
1381 case 'T': 1382 case 'T':
1382 glob_opt.timeout = atoi(optarg); 1383 glob_opt.timeout = atoi(optarg);
1383 break; 1384 break;
1384 1385
1385 case 0: 1386 case 0:
1386 PRINT_INFO("0 from getopt"); 1387 PRINT_INFO("0 from getopt");
1387 break; 1388 break;
1388 1389
1389 case '?': 1390 case '?':
1390 display_usage(); 1391 display_usage();
1391 return 1; 1392 return 1;
1392 1393
1393 default: 1394 default:
1394 DIE("default from getopt"); 1395 DIE("default from getopt");
1395 } 1396 }
1396 } 1397 }
1397 1398
1398 if( 1399 if(
1399 0 == glob_opt.listen_port 1400 0 == glob_opt.listen_port
1400 || (!glob_opt.notls && (NULL == glob_opt.cert || NULL == glob_opt.cert_key)) 1401 || (!glob_opt.notls && (NULL == glob_opt.cert || NULL == glob_opt.cert_key))
@@ -1404,7 +1405,7 @@ main (int argc, char *const *argv)
1404 display_usage(); 1405 display_usage();
1405 return 1; 1406 return 1;
1406 } 1407 }
1407 1408
1408 return run(); 1409 return run();
1409} 1410}
1410 1411