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