2 * Copyright (C) 2006 Benjamin Otte <otte@gnome.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301 USA
24 #include <libsoup/soup.h>
28 #include "swfdec_gtk_loader.h"
33 * SECTION:GtkExtensions
34 * @title: Gtk extensions
35 * @short_description: extension objects for @SwfdecGtkPlayer
37 * Swfdec-Gtk provides some objects that implement the various extensions
38 * provided by the @SwfdecPlayer object. They are used by default in the
39 * #SwfdecGtkPlayer object, but you can use them outside of it, too.
40 * However, they require certain Gtk functionality, such as a running glib
47 * #SwfdecGtkLoader is a #SwfdecLoader that is intended as an easy way to be
48 * access ressources that are not stored in files, such as HTTP. It is a
52 struct _SwfdecGtkLoader
56 SoupMessage
* message
; /* the message we're sending */
57 gboolean opened
; /* set after first bytes of data have arrived */
60 struct _SwfdecGtkLoaderClass
{
61 SwfdecLoaderClass loader_class
;
63 SoupSession
* session
; /* the session used by the loader */
66 /*** SwfdecGtkLoader ***/
68 G_DEFINE_TYPE (SwfdecGtkLoader
, swfdec_gtk_loader
, SWFDEC_TYPE_FILE_LOADER
)
71 swfdec_gtk_loader_ensure_open (SwfdecGtkLoader
*gtk
)
78 real_uri
= soup_uri_to_string (soup_message_get_uri (gtk
->message
), FALSE
);
79 swfdec_loader_set_url (SWFDEC_LOADER (gtk
), real_uri
);
81 if (soup_message_headers_get_encoding (gtk
->message
->response_headers
) == SOUP_ENCODING_CONTENT_LENGTH
) {
82 swfdec_loader_set_size (SWFDEC_LOADER (gtk
),
83 soup_message_headers_get_content_length (gtk
->message
->response_headers
));
85 swfdec_stream_open (SWFDEC_STREAM (gtk
));
90 swfdec_gtk_loader_push (SoupMessage
*msg
, SoupBuffer
*chunk
, gpointer loader
)
92 SwfdecGtkLoader
*gtk
= SWFDEC_GTK_LOADER (loader
);
95 chunk
= soup_buffer_copy (chunk
);
97 swfdec_gtk_loader_ensure_open (gtk
);
98 buffer
= swfdec_buffer_new_full ((unsigned char *) chunk
->data
, chunk
->length
,
99 (SwfdecBufferFreeFunc
) soup_buffer_free
, chunk
);
100 swfdec_stream_push (loader
, buffer
);
104 swfdec_gtk_loader_finished (SoupMessage
*msg
, gpointer loader
)
106 if (SOUP_STATUS_IS_SUCCESSFUL (msg
->status_code
)) {
107 swfdec_gtk_loader_ensure_open (loader
);
108 swfdec_stream_close (loader
);
110 if (!SWFDEC_GTK_LOADER (loader
)->opened
) {
111 char *real_uri
= soup_uri_to_string (soup_message_get_uri (msg
), FALSE
);
112 swfdec_loader_set_url (loader
, real_uri
);
115 swfdec_stream_error (loader
, "%u %s", msg
->status_code
, msg
->reason_phrase
);
120 swfdec_gtk_loader_dispose (GObject
*object
)
122 SwfdecGtkLoader
*gtk
= SWFDEC_GTK_LOADER (object
);
125 g_signal_handlers_disconnect_by_func (gtk
->message
, swfdec_gtk_loader_push
, gtk
);
126 g_signal_handlers_disconnect_by_func (gtk
->message
, swfdec_gtk_loader_finished
, gtk
);
127 g_object_unref (gtk
->message
);
131 G_OBJECT_CLASS (swfdec_gtk_loader_parent_class
)->dispose (object
);
135 swfdec_gtk_loader_load (SwfdecLoader
*loader
, SwfdecPlayer
*player
,
136 const char *url_string
, SwfdecBuffer
*buffer
, guint n_headers
,
137 const char **header_names
, const char **header_values
)
142 if (swfdec_url_path_is_relative (url_string
)) {
143 url
= swfdec_url_new_relative (swfdec_player_get_base_url (player
), url_string
);
145 url
= swfdec_url_new (url_string
);
149 swfdec_stream_error (SWFDEC_STREAM (loader
), "invalid URL %s", url_string
);
152 if (!swfdec_url_has_protocol (url
, "http") &&
153 !swfdec_url_has_protocol (url
, "https")) {
154 SWFDEC_LOADER_CLASS (swfdec_gtk_loader_parent_class
)->load (loader
, player
,
155 url_string
, buffer
, n_headers
, header_names
, header_values
);
157 SwfdecGtkLoader
*gtk
= SWFDEC_GTK_LOADER (loader
);
158 SwfdecGtkLoaderClass
*klass
= SWFDEC_GTK_LOADER_GET_CLASS (gtk
);
160 gtk
->message
= soup_message_new (buffer
!= NULL
? "POST" : "GET",
161 swfdec_url_get_url (url
));
162 soup_message_set_flags (gtk
->message
, SOUP_MESSAGE_OVERWRITE_CHUNKS
);
164 for (i
= 0; i
< n_headers
; i
++) {
165 soup_message_headers_append (gtk
->message
->request_headers
,
166 header_names
[i
], header_values
[i
]);
169 g_signal_connect (gtk
->message
, "got-chunk", G_CALLBACK (swfdec_gtk_loader_push
), gtk
);
170 g_signal_connect (gtk
->message
, "finished", G_CALLBACK (swfdec_gtk_loader_finished
), gtk
);
172 soup_message_set_request (gtk
->message
, "appliation/x-www-form-urlencoded",
173 SOUP_MEMORY_COPY
, (char *) buffer
->data
, buffer
->length
);
174 g_object_ref (gtk
->message
);
175 soup_session_queue_message (klass
->session
, gtk
->message
, NULL
, NULL
);
177 swfdec_url_free (url
);
181 swfdec_gtk_loader_close (SwfdecStream
*stream
)
183 SwfdecGtkLoader
*gtk
= SWFDEC_GTK_LOADER (stream
);
185 if (gtk
->message
&& !swfdec_stream_is_complete (stream
)) {
186 SwfdecGtkLoaderClass
*klass
= SWFDEC_GTK_LOADER_GET_CLASS (gtk
);
188 soup_session_cancel_message (klass
->session
, gtk
->message
, SOUP_STATUS_CANCELLED
);
189 g_object_unref (gtk
->message
);
195 swfdec_gtk_loader_class_init (SwfdecGtkLoaderClass
*klass
)
197 GObjectClass
*object_class
= G_OBJECT_CLASS (klass
);
198 SwfdecStreamClass
*stream_class
= SWFDEC_STREAM_CLASS (klass
);
199 SwfdecLoaderClass
*loader_class
= SWFDEC_LOADER_CLASS (klass
);
201 object_class
->dispose
= swfdec_gtk_loader_dispose
;
203 stream_class
->close
= swfdec_gtk_loader_close
;
205 loader_class
->load
= swfdec_gtk_loader_load
;
207 klass
->session
= soup_session_async_new ();
211 swfdec_gtk_loader_init (SwfdecGtkLoader
*gtk_loader
)