# HG changeset patch # User Daniel Atallah # Date 1211312966 0 # Node ID 2b91ea8c94d560b2274894cbc493b2cd68a5c367 # Parent c9592f5b3a522757774dda1071ce9cf8940a857c 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. diff -r c9592f5b3a52 -r 2b91ea8c94d5 libpurple/proxy.c --- a/libpurple/proxy.c Tue May 20 04:31:39 2008 +0000 +++ b/libpurple/proxy.c Tue May 20 19:49:26 2008 +0000 @@ -837,33 +837,10 @@ } static void -http_canwrite(gpointer data, gint source, PurpleInputCondition cond) -{ +http_start_connect_tunneling(PurpleProxyConnectData *connect_data) { GString *request; - PurpleProxyConnectData *connect_data; - int error = ETIMEDOUT; int ret; - connect_data = data; - - purple_debug_info("proxy", "Connected to %s:%d.\n", - connect_data->host, connect_data->port); - - if (connect_data->inpa > 0) - { - purple_input_remove(connect_data->inpa); - connect_data->inpa = 0; - } - - ret = purple_input_get_error(connect_data->fd, &error); - if ((ret != 0) || (error != 0)) - { - if (ret != 0) - error = errno; - purple_proxy_connect_data_disconnect(connect_data, g_strerror(error)); - return; - } - purple_debug_info("proxy", "Using CONNECT tunneling for %s:%d\n", connect_data->host, connect_data->port); @@ -912,7 +889,45 @@ connect_data->inpa = purple_input_add(connect_data->fd, PURPLE_INPUT_WRITE, proxy_do_write, connect_data); - proxy_do_write(connect_data, connect_data->fd, cond); + proxy_do_write(connect_data, connect_data->fd, PURPLE_INPUT_WRITE); +} + +static void +http_canwrite(gpointer data, gint source, PurpleInputCondition cond) { + PurpleProxyConnectData *connect_data = data; + int ret, error = ETIMEDOUT; + + purple_debug_info("proxy", "Connected to %s:%d.\n", + connect_data->host, connect_data->port); + + if (connect_data->inpa > 0) { + purple_input_remove(connect_data->inpa); + connect_data->inpa = 0; + } + + ret = purple_input_get_error(connect_data->fd, &error); + if (ret != 0 || error != 0) { + if (ret != 0) + error = errno; + purple_proxy_connect_data_disconnect(connect_data, g_strerror(error)); + return; + } + + if (connect_data->port == 80) { + /* + * If we're trying to connect to something running on + * port 80 then we assume the traffic using this + * connection is going to be HTTP traffic. If it's + * not then this will fail (uglily). But it's good + * to avoid using the CONNECT method because it's + * not always allowed. + */ + purple_debug_info("proxy", "HTTP proxy connection established\n"); + purple_proxy_connect_data_connected(connect_data); + } else { + http_start_connect_tunneling(connect_data); + } + } static void @@ -940,39 +955,15 @@ fcntl(connect_data->fd, F_SETFD, FD_CLOEXEC); #endif - if (connect(connect_data->fd, addr, addrlen) != 0) - { - if ((errno == EINPROGRESS) || (errno == EINTR)) - { + if (connect(connect_data->fd, addr, addrlen) != 0) { + if (errno == EINPROGRESS || errno == EINTR) { purple_debug_info("proxy", "Connection in progress\n"); - if (connect_data->port != 80) - { - /* we need to do CONNECT first */ - connect_data->inpa = purple_input_add(connect_data->fd, - PURPLE_INPUT_WRITE, http_canwrite, connect_data); - } - else - { - /* - * If we're trying to connect to something running on - * port 80 then we assume the traffic using this - * connection is going to be HTTP traffic. If it's - * not then this will fail (uglily). But it's good - * to avoid using the CONNECT method because it's - * not always allowed. - */ - purple_debug_info("proxy", "HTTP proxy connection established\n"); - purple_proxy_connect_data_connected(connect_data); - } - } - else - { + connect_data->inpa = purple_input_add(connect_data->fd, + PURPLE_INPUT_WRITE, http_canwrite, connect_data); + } else purple_proxy_connect_data_disconnect(connect_data, g_strerror(errno)); - } - } - else - { + } else { purple_debug_info("proxy", "Connected immediately.\n"); http_canwrite(connect_data, connect_data->fd, PURPLE_INPUT_WRITE);