2 * purple - Jabber Protocol Plugin
4 * Purple is the legal property of its developers, whose names are too numerous
5 * to list here. Please refer to the COPYRIGHT file distributed with this
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
33 typedef struct _JabberOOBXfer
{
37 PurpleHttpConnection
*hc
;
40 static void jabber_oob_xfer_init(PurpleXfer
*xfer
)
42 purple_xfer_start(xfer
, -1, NULL
, 0);
45 static void jabber_oob_xfer_free(PurpleXfer
*xfer
)
47 JabberOOBXfer
*jox
= purple_xfer_get_protocol_data(xfer
);
49 purple_xfer_set_protocol_data(xfer
, NULL
);
50 jox
->js
->oob_file_transfers
= g_list_remove(jox
->js
->oob_file_transfers
,
58 static void jabber_oob_xfer_end(PurpleXfer
*xfer
)
60 JabberOOBXfer
*jox
= purple_xfer_get_protocol_data(xfer
);
63 iq
= jabber_iq_new(jox
->js
, JABBER_IQ_RESULT
);
64 purple_xmlnode_set_attrib(iq
->node
, "to", purple_xfer_get_remote_user(xfer
));
65 jabber_iq_set_id(iq
, jox
->iq_id
);
69 jabber_oob_xfer_free(xfer
);
73 jabber_oob_xfer_got(PurpleHttpConnection
*hc
, PurpleHttpResponse
*response
,
76 PurpleXfer
*xfer
= _xfer
;
79 if (purple_xfer_is_cancelled(xfer
))
82 jox
= purple_xfer_get_protocol_data(xfer
);
85 if (!purple_http_response_is_successful(response
) ||
86 purple_xfer_get_bytes_remaining(xfer
) > 0)
88 purple_xfer_set_status(xfer
, PURPLE_XFER_STATUS_CANCEL_REMOTE
);
89 purple_xfer_end(xfer
);
91 purple_xfer_set_completed(xfer
, TRUE
);
92 purple_xfer_end(xfer
);
97 jabber_oob_xfer_progress_watcher(PurpleHttpConnection
*hc
,
98 gboolean reading_state
, int processed
, int total
, gpointer _xfer
)
100 PurpleXfer
*xfer
= _xfer
;
105 purple_xfer_set_size(xfer
, total
);
106 purple_xfer_update_progress(xfer
);
110 jabber_oob_xfer_writer(PurpleHttpConnection
*http_conn
,
111 PurpleHttpResponse
*response
, const gchar
*buffer
, size_t offset
,
112 size_t length
, gpointer _xfer
)
114 PurpleXfer
*xfer
= _xfer
;
116 return purple_xfer_write_file(xfer
, (const guchar
*)buffer
, length
);
119 static void jabber_oob_xfer_start(PurpleXfer
*xfer
)
121 PurpleHttpRequest
*req
;
122 JabberOOBXfer
*jox
= purple_xfer_get_protocol_data(xfer
);
124 req
= purple_http_request_new(jox
->url
);
125 purple_http_request_set_timeout(req
, -1);
126 purple_http_request_set_max_len(req
, -1);
127 purple_http_request_set_response_writer(req
, jabber_oob_xfer_writer
,
129 jox
->hc
= purple_http_request(jox
->js
->gc
, req
, jabber_oob_xfer_got
,
132 purple_http_conn_set_progress_watcher(jox
->hc
,
133 jabber_oob_xfer_progress_watcher
, xfer
, -1);
136 static void jabber_oob_xfer_recv_error(PurpleXfer
*xfer
, const char *code
) {
137 JabberOOBXfer
*jox
= purple_xfer_get_protocol_data(xfer
);
139 PurpleXmlNode
*y
, *z
;
141 iq
= jabber_iq_new(jox
->js
, JABBER_IQ_ERROR
);
142 purple_xmlnode_set_attrib(iq
->node
, "to", purple_xfer_get_remote_user(xfer
));
143 jabber_iq_set_id(iq
, jox
->iq_id
);
144 y
= purple_xmlnode_new_child(iq
->node
, "error");
145 purple_xmlnode_set_attrib(y
, "code", code
);
146 if(!strcmp(code
, "406")) {
147 z
= purple_xmlnode_new_child(y
, "not-acceptable");
148 purple_xmlnode_set_attrib(y
, "type", "modify");
149 purple_xmlnode_set_namespace(z
, NS_XMPP_STANZAS
);
150 } else if(!strcmp(code
, "404")) {
151 z
= purple_xmlnode_new_child(y
, "not-found");
152 purple_xmlnode_set_attrib(y
, "type", "cancel");
153 purple_xmlnode_set_namespace(z
, NS_XMPP_STANZAS
);
157 jabber_oob_xfer_free(xfer
);
160 static void jabber_oob_xfer_recv_denied(PurpleXfer
*xfer
) {
161 jabber_oob_xfer_recv_error(xfer
, "406");
164 static void jabber_oob_xfer_recv_cancelled(PurpleXfer
*xfer
) {
165 JabberOOBXfer
*jox
= purple_xfer_get_protocol_data(xfer
);
167 purple_http_conn_cancel(jox
->hc
);
168 jabber_oob_xfer_recv_error(xfer
, "404");
171 void jabber_oob_parse(JabberStream
*js
, const char *from
, JabberIqType type
,
172 const char *id
, PurpleXmlNode
*querynode
) {
175 const gchar
*filename
, *slash
;
177 PurpleXmlNode
*urlnode
;
179 if(type
!= JABBER_IQ_SET
)
185 if(!(urlnode
= purple_xmlnode_get_child(querynode
, "url")))
188 url
= purple_xmlnode_get_data(urlnode
);
192 xfer
= purple_xfer_new(purple_connection_get_account(js
->gc
),
193 PURPLE_XFER_TYPE_RECEIVE
, from
);
199 jox
= g_new0(JabberOOBXfer
, 1);
200 jox
->iq_id
= g_strdup(id
);
203 purple_xfer_set_protocol_data(xfer
, jox
);
205 slash
= strrchr(url
, '/');
209 filename
= slash
+ 1;
210 purple_xfer_set_filename(xfer
, filename
);
212 purple_xfer_set_init_fnc(xfer
, jabber_oob_xfer_init
);
213 purple_xfer_set_end_fnc(xfer
, jabber_oob_xfer_end
);
214 purple_xfer_set_request_denied_fnc(xfer
, jabber_oob_xfer_recv_denied
);
215 purple_xfer_set_cancel_recv_fnc(xfer
, jabber_oob_xfer_recv_cancelled
);
216 purple_xfer_set_start_fnc(xfer
, jabber_oob_xfer_start
);
218 js
->oob_file_transfers
= g_list_append(js
->oob_file_transfers
, xfer
);
220 purple_xfer_request(xfer
);