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.c158
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
140static regex_t uri_preg; 140static regex_t uri_preg;
141 141
142static bool call_spdy_run;
143static bool call_curl_run;
144
142 145
143struct Proxy 146struct 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
701static int 712static int
702run () 713run ()
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