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 }