src/proxy.c

changeset 7834
6a092463d774
parent 7652
d60ba2565661
child 7982
db8c1b6137eb
equal deleted inserted replaced
7833:7bfbab3c59ec 7834:6a092463d774
194 if (condition & GAIM_READ_COND) 194 if (condition & GAIM_READ_COND)
195 gaim_cond |= GAIM_INPUT_READ; 195 gaim_cond |= GAIM_INPUT_READ;
196 if (condition & GAIM_WRITE_COND) 196 if (condition & GAIM_WRITE_COND)
197 gaim_cond |= GAIM_INPUT_WRITE; 197 gaim_cond |= GAIM_INPUT_WRITE;
198 198
199 /* 199 #if 0
200 gaim_debug(GAIM_DEBUG_MISC, "proxy", 200 gaim_debug(GAIM_DEBUG_MISC, "proxy",
201 "CLOSURE: callback for %d, fd is %d\n", 201 "CLOSURE: callback for %d, fd is %d\n",
202 closure->result, g_io_channel_unix_get_fd(source)); 202 closure->result, g_io_channel_unix_get_fd(source));
203 */ 203 #endif
204 204
205 closure->function(closure->data, g_io_channel_unix_get_fd(source), gaim_cond); 205 closure->function(closure->data, g_io_channel_unix_get_fd(source), gaim_cond);
206 206
207 return TRUE; 207 return TRUE;
208 } 208 }
223 223
224 channel = g_io_channel_unix_new(source); 224 channel = g_io_channel_unix_new(source);
225 closure->result = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, cond, 225 closure->result = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, cond,
226 gaim_io_invoke, closure, gaim_io_destroy); 226 gaim_io_invoke, closure, gaim_io_destroy);
227 227
228 /* 228 #if 0
229 gaim_debug(GAIM_DEBUG_MISC, "proxy", 229 gaim_debug(GAIM_DEBUG_MISC, "proxy",
230 "CLOSURE: adding input watcher %d for fd %d\n", 230 "CLOSURE: adding input watcher %d for fd %d\n",
231 closure->result, source); 231 closure->result, source);
232 */ 232 #endif
233 233
234 g_io_channel_unref(channel); 234 g_io_channel_unref(channel);
235 return closure->result; 235 return closure->result;
236 } 236 }
237 237
935 935
936 return TRUE; 936 return TRUE;
937 } 937 }
938 #endif 938 #endif
939 939
940
941 static void
942 http_complete(struct PHB *phb, gint source)
943 {
944 gaim_debug(GAIM_DEBUG_INFO, "http proxy", "proxy connection established\n");
945 if(!phb->account || phb->account->gc)
946 phb->func(phb->data, source, GAIM_INPUT_READ);
947 g_free(phb->host);
948 g_free(phb);
949 }
950
951
952 /* read the response to the CONNECT request, if we are requesting a non-port-80 tunnel */
940 static void 953 static void
941 http_canread(gpointer data, gint source, GaimInputCondition cond) 954 http_canread(gpointer data, gint source, GaimInputCondition cond)
942 { 955 {
943 int nlc = 0; 956 int nlc = 0;
944 int pos = 0; 957 int pos = 0;
979 close(source); 992 close(source);
980 source=-1; 993 source=-1;
981 } 994 }
982 else if(status!=200) { 995 else if(status!=200) {
983 gaim_debug(GAIM_DEBUG_ERROR, "proxy", 996 gaim_debug(GAIM_DEBUG_ERROR, "proxy",
984 "Proxy server replied: (%s)\n", p); 997 "Proxy server replied with:\n%s\n", p);
985 close(source); 998 close(source);
986 source=-1; 999 source = -1;
987 } 1000
988 1001 if ( status == 403 /* Forbidden */ )
989 if(!phb->account || phb->account->gc) 1002 gaim_connection_error(phb->account->gc, _("Access denied: proxy server forbids port 80 tunnelling."));
990 phb->func(phb->data, source, GAIM_INPUT_READ); 1003 else {
991 g_free(phb->host); 1004 char *msg = g_strdup_printf(_("Proxy connection error %d"), status);
992 g_free(phb); 1005 gaim_connection_error(phb->account->gc, msg);
1006 g_free(msg);
1007 }
1008
1009 } else {
1010 http_complete(phb, source);
1011 }
1012
993 return; 1013 return;
994 } 1014 }
995 1015
996 static void 1016 static void
997 http_canwrite(gpointer data, gint source, GaimInputCondition cond) 1017 http_canwrite(gpointer data, gint source, GaimInputCondition cond)
1020 1040
1021 g_free(phb->host); 1041 g_free(phb->host);
1022 g_free(phb); 1042 g_free(phb);
1023 return; 1043 return;
1024 } 1044 }
1045
1046 gaim_debug(GAIM_DEBUG_INFO, "proxy", "using CONNECT tunnelling for %s:%d\n", phb->host, phb->port);
1025 request_len = g_snprintf(request, sizeof(request), 1047 request_len = g_snprintf(request, sizeof(request),
1026 "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n", 1048 "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n",
1027 phb->host, phb->port, phb->host, phb->port); 1049 phb->host, phb->port, phb->host, phb->port);
1028 1050
1029 if (gaim_proxy_info_get_username(phb->gpi) != NULL) { 1051 if (gaim_proxy_info_get_username(phb->gpi) != NULL) {
1030 char *t1, *t2; 1052 char *t1, *t2;
1031 t1 = g_strdup_printf("%s:%s", 1053 t1 = g_strdup_printf("%s:%s",
1032 gaim_proxy_info_get_username(phb->gpi), 1054 gaim_proxy_info_get_username(phb->gpi),
1033 gaim_proxy_info_get_password(phb->gpi) ? 1055 gaim_proxy_info_get_password(phb->gpi) ?
1034 gaim_proxy_info_get_password(phb->gpi) : ""); 1056 gaim_proxy_info_get_password(phb->gpi) : "");
1035 t2 = gaim_base64_encode(t1, strlen(t1)); 1057 t2 = gaim_base64_encode(t1, strlen(t1));
1036 g_free(t1); 1058 g_free(t1);
1037 g_return_if_fail(request_len < sizeof(request)); 1059 g_return_if_fail(request_len < sizeof(request));
1038 request_len += g_snprintf(request + request_len, 1060 request_len += g_snprintf(request + request_len,
1039 sizeof(request) - request_len, 1061 sizeof(request) - request_len,
1040 "Proxy-Authorization: Basic %s\r\n", t2); 1062 "Proxy-Authorization: Basic %s\r\n", t2);
1041 g_free(t2); 1063 g_free(t2);
1042 } 1064 }
1043 1065
1044 g_return_if_fail(request_len < sizeof(request)); 1066 g_return_if_fail(request_len < sizeof(request));
1045 strcpy(request + request_len, "\r\n"); 1067 strcpy(request + request_len, "\r\n");
1057 g_free(phb->host); 1079 g_free(phb->host);
1058 g_free(phb); 1080 g_free(phb);
1059 return; 1081 return;
1060 } 1082 }
1061 1083
1084 /* register the response handler for the CONNECT request */
1062 phb->inpa = gaim_input_add(source, GAIM_INPUT_READ, http_canread, phb); 1085 phb->inpa = gaim_input_add(source, GAIM_INPUT_READ, http_canread, phb);
1063 } 1086 }
1064 1087
1065 static int 1088 static int
1066 proxy_connect_http(struct PHB *phb, struct sockaddr *addr, socklen_t addrlen) 1089 proxy_connect_http(struct PHB *phb, struct sockaddr *addr, socklen_t addrlen)
1081 1104
1082 if (connect(fd, addr, addrlen) < 0) { 1105 if (connect(fd, addr, addrlen) < 0) {
1083 if ((errno == EINPROGRESS) || (errno == EINTR)) { 1106 if ((errno == EINPROGRESS) || (errno == EINTR)) {
1084 gaim_debug(GAIM_DEBUG_WARNING, "http proxy", 1107 gaim_debug(GAIM_DEBUG_WARNING, "http proxy",
1085 "Connect would have blocked.\n"); 1108 "Connect would have blocked.\n");
1086 phb->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE, 1109
1087 http_canwrite, phb); 1110 if (phb->port != 80) {
1111 /* we need to do CONNECT first */
1112 phb->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE,
1113 http_canwrite, phb);
1114 } else {
1115 http_complete(phb, fd);
1116 }
1088 } else { 1117 } else {
1089 close(fd); 1118 close(fd);
1090 return -1; 1119 return -1;
1091 } 1120 }
1092 } 1121 }

mercurial