Mercurial > pidgin.yaz
comparison src/protocols/msn/httpconn.c @ 10463:9bed28273ec7
[gaim-migrate @ 11737]
Felipe Contreras fixed the MSN HTTP Method. Yay! Thanks Felipe.
committer: Tailor Script <tailor@pidgin.im>
author | Stu Tomlinson <stu@nosnilmot.com> |
---|---|
date | Fri, 31 Dec 2004 16:34:22 +0000 |
parents | |
children | bcfea6c3d5c9 |
comparison
equal
deleted
inserted
replaced
10462:f7b32dd67bdf | 10463:9bed28273ec7 |
---|---|
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 *buffer; | |
32 size_t size; | |
33 | |
34 } MsnHttpQueueData; | |
35 | |
36 static void read_cb(gpointer data, gint source, GaimInputCondition cond); | |
37 void msn_httpconn_process_queue(MsnHttpConn *httpconn); | |
38 gboolean msn_httpconn_parse_data(MsnHttpConn *httpconn, const char *buf, | |
39 size_t size, char **ret_buf, size_t *ret_size, | |
40 gboolean *error); | |
41 | |
42 MsnHttpConn * | |
43 msn_httpconn_new(MsnServConn *servconn) | |
44 { | |
45 MsnHttpConn *httpconn; | |
46 | |
47 g_return_val_if_fail(servconn != NULL, NULL); | |
48 | |
49 httpconn = g_new0(MsnHttpConn, 1); | |
50 | |
51 /* TODO: Remove this */ | |
52 httpconn->session = servconn->session; | |
53 | |
54 httpconn->servconn = servconn; | |
55 | |
56 return httpconn; | |
57 } | |
58 | |
59 void | |
60 msn_httpconn_destroy(MsnHttpConn *httpconn) | |
61 { | |
62 g_return_if_fail(httpconn != NULL); | |
63 | |
64 if (httpconn->connected) | |
65 msn_httpconn_disconnect(httpconn); | |
66 | |
67 if (httpconn->host != NULL) | |
68 g_free(httpconn->host); | |
69 | |
70 g_free(httpconn); | |
71 } | |
72 | |
73 static void | |
74 show_error(MsnHttpConn *httpconn) | |
75 { | |
76 GaimConnection *gc; | |
77 char *tmp; | |
78 char *cmd; | |
79 | |
80 const char *names[] = { "Notification", "Switchboard" }; | |
81 const char *name; | |
82 | |
83 gc = gaim_account_get_connection(httpconn->servconn->session->account); | |
84 name = names[httpconn->servconn->type]; | |
85 | |
86 switch (httpconn->servconn->cmdproc->error) | |
87 { | |
88 case MSN_ERROR_CONNECT: | |
89 tmp = g_strdup_printf(_("Unable to connect to %s server"), | |
90 name); | |
91 break; | |
92 case MSN_ERROR_WRITE: | |
93 tmp = g_strdup_printf(_("Error writing to %s server"), name); | |
94 break; | |
95 case MSN_ERROR_READ: | |
96 cmd = httpconn->servconn->cmdproc->last_trans; | |
97 tmp = g_strdup_printf(_("Error reading from %s server"), name); | |
98 gaim_debug_info("msn", "Last command was: %s\n", cmd); | |
99 break; | |
100 default: | |
101 tmp = g_strdup_printf(_("Unknown error from %s server"), name); | |
102 break; | |
103 } | |
104 | |
105 if (httpconn->servconn->type == MSN_SERVER_NS) | |
106 { | |
107 gaim_connection_error(gc, tmp); | |
108 } | |
109 else | |
110 { | |
111 MsnSwitchBoard *swboard; | |
112 swboard = httpconn->servconn->cmdproc->data; | |
113 swboard->error = MSN_SB_ERROR_CONNECTION; | |
114 } | |
115 | |
116 g_free(tmp); | |
117 } | |
118 | |
119 static ssize_t | |
120 write_raw(MsnHttpConn *httpconn, const void *buffer, size_t len) | |
121 { | |
122 ssize_t s; | |
123 ssize_t res; /* result of the write operation */ | |
124 | |
125 #ifdef MSN_DEBUG_HTTP | |
126 gaim_debug_misc("msn", "Writing HTTP: {%s}\n", buffer); | |
127 #endif | |
128 | |
129 s = 0; | |
130 | |
131 do | |
132 { | |
133 res = write(httpconn->fd, buffer, len); | |
134 if (res >= 0) | |
135 { | |
136 s += res; | |
137 } | |
138 else if (errno != EAGAIN) | |
139 { | |
140 httpconn->servconn->cmdproc->error = MSN_ERROR_WRITE; | |
141 show_error(httpconn); | |
142 return -1; | |
143 } | |
144 } while (s < len); | |
145 | |
146 return s; | |
147 } | |
148 | |
149 void | |
150 msn_httpconn_poll(MsnHttpConn *httpconn) | |
151 { | |
152 int r; | |
153 char *temp; | |
154 | |
155 g_return_if_fail(httpconn != NULL); | |
156 | |
157 if (httpconn->waiting_response || | |
158 httpconn->queue != NULL) | |
159 { | |
160 return; | |
161 } | |
162 | |
163 temp = g_strdup_printf( | |
164 "POST http://%s/gateway/gateway.dll?Action=poll&SessionID=%s HTTP/1.1\r\n" | |
165 "Accept: */*\r\n" | |
166 "Accept-Language: en-us\r\n" | |
167 "User-Agent: MSMSGS\r\n" | |
168 "Host: %s\r\n" | |
169 "Proxy-Connection: Keep-Alive\r\n" | |
170 "Connection: Keep-Alive\r\n" | |
171 "Pragma: no-cache\r\n" | |
172 "Content-Type: application/x-msn-messenger\r\n" | |
173 "Content-Length: 0\r\n" | |
174 "\r\n", | |
175 httpconn->host, | |
176 httpconn->full_session_id, | |
177 httpconn->host); | |
178 | |
179 r = write_raw(httpconn, temp, strlen(temp)); | |
180 | |
181 g_free(temp); | |
182 | |
183 if (r > 0) | |
184 { | |
185 httpconn->waiting_response = TRUE; | |
186 httpconn->dirty = FALSE; | |
187 } | |
188 } | |
189 | |
190 static gboolean | |
191 poll(gpointer data) | |
192 { | |
193 MsnHttpConn *httpconn; | |
194 | |
195 httpconn = data; | |
196 | |
197 #if 0 | |
198 gaim_debug_info("msn", "polling from %s\n", httpconn->session_id); | |
199 #endif | |
200 | |
201 if (httpconn->dirty) | |
202 msn_httpconn_poll(httpconn); | |
203 | |
204 return TRUE; | |
205 } | |
206 | |
207 static void | |
208 connect_cb(gpointer data, gint source, GaimInputCondition cond) | |
209 { | |
210 MsnHttpConn *httpconn = data; | |
211 | |
212 httpconn->fd = source; | |
213 | |
214 if (source > 0) | |
215 { | |
216 httpconn->inpa = gaim_input_add(httpconn->fd, GAIM_INPUT_READ, | |
217 read_cb, data); | |
218 | |
219 httpconn->timer = gaim_timeout_add(2000, poll, httpconn); | |
220 | |
221 httpconn->waiting_response = FALSE; | |
222 msn_httpconn_process_queue(httpconn); | |
223 } | |
224 else | |
225 { | |
226 gaim_debug_error("msn", "HTTP: Connection error\n"); | |
227 show_error(httpconn); | |
228 } | |
229 } | |
230 | |
231 gboolean | |
232 msn_httpconn_connect(MsnHttpConn *httpconn, const char *host, int port) | |
233 { | |
234 int r; | |
235 | |
236 g_return_val_if_fail(httpconn != NULL, FALSE); | |
237 g_return_val_if_fail(host != NULL, FALSE); | |
238 g_return_val_if_fail(port > 0, FALSE); | |
239 | |
240 if (httpconn->connected) | |
241 msn_httpconn_disconnect(httpconn); | |
242 | |
243 r = gaim_proxy_connect(httpconn->session->account, | |
244 "gateway.messenger.hotmail.com", 80, connect_cb, | |
245 httpconn); | |
246 | |
247 if (r == 0) | |
248 { | |
249 httpconn->waiting_response = TRUE; | |
250 httpconn->connected = TRUE; | |
251 } | |
252 | |
253 return httpconn->connected; | |
254 } | |
255 | |
256 void | |
257 msn_httpconn_disconnect(MsnHttpConn *httpconn) | |
258 { | |
259 g_return_if_fail(httpconn != NULL); | |
260 g_return_if_fail(httpconn->connected); | |
261 | |
262 if (httpconn->timer) | |
263 gaim_timeout_remove(httpconn->timer); | |
264 | |
265 httpconn->timer = 0; | |
266 | |
267 if (httpconn->inpa > 0) | |
268 { | |
269 gaim_input_remove(httpconn->inpa); | |
270 httpconn->inpa = 0; | |
271 } | |
272 | |
273 close(httpconn->fd); | |
274 | |
275 httpconn->rx_buf = NULL; | |
276 httpconn->rx_len = 0; | |
277 | |
278 httpconn->connected = FALSE; | |
279 | |
280 /* msn_servconn_disconnect(httpconn->servconn); */ | |
281 } | |
282 | |
283 static void | |
284 read_cb(gpointer data, gint source, GaimInputCondition cond) | |
285 { | |
286 MsnHttpConn *httpconn; | |
287 MsnServConn *servconn; | |
288 MsnSession *session; | |
289 char buf[MSN_BUF_LEN]; | |
290 char *cur, *end, *old_rx_buf; | |
291 int len, cur_len; | |
292 char *result_msg = NULL; | |
293 size_t result_len = 0; | |
294 gboolean error; | |
295 | |
296 httpconn = data; | |
297 servconn = NULL; | |
298 session = httpconn->session; | |
299 | |
300 len = read(httpconn->fd, buf, sizeof(buf) - 1); | |
301 | |
302 if (len <= 0) | |
303 { | |
304 gaim_debug_error("msn", "HTTP: Read error\n"); | |
305 show_error(httpconn); | |
306 msn_httpconn_disconnect(httpconn); | |
307 | |
308 return; | |
309 } | |
310 | |
311 buf[len] = '\0'; | |
312 | |
313 httpconn->rx_buf = g_realloc(httpconn->rx_buf, len + httpconn->rx_len + 1); | |
314 memcpy(httpconn->rx_buf + httpconn->rx_len, buf, len + 1); | |
315 httpconn->rx_len += len; | |
316 | |
317 if (!msn_httpconn_parse_data(httpconn, httpconn->rx_buf, httpconn->rx_len, | |
318 &result_msg, &result_len, &error)) | |
319 { | |
320 /* We must wait for more input */ | |
321 | |
322 return; | |
323 } | |
324 | |
325 httpconn->servconn->processing = FALSE; | |
326 | |
327 servconn = httpconn->servconn; | |
328 | |
329 if (error) | |
330 { | |
331 gaim_debug_error("msn", "HTTP: Special error\n"); | |
332 show_error(httpconn); | |
333 msn_httpconn_disconnect(httpconn); | |
334 | |
335 return; | |
336 } | |
337 | |
338 if (result_len == 0) | |
339 { | |
340 /* Nothing to do here */ | |
341 #if 0 | |
342 gaim_debug_info("msn", "HTTP: nothing to do here\n"); | |
343 #endif | |
344 g_free(httpconn->rx_buf); | |
345 httpconn->rx_buf = NULL; | |
346 httpconn->rx_len = 0; | |
347 return; | |
348 } | |
349 | |
350 g_free(httpconn->rx_buf); | |
351 httpconn->rx_buf = NULL; | |
352 httpconn->rx_len = 0; | |
353 | |
354 servconn->rx_buf = result_msg; | |
355 servconn->rx_len = result_len; | |
356 | |
357 end = old_rx_buf = servconn->rx_buf; | |
358 | |
359 servconn->processing = TRUE; | |
360 | |
361 do | |
362 { | |
363 cur = end; | |
364 | |
365 if (servconn->payload_len) | |
366 { | |
367 if (servconn->payload_len > servconn->rx_len) | |
368 /* The payload is still not complete. */ | |
369 break; | |
370 | |
371 cur_len = servconn->payload_len; | |
372 end += cur_len; | |
373 } | |
374 else | |
375 { | |
376 end = strstr(cur, "\r\n"); | |
377 | |
378 if (end == NULL) | |
379 /* The command is still not complete. */ | |
380 break; | |
381 | |
382 *end = '\0'; | |
383 end += 2; | |
384 cur_len = end - cur; | |
385 } | |
386 | |
387 servconn->rx_len -= cur_len; | |
388 | |
389 if (servconn->payload_len) | |
390 { | |
391 msn_cmdproc_process_payload(servconn->cmdproc, cur, cur_len); | |
392 servconn->payload_len = 0; | |
393 } | |
394 else | |
395 { | |
396 msn_cmdproc_process_cmd_text(servconn->cmdproc, cur); | |
397 } | |
398 } while (servconn->connected && servconn->rx_len > 0); | |
399 | |
400 if (servconn->connected) | |
401 { | |
402 if (servconn->rx_len > 0) | |
403 servconn->rx_buf = g_memdup(cur, servconn->rx_len); | |
404 else | |
405 servconn->rx_buf = NULL; | |
406 } | |
407 | |
408 servconn->processing = FALSE; | |
409 | |
410 if (servconn->wasted) | |
411 msn_servconn_destroy(servconn); | |
412 | |
413 g_free(old_rx_buf); | |
414 } | |
415 | |
416 void | |
417 msn_httpconn_process_queue(MsnHttpConn *httpconn) | |
418 { | |
419 if (httpconn->queue != NULL) | |
420 { | |
421 MsnHttpQueueData *queue_data; | |
422 | |
423 queue_data = (MsnHttpQueueData *)httpconn->queue->data; | |
424 | |
425 httpconn->queue = g_list_remove(httpconn->queue, queue_data); | |
426 | |
427 msn_httpconn_write(queue_data->httpconn, | |
428 queue_data->buffer, | |
429 queue_data->size); | |
430 | |
431 g_free(queue_data->buffer); | |
432 g_free(queue_data); | |
433 } | |
434 else | |
435 { | |
436 httpconn->dirty = TRUE; | |
437 } | |
438 } | |
439 | |
440 size_t | |
441 msn_httpconn_write(MsnHttpConn *httpconn, const char *buf, size_t size) | |
442 { | |
443 char *params; | |
444 char *temp; | |
445 gboolean first; | |
446 const char *server_types[] = { "NS", "SB" }; | |
447 const char *server_type; | |
448 size_t r; /* result of the write operation */ | |
449 size_t len; | |
450 char *host; | |
451 MsnServConn *servconn; | |
452 | |
453 /* TODO: remove http data from servconn */ | |
454 | |
455 g_return_val_if_fail(httpconn != NULL, 0); | |
456 g_return_val_if_fail(buf != NULL, 0); | |
457 g_return_val_if_fail(size > 0, 0); | |
458 | |
459 servconn = httpconn->servconn; | |
460 | |
461 if (httpconn->waiting_response) | |
462 { | |
463 MsnHttpQueueData *queue_data = g_new0(MsnHttpQueueData, 1); | |
464 | |
465 queue_data->httpconn = httpconn; | |
466 queue_data->buffer = g_memdup(buf, size); | |
467 queue_data->size = size; | |
468 | |
469 httpconn->queue = g_list_append(httpconn->queue, queue_data); | |
470 /* httpconn->dirty = TRUE; */ | |
471 | |
472 /* servconn->processing = TRUE; */ | |
473 | |
474 return size; | |
475 } | |
476 | |
477 first = httpconn->virgin; | |
478 server_type = server_types[servconn->type]; | |
479 | |
480 if (first) | |
481 { | |
482 host = "gateway.messenger.hotmail.com"; | |
483 | |
484 /* The first time servconn->host is the host we should connect to. */ | |
485 params = g_strdup_printf("Action=open&Server=%s&IP=%s", | |
486 server_type, | |
487 servconn->host); | |
488 } | |
489 else | |
490 { | |
491 /* The rest of the times servconn->host is the gateway host. */ | |
492 host = httpconn->host; | |
493 | |
494 params = g_strdup_printf("SessionID=%s", | |
495 httpconn->full_session_id); | |
496 } | |
497 | |
498 temp = g_strdup_printf( | |
499 "POST http://%s/gateway/gateway.dll?%s HTTP/1.1\r\n" | |
500 "Accept: */*\r\n" | |
501 "Accept-Language: en-us\r\n" | |
502 "User-Agent: MSMSGS\r\n" | |
503 "Host: %s\r\n" | |
504 "Proxy-Connection: Keep-Alive\r\n" | |
505 "Connection: Keep-Alive\r\n" | |
506 "Pragma: no-cache\r\n" | |
507 "Content-Type: application/x-msn-messenger\r\n" | |
508 "Content-Length: %d\r\n" | |
509 "\r\n", | |
510 host, | |
511 params, | |
512 host, | |
513 (int)size); | |
514 | |
515 g_free(params); | |
516 | |
517 len = strlen(temp); | |
518 temp = g_realloc(temp, len + size + 1); | |
519 memcpy(temp + len, buf, size); | |
520 len += size; | |
521 temp[len] = '\0'; | |
522 | |
523 r = write_raw(httpconn, temp, len); | |
524 | |
525 g_free(temp); | |
526 | |
527 if (r > 0) | |
528 { | |
529 httpconn->virgin = FALSE; | |
530 httpconn->waiting_response = TRUE; | |
531 httpconn->dirty = FALSE; | |
532 } | |
533 | |
534 return r; | |
535 } | |
536 | |
537 gboolean | |
538 msn_httpconn_parse_data(MsnHttpConn *httpconn, const char *buf, | |
539 size_t size, char **ret_buf, size_t *ret_size, | |
540 gboolean *error) | |
541 { | |
542 GaimConnection *gc; | |
543 const char *s, *c; | |
544 char *headers, *body; | |
545 const char *body_start; | |
546 char *tmp; | |
547 size_t body_len = 0; | |
548 gboolean wasted = FALSE; | |
549 | |
550 g_return_val_if_fail(httpconn != NULL, FALSE); | |
551 g_return_val_if_fail(buf != NULL, FALSE); | |
552 g_return_val_if_fail(size > 0, FALSE); | |
553 g_return_val_if_fail(ret_buf != NULL, FALSE); | |
554 g_return_val_if_fail(ret_size != NULL, FALSE); | |
555 g_return_val_if_fail(error != NULL, FALSE); | |
556 | |
557 #if 0 | |
558 gaim_debug_info("msn", "HTTP: parsing data {%s}\n", buf); | |
559 #endif | |
560 | |
561 httpconn->waiting_response = FALSE; | |
562 | |
563 gc = gaim_account_get_connection(httpconn->session->account); | |
564 | |
565 /* Healthy defaults. */ | |
566 body = NULL; | |
567 | |
568 *ret_buf = NULL; | |
569 *ret_size = 0; | |
570 *error = FALSE; | |
571 | |
572 /* First, some tests to see if we have a full block of stuff. */ | |
573 if (((strncmp(buf, "HTTP/1.1 200 OK\r\n", 17) != 0) && | |
574 (strncmp(buf, "HTTP/1.1 100 Continue\r\n", 23) != 0)) && | |
575 ((strncmp(buf, "HTTP/1.0 200 OK\r\n", 17) != 0) && | |
576 (strncmp(buf, "HTTP/1.0 100 Continue\r\n", 23) != 0))) | |
577 { | |
578 *error = TRUE; | |
579 | |
580 return FALSE; | |
581 } | |
582 | |
583 if (strncmp(buf, "HTTP/1.1 100 Continue\r\n", 23) == 0) | |
584 { | |
585 if ((s = strstr(buf, "\r\n\r\n")) == NULL) | |
586 return FALSE; | |
587 | |
588 s += 4; | |
589 | |
590 if (*s == '\0') | |
591 { | |
592 *ret_buf = g_strdup(""); | |
593 *ret_size = 0; | |
594 | |
595 msn_httpconn_process_queue(httpconn); | |
596 | |
597 return TRUE; | |
598 } | |
599 | |
600 buf = s; | |
601 size -= (s - buf); | |
602 } | |
603 | |
604 if ((s = strstr(buf, "\r\n\r\n")) == NULL) | |
605 return FALSE; | |
606 | |
607 headers = g_strndup(buf, s - buf); | |
608 s += 4; /* Skip \r\n */ | |
609 body_start = s; | |
610 body_len = size - (body_start - buf); | |
611 | |
612 if ((s = strstr(headers, "Content-Length: ")) != NULL) | |
613 { | |
614 int tmp_len; | |
615 | |
616 s += strlen("Content-Length: "); | |
617 | |
618 if ((c = strchr(s, '\r')) == NULL) | |
619 { | |
620 g_free(headers); | |
621 | |
622 return FALSE; | |
623 } | |
624 | |
625 tmp = g_strndup(s, c - s); | |
626 tmp_len = atoi(tmp); | |
627 g_free(tmp); | |
628 | |
629 if (body_len != tmp_len) | |
630 { | |
631 g_free(headers); | |
632 | |
633 #if 0 | |
634 gaim_debug_warning("msn", | |
635 "body length (%d) != content length (%d)\n", | |
636 body_len, tmp_len); | |
637 #endif | |
638 | |
639 return FALSE; | |
640 } | |
641 } | |
642 | |
643 body = g_memdup(body_start, body_len); | |
644 | |
645 #ifdef MSN_DEBUG_HTTP | |
646 gaim_debug_misc("msn", "Incoming HTTP buffer: {%s\r\n\r\n%s}\n", headers, body); | |
647 #endif | |
648 | |
649 /* Now we should be able to process the data. */ | |
650 if ((s = strstr(headers, "X-MSN-Messenger: ")) != NULL) | |
651 { | |
652 char *full_session_id, *gw_ip, *session_action; | |
653 char *t, *session_id; | |
654 char **elems, **cur, **tokens; | |
655 | |
656 full_session_id = gw_ip = session_action = NULL; | |
657 | |
658 s += strlen("X-MSN-Messenger: "); | |
659 | |
660 if ((c = strchr(s, '\r')) == NULL) | |
661 { | |
662 gaim_connection_error(gc, "Malformed X-MSN-Messenger field."); | |
663 gaim_debug_error("msn", "Malformed X-MSN-Messenger field.\n{%s}", | |
664 buf); | |
665 | |
666 return FALSE; | |
667 } | |
668 | |
669 tmp = g_strndup(s, c - s); | |
670 | |
671 elems = g_strsplit(tmp, "; ", 0); | |
672 | |
673 for (cur = elems; *cur != NULL; cur++) | |
674 { | |
675 tokens = g_strsplit(*cur, "=", 2); | |
676 | |
677 if (strcmp(tokens[0], "SessionID") == 0) | |
678 full_session_id = tokens[1]; | |
679 else if (strcmp(tokens[0], "GW-IP") == 0) | |
680 gw_ip = tokens[1]; | |
681 else if (strcmp(tokens[0], "Session") == 0) | |
682 session_action = tokens[1]; | |
683 | |
684 g_free(tokens[0]); | |
685 /* Don't free each of the tokens, only the array. */ | |
686 g_free(tokens); | |
687 } | |
688 | |
689 g_strfreev(elems); | |
690 | |
691 g_free(tmp); | |
692 | |
693 if ((session_action != NULL) && (strcmp(session_action, "close") == 0)) | |
694 wasted = TRUE; | |
695 | |
696 g_free(session_action); | |
697 | |
698 t = strchr(full_session_id, '.'); | |
699 session_id = g_strndup(full_session_id, t - full_session_id); | |
700 | |
701 if (!wasted) | |
702 { | |
703 if (httpconn->full_session_id != NULL); | |
704 g_free(httpconn->full_session_id); | |
705 | |
706 httpconn->full_session_id = full_session_id; | |
707 | |
708 if (httpconn->session_id != NULL); | |
709 g_free(httpconn->session_id); | |
710 | |
711 httpconn->session_id = session_id; | |
712 | |
713 if (httpconn->host != NULL); | |
714 g_free(httpconn->host); | |
715 | |
716 httpconn->host = gw_ip; | |
717 } | |
718 else | |
719 { | |
720 MsnServConn *servconn; | |
721 | |
722 /* It's going to die. */ | |
723 | |
724 servconn = httpconn->servconn; | |
725 | |
726 if (servconn != NULL) | |
727 servconn->wasted = TRUE; | |
728 | |
729 g_free(full_session_id); | |
730 g_free(gw_ip); | |
731 } | |
732 } | |
733 | |
734 g_free(headers); | |
735 | |
736 *ret_buf = body; | |
737 *ret_size = body_len; | |
738 | |
739 msn_httpconn_process_queue(httpconn); | |
740 | |
741 return TRUE; | |
742 } |