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 struct _JabberOOBXfer
{
37 PurpleHttpConnection
*hc
;
40 G_DEFINE_DYNAMIC_TYPE(JabberOOBXfer
, jabber_oob_xfer
, PURPLE_TYPE_XFER
);
42 static void jabber_oob_xfer_xfer_init(PurpleXfer
*xfer
)
44 purple_xfer_start(xfer
, -1, NULL
, 0);
47 static void jabber_oob_xfer_end(PurpleXfer
*xfer
)
49 JabberOOBXfer
*jox
= JABBER_OOB_XFER(xfer
);
52 iq
= jabber_iq_new(jox
->js
, JABBER_IQ_RESULT
);
53 purple_xmlnode_set_attrib(iq
->node
, "to", purple_xfer_get_remote_user(xfer
));
54 jabber_iq_set_id(iq
, jox
->iq_id
);
60 jabber_oob_xfer_got(PurpleHttpConnection
*hc
, PurpleHttpResponse
*response
,
63 PurpleXfer
*xfer
= _xfer
;
66 if (purple_xfer_is_cancelled(xfer
))
69 jox
= JABBER_OOB_XFER(xfer
);
72 if (!purple_http_response_is_successful(response
) ||
73 purple_xfer_get_bytes_remaining(xfer
) > 0)
75 purple_xfer_set_status(xfer
, PURPLE_XFER_STATUS_CANCEL_REMOTE
);
76 purple_xfer_end(xfer
);
78 purple_xfer_set_completed(xfer
, TRUE
);
79 purple_xfer_end(xfer
);
84 jabber_oob_xfer_progress_watcher(PurpleHttpConnection
*hc
,
85 gboolean reading_state
, int processed
, int total
, gpointer _xfer
)
87 PurpleXfer
*xfer
= _xfer
;
92 purple_xfer_set_size(xfer
, total
);
93 purple_xfer_update_progress(xfer
);
97 jabber_oob_xfer_writer(PurpleHttpConnection
*http_conn
,
98 PurpleHttpResponse
*response
, const gchar
*buffer
, size_t offset
,
99 size_t length
, gpointer _xfer
)
101 PurpleXfer
*xfer
= _xfer
;
103 return purple_xfer_write_file(xfer
, (const guchar
*)buffer
, length
);
106 static void jabber_oob_xfer_start(PurpleXfer
*xfer
)
108 PurpleHttpRequest
*req
;
109 JabberOOBXfer
*jox
= JABBER_OOB_XFER(xfer
);
111 req
= purple_http_request_new(jox
->url
);
112 purple_http_request_set_timeout(req
, -1);
113 purple_http_request_set_max_len(req
, -1);
114 purple_http_request_set_response_writer(req
, jabber_oob_xfer_writer
,
116 jox
->hc
= purple_http_request(jox
->js
->gc
, req
, jabber_oob_xfer_got
,
119 purple_http_conn_set_progress_watcher(jox
->hc
,
120 jabber_oob_xfer_progress_watcher
, xfer
, -1);
123 static void jabber_oob_xfer_recv_error(PurpleXfer
*xfer
, const char *code
) {
124 JabberOOBXfer
*jox
= JABBER_OOB_XFER(xfer
);
126 PurpleXmlNode
*y
, *z
;
128 iq
= jabber_iq_new(jox
->js
, JABBER_IQ_ERROR
);
129 purple_xmlnode_set_attrib(iq
->node
, "to", purple_xfer_get_remote_user(xfer
));
130 jabber_iq_set_id(iq
, jox
->iq_id
);
131 y
= purple_xmlnode_new_child(iq
->node
, "error");
132 purple_xmlnode_set_attrib(y
, "code", code
);
133 if(purple_strequal(code
, "406")) {
134 z
= purple_xmlnode_new_child(y
, "not-acceptable");
135 purple_xmlnode_set_attrib(y
, "type", "modify");
136 purple_xmlnode_set_namespace(z
, NS_XMPP_STANZAS
);
137 } else if(purple_strequal(code
, "404")) {
138 z
= purple_xmlnode_new_child(y
, "not-found");
139 purple_xmlnode_set_attrib(y
, "type", "cancel");
140 purple_xmlnode_set_namespace(z
, NS_XMPP_STANZAS
);
145 static void jabber_oob_xfer_recv_denied(PurpleXfer
*xfer
) {
146 jabber_oob_xfer_recv_error(xfer
, "406");
149 static void jabber_oob_xfer_recv_cancelled(PurpleXfer
*xfer
) {
150 JabberOOBXfer
*jox
= JABBER_OOB_XFER(xfer
);
152 purple_http_conn_cancel(jox
->hc
);
153 jabber_oob_xfer_recv_error(xfer
, "404");
156 void jabber_oob_parse(JabberStream
*js
, const char *from
, JabberIqType type
,
157 const char *id
, PurpleXmlNode
*querynode
) {
159 const gchar
*filename
, *slash
;
161 PurpleXmlNode
*urlnode
;
163 if(type
!= JABBER_IQ_SET
)
169 if(!(urlnode
= purple_xmlnode_get_child(querynode
, "url")))
172 url
= purple_xmlnode_get_data(urlnode
);
177 JABBER_TYPE_OOB_XFER
,
178 "account", purple_connection_get_account(js
->gc
),
179 "type", PURPLE_XFER_TYPE_RECEIVE
,
184 jox
->iq_id
= g_strdup(id
);
188 slash
= strrchr(url
, '/');
192 filename
= slash
+ 1;
195 purple_xfer_set_filename(PURPLE_XFER(jox
), filename
);
197 js
->oob_file_transfers
= g_list_append(js
->oob_file_transfers
, jox
);
199 purple_xfer_request(PURPLE_XFER(jox
));
203 jabber_oob_xfer_init(JabberOOBXfer
*xfer
) {
208 jabber_oob_xfer_finalize(GObject
*obj
) {
209 JabberOOBXfer
*jox
= JABBER_OOB_XFER(obj
);
211 jox
->js
->oob_file_transfers
= g_list_remove(jox
->js
->oob_file_transfers
,
217 G_OBJECT_CLASS(jabber_oob_xfer_parent_class
)->finalize(obj
);
221 jabber_oob_xfer_class_finalize(JabberOOBXferClass
*klass
) {
226 jabber_oob_xfer_class_init(JabberOOBXferClass
*klass
) {
227 GObjectClass
*obj_class
= G_OBJECT_CLASS(klass
);
228 PurpleXferClass
*xfer_class
= PURPLE_XFER_CLASS(klass
);
230 obj_class
->finalize
= jabber_oob_xfer_finalize
;
232 xfer_class
->init
= jabber_oob_xfer_xfer_init
;
233 xfer_class
->end
= jabber_oob_xfer_end
;
234 xfer_class
->request_denied
= jabber_oob_xfer_recv_denied
;
235 xfer_class
->cancel_recv
= jabber_oob_xfer_recv_cancelled
;
236 xfer_class
->start
= jabber_oob_xfer_start
;
240 jabber_oob_xfer_register(GTypeModule
*module
) {
241 jabber_oob_xfer_register_type(module
);