@@ -36,7 +36,6 @@ typedef struct {
3636 gchar * passwd ;
3737} PurpleHttpURL ;
3838
39-
4039static inline PurpleHttpURL * purple_http_url_parse (const gchar * url ) {
4140 PurpleHttpURL * ret = g_new0 (PurpleHttpURL , 1 );
4241 purple_url_parse (url , & (ret -> host ), & (ret -> port ), & (ret -> path ), & (ret -> user ), & (ret -> passwd ));
@@ -56,24 +55,41 @@ static inline void purple_http_url_free(PurpleHttpURL *phl) { g_free(phl->host);
5655
5756static void jabber_hfu_http_read (gpointer user_data , PurpleSslConnection * ssl_connection , PurpleInputCondition cond )
5857{
59- gchar buf [1024 ];
58+ PurpleXfer * xfer = user_data ;
59+ gchar buf [1024 ] = {0 };
60+
61+ //Read the server buffer
62+ size_t rl = purple_ssl_read (ssl_connection , buf , 1024 );
63+ purple_debug_info ("jabber_http_upload" , "Server file send response was %ld bytes: %s\n" , rl , buf );
64+
65+ if (rl == (size_t )-1 )
66+ return ;
6067
61- //Flush the server buffer
62- purple_ssl_read (ssl_connection , buf , 1024 );
63- purple_debug_info ("jabber_http_upload" , "Server file send response was %s\n" , buf );
68+ if ((purple_xfer_get_bytes_sent (xfer )) >= purple_xfer_get_size (xfer )) {
69+ // Looking for HTTP/1.1 201
70+ if (rl > 12 && g_str_has_prefix (buf , "HTTP/1." ) && g_str_has_prefix (buf + 8 , " 20" )) {
71+ // 20x statuses are good, should be 201 but who knows those servers
72+ purple_xfer_set_completed (xfer , TRUE);
73+ purple_xfer_end (xfer );
74+ return ;
75+ }
76+ }
77+ // We've read everything it seems but didn't understand a word
78+ purple_xfer_cancel_remote (xfer );
79+ g_return_if_reached ();
6480}
6581
6682static void jabber_hfu_http_send_connect_cb (gpointer data , PurpleSslConnection * ssl_connection , PurpleInputCondition cond )
6783{
6884 PurpleHttpURL * httpurl ;
69- gchar * headers , * host , * path , * auth = NULL , * expire = NULL , * cookie = NULL ;
85+ g_autofree gchar * headers , * auth = NULL , * expire = NULL , * cookie = NULL ;
7086
7187 PurpleXfer * xfer = data ;
7288 HFUXfer * hfux = purple_xfer_get_protocol_data (xfer );
7389 HFUJabberStreamData * js_data = hfux -> js_data ;
90+ g_autofree char * filemime = file_get_mime (purple_xfer_get_local_filename (xfer ));
7491
7592 httpurl = purple_http_url_parse (hfux -> put_url );
76- path = purple_http_url_get_path (httpurl );
7793
7894 if (str_equal (js_data -> ns , NS_HTTP_FILE_UPLOAD_V0 )) {
7995 char * a = g_hash_table_lookup (hfux -> put_headers , "Authorisation" );
@@ -86,35 +102,30 @@ static void jabber_hfu_http_send_connect_cb(gpointer data, PurpleSslConnection *
86102 if (e )
87103 expire = g_strdup_printf ("Expires: %s\r\n" , e );
88104 }
89- host = purple_http_url_get_host (httpurl );
90-
91105
92106 headers = g_strdup_printf ("PUT /%s HTTP/1.0\r\n"
93107 "Connection: close\r\n"
94108 "Host: %s\r\n"
95109 "Content-Length: %" G_GSIZE_FORMAT "\r\n"
96- "Content-Type: application/octet-stream \r\n"
110+ "Content-Type: %s \r\n"
97111 "User-Agent: libpurple\r\n"
98112 "%s%s%s\r\n" ,
99- path , host , (gsize ) purple_xfer_get_size (xfer ),
113+ purple_http_url_get_path (httpurl ),
114+ purple_http_url_get_host (httpurl ),
115+ (gsize ) purple_xfer_get_size (xfer ),
116+ (filemime ?:"application/octet-stream" ),
100117 (auth ?:"" ), (expire ?:"" ), (cookie ?:"" ));
101118
102- g_free (auth );
103- g_free (expire );
104- g_free (cookie );
105-
106- purple_ssl_write (ssl_connection , headers , strlen (headers ));
107-
108119 hfux -> ssl_conn = ssl_connection ;
109120 purple_ssl_input_add (ssl_connection , jabber_hfu_http_read , xfer );
110121
122+ purple_ssl_write (ssl_connection , headers , strlen (headers ));
123+
111124 purple_xfer_ref (xfer );
112125 purple_xfer_start (xfer , ssl_connection -> fd , NULL , 0 );
113126
114127 purple_xfer_prpl_ready (xfer );
115-
116- g_free (headers );
117-
128+ purple_http_url_free (httpurl );
118129}
119130
120131static void jabber_hfu_http_error_connect_cb (PurpleSslConnection * ssl_connection , PurpleSslErrorType * error_type , gpointer data )
@@ -129,13 +140,13 @@ static void jabber_hfu_request_cb(JabberStream *js, const char *from,
129140 PurpleAccount * account ;
130141 xmlnode * slot , * put , * get , * header = NULL ;
131142 PurpleHttpURL * put_httpurl ;
132- gchar * put_host ;
133143
134144 PurpleXfer * xfer = data ;
135145 HFUXfer * hfux = purple_xfer_get_protocol_data (xfer );
136146 HFUJabberStreamData * js_data = hfux -> js_data ;
137147 account = purple_connection_get_account (js -> gc );
138148
149+
139150 if (!(slot = xmlnode_get_child_with_namespace (packet , "slot" , js_data -> ns )))
140151 {
141152 purple_xfer_cancel_remote (xfer );
@@ -151,7 +162,7 @@ static void jabber_hfu_request_cb(JabberStream *js, const char *from,
151162 for (header = xmlnode_get_child (put , "header" ) ; header ;
152163 header = xmlnode_get_next_twin (header ))
153164 {
154- g_hash_table_insert (hfux -> put_headers , g_strdup (xmlnode_get_attrib (header , "name" )), g_strdup ( xmlnode_get_data (header ) ));
165+ g_hash_table_insert (hfux -> put_headers , g_strdup (xmlnode_get_attrib (header , "name" )), xmlnode_get_data (header ));
155166 }
156167
157168 hfux -> put_url = g_strdup (xmlnode_get_attrib (put , "url" ));
@@ -164,9 +175,10 @@ static void jabber_hfu_request_cb(JabberStream *js, const char *from,
164175 }
165176
166177 put_httpurl = purple_http_url_parse (hfux -> put_url );
167- put_host = purple_http_url_get_host (put_httpurl );
168178
169- purple_ssl_connect (account , put_host , purple_http_url_get_port (put_httpurl ), jabber_hfu_http_send_connect_cb , (PurpleSslErrorFunction )jabber_hfu_http_error_connect_cb , xfer );
179+ g_debug ("Connecting to %s:%d for %s" , purple_http_url_get_host (put_httpurl ), purple_http_url_get_port (put_httpurl ), hfux -> put_url );
180+ purple_ssl_connect (account , purple_http_url_get_host (put_httpurl ), purple_http_url_get_port (put_httpurl ),
181+ jabber_hfu_http_send_connect_cb , (PurpleSslErrorFunction )jabber_hfu_http_error_connect_cb , xfer );
170182
171183 purple_http_url_free (put_httpurl );
172184}
@@ -177,15 +189,11 @@ static void jabber_hfu_xfer_free(PurpleXfer *xfer)
177189
178190 g_return_if_fail (hfux != NULL );
179191
180- if (hfux -> put_url )
181- {
182- g_free (hfux -> put_url );
183- }
192+ g_free (hfux -> put_url );
193+ g_free (hfux -> get_url );
184194
185- if (hfux -> get_url )
186- {
187- g_free (hfux -> get_url );
188- }
195+ if (hfux -> put_headers )
196+ g_hash_table_destroy (hfux -> put_headers );
189197
190198 if (hfux -> ssl_conn )
191199 {
@@ -261,7 +269,8 @@ jabber_hfu_xmlnode_send_cb(PurpleConnection *gc, xmlnode **packet, gpointer null
261269 if (g_strcmp0 ((* packet )-> name , "message" ) == 0 ) {
262270 xmlnode * node_body = xmlnode_get_child (* packet , "body" );
263271 if (node_body ) {
264- HFUXfer * hfux = g_hash_table_lookup (ht_hfu_sending , xmlnode_get_data (node_body ));
272+ g_autofree char * url = xmlnode_get_data (node_body );
273+ HFUXfer * hfux = g_hash_table_lookup (ht_hfu_sending , url );
265274 if (hfux ) {
266275 xmlnode * x , * url ;
267276 x = xmlnode_new_child (* packet , "x" );
@@ -313,6 +322,7 @@ static void jabber_hfu_send_url_to_conv(PurpleXfer *xfer)
313322
314323static void jabber_hfu_xfer_end (PurpleXfer * xfer )
315324{
325+ g_debug ("This is the end." );
316326 jabber_hfu_send_url_to_conv (xfer );
317327
318328 jabber_hfu_xfer_free (xfer );
@@ -336,21 +346,22 @@ static gssize jabber_hfu_xfer_write(const guchar *buffer, size_t len, PurpleXfer
336346
337347 if (tlen == -1 )
338348 {
339- if (purple_xfer_get_bytes_sent (xfer ) >= purple_xfer_get_size (xfer ))
340- purple_xfer_set_completed (xfer , TRUE);
341-
342349 if ((errno != EAGAIN ) && (errno != EINTR ))
343350 return -1 ;
344351
345352 return 0 ;
346- }
347-
348- if ((purple_xfer_get_bytes_sent (xfer ) + tlen ) >= purple_xfer_get_size (xfer ))
349- purple_xfer_set_completed (xfer , TRUE);
353+ } else if ((purple_xfer_get_bytes_sent (xfer )+ tlen ) >= purple_xfer_get_size (xfer ))
354+ xfer -> status = PURPLE_XFER_STATUS_DONE ; // sneaky cheat
350355
351356 return tlen ;
352357}
353358
359+ static void jabber_hfu_xfer_ack (PurpleXfer * xfer , const guchar * buffer , size_t len )
360+ {
361+ if (purple_xfer_is_completed (xfer ))
362+ xfer -> status = PURPLE_XFER_STATUS_STARTED ; // hideous uncheat
363+ }
364+
354365static void jabber_hfu_xfer_init (PurpleXfer * xfer )
355366{
356367 HFUXfer * hfux = purple_xfer_get_protocol_data (xfer );
@@ -386,7 +397,6 @@ static void jabber_hfu_xfer_init(PurpleXfer *xfer)
386397}
387398
388399
389-
390400PurpleXfer * jabber_hfu_new_xfer (PurpleConnection * gc , const char * who )
391401{
392402 JabberStream * js ;
@@ -403,8 +413,9 @@ PurpleXfer *jabber_hfu_new_xfer(PurpleConnection *gc, const char *who)
403413
404414 purple_xfer_set_init_fnc (xfer , jabber_hfu_xfer_init );
405415 purple_xfer_set_cancel_send_fnc (xfer , jabber_hfu_xfer_cancel_send );
406- purple_xfer_set_end_fnc (xfer , jabber_hfu_xfer_end );
407416 purple_xfer_set_write_fnc (xfer , jabber_hfu_xfer_write );
417+ purple_xfer_set_ack_fnc (xfer , jabber_hfu_xfer_ack );
418+ purple_xfer_set_end_fnc (xfer , jabber_hfu_xfer_end );
408419
409420 return xfer ;
410421}
@@ -498,6 +509,11 @@ static GList *jabber_hfu_blist_node_menu(PurpleBlistNode *node)
498509
499510gboolean plugin_unload (PurplePlugin * plugin )
500511{
512+ PurplePlugin * jabber_plugin = purple_plugins_find_with_id (JABBER_PLUGIN_ID );
513+
514+ PurplePluginProtocolInfo * jabber_protocol_info = PURPLE_PLUGIN_PROTOCOL_INFO (jabber_plugin );
515+ jabber_protocol_info -> blist_node_menu = old_blist_node_menu ;
516+
501517 purple_signals_disconnect_by_handle (plugin );
502518 g_hash_table_destroy (ht_hfu_sending );
503519 g_hash_table_destroy (HFUJabberStreamDataTable );
0 commit comments