Mercurial > pidgin
comparison src/protocols/msn/soap.c @ 19784:bc30c6270d9f
[gaim-migrate @ 16473]
add the Framework of SOAP request
Now can retrieve the Contact via SOAP Request.
so many bug still exist!
commited by MaYuan<mayuan2006@gmail.com>
committer: Ethan Blanton <elb@pidgin.im>
author | Ma Yuan <mayuan2006@gmail.com> |
---|---|
date | Sun, 09 Jul 2006 16:48:25 +0000 |
parents | |
children | 852b32710df0 |
comparison
equal
deleted
inserted
replaced
19783:995aea35b05c | 19784:bc30c6270d9f |
---|---|
1 /** | |
2 * @file soap.c | |
3 * SOAP connection related process | |
4 * Author | |
5 * MaYuan<mayuan2006@gmail.com> | |
6 * gaim | |
7 * | |
8 * Gaim is the legal property of its developers, whose names are too numerous | |
9 * to list here. Please refer to the COPYRIGHT file distributed with this | |
10 * source distribution. | |
11 * | |
12 * This program is free software; you can redistribute it and/or modify | |
13 * it under the terms of the GNU General Public License as published by | |
14 * the Free Software Foundation; either version 2 of the License, or | |
15 * (at your option) any later version. | |
16 * | |
17 * This program is distributed in the hope that it will be useful, | |
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20 * GNU General Public License for more details. | |
21 * | |
22 * You should have received a copy of the GNU General Public License | |
23 * along with this program; if not, write to the Free Software | |
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
25 */ | |
26 #include "msn.h" | |
27 #include "soap.h" | |
28 | |
29 /*new a soap connection*/ | |
30 MsnSoapConn * | |
31 msn_soap_new(MsnSession *session) | |
32 { | |
33 MsnSoapConn *soapconn; | |
34 | |
35 soapconn = g_new0(MsnSoapConn, 1); | |
36 soapconn->session = session; | |
37 soapconn->input_handler = -1; | |
38 soapconn->output_handler = -1; | |
39 return soapconn; | |
40 } | |
41 | |
42 /*ssl soap connect callback*/ | |
43 void | |
44 msn_soap_connect_cb(gpointer data, GaimSslConnection *gsc, | |
45 GaimInputCondition cond) | |
46 { | |
47 MsnSoapConn * soapconn; | |
48 MsnSession *session; | |
49 | |
50 gaim_debug_info("MaYuan","Soap connection connected!\n"); | |
51 soapconn = data; | |
52 g_return_if_fail(soapconn != NULL); | |
53 | |
54 session = soapconn->session; | |
55 g_return_if_fail(session != NULL); | |
56 | |
57 soapconn->gsc = gsc; | |
58 | |
59 /*connection callback*/ | |
60 if(soapconn->connect_cb != NULL){ | |
61 soapconn->connect_cb(data,gsc,cond); | |
62 } | |
63 } | |
64 | |
65 /*ssl soap error callback*/ | |
66 static void | |
67 msn_soap_error_cb(GaimSslConnection *gsc, GaimSslErrorType error, void *data) | |
68 { | |
69 MsnSoapConn * soapconn = data; | |
70 g_return_if_fail(data != NULL); | |
71 gaim_debug_info("MaYuan","Soap connection error!\n"); | |
72 /*error callback*/ | |
73 if(soapconn->error_cb != NULL){ | |
74 soapconn->error_cb(gsc,error,data); | |
75 } | |
76 } | |
77 | |
78 /*init the soap connection*/ | |
79 void | |
80 msn_soap_init(MsnSoapConn *soapconn,char * host,int ssl, | |
81 GaimSslInputFunction connect_cb, | |
82 GaimSslErrorFunction error_cb) | |
83 { | |
84 soapconn->login_host = g_strdup(host); | |
85 soapconn->ssl_conn = ssl; | |
86 soapconn->connect_cb = connect_cb; | |
87 soapconn->error_cb = error_cb; | |
88 if(soapconn->ssl_conn){ | |
89 gaim_ssl_connect(soapconn->session->account, soapconn->login_host, | |
90 GAIM_SSL_DEFAULT_PORT, msn_soap_connect_cb, msn_soap_error_cb, | |
91 soapconn); | |
92 }else{ | |
93 } | |
94 } | |
95 | |
96 /*destroy the soap connection*/ | |
97 void | |
98 msn_soap_destroy(MsnSoapConn *soapconn) | |
99 { | |
100 g_free(soapconn->login_host); | |
101 g_free(soapconn->login_path); | |
102 | |
103 /*remove the write handler*/ | |
104 if (soapconn->output_handler > 0){ | |
105 gaim_input_remove(soapconn->output_handler); | |
106 } | |
107 /*remove the read handler*/ | |
108 if (soapconn->input_handler > 0){ | |
109 gaim_input_remove(soapconn->input_handler); | |
110 } | |
111 msn_soap_free_read_buf(soapconn); | |
112 msn_soap_free_write_buf(soapconn); | |
113 | |
114 /*close ssl connection*/ | |
115 gaim_ssl_close(soapconn->gsc); | |
116 soapconn->gsc = NULL; | |
117 | |
118 g_free(soapconn); | |
119 } | |
120 | |
121 /*read and append the content to the buffer*/ | |
122 static gssize | |
123 msn_soap_read(MsnSoapConn *soapconn) | |
124 { | |
125 gssize len; | |
126 gssize total_len = 0; | |
127 char temp_buf[10240]; | |
128 | |
129 if(soapconn->ssl_conn){ | |
130 len = gaim_ssl_read(soapconn->gsc, temp_buf,sizeof(temp_buf)); | |
131 }else{ | |
132 len = read(soapconn->fd, temp_buf,sizeof(temp_buf)); | |
133 } | |
134 if(len >0){ | |
135 total_len += len; | |
136 soapconn->read_buf = g_realloc(soapconn->read_buf, | |
137 soapconn->read_len + len + 1); | |
138 // strncpy(soapconn->read_buf + soapconn->read_len, temp_buf, len); | |
139 memcpy(soapconn->read_buf + soapconn->read_len, temp_buf, len); | |
140 soapconn->read_len += len; | |
141 soapconn->read_buf[soapconn->read_len] = '\0'; | |
142 } | |
143 // gaim_debug_info("MaYuan","nexus ssl read:{%s}\n",soapconn->read_buf); | |
144 return total_len; | |
145 } | |
146 | |
147 /*read the whole SOAP server response*/ | |
148 void | |
149 msn_soap_read_cb(gpointer data, gint source, GaimInputCondition cond) | |
150 { | |
151 MsnSoapConn *soapconn = data; | |
152 MsnSession *session; | |
153 int len; | |
154 char * body_start,*body_len; | |
155 char *length_start,*length_end; | |
156 | |
157 gaim_debug_misc("MaYuan", "soap read cb\n"); | |
158 session = soapconn->session; | |
159 g_return_if_fail(session != NULL); | |
160 | |
161 if (soapconn->input_handler == -1){ | |
162 soapconn->input_handler = gaim_input_add(soapconn->gsc->fd, | |
163 GAIM_INPUT_READ, msn_soap_read_cb, soapconn); | |
164 } | |
165 | |
166 /*read the request header*/ | |
167 len = msn_soap_read(soapconn); | |
168 if (len < 0 && errno == EAGAIN){ | |
169 return; | |
170 }else if (len < 0) { | |
171 gaim_debug_error("msn", "read Error!len:%d\n",len); | |
172 gaim_input_remove(soapconn->input_handler); | |
173 soapconn->input_handler = -1; | |
174 g_free(soapconn->read_buf); | |
175 soapconn->read_buf = NULL; | |
176 soapconn->read_len = 0; | |
177 /* TODO: error handling */ | |
178 return; | |
179 } | |
180 | |
181 if(soapconn->read_buf == NULL){ | |
182 return; | |
183 } | |
184 | |
185 body_start = (char *)g_strstr_len(soapconn->read_buf, soapconn->read_len,"\r\n\r\n"); | |
186 if(!body_start){ | |
187 return; | |
188 } | |
189 body_start += 4; | |
190 | |
191 // gaim_debug_misc("msn", "Soap Read: {%s}\n", soapconn->read_buf); | |
192 | |
193 /* we read the content-length*/ | |
194 length_start = strstr(soapconn->read_buf, "Content-Length: "); | |
195 length_start += strlen("Content-Length: "); | |
196 length_end = strstr(length_start, "\r\n"); | |
197 body_len = g_strndup(length_start,length_end - length_start); | |
198 | |
199 /*setup the conn body */ | |
200 soapconn->body = body_start; | |
201 soapconn->body_len = atoi(body_len); | |
202 // gaim_debug_misc("MaYuan","content length :%d",soapconn->body_len); | |
203 | |
204 if(soapconn->read_len < body_start - soapconn->read_buf + atoi(body_len)){ | |
205 return; | |
206 } | |
207 | |
208 g_free(body_len); | |
209 | |
210 /*call the read callback*/ | |
211 if(soapconn->read_cb != NULL){ | |
212 soapconn->read_cb(soapconn,source,0); | |
213 } | |
214 #if 0 | |
215 /*clear the read buffer*/ | |
216 msn_soap_free_read_buf(soapconn); | |
217 | |
218 /*remove the read handler*/ | |
219 gaim_input_remove(soapconn->input_handler); | |
220 soapconn->input_handler = -1; | |
221 gaim_ssl_close(soapconn->gsc); | |
222 soapconn->gsc = NULL; | |
223 #endif | |
224 } | |
225 | |
226 void | |
227 msn_soap_free_read_buf(MsnSoapConn *soapconn) | |
228 { | |
229 if(soapconn->read_buf){ | |
230 g_free(soapconn->read_buf); | |
231 } | |
232 soapconn->read_buf = NULL; | |
233 soapconn->read_len = 0; | |
234 } | |
235 | |
236 void | |
237 msn_soap_free_write_buf(MsnSoapConn *soapconn) | |
238 { | |
239 if(soapconn->write_buf){ | |
240 g_free(soapconn->write_buf); | |
241 } | |
242 soapconn->write_buf = NULL; | |
243 soapconn->written_len = 0; | |
244 } | |
245 | |
246 /*Soap write process func*/ | |
247 static void | |
248 msn_soap_write_cb(gpointer data, gint source, GaimInputCondition cond) | |
249 { | |
250 MsnSoapConn *soapconn = data; | |
251 int len, total_len; | |
252 | |
253 total_len = strlen(soapconn->write_buf); | |
254 | |
255 /* | |
256 * write the content to SSL server, | |
257 */ | |
258 len = gaim_ssl_write(soapconn->gsc, | |
259 soapconn->write_buf + soapconn->written_len, | |
260 total_len - soapconn->written_len); | |
261 | |
262 if (len < 0 && errno == EAGAIN) | |
263 return; | |
264 else if (len <= 0){ | |
265 /*SSL write error!*/ | |
266 gaim_input_remove(soapconn->output_handler); | |
267 soapconn->output_handler = -1; | |
268 /* TODO: notify of the error */ | |
269 return; | |
270 } | |
271 soapconn->written_len += len; | |
272 | |
273 if (soapconn->written_len < total_len) | |
274 return; | |
275 | |
276 gaim_input_remove(soapconn->output_handler); | |
277 soapconn->output_handler = -1; | |
278 | |
279 /*clear the write buff*/ | |
280 msn_soap_free_write_buf(soapconn); | |
281 | |
282 /* Write finish! | |
283 * callback for write done | |
284 */ | |
285 if(soapconn->written_cb != NULL){ | |
286 soapconn->written_cb(soapconn, source, 0); | |
287 } | |
288 } | |
289 | |
290 /*write the buffer to SOAP connection*/ | |
291 void | |
292 msn_soap_write(MsnSoapConn * soapconn, char *write_buf, GaimInputFunction written_cb) | |
293 { | |
294 soapconn->write_buf = write_buf; | |
295 soapconn->written_len = 0; | |
296 soapconn->written_cb = written_cb; | |
297 /*start the write*/ | |
298 soapconn->output_handler = gaim_input_add(soapconn->gsc->fd, GAIM_INPUT_WRITE, | |
299 msn_soap_write_cb, soapconn); | |
300 msn_soap_write_cb(soapconn, soapconn->gsc->fd, GAIM_INPUT_WRITE); | |
301 } | |
302 |