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