2 * Copyright (C) 2007 Benjamin Otte <otte@gnome.org>
3 * 2007 Pekka Lampila <pekka.lampila@iki.fi>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301 USA
26 #include "swfdec_load_object.h"
27 #include "swfdec_as_internal.h"
28 #include "swfdec_as_strings.h"
29 #include "swfdec_debug.h"
30 #include "swfdec_loader_internal.h"
31 #include "swfdec_player_internal.h"
34 swfdec_load_object_on_finish (SwfdecPlayer
*player
, const SwfdecAsValue
*target
, const char *text
)
36 SwfdecAsObject
*object
;
39 object
= SWFDEC_AS_VALUE_GET_COMPOSITE (target
);
44 SWFDEC_AS_VALUE_SET_STRING (&val
, text
);
46 SWFDEC_AS_VALUE_SET_UNDEFINED (&val
);
49 swfdec_as_object_call (object
, SWFDEC_AS_STR_onData
, 1, &val
, NULL
);
53 swfdec_load_object_on_progress (SwfdecPlayer
*player
, const SwfdecAsValue
*target
,
54 glong size
, glong loaded
)
56 SwfdecAsContext
*cx
= SWFDEC_AS_CONTEXT (player
);
57 SwfdecAsObject
*object
;
60 object
= SWFDEC_AS_VALUE_GET_COMPOSITE (target
);
63 swfdec_as_value_set_number (cx
, &val
, loaded
);
64 swfdec_as_object_set_variable_and_flags (object
, SWFDEC_AS_STR__bytesLoaded
,
65 &val
, SWFDEC_AS_VARIABLE_HIDDEN
);
68 swfdec_as_value_set_number (cx
, &val
, size
);
70 swfdec_as_value_set_number (cx
, &val
, loaded
);
72 swfdec_as_object_set_variable_and_flags (object
, SWFDEC_AS_STR__bytesTotal
,
73 &val
, SWFDEC_AS_VARIABLE_HIDDEN
);
76 SWFDEC_AS_NATIVE (301, 0, swfdec_load_object_as_load
)
78 swfdec_load_object_as_load (SwfdecAsContext
*cx
, SwfdecAsObject
*object
, guint argc
,
79 SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
84 SWFDEC_AS_VALUE_SET_BOOLEAN (rval
, FALSE
);
85 SWFDEC_AS_CHECK (SWFDEC_TYPE_AS_OBJECT
, &object
, "s", &url
);
87 SWFDEC_AS_VALUE_SET_COMPOSITE (&val
, object
);
88 swfdec_load_object_create (SWFDEC_PLAYER (cx
), &val
, url
, NULL
, 0, NULL
, NULL
,
89 swfdec_load_object_on_progress
, swfdec_load_object_on_finish
);
91 swfdec_as_value_set_integer (cx
, &val
, 0);
92 swfdec_as_object_set_variable_and_flags (object
, SWFDEC_AS_STR__bytesLoaded
,
93 &val
, SWFDEC_AS_VARIABLE_HIDDEN
);
94 SWFDEC_AS_VALUE_SET_UNDEFINED (&val
);
95 swfdec_as_object_set_variable_and_flags (object
, SWFDEC_AS_STR__bytesTotal
,
96 &val
, SWFDEC_AS_VARIABLE_HIDDEN
);
98 SWFDEC_AS_VALUE_SET_BOOLEAN (&val
, FALSE
);
99 swfdec_as_object_set_variable_and_flags (object
, SWFDEC_AS_STR_loaded
, &val
,
100 SWFDEC_AS_VARIABLE_HIDDEN
);
102 SWFDEC_AS_VALUE_SET_BOOLEAN (rval
, TRUE
);
105 #define ALLOWED_CHARACTERS " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
107 swfdec_load_object_as_get_headers (SwfdecAsObject
*object
, guint
*header_count
,
108 char ***header_names
, char ***header_values
)
110 // Should these be filtered at some other point instead?
111 static const char *disallowed_names
[] = { "Accept-Ranges", "Age", "Allow",
112 "Allowed", "Connection", "Content-Length", "Content-Location",
113 "Content-Range", "ETag", "Host", "Last-Modified", "Location",
114 "Max-Forwards", "Proxy-Authenticate", "Proxy-Authorization", "Public",
115 "Range", "Referer", "Retry-After", "Server", "TE", "Trailer",
116 "Transfer-Encoding", "Upgrade", "URI", "Vary", "Via", "Warning",
117 "WWW-Authenticate", "x-flash-version" };
118 GPtrArray
*array_names
, *array_values
;
120 SwfdecAsObject
*list
;
126 cx
= swfdec_gc_object_get_context (object
);
128 array_names
= g_ptr_array_new ();
129 array_values
= g_ptr_array_new ();
131 if (swfdec_as_object_get_variable (object
, SWFDEC_AS_STR_contentType
, &val
))
133 g_ptr_array_add (array_names
, g_strdup (SWFDEC_AS_STR_Content_Type
));
134 g_ptr_array_add (array_values
,
135 g_strdup (swfdec_as_value_to_string (cx
, &val
)));
138 if (!swfdec_as_object_get_variable (object
, SWFDEC_AS_STR__customHeaders
,
141 if (!SWFDEC_AS_VALUE_IS_COMPOSITE (&val
)) {
142 SWFDEC_WARNING ("_customHeaders is not an object");
145 list
= SWFDEC_AS_VALUE_GET_COMPOSITE (&val
);
147 swfdec_as_object_get_variable (list
, SWFDEC_AS_STR_length
, &val
);
148 length
= swfdec_as_value_to_integer (cx
, &val
);
150 /* FIXME: solve this with foreach, so it gets faster for weird cases */
152 for (i
= 0; i
< length
; i
++) {
153 swfdec_as_object_get_variable (list
, swfdec_as_integer_to_string (cx
, i
),
156 name
= swfdec_as_value_to_string (cx
, &val
);
158 const char *value
= swfdec_as_value_to_string (cx
, &val
);
159 for (j
= 0; j
< G_N_ELEMENTS (disallowed_names
); j
++) {
160 if (g_ascii_strcasecmp (name
, disallowed_names
[j
]) == 0)
163 if (j
< G_N_ELEMENTS (disallowed_names
)) {
164 SWFDEC_WARNING ("Custom header with name %s is not allowed", name
);
165 } else if (strspn (name
, ALLOWED_CHARACTERS
) != strlen (name
) || strchr (name
, ':') != NULL
|| strchr (name
, ' ') != NULL
) {
166 SWFDEC_WARNING ("Custom header's name (%s) contains characters that are not allowed", name
);
167 } else if (strspn (value
, ALLOWED_CHARACTERS
) != strlen (value
)) {
168 SWFDEC_WARNING ("Custom header's value (%s) contains characters that are not allowed", value
);
170 g_ptr_array_add (array_names
, g_strdup (name
));
171 g_ptr_array_add (array_values
, g_strdup (value
));
176 // if there is uneven amount of elements, just ignore the last one
178 SWFDEC_WARNING ("_customHeaders with uneven amount of elements");
181 g_assert (array_names
->len
== array_values
->len
);
182 *header_count
= array_names
->len
;
183 g_ptr_array_add (array_names
, NULL
);
184 g_ptr_array_add (array_values
, NULL
);
185 *header_names
= (char **)g_ptr_array_free (array_names
, FALSE
);
186 *header_values
= (char **)g_ptr_array_free (array_values
, FALSE
);
188 #undef ALLOWED_CHARACTERS
190 SWFDEC_AS_NATIVE (301, 1, swfdec_load_object_as_send
)
192 swfdec_load_object_as_send (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
193 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
195 const char *url
, *target
= SWFDEC_AS_STR_EMPTY
, *method
= NULL
, *data
;
197 char **header_names
, **header_values
;
199 SwfdecBuffer
*buffer
;
201 SWFDEC_AS_VALUE_SET_BOOLEAN (rval
, FALSE
);
202 SWFDEC_AS_CHECK (SWFDEC_TYPE_AS_OBJECT
, &object
, "s|ss", &url
, &target
, &method
);
204 SWFDEC_AS_VALUE_SET_COMPOSITE (&val
, object
);
205 data
= swfdec_as_value_to_string (cx
, &val
);
207 if (method
== NULL
|| g_ascii_strcasecmp (method
, "GET") == 0) {
208 url
= swfdec_as_context_give_string (cx
,
209 g_strjoin (NULL
, url
, "?", data
, NULL
));
212 // don't send the nul-byte
213 buffer
= swfdec_buffer_new_for_data (g_memdup (data
, strlen (data
)),
217 swfdec_load_object_as_get_headers (object
, &header_count
, &header_names
,
219 swfdec_player_launch_with_headers (SWFDEC_PLAYER (cx
), url
, target
, buffer
,
220 header_count
, header_names
, header_values
);
222 SWFDEC_AS_VALUE_SET_BOOLEAN (rval
, TRUE
);
225 SWFDEC_AS_NATIVE (301, 2, swfdec_load_object_as_sendAndLoad
)
227 swfdec_load_object_as_sendAndLoad (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
228 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
230 const char *url
, *data
, *method
= NULL
;
232 char **header_names
, **header_values
;
233 SwfdecAsObject
*target
;
235 SwfdecBuffer
*buffer
;
237 SWFDEC_AS_CHECK (SWFDEC_TYPE_AS_OBJECT
, &object
, "so|s", &url
, &target
,
240 SWFDEC_AS_VALUE_SET_COMPOSITE (&val
, object
);
241 data
= swfdec_as_value_to_string (cx
, &val
);
243 if (method
!= NULL
&& g_ascii_strcasecmp (method
, "GET") == 0) {
244 url
= swfdec_as_context_give_string (cx
,
245 g_strjoin (NULL
, url
, "?", data
, NULL
));
248 gsize len
= strlen (data
);
249 // don't send the nul-byte
250 buffer
= swfdec_buffer_new_for_data (g_memdup (data
, len
), len
);
253 swfdec_load_object_as_get_headers (object
, &header_count
, &header_names
,
255 SWFDEC_AS_VALUE_SET_COMPOSITE (&val
, target
);
256 swfdec_load_object_create (SWFDEC_PLAYER (cx
), &val
, url
, buffer
, header_count
, header_names
,
257 header_values
, swfdec_load_object_on_progress
,
258 swfdec_load_object_on_finish
);
260 swfdec_as_value_set_integer (cx
, &val
, 0);
261 swfdec_as_object_set_variable_and_flags (target
, SWFDEC_AS_STR__bytesLoaded
,
262 &val
, SWFDEC_AS_VARIABLE_HIDDEN
);
263 SWFDEC_AS_VALUE_SET_UNDEFINED (&val
);
264 swfdec_as_object_set_variable_and_flags (target
, SWFDEC_AS_STR__bytesTotal
,
265 &val
, SWFDEC_AS_VARIABLE_HIDDEN
);
267 SWFDEC_AS_VALUE_SET_BOOLEAN (&val
, FALSE
);
268 swfdec_as_object_set_variable_and_flags (target
, SWFDEC_AS_STR_loaded
, &val
,
269 SWFDEC_AS_VARIABLE_HIDDEN
);
271 SWFDEC_AS_VALUE_SET_BOOLEAN (rval
, TRUE
);