src/proxy.c

changeset 7834
6a092463d774
parent 7652
d60ba2565661
child 7982
db8c1b6137eb
--- a/src/proxy.c	Thu Dec 11 19:28:00 2003 +0000
+++ b/src/proxy.c	Fri Dec 12 00:14:40 2003 +0000
@@ -196,11 +196,11 @@
 	if (condition & GAIM_WRITE_COND)
 		gaim_cond |= GAIM_INPUT_WRITE;
 
-	/*
+#if 0
 	gaim_debug(GAIM_DEBUG_MISC, "proxy",
 			   "CLOSURE: callback for %d, fd is %d\n",
 			   closure->result, g_io_channel_unix_get_fd(source));
-	*/
+#endif
 
 	closure->function(closure->data, g_io_channel_unix_get_fd(source), gaim_cond);
 
@@ -225,11 +225,11 @@
 	closure->result = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, cond,
 					      gaim_io_invoke, closure, gaim_io_destroy);
 
-	/*
+#if 0
 	gaim_debug(GAIM_DEBUG_MISC, "proxy",
 			   "CLOSURE: adding input watcher %d for fd %d\n",
 			   closure->result, source);
-	*/
+#endif
 
 	g_io_channel_unref(channel);
 	return closure->result;
@@ -937,6 +937,19 @@
 }
 #endif
 
+
+static void
+http_complete(struct PHB *phb, gint source)
+{
+	gaim_debug(GAIM_DEBUG_INFO, "http proxy", "proxy connection established\n");
+	if(!phb->account || phb->account->gc)
+		phb->func(phb->data, source, GAIM_INPUT_READ);
+	g_free(phb->host);
+	g_free(phb);
+}
+
+
+/* read the response to the CONNECT request, if we are requesting a non-port-80 tunnel */
 static void
 http_canread(gpointer data, gint source, GaimInputCondition cond)
 {
@@ -981,15 +994,22 @@
 	}
 	else if(status!=200) {
 		gaim_debug(GAIM_DEBUG_ERROR, "proxy",
-				   "Proxy server replied: (%s)\n", p);
-		close(source);
-		source=-1;
+				   "Proxy server replied with:\n%s\n", p);
+ 		close(source);
+		source = -1;
+		
+		if ( status == 403 /* Forbidden */ )
+			gaim_connection_error(phb->account->gc, _("Access denied: proxy server forbids port 80 tunnelling."));
+		else {
+			char *msg = g_strdup_printf(_("Proxy connection error %d"), status);
+			gaim_connection_error(phb->account->gc, msg);
+			g_free(msg);
+		}
+		
+	} else {
+		http_complete(phb, source);
 	}
-
-	if(!phb->account || phb->account->gc)
-		phb->func(phb->data, source, GAIM_INPUT_READ);
-	g_free(phb->host);
-	g_free(phb);
+	
 	return;
 }
 
@@ -1022,22 +1042,24 @@
 		g_free(phb);
 		return;
 	}
+
+	gaim_debug(GAIM_DEBUG_INFO, "proxy", "using CONNECT tunnelling for %s:%d\n", phb->host, phb->port);
 	request_len = g_snprintf(request, sizeof(request),
-							 "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n",
-							 phb->host, phb->port, phb->host, phb->port);
+				 "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n",
+				 phb->host, phb->port, phb->host, phb->port);
 
 	if (gaim_proxy_info_get_username(phb->gpi) != NULL) {
 		char *t1, *t2;
 		t1 = g_strdup_printf("%s:%s",
-							 gaim_proxy_info_get_username(phb->gpi),
-							 gaim_proxy_info_get_password(phb->gpi) ? 
-							 gaim_proxy_info_get_password(phb->gpi) : "");
+				     gaim_proxy_info_get_username(phb->gpi),
+				     gaim_proxy_info_get_password(phb->gpi) ? 
+				     gaim_proxy_info_get_password(phb->gpi) : "");
 		t2 = gaim_base64_encode(t1, strlen(t1));
 		g_free(t1);
 		g_return_if_fail(request_len < sizeof(request));
 		request_len += g_snprintf(request + request_len,
-								  sizeof(request) - request_len,
-								  "Proxy-Authorization: Basic %s\r\n", t2);
+					  sizeof(request) - request_len,
+					  "Proxy-Authorization: Basic %s\r\n", t2);
 		g_free(t2);
 	}
 
@@ -1059,6 +1081,7 @@
 		return;
 	}
 
+	/* register the response handler for the CONNECT request */
 	phb->inpa = gaim_input_add(source, GAIM_INPUT_READ, http_canread, phb);
 }
 
@@ -1083,8 +1106,14 @@
 		if ((errno == EINPROGRESS) || (errno == EINTR)) {
 			gaim_debug(GAIM_DEBUG_WARNING, "http proxy",
 					   "Connect would have blocked.\n");
-			phb->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE,
-									   http_canwrite, phb);
+			
+			if (phb->port != 80) {
+				/* we need to do CONNECT first */
+				phb->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE,
+							   http_canwrite, phb);
+			} else {
+				http_complete(phb, fd);
+			}
 		} else {
 			close(fd);
 			return -1;

mercurial