diff options
Diffstat (limited to 'src/spdy2http/proxy.c')
-rw-r--r-- | src/spdy2http/proxy.c | 158 |
1 files changed, 90 insertions, 68 deletions
diff --git a/src/spdy2http/proxy.c b/src/spdy2http/proxy.c index c5011ae3..22c0a40b 100644 --- a/src/spdy2http/proxy.c +++ b/src/spdy2http/proxy.c | |||
@@ -139,6 +139,9 @@ static int still_running = 0; /* keep number of running handles */ | |||
139 | 139 | ||
140 | static regex_t uri_preg; | 140 | static regex_t uri_preg; |
141 | 141 | ||
142 | static bool call_spdy_run; | ||
143 | static bool call_curl_run; | ||
144 | |||
142 | 145 | ||
143 | struct Proxy | 146 | struct Proxy |
144 | { | 147 | { |
@@ -429,6 +432,8 @@ curl_header_cb(void *ptr, size_t size, size_t nmemb, void *userp) | |||
429 | proxy)) | 432 | proxy)) |
430 | DIE("no queue"); | 433 | DIE("no queue"); |
431 | 434 | ||
435 | call_spdy_run = true; | ||
436 | |||
432 | return realsize; | 437 | return realsize; |
433 | } | 438 | } |
434 | 439 | ||
@@ -545,6 +550,8 @@ curl_write_cb(void *contents, size_t size, size_t nmemb, void *userp) | |||
545 | 550 | ||
546 | PRINT_VERBOSE2("received bytes from curl: %zu", realsize); | 551 | PRINT_VERBOSE2("received bytes from curl: %zu", realsize); |
547 | 552 | ||
553 | call_spdy_run = true; | ||
554 | |||
548 | return realsize; | 555 | return realsize; |
549 | } | 556 | } |
550 | 557 | ||
@@ -609,6 +616,7 @@ standard_request_handler(void *cls, | |||
609 | struct SPDY_Session *session; | 616 | struct SPDY_Session *session; |
610 | 617 | ||
611 | PRINT_VERBOSE2("received request for '%s %s %s'\n", method, path, version); | 618 | PRINT_VERBOSE2("received request for '%s %s %s'\n", method, path, version); |
619 | |||
612 | if(NULL == (proxy = malloc(sizeof(struct Proxy)))) | 620 | if(NULL == (proxy = malloc(sizeof(struct Proxy)))) |
613 | DIE("No memory"); | 621 | DIE("No memory"); |
614 | memset(proxy, 0, sizeof(struct Proxy)); | 622 | memset(proxy, 0, sizeof(struct Proxy)); |
@@ -688,30 +696,38 @@ standard_request_handler(void *cls, | |||
688 | PRINT_INFO2("curl_multi_add_handle failed (%i)", ret); | 696 | PRINT_INFO2("curl_multi_add_handle failed (%i)", ret); |
689 | abort(); | 697 | abort(); |
690 | } | 698 | } |
691 | 699 | ||
700 | //~5ms additional latency for calling this | ||
692 | if(CURLM_OK != (ret = curl_multi_perform(multi_handle, &still_running)) | 701 | if(CURLM_OK != (ret = curl_multi_perform(multi_handle, &still_running)) |
693 | && CURLM_CALL_MULTI_PERFORM != ret) | 702 | && CURLM_CALL_MULTI_PERFORM != ret) |
694 | { | 703 | { |
695 | PRINT_INFO2("curl_multi_perform failed (%i)", ret); | 704 | PRINT_INFO2("curl_multi_perform failed (%i)", ret); |
696 | abort(); | 705 | abort(); |
697 | } | 706 | } |
707 | |||
708 | call_curl_run = true; | ||
698 | } | 709 | } |
699 | 710 | ||
700 | 711 | ||
701 | static int | 712 | static int |
702 | run () | 713 | run () |
703 | { | 714 | { |
704 | unsigned long long timeoutlong=0; | 715 | unsigned long long timeoutlong = 0; |
705 | long curl_timeo = -1; | 716 | unsigned long long timeout_spdy = 0; |
717 | long timeout_curl = -1; | ||
706 | struct timeval timeout; | 718 | struct timeval timeout; |
707 | int ret; | 719 | int ret; |
720 | //int ret2; | ||
721 | int ret_curl; | ||
722 | int ret_spdy; | ||
708 | fd_set rs; | 723 | fd_set rs; |
709 | fd_set ws; | 724 | fd_set ws; |
710 | fd_set es; | 725 | fd_set es; |
711 | fd_set curl_rs; | 726 | //fd_set curl_rs; |
712 | fd_set curl_ws; | 727 | //fd_set curl_ws; |
713 | fd_set curl_es; | 728 | //fd_set curl_es; |
714 | int maxfd = -1; | 729 | int maxfd = -1; |
730 | int maxfd_curl = -1; | ||
715 | struct SPDY_Daemon *daemon; | 731 | struct SPDY_Daemon *daemon; |
716 | CURLMsg *msg; | 732 | CURLMsg *msg; |
717 | int msgs_left; | 733 | int msgs_left; |
@@ -803,87 +819,77 @@ run () | |||
803 | FD_ZERO(&rs); | 819 | FD_ZERO(&rs); |
804 | FD_ZERO(&ws); | 820 | FD_ZERO(&ws); |
805 | FD_ZERO(&es); | 821 | FD_ZERO(&es); |
806 | FD_ZERO(&curl_rs); | 822 | |
807 | FD_ZERO(&curl_ws); | 823 | ret_spdy = SPDY_get_timeout(daemon, &timeout_spdy); |
808 | FD_ZERO(&curl_es); | 824 | if(SPDY_NO == ret_spdy || timeout_spdy > 5000) |
809 | 825 | timeoutlong = 5000; | |
810 | if(still_running > 0) | 826 | else |
811 | timeout.tv_sec = 0; //return immediately | 827 | timeoutlong = timeout_spdy; |
812 | else | 828 | PRINT_VERBOSE2("SPDY timeout %i; %i", timeout_spdy, ret_spdy); |
813 | { | 829 | |
814 | ret = SPDY_get_timeout(daemon, &timeoutlong); | 830 | if(CURLM_OK != (ret_curl = curl_multi_timeout(multi_handle, &timeout_curl))) |
815 | if(SPDY_NO == ret) | 831 | { |
816 | timeout.tv_sec = 1; | 832 | PRINT_VERBOSE2("curl_multi_timeout failed (%i)", ret_curl); |
817 | else | 833 | //curl_timeo = timeoutlong; |
818 | timeout.tv_sec = timeoutlong; | 834 | } |
819 | } | 835 | else if(timeoutlong > timeout_curl) |
820 | timeout.tv_usec = 0; | 836 | timeoutlong = timeout_curl; |
821 | 837 | ||
838 | PRINT_VERBOSE2("curl timeout %i", timeout_curl); | ||
839 | |||
840 | timeout.tv_sec = timeoutlong / 1000; | ||
841 | timeout.tv_usec = (timeoutlong % 1000) * 1000; | ||
842 | |||
822 | maxfd = SPDY_get_fdset (daemon, | 843 | maxfd = SPDY_get_fdset (daemon, |
823 | &rs, | 844 | &rs, |
824 | &ws, | 845 | &ws, |
825 | &es); | 846 | &es); |
826 | assert(-1 != maxfd); | 847 | assert(-1 != maxfd); |
827 | |||
828 | ret = select(maxfd+1, &rs, &ws, &es, &timeout); | ||
829 | |||
830 | switch(ret) { | ||
831 | case -1: | ||
832 | PRINT_INFO2("select error: %i", errno); | ||
833 | break; | ||
834 | case 0: | ||
835 | break; | ||
836 | default: | ||
837 | PRINT_VERBOSE("run"); | ||
838 | SPDY_run(daemon); | ||
839 | break; | ||
840 | } | ||
841 | |||
842 | timeout.tv_sec = 0; | ||
843 | if(still_running > 0) | ||
844 | { | ||
845 | if(CURLM_OK != (ret = curl_multi_timeout(multi_handle, &curl_timeo))) | ||
846 | { | ||
847 | PRINT_INFO2("curl_multi_timeout failed (%i)", ret); | ||
848 | abort(); | ||
849 | } | ||
850 | if(curl_timeo >= 0 && curl_timeo < 500) | ||
851 | timeout.tv_usec = curl_timeo * 1000; | ||
852 | else | ||
853 | timeout.tv_usec = 500000; | ||
854 | } | ||
855 | else continue; | ||
856 | //else timeout.tv_usec = 500000; | ||
857 | 848 | ||
858 | if(CURLM_OK != (ret = curl_multi_fdset(multi_handle, &curl_rs, &curl_ws, &curl_es, &maxfd))) | 849 | if(CURLM_OK != (ret = curl_multi_fdset(multi_handle, &rs, |
850 | &ws, | ||
851 | &es, &maxfd_curl))) | ||
859 | { | 852 | { |
860 | PRINT_INFO2("curl_multi_fdset failed (%i)", ret); | 853 | PRINT_INFO2("curl_multi_fdset failed (%i)", ret); |
861 | abort(); | 854 | abort(); |
862 | } | 855 | } |
863 | if(-1 == maxfd) | 856 | |
864 | { | 857 | if(maxfd_curl > maxfd) |
865 | PRINT_INFO("maxfd is -1"); | 858 | maxfd = maxfd_curl; |
866 | //continue; | 859 | |
867 | ret = 0; | 860 | PRINT_VERBOSE2("timeout before %i %i", timeout.tv_sec, timeout.tv_usec); |
868 | } | 861 | ret = select(maxfd+1, &rs, &ws, &es, &timeout); |
869 | else | 862 | PRINT_VERBOSE2("timeout after %i %i; ret is %i", timeout.tv_sec, timeout.tv_usec, ret); |
870 | ret = select(maxfd+1, &curl_rs, &curl_ws, &curl_es, &timeout); | 863 | |
871 | 864 | /*switch(ret) { | |
872 | switch(ret) { | ||
873 | case -1: | 865 | case -1: |
874 | PRINT_INFO2("select error: %i", errno); | 866 | PRINT_INFO2("select error: %i", errno); |
875 | break; | 867 | break; |
876 | case 0: /* timeout */ | 868 | case 0: |
877 | //break or not | 869 | break; |
878 | default: /* action */ | 870 | default:*/ |
871 | |||
872 | //the second part should not happen with current implementation | ||
873 | if(ret > 0 || (SPDY_YES == ret_spdy && 0 == timeout_spdy)) | ||
874 | { | ||
875 | PRINT_VERBOSE("run spdy"); | ||
876 | SPDY_run(daemon); | ||
877 | call_spdy_run = false; | ||
878 | } | ||
879 | |||
880 | if(ret > 0 || (CURLM_OK == ret_curl && 0 == timeout_curl) || call_curl_run) | ||
881 | { | ||
882 | PRINT_VERBOSE("run curl"); | ||
879 | if(CURLM_OK != (ret = curl_multi_perform(multi_handle, &still_running)) | 883 | if(CURLM_OK != (ret = curl_multi_perform(multi_handle, &still_running)) |
880 | && CURLM_CALL_MULTI_PERFORM != ret) | 884 | && CURLM_CALL_MULTI_PERFORM != ret) |
881 | { | 885 | { |
882 | PRINT_INFO2("curl_multi_perform failed (%i)", ret); | 886 | PRINT_INFO2("curl_multi_perform failed (%i)", ret); |
883 | abort(); | 887 | abort(); |
884 | } | 888 | } |
885 | break; | 889 | call_curl_run = false; |
886 | } | 890 | } |
891 | /*break; | ||
892 | }*/ | ||
887 | 893 | ||
888 | while ((msg = curl_multi_info_read(multi_handle, &msgs_left))) { | 894 | while ((msg = curl_multi_info_read(multi_handle, &msgs_left))) { |
889 | if (msg->msg == CURLMSG_DONE) { | 895 | if (msg->msg == CURLMSG_DONE) { |
@@ -896,6 +902,7 @@ run () | |||
896 | } | 902 | } |
897 | 903 | ||
898 | proxy->done = true; | 904 | proxy->done = true; |
905 | call_spdy_run = true; | ||
899 | } | 906 | } |
900 | else | 907 | else |
901 | { | 908 | { |
@@ -905,6 +912,21 @@ run () | |||
905 | } | 912 | } |
906 | else PRINT_INFO("shouldn't happen"); | 913 | else PRINT_INFO("shouldn't happen"); |
907 | } | 914 | } |
915 | |||
916 | if(call_spdy_run) | ||
917 | { | ||
918 | PRINT_VERBOSE("second call to SPDY_run"); | ||
919 | SPDY_run(daemon); | ||
920 | call_spdy_run = false; | ||
921 | } | ||
922 | |||
923 | if(glob_opt.verbose) | ||
924 | { | ||
925 | |||
926 | struct timespec ts; | ||
927 | if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) | ||
928 | PRINT_VERBOSE2("time now %i %i", ts.tv_sec, ts.tv_nsec); | ||
929 | } | ||
908 | } | 930 | } |
909 | while(loop); | 931 | while(loop); |
910 | 932 | ||