Mercurial > pidgin
annotate libgaim/protocols/msn/httpconn.c @ 20391:0b0ecee55091
The second msn.tgz from SF Patch #1621854 from Ka-Hing Cheung.
"new version, fixes some crashes because group_id is char * but in some
places it's set to an int (!). skadotnet, I don't understand why you need
`if (!strcmp(type, "MFN")) {` in so many places, so I didn't include most
of them. I also have different versions of some of your fixes because I
already fixed them.
Group manipulations may still not work, at least it's not crashing :-)"
committer: Richard Laager <rlaager@wiktel.com>
author | Ka-Hing Cheung <khc@hxbc.us> |
---|---|
date | Sun, 15 Apr 2007 02:43:47 +0000 |
parents | c157efddc62a |
children |
rev | line source |
---|---|
14192 | 1 /** |
2 * @file httpmethod.c HTTP connection method | |
3 * | |
4 * gaim | |
5 * | |
6 * Gaim is the legal property of its developers, whose names are too numerous | |
7 * to list here. Please refer to the COPYRIGHT file distributed with this | |
8 * source distribution. | |
9 * | |
10 * This program is free software; you can redistribute it and/or modify | |
11 * it under the terms of the GNU General Public License as published by | |
12 * the Free Software Foundation; either version 2 of the License, or | |
13 * (at your option) any later version. | |
14 * | |
15 * This program is distributed in the hope that it will be useful, | |
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 * GNU General Public License for more details. | |
19 * | |
20 * You should have received a copy of the GNU General Public License | |
21 * along with this program; if not, write to the Free Software | |
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
23 */ | |
24 #include "msn.h" | |
25 #include "debug.h" | |
26 #include "httpconn.h" | |
27 | |
28 typedef struct | |
29 { | |
30 MsnHttpConn *httpconn; | |
31 char *body; | |
32 size_t body_len; | |
33 } MsnHttpQueueData; | |
34 | |
35 static void | |
36 msn_httpconn_process_queue(MsnHttpConn *httpconn) | |
37 { | |
38 httpconn->waiting_response = FALSE; | |
39 | |
40 if (httpconn->queue != NULL) | |
41 { | |
42 MsnHttpQueueData *queue_data; | |
43 | |
44 queue_data = (MsnHttpQueueData *)httpconn->queue->data; | |
45 | |
46 httpconn->queue = g_list_remove(httpconn->queue, queue_data); | |
47 | |
48 msn_httpconn_write(queue_data->httpconn, | |
49 queue_data->body, | |
50 queue_data->body_len); | |
51 | |
52 g_free(queue_data->body); | |
53 g_free(queue_data); | |
54 } | |
55 } | |
56 | |
57 static gboolean | |
58 msn_httpconn_parse_data(MsnHttpConn *httpconn, const char *buf, | |
59 size_t size, char **ret_buf, size_t *ret_size, | |
60 gboolean *error) | |
61 { | |
62 const char *s, *c; | |
63 char *header, *body; | |
64 const char *body_start; | |
65 char *tmp; | |
66 size_t body_len = 0; | |
67 gboolean wasted = FALSE; | |
68 | |
69 g_return_val_if_fail(httpconn != NULL, FALSE); | |
70 g_return_val_if_fail(buf != NULL, FALSE); | |
71 g_return_val_if_fail(size > 0, FALSE); | |
72 g_return_val_if_fail(ret_buf != NULL, FALSE); | |
73 g_return_val_if_fail(ret_size != NULL, FALSE); | |
74 g_return_val_if_fail(error != NULL, FALSE); | |
75 | |
76 #if 0 | |
77 gaim_debug_info("msn", "HTTP: parsing data {%s}\n", buf); | |
78 #endif | |
79 | |
80 /* Healthy defaults. */ | |
81 body = NULL; | |
82 | |
83 *ret_buf = NULL; | |
84 *ret_size = 0; | |
85 *error = FALSE; | |
86 | |
87 /* First, some tests to see if we have a full block of stuff. */ | |
88 if (((strncmp(buf, "HTTP/1.1 200 OK\r\n", 17) != 0) && | |
89 (strncmp(buf, "HTTP/1.1 100 Continue\r\n", 23) != 0)) && | |
90 ((strncmp(buf, "HTTP/1.0 200 OK\r\n", 17) != 0) && | |
91 (strncmp(buf, "HTTP/1.0 100 Continue\r\n", 23) != 0))) | |
92 { | |
93 *error = TRUE; | |
94 | |
95 return FALSE; | |
96 } | |
97 | |
98 if (strncmp(buf, "HTTP/1.1 100 Continue\r\n", 23) == 0) | |
99 { | |
100 if ((s = strstr(buf, "\r\n\r\n")) == NULL) | |
101 return FALSE; | |
102 | |
103 s += 4; | |
104 | |
105 if (*s == '\0') | |
106 { | |
107 *ret_buf = g_strdup(""); | |
108 *ret_size = 0; | |
109 | |
110 msn_httpconn_process_queue(httpconn); | |
111 | |
112 return TRUE; | |
113 } | |
114 | |
115 buf = s; | |
116 size -= (s - buf); | |
117 } | |
118 | |
119 if ((s = strstr(buf, "\r\n\r\n")) == NULL) | |
120 /* Need to wait for the full HTTP header to arrive */ | |
121 return FALSE; | |
122 | |
123 s += 4; /* Skip \r\n */ | |
124 header = g_strndup(buf, s - buf); | |
125 body_start = s; | |
126 body_len = size - (body_start - buf); | |
127 | |
128 if ((s = gaim_strcasestr(header, "Content-Length: ")) != NULL) | |
129 { | |
130 int tmp_len; | |
131 | |
132 s += strlen("Content-Length: "); | |
133 | |
134 if ((c = strchr(s, '\r')) == NULL) | |
135 { | |
136 g_free(header); | |
137 | |
138 return FALSE; | |
139 } | |
140 | |
141 tmp = g_strndup(s, c - s); | |
142 tmp_len = atoi(tmp); | |
143 g_free(tmp); | |
144 | |
145 if (body_len != tmp_len) | |
146 { | |
147 /* Need to wait for the full packet to arrive */ | |
148 | |
149 g_free(header); | |
150 | |
151 #if 0 | |
152 gaim_debug_warning("msn", | |
153 "body length (%d) != content length (%d)\n", | |
154 body_len, tmp_len); | |
155 #endif | |
156 | |
157 return FALSE; | |
158 } | |
159 } | |
160 | |
161 body = g_malloc0(body_len + 1); | |
162 memcpy(body, body_start, body_len); | |
163 | |
164 #ifdef MSN_DEBUG_HTTP | |
165 gaim_debug_misc("msn", "Incoming HTTP buffer (header): {%s\r\n}\n", | |
166 header); | |
167 #endif | |
168 | |
169 /* Now we should be able to process the data. */ | |
170 if ((s = gaim_strcasestr(header, "X-MSN-Messenger: ")) != NULL) | |
171 { | |
172 char *full_session_id, *gw_ip, *session_action; | |
173 char *t, *session_id; | |
174 char **elems, **cur, **tokens; | |
175 | |
176 full_session_id = gw_ip = session_action = NULL; | |
177 | |
178 s += strlen("X-MSN-Messenger: "); | |
179 | |
180 if ((c = strchr(s, '\r')) == NULL) | |
181 { | |
182 msn_session_set_error(httpconn->session, | |
183 MSN_ERROR_HTTP_MALFORMED, NULL); | |
184 gaim_debug_error("msn", "Malformed X-MSN-Messenger field.\n{%s}", | |
185 buf); | |
186 | |
187 g_free(body); | |
188 return FALSE; | |
189 } | |
190 | |
191 tmp = g_strndup(s, c - s); | |
192 | |
193 elems = g_strsplit(tmp, "; ", 0); | |
194 | |
195 for (cur = elems; *cur != NULL; cur++) | |
196 { | |
197 tokens = g_strsplit(*cur, "=", 2); | |
198 | |
199 if (strcmp(tokens[0], "SessionID") == 0) | |
200 full_session_id = tokens[1]; | |
201 else if (strcmp(tokens[0], "GW-IP") == 0) | |
202 gw_ip = tokens[1]; | |
203 else if (strcmp(tokens[0], "Session") == 0) | |
204 session_action = tokens[1]; | |
205 else | |
206 g_free(tokens[1]); | |
207 | |
208 g_free(tokens[0]); | |
209 /* Don't free each of the tokens, only the array. */ | |
210 g_free(tokens); | |
211 } | |
212 | |
213 g_strfreev(elems); | |
214 | |
215 g_free(tmp); | |
216 | |
217 if ((session_action != NULL) && (strcmp(session_action, "close") == 0)) | |
218 wasted = TRUE; | |
219 | |
220 g_free(session_action); | |
221 | |
222 t = strchr(full_session_id, '.'); | |
223 session_id = g_strndup(full_session_id, t - full_session_id); | |
224 | |
225 if (!wasted) | |
226 { | |
227 g_free(httpconn->full_session_id); | |
228 httpconn->full_session_id = full_session_id; | |
229 | |
230 g_free(httpconn->session_id); | |
231 httpconn->session_id = session_id; | |
232 | |
233 g_free(httpconn->host); | |
234 httpconn->host = gw_ip; | |
235 } | |
236 else | |
237 { | |
238 MsnServConn *servconn; | |
239 | |
240 /* It's going to die. */ | |
241 /* poor thing */ | |
242 | |
243 servconn = httpconn->servconn; | |
244 | |
245 /* I'll be honest, I don't fully understand all this, but this | |
246 * causes crashes, Stu. */ | |
247 /* if (servconn != NULL) | |
248 servconn->wasted = TRUE; */ | |
249 | |
250 g_free(full_session_id); | |
251 g_free(session_id); | |
252 g_free(gw_ip); | |
253 } | |
254 } | |
255 | |
256 g_free(header); | |
257 | |
258 *ret_buf = body; | |
259 *ret_size = body_len; | |
260 | |
261 msn_httpconn_process_queue(httpconn); | |
262 | |
263 return TRUE; | |
264 } | |
265 | |
266 static void | |
267 read_cb(gpointer data, gint source, GaimInputCondition cond) | |
268 { | |
269 MsnHttpConn *httpconn; | |
270 MsnServConn *servconn; | |
271 MsnSession *session; | |
272 char buf[MSN_BUF_LEN]; | |
273 char *cur, *end, *old_rx_buf; | |
274 int len, cur_len; | |
275 char *result_msg = NULL; | |
276 size_t result_len = 0; | |
277 gboolean error = FALSE; | |
278 | |
279 httpconn = data; | |
280 servconn = NULL; | |
281 session = httpconn->session; | |
282 | |
283 len = read(httpconn->fd, buf, sizeof(buf) - 1); | |
284 | |
285 if (len < 0 && errno == EAGAIN) | |
286 return; | |
287 else if (len <= 0) | |
288 { | |
289 gaim_debug_error("msn", "HTTP: Read error\n"); | |
290 msn_servconn_got_error(httpconn->servconn, MSN_SERVCONN_ERROR_READ); | |
291 | |
292 return; | |
293 } | |
294 | |
295 buf[len] = '\0'; | |
296 | |
297 httpconn->rx_buf = g_realloc(httpconn->rx_buf, len + httpconn->rx_len + 1); | |
298 memcpy(httpconn->rx_buf + httpconn->rx_len, buf, len + 1); | |
299 httpconn->rx_len += len; | |
300 | |
301 if (!msn_httpconn_parse_data(httpconn, httpconn->rx_buf, httpconn->rx_len, | |
302 &result_msg, &result_len, &error)) | |
303 { | |
304 /* Either we must wait for more input, or something went wrong */ | |
305 if (error) | |
306 msn_servconn_got_error(httpconn->servconn, MSN_SERVCONN_ERROR_READ); | |
307 | |
308 return; | |
309 } | |
310 | |
311 httpconn->servconn->processing = FALSE; | |
312 | |
313 servconn = httpconn->servconn; | |
314 | |
315 if (error) | |
316 { | |
317 gaim_debug_error("msn", "HTTP: Special error\n"); | |
318 msn_servconn_got_error(httpconn->servconn, MSN_SERVCONN_ERROR_READ); | |
319 | |
320 return; | |
321 } | |
322 | |
323 g_free(httpconn->rx_buf); | |
324 httpconn->rx_buf = NULL; | |
325 httpconn->rx_len = 0; | |
326 | |
327 if (result_len == 0) | |
328 { | |
329 /* Nothing to do here */ | |
330 #if 0 | |
331 gaim_debug_info("msn", "HTTP: nothing to do here\n"); | |
332 #endif | |
333 g_free(result_msg); | |
334 return; | |
335 } | |
336 | |
337 g_free(servconn->rx_buf); | |
338 servconn->rx_buf = result_msg; | |
339 servconn->rx_len = result_len; | |
340 | |
341 end = old_rx_buf = servconn->rx_buf; | |
342 | |
343 servconn->processing = TRUE; | |
344 | |
345 do | |
346 { | |
347 cur = end; | |
348 | |
349 if (servconn->payload_len) | |
350 { | |
351 if (servconn->payload_len > servconn->rx_len) | |
352 /* The payload is still not complete. */ | |
353 break; | |
354 | |
355 cur_len = servconn->payload_len; | |
356 end += cur_len; | |
357 } | |
358 else | |
359 { | |
360 end = strstr(cur, "\r\n"); | |
361 | |
362 if (end == NULL) | |
363 /* The command is still not complete. */ | |
364 break; | |
365 | |
366 *end = '\0'; | |
367 end += 2; | |
368 cur_len = end - cur; | |
369 } | |
370 | |
371 servconn->rx_len -= cur_len; | |
372 | |
373 if (servconn->payload_len) | |
374 { | |
375 msn_cmdproc_process_payload(servconn->cmdproc, cur, cur_len); | |
376 servconn->payload_len = 0; | |
377 } | |
378 else | |
379 { | |
380 msn_cmdproc_process_cmd_text(servconn->cmdproc, cur); | |
381 } | |
382 } while (servconn->connected && servconn->rx_len > 0); | |
383 | |
384 if (servconn->connected) | |
385 { | |
386 if (servconn->rx_len > 0) | |
387 servconn->rx_buf = g_memdup(cur, servconn->rx_len); | |
388 else | |
389 servconn->rx_buf = NULL; | |
390 } | |
391 | |
392 servconn->processing = FALSE; | |
393 | |
394 if (servconn->wasted) | |
395 msn_servconn_destroy(servconn); | |
396 | |
397 g_free(old_rx_buf); | |
398 } | |
399 | |
400 static void | |
401 httpconn_write_cb(gpointer data, gint source, GaimInputCondition cond) | |
402 { | |
403 MsnHttpConn *httpconn; | |
404 int ret, writelen; | |
405 | |
406 httpconn = data; | |
407 writelen = gaim_circ_buffer_get_max_read(httpconn->tx_buf); | |
408 | |
409 if (writelen == 0) | |
410 { | |
411 gaim_input_remove(httpconn->tx_handler); | |
412 httpconn->tx_handler = 0; | |
413 return; | |
414 } | |
415 | |
416 ret = write(httpconn->fd, httpconn->tx_buf->outptr, writelen); | |
417 if (ret <= 0) | |
418 { | |
419 if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) | |
420 /* No worries */ | |
421 return; | |
422 | |
423 /* Error! */ | |
424 msn_servconn_got_error(httpconn->servconn, MSN_SERVCONN_ERROR_WRITE); | |
425 return; | |
426 } | |
427 | |
428 gaim_circ_buffer_mark_read(httpconn->tx_buf, ret); | |
429 | |
430 /* TODO: I don't think these 2 lines are needed. Remove them? */ | |
431 if (ret == writelen) | |
432 httpconn_write_cb(data, source, cond); | |
433 } | |
434 | |
435 static gboolean | |
436 write_raw(MsnHttpConn *httpconn, const char *data, size_t data_len) | |
437 { | |
438 ssize_t res; /* result of the write operation */ | |
439 | |
440 if (httpconn->tx_handler == 0) | |
441 res = write(httpconn->fd, data, data_len); | |
442 else | |
443 { | |
444 res = -1; | |
445 errno = EAGAIN; | |
446 } | |
447 | |
448 if ((res <= 0) && ((errno != EAGAIN) && (errno != EWOULDBLOCK))) | |
449 { | |
450 msn_servconn_got_error(httpconn->servconn, MSN_SERVCONN_ERROR_WRITE); | |
451 return FALSE; | |
452 } | |
453 | |
454 if (res < 0 || res < data_len) | |
455 { | |
456 if (res < 0) | |
457 res = 0; | |
458 if (httpconn->tx_handler == 0 && httpconn->fd) | |
459 httpconn->tx_handler = gaim_input_add(httpconn->fd, | |
460 GAIM_INPUT_WRITE, httpconn_write_cb, httpconn); | |
461 gaim_circ_buffer_append(httpconn->tx_buf, data + res, | |
462 data_len - res); | |
463 } | |
464 | |
465 return TRUE; | |
466 } | |
467 | |
468 static char * | |
469 msn_httpconn_proxy_auth(MsnHttpConn *httpconn) | |
470 { | |
471 GaimAccount *account; | |
472 GaimProxyInfo *gpi; | |
473 const char *username, *password; | |
474 char *auth = NULL; | |
475 | |
476 account = httpconn->session->account; | |
477 | |
14979
c157efddc62a
[gaim-migrate @ 17758]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
14837
diff
changeset
|
478 gpi = gaim_proxy_get_setup(account); |
14192 | 479 |
480 if (gpi == NULL || !(gaim_proxy_info_get_type(gpi) == GAIM_PROXY_HTTP || | |
481 gaim_proxy_info_get_type(gpi) == GAIM_PROXY_USE_ENVVAR)) | |
482 return NULL; | |
483 | |
484 username = gaim_proxy_info_get_username(gpi); | |
485 password = gaim_proxy_info_get_password(gpi); | |
486 | |
487 if (username != NULL) { | |
488 char *tmp; | |
489 auth = g_strdup_printf("%s:%s", username, password ? password : ""); | |
490 tmp = gaim_base64_encode((const guchar *)auth, strlen(auth)); | |
491 g_free(auth); | |
492 auth = g_strdup_printf("Proxy-Authorization: Basic %s\r\n", tmp); | |
493 g_free(tmp); | |
494 } | |
495 | |
496 return auth; | |
497 } | |
498 | |
499 static gboolean | |
500 msn_httpconn_poll(gpointer data) | |
501 { | |
502 MsnHttpConn *httpconn; | |
503 char *header; | |
504 char *auth; | |
505 | |
506 httpconn = data; | |
507 | |
508 g_return_val_if_fail(httpconn != NULL, FALSE); | |
509 | |
510 if ((httpconn->host == NULL) || (httpconn->full_session_id == NULL)) | |
511 { | |
512 /* There's no need to poll if the session is not fully established */ | |
513 return TRUE; | |
514 } | |
515 | |
516 if (httpconn->waiting_response) | |
517 { | |
518 /* There's no need to poll if we're already waiting for a response */ | |
519 return TRUE; | |
520 } | |
521 | |
522 auth = msn_httpconn_proxy_auth(httpconn); | |
523 | |
524 header = g_strdup_printf( | |
525 "POST http://%s/gateway/gateway.dll?Action=poll&SessionID=%s HTTP/1.1\r\n" | |
526 "Accept: */*\r\n" | |
527 "Accept-Language: en-us\r\n" | |
528 "User-Agent: MSMSGS\r\n" | |
529 "Host: %s\r\n" | |
530 "Proxy-Connection: Keep-Alive\r\n" | |
531 "%s" /* Proxy auth */ | |
532 "Connection: Keep-Alive\r\n" | |
533 "Pragma: no-cache\r\n" | |
534 "Content-Type: application/x-msn-messenger\r\n" | |
535 "Content-Length: 0\r\n\r\n", | |
536 httpconn->host, | |
537 httpconn->full_session_id, | |
538 httpconn->host, | |
539 auth ? auth : ""); | |
540 | |
541 g_free(auth); | |
542 | |
543 if (write_raw(httpconn, header, strlen(header))) | |
544 httpconn->waiting_response = TRUE; | |
545 | |
546 g_free(header); | |
547 | |
548 return TRUE; | |
549 } | |
550 | |
551 ssize_t | |
552 msn_httpconn_write(MsnHttpConn *httpconn, const char *body, size_t body_len) | |
553 { | |
554 char *params; | |
555 char *data; | |
556 int header_len; | |
557 char *auth; | |
558 const char *server_types[] = { "NS", "SB" }; | |
559 const char *server_type; | |
560 char *host; | |
561 MsnServConn *servconn; | |
562 | |
563 /* TODO: remove http data from servconn */ | |
564 | |
565 g_return_val_if_fail(httpconn != NULL, 0); | |
566 g_return_val_if_fail(body != NULL, 0); | |
567 g_return_val_if_fail(body_len > 0, 0); | |
568 | |
569 servconn = httpconn->servconn; | |
570 | |
571 if (httpconn->waiting_response) | |
572 { | |
573 MsnHttpQueueData *queue_data = g_new0(MsnHttpQueueData, 1); | |
574 | |
575 queue_data->httpconn = httpconn; | |
576 queue_data->body = g_memdup(body, body_len); | |
577 queue_data->body_len = body_len; | |
578 | |
579 httpconn->queue = g_list_append(httpconn->queue, queue_data); | |
580 | |
581 return body_len; | |
582 } | |
583 | |
584 server_type = server_types[servconn->type]; | |
585 | |
586 if (httpconn->virgin) | |
587 { | |
588 host = "gateway.messenger.hotmail.com"; | |
589 | |
590 /* The first time servconn->host is the host we should connect to. */ | |
591 params = g_strdup_printf("Action=open&Server=%s&IP=%s", | |
592 server_type, | |
593 servconn->host); | |
594 httpconn->virgin = FALSE; | |
595 } | |
596 else | |
597 { | |
598 /* The rest of the times servconn->host is the gateway host. */ | |
599 host = httpconn->host; | |
600 | |
601 if (host == NULL || httpconn->full_session_id == NULL) | |
602 { | |
603 gaim_debug_warning("msn", "Attempted HTTP write before session is established\n"); | |
604 return -1; | |
605 } | |
606 | |
607 params = g_strdup_printf("SessionID=%s", | |
608 httpconn->full_session_id); | |
609 } | |
610 | |
611 auth = msn_httpconn_proxy_auth(httpconn); | |
612 | |
613 data = g_strdup_printf( | |
614 "POST http://%s/gateway/gateway.dll?%s HTTP/1.1\r\n" | |
615 "Accept: */*\r\n" | |
616 "Accept-Language: en-us\r\n" | |
617 "User-Agent: MSMSGS\r\n" | |
618 "Host: %s\r\n" | |
619 "Proxy-Connection: Keep-Alive\r\n" | |
620 "%s" /* Proxy auth */ | |
621 "Connection: Keep-Alive\r\n" | |
622 "Pragma: no-cache\r\n" | |
623 "Content-Type: application/x-msn-messenger\r\n" | |
624 "Content-Length: %d\r\n\r\n", | |
625 host, | |
626 params, | |
627 host, | |
628 auth ? auth : "", | |
629 (int) body_len); | |
630 | |
631 g_free(params); | |
632 | |
633 g_free(auth); | |
634 | |
635 header_len = strlen(data); | |
636 data = g_realloc(data, header_len + body_len); | |
637 memcpy(data + header_len, body, body_len); | |
638 | |
639 if (write_raw(httpconn, data, header_len + body_len)) | |
640 httpconn->waiting_response = TRUE; | |
641 | |
642 g_free(data); | |
643 | |
644 return body_len; | |
645 } | |
646 | |
647 MsnHttpConn * | |
648 msn_httpconn_new(MsnServConn *servconn) | |
649 { | |
650 MsnHttpConn *httpconn; | |
651 | |
652 g_return_val_if_fail(servconn != NULL, NULL); | |
653 | |
654 httpconn = g_new0(MsnHttpConn, 1); | |
655 | |
656 gaim_debug_info("msn", "new httpconn (%p)\n", httpconn); | |
657 | |
658 /* TODO: Remove this */ | |
659 httpconn->session = servconn->session; | |
660 | |
661 httpconn->servconn = servconn; | |
662 | |
663 httpconn->tx_buf = gaim_circ_buffer_new(MSN_BUF_LEN); | |
664 httpconn->tx_handler = 0; | |
665 | |
666 return httpconn; | |
667 } | |
668 | |
669 void | |
670 msn_httpconn_destroy(MsnHttpConn *httpconn) | |
671 { | |
672 g_return_if_fail(httpconn != NULL); | |
673 | |
674 gaim_debug_info("msn", "destroy httpconn (%p)\n", httpconn); | |
675 | |
676 if (httpconn->connected) | |
677 msn_httpconn_disconnect(httpconn); | |
678 | |
679 g_free(httpconn->full_session_id); | |
680 | |
681 g_free(httpconn->session_id); | |
682 | |
683 g_free(httpconn->host); | |
684 | |
685 gaim_circ_buffer_destroy(httpconn->tx_buf); | |
686 if (httpconn->tx_handler > 0) | |
687 gaim_input_remove(httpconn->tx_handler); | |
688 | |
689 g_free(httpconn); | |
690 } | |
691 | |
692 static void | |
693 connect_cb(gpointer data, gint source, const gchar *error_message) | |
694 { | |
695 MsnHttpConn *httpconn; | |
696 | |
697 httpconn = data; | |
14262 | 698 httpconn->connect_data = NULL; |
14192 | 699 httpconn->fd = source; |
700 | |
701 if (source >= 0) | |
702 { | |
703 httpconn->inpa = gaim_input_add(httpconn->fd, GAIM_INPUT_READ, | |
704 read_cb, data); | |
705 | |
706 httpconn->timer = gaim_timeout_add(2000, msn_httpconn_poll, httpconn); | |
707 | |
708 msn_httpconn_process_queue(httpconn); | |
709 } | |
710 else | |
711 { | |
712 gaim_debug_error("msn", "HTTP: Connection error\n"); | |
713 msn_servconn_got_error(httpconn->servconn, MSN_SERVCONN_ERROR_CONNECT); | |
714 } | |
715 } | |
716 | |
717 gboolean | |
718 msn_httpconn_connect(MsnHttpConn *httpconn, const char *host, int port) | |
719 { | |
720 g_return_val_if_fail(httpconn != NULL, FALSE); | |
721 g_return_val_if_fail(host != NULL, FALSE); | |
722 g_return_val_if_fail(port > 0, FALSE); | |
723 | |
724 if (httpconn->connected) | |
725 msn_httpconn_disconnect(httpconn); | |
726 | |
14837 | 727 httpconn->connect_data = gaim_proxy_connect(NULL, httpconn->session->account, |
14192 | 728 "gateway.messenger.hotmail.com", 80, connect_cb, httpconn); |
729 | |
14262 | 730 if (httpconn->connect_data != NULL) |
14192 | 731 { |
732 httpconn->waiting_response = TRUE; | |
733 httpconn->connected = TRUE; | |
734 } | |
735 | |
736 return httpconn->connected; | |
737 } | |
738 | |
739 void | |
740 msn_httpconn_disconnect(MsnHttpConn *httpconn) | |
741 { | |
742 g_return_if_fail(httpconn != NULL); | |
743 | |
744 if (!httpconn->connected) | |
745 return; | |
746 | |
14262 | 747 if (httpconn->connect_data != NULL) |
14192 | 748 { |
14262 | 749 gaim_proxy_connect_cancel(httpconn->connect_data); |
750 httpconn->connect_data = NULL; | |
14192 | 751 } |
752 | |
753 if (httpconn->timer) | |
754 { | |
755 gaim_timeout_remove(httpconn->timer); | |
756 httpconn->timer = 0; | |
757 } | |
758 | |
759 if (httpconn->inpa > 0) | |
760 { | |
761 gaim_input_remove(httpconn->inpa); | |
762 httpconn->inpa = 0; | |
763 } | |
764 | |
765 close(httpconn->fd); | |
766 httpconn->fd = -1; | |
767 | |
768 g_free(httpconn->rx_buf); | |
769 httpconn->rx_buf = NULL; | |
770 httpconn->rx_len = 0; | |
771 | |
772 httpconn->connected = FALSE; | |
773 | |
774 /* msn_servconn_disconnect(httpconn->servconn); */ | |
775 } |