Mercurial > pidgin.yaz
comparison libpurple/proxy.c @ 23012:2b91ea8c94d5
Rearrange some of the HTTP proxy handling to make sure that we're actually
connected to the proxy server before calling the callback (in the case where
we were trying to bypass CONNECT tunneling, that wasn't happening).
Thanks to dasvo for tracking down what was happening. Fixes #5057.
author | Daniel Atallah <daniel.atallah@gmail.com> |
---|---|
date | Tue, 20 May 2008 19:49:26 +0000 |
parents | d0f933c88fc6 |
children | 313b87adb730 |
comparison
equal
deleted
inserted
replaced
23011:c9592f5b3a52 | 23012:2b91ea8c94d5 |
---|---|
835 return; | 835 return; |
836 } | 836 } |
837 } | 837 } |
838 | 838 |
839 static void | 839 static void |
840 http_canwrite(gpointer data, gint source, PurpleInputCondition cond) | 840 http_start_connect_tunneling(PurpleProxyConnectData *connect_data) { |
841 { | |
842 GString *request; | 841 GString *request; |
843 PurpleProxyConnectData *connect_data; | |
844 int error = ETIMEDOUT; | |
845 int ret; | 842 int ret; |
846 | |
847 connect_data = data; | |
848 | |
849 purple_debug_info("proxy", "Connected to %s:%d.\n", | |
850 connect_data->host, connect_data->port); | |
851 | |
852 if (connect_data->inpa > 0) | |
853 { | |
854 purple_input_remove(connect_data->inpa); | |
855 connect_data->inpa = 0; | |
856 } | |
857 | |
858 ret = purple_input_get_error(connect_data->fd, &error); | |
859 if ((ret != 0) || (error != 0)) | |
860 { | |
861 if (ret != 0) | |
862 error = errno; | |
863 purple_proxy_connect_data_disconnect(connect_data, g_strerror(error)); | |
864 return; | |
865 } | |
866 | 843 |
867 purple_debug_info("proxy", "Using CONNECT tunneling for %s:%d\n", | 844 purple_debug_info("proxy", "Using CONNECT tunneling for %s:%d\n", |
868 connect_data->host, connect_data->port); | 845 connect_data->host, connect_data->port); |
869 | 846 |
870 request = g_string_sized_new(4096); | 847 request = g_string_sized_new(4096); |
910 connect_data->written_len = 0; | 887 connect_data->written_len = 0; |
911 connect_data->read_cb = http_canread; | 888 connect_data->read_cb = http_canread; |
912 | 889 |
913 connect_data->inpa = purple_input_add(connect_data->fd, | 890 connect_data->inpa = purple_input_add(connect_data->fd, |
914 PURPLE_INPUT_WRITE, proxy_do_write, connect_data); | 891 PURPLE_INPUT_WRITE, proxy_do_write, connect_data); |
915 proxy_do_write(connect_data, connect_data->fd, cond); | 892 proxy_do_write(connect_data, connect_data->fd, PURPLE_INPUT_WRITE); |
893 } | |
894 | |
895 static void | |
896 http_canwrite(gpointer data, gint source, PurpleInputCondition cond) { | |
897 PurpleProxyConnectData *connect_data = data; | |
898 int ret, error = ETIMEDOUT; | |
899 | |
900 purple_debug_info("proxy", "Connected to %s:%d.\n", | |
901 connect_data->host, connect_data->port); | |
902 | |
903 if (connect_data->inpa > 0) { | |
904 purple_input_remove(connect_data->inpa); | |
905 connect_data->inpa = 0; | |
906 } | |
907 | |
908 ret = purple_input_get_error(connect_data->fd, &error); | |
909 if (ret != 0 || error != 0) { | |
910 if (ret != 0) | |
911 error = errno; | |
912 purple_proxy_connect_data_disconnect(connect_data, g_strerror(error)); | |
913 return; | |
914 } | |
915 | |
916 if (connect_data->port == 80) { | |
917 /* | |
918 * If we're trying to connect to something running on | |
919 * port 80 then we assume the traffic using this | |
920 * connection is going to be HTTP traffic. If it's | |
921 * not then this will fail (uglily). But it's good | |
922 * to avoid using the CONNECT method because it's | |
923 * not always allowed. | |
924 */ | |
925 purple_debug_info("proxy", "HTTP proxy connection established\n"); | |
926 purple_proxy_connect_data_connected(connect_data); | |
927 } else { | |
928 http_start_connect_tunneling(connect_data); | |
929 } | |
930 | |
916 } | 931 } |
917 | 932 |
918 static void | 933 static void |
919 proxy_connect_http(PurpleProxyConnectData *connect_data, struct sockaddr *addr, socklen_t addrlen) | 934 proxy_connect_http(PurpleProxyConnectData *connect_data, struct sockaddr *addr, socklen_t addrlen) |
920 { | 935 { |
938 fcntl(connect_data->fd, F_SETFL, flags | O_NONBLOCK); | 953 fcntl(connect_data->fd, F_SETFL, flags | O_NONBLOCK); |
939 #ifndef _WIN32 | 954 #ifndef _WIN32 |
940 fcntl(connect_data->fd, F_SETFD, FD_CLOEXEC); | 955 fcntl(connect_data->fd, F_SETFD, FD_CLOEXEC); |
941 #endif | 956 #endif |
942 | 957 |
943 if (connect(connect_data->fd, addr, addrlen) != 0) | 958 if (connect(connect_data->fd, addr, addrlen) != 0) { |
944 { | 959 if (errno == EINPROGRESS || errno == EINTR) { |
945 if ((errno == EINPROGRESS) || (errno == EINTR)) | |
946 { | |
947 purple_debug_info("proxy", "Connection in progress\n"); | 960 purple_debug_info("proxy", "Connection in progress\n"); |
948 | 961 |
949 if (connect_data->port != 80) | 962 connect_data->inpa = purple_input_add(connect_data->fd, |
950 { | 963 PURPLE_INPUT_WRITE, http_canwrite, connect_data); |
951 /* we need to do CONNECT first */ | 964 } else |
952 connect_data->inpa = purple_input_add(connect_data->fd, | |
953 PURPLE_INPUT_WRITE, http_canwrite, connect_data); | |
954 } | |
955 else | |
956 { | |
957 /* | |
958 * If we're trying to connect to something running on | |
959 * port 80 then we assume the traffic using this | |
960 * connection is going to be HTTP traffic. If it's | |
961 * not then this will fail (uglily). But it's good | |
962 * to avoid using the CONNECT method because it's | |
963 * not always allowed. | |
964 */ | |
965 purple_debug_info("proxy", "HTTP proxy connection established\n"); | |
966 purple_proxy_connect_data_connected(connect_data); | |
967 } | |
968 } | |
969 else | |
970 { | |
971 purple_proxy_connect_data_disconnect(connect_data, g_strerror(errno)); | 965 purple_proxy_connect_data_disconnect(connect_data, g_strerror(errno)); |
972 } | 966 } else { |
973 } | |
974 else | |
975 { | |
976 purple_debug_info("proxy", "Connected immediately.\n"); | 967 purple_debug_info("proxy", "Connected immediately.\n"); |
977 | 968 |
978 http_canwrite(connect_data, connect_data->fd, PURPLE_INPUT_WRITE); | 969 http_canwrite(connect_data, connect_data->fd, PURPLE_INPUT_WRITE); |
979 } | 970 } |
980 } | 971 } |