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 (0, NULL
, "s", &url
);
89 SWFDEC_AS_VALUE_SET_COMPOSITE (&val
, object
);
90 swfdec_load_object_create (SWFDEC_PLAYER (cx
), &val
, url
, NULL
, 0, NULL
, NULL
,
91 swfdec_load_object_on_progress
, swfdec_load_object_on_finish
);
93 swfdec_as_value_set_integer (cx
, &val
, 0);
94 swfdec_as_object_set_variable_and_flags (object
, SWFDEC_AS_STR__bytesLoaded
,
95 &val
, SWFDEC_AS_VARIABLE_HIDDEN
);
96 SWFDEC_AS_VALUE_SET_UNDEFINED (&val
);
97 swfdec_as_object_set_variable_and_flags (object
, SWFDEC_AS_STR__bytesTotal
,
98 &val
, SWFDEC_AS_VARIABLE_HIDDEN
);
100 SWFDEC_AS_VALUE_SET_BOOLEAN (&val
, FALSE
);
101 swfdec_as_object_set_variable_and_flags (object
, SWFDEC_AS_STR_loaded
, &val
,
102 SWFDEC_AS_VARIABLE_HIDDEN
);
104 SWFDEC_AS_VALUE_SET_BOOLEAN (rval
, TRUE
);
107 #define ALLOWED_CHARACTERS " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
109 swfdec_load_object_as_get_headers (SwfdecAsObject
*object
, guint
*header_count
,
110 char ***header_names
, char ***header_values
)
112 // Should these be filtered at some other point instead?
113 static const char *disallowed_names
[] = { "Accept-Ranges", "Age", "Allow",
114 "Allowed", "Connection", "Content-Length", "Content-Location",
115 "Content-Range", "ETag", "Host", "Last-Modified", "Location",
116 "Max-Forwards", "Proxy-Authenticate", "Proxy-Authorization", "Public",
117 "Range", "Referer", "Retry-After", "Server", "TE", "Trailer",
118 "Transfer-Encoding", "Upgrade", "URI", "Vary", "Via", "Warning",
119 "WWW-Authenticate", "x-flash-version" };
120 GPtrArray
*array_names
, *array_values
;
122 SwfdecAsObject
*list
;
128 cx
= object
->context
;
130 array_names
= g_ptr_array_new ();
131 array_values
= g_ptr_array_new ();
133 if (swfdec_as_object_get_variable (object
, SWFDEC_AS_STR_contentType
, &val
))
135 g_ptr_array_add (array_names
, g_strdup (SWFDEC_AS_STR_Content_Type
));
136 g_ptr_array_add (array_values
,
137 g_strdup (swfdec_as_value_to_string (cx
, val
)));
140 if (!swfdec_as_object_get_variable (object
, SWFDEC_AS_STR__customHeaders
,
143 if (!SWFDEC_AS_VALUE_IS_COMPOSITE (&val
)) {
144 SWFDEC_WARNING ("_customHeaders is not an object");
147 list
= SWFDEC_AS_VALUE_GET_COMPOSITE (&val
);
149 swfdec_as_object_get_variable (list
, SWFDEC_AS_STR_length
, &val
);
150 length
= swfdec_as_value_to_integer (cx
, &val
);
152 /* FIXME: solve this with foreach, so it gets faster for weird cases */
154 for (i
= 0; i
< length
; i
++) {
155 swfdec_as_object_get_variable (list
, swfdec_as_integer_to_string (cx
, i
),
158 name
= swfdec_as_value_to_string (cx
, val
);
160 const char *value
= swfdec_as_value_to_string (cx
, val
);
161 for (j
= 0; j
< G_N_ELEMENTS (disallowed_names
); j
++) {
162 if (g_ascii_strcasecmp (name
, disallowed_names
[j
]) == 0)
165 if (j
< G_N_ELEMENTS (disallowed_names
)) {
166 SWFDEC_WARNING ("Custom header with name %s is not allowed", name
);
167 } else if (strspn (name
, ALLOWED_CHARACTERS
) != strlen (name
) || strchr (name
, ':') != NULL
|| strchr (name
, ' ') != NULL
) {
168 SWFDEC_WARNING ("Custom header's name (%s) contains characters that are not allowed", name
);
169 } else if (strspn (value
, ALLOWED_CHARACTERS
) != strlen (value
)) {
170 SWFDEC_WARNING ("Custom header's value (%s) contains characters that are not allowed", value
);
172 g_ptr_array_add (array_names
, g_strdup (name
));
173 g_ptr_array_add (array_values
, g_strdup (value
));
178 // if there is uneven amount of elements, just ignore the last one
180 SWFDEC_WARNING ("_customHeaders with uneven amount of elements");
183 g_assert (array_names
->len
== array_values
->len
);
184 *header_count
= array_names
->len
;
185 g_ptr_array_add (array_names
, NULL
);
186 g_ptr_array_add (array_values
, NULL
);
187 *header_names
= (char **)g_ptr_array_free (array_names
, FALSE
);
188 *header_values
= (char **)g_ptr_array_free (array_values
, FALSE
);
190 #undef ALLOWED_CHARACTERS
192 SWFDEC_AS_NATIVE (301, 1, swfdec_load_object_as_send
)
194 swfdec_load_object_as_send (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
195 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
197 const char *url
, *target
= SWFDEC_AS_STR_EMPTY
, *method
= NULL
, *data
;
199 char **header_names
, **header_values
;
201 SwfdecBuffer
*buffer
;
203 SWFDEC_AS_VALUE_SET_BOOLEAN (rval
, FALSE
);
204 SWFDEC_AS_CHECK (0, NULL
, "s|ss", &url
, &target
, &method
);
208 SWFDEC_AS_VALUE_SET_COMPOSITE (&val
, object
);
209 data
= swfdec_as_value_to_string (cx
, val
);
211 if (method
== NULL
|| g_ascii_strcasecmp (method
, "GET") == 0) {
212 url
= swfdec_as_context_give_string (cx
,
213 g_strjoin (NULL
, url
, "?", data
, NULL
));
216 // don't send the nul-byte
217 buffer
= swfdec_buffer_new_for_data (g_memdup (data
, strlen (data
)),
221 swfdec_load_object_as_get_headers (object
, &header_count
, &header_names
,
223 swfdec_player_launch_with_headers (SWFDEC_PLAYER (cx
), url
, target
, buffer
,
224 header_count
, header_names
, header_values
);
226 SWFDEC_AS_VALUE_SET_BOOLEAN (rval
, TRUE
);
229 SWFDEC_AS_NATIVE (301, 2, swfdec_load_object_as_sendAndLoad
)
231 swfdec_load_object_as_sendAndLoad (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
232 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
234 const char *url
, *data
, *method
= NULL
;
236 char **header_names
, **header_values
;
237 SwfdecAsObject
*target
;
239 SwfdecBuffer
*buffer
;
241 SWFDEC_AS_CHECK (0, NULL
, "so|s", &url
, &target
,
246 SWFDEC_AS_VALUE_SET_COMPOSITE (&val
, object
);
247 data
= swfdec_as_value_to_string (cx
, val
);
249 if (method
!= NULL
&& g_ascii_strcasecmp (method
, "GET") == 0) {
250 url
= swfdec_as_context_give_string (cx
,
251 g_strjoin (NULL
, url
, "?", data
, NULL
));
254 gsize len
= strlen (data
);
255 // don't send the nul-byte
256 buffer
= swfdec_buffer_new_for_data (g_memdup (data
, len
), len
);
259 swfdec_load_object_as_get_headers (object
, &header_count
, &header_names
,
261 SWFDEC_AS_VALUE_SET_COMPOSITE (&val
, target
);
262 swfdec_load_object_create (SWFDEC_PLAYER (cx
), &val
, url
, buffer
, header_count
, header_names
,
263 header_values
, swfdec_load_object_on_progress
,
264 swfdec_load_object_on_finish
);
266 swfdec_as_value_set_integer (cx
, &val
, 0);
267 swfdec_as_object_set_variable_and_flags (target
, SWFDEC_AS_STR__bytesLoaded
,
268 &val
, SWFDEC_AS_VARIABLE_HIDDEN
);
269 SWFDEC_AS_VALUE_SET_UNDEFINED (&val
);
270 swfdec_as_object_set_variable_and_flags (target
, SWFDEC_AS_STR__bytesTotal
,
271 &val
, SWFDEC_AS_VARIABLE_HIDDEN
);
273 SWFDEC_AS_VALUE_SET_BOOLEAN (&val
, FALSE
);
274 swfdec_as_object_set_variable_and_flags (target
, SWFDEC_AS_STR_loaded
, &val
,
275 SWFDEC_AS_VARIABLE_HIDDEN
);
277 SWFDEC_AS_VALUE_SET_BOOLEAN (rval
, TRUE
);