actually set the variable here
[swfdec.git] / swfdec / swfdec_load_object_as.c
blob1f41642420165cc8c94f841224ac223065de54ac
1 /* Swfdec
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.
9 *
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
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
25 #include <string.h>
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"
33 static void
34 swfdec_load_object_on_finish (SwfdecPlayer *player, const SwfdecAsValue *target, const char *text)
36 SwfdecAsObject *object;
37 SwfdecAsValue val;
39 object = SWFDEC_AS_VALUE_GET_COMPOSITE (target);
40 if (object == NULL)
41 return;
43 if (text != NULL) {
44 SWFDEC_AS_VALUE_SET_STRING (&val, text);
45 } else {
46 SWFDEC_AS_VALUE_SET_UNDEFINED (&val);
49 swfdec_as_object_call (object, SWFDEC_AS_STR_onData, 1, &val, NULL);
52 static void
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;
58 SwfdecAsValue val;
60 object = SWFDEC_AS_VALUE_GET_COMPOSITE (target);
61 if (object == NULL)
62 return;
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);
67 if (size >= 0) {
68 swfdec_as_value_set_number (cx, &val, size);
69 } else {
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)
77 void
78 swfdec_load_object_as_load (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc,
79 SwfdecAsValue *argv, SwfdecAsValue *rval)
81 SwfdecAsValue val;
82 const char *url;
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{|}~"
106 static void
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;
119 SwfdecAsValue val;
120 SwfdecAsObject *list;
121 int i, length;
122 guint j;
123 const char *name;
124 SwfdecAsContext *cx;
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,
139 &val))
140 goto end;
141 if (!SWFDEC_AS_VALUE_IS_COMPOSITE (&val)) {
142 SWFDEC_WARNING ("_customHeaders is not an object");
143 goto end;
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 */
151 name = NULL;
152 for (i = 0; i < length; i++) {
153 swfdec_as_object_get_variable (list, swfdec_as_integer_to_string (cx, i),
154 &val);
155 if (name == NULL) {
156 name = swfdec_as_value_to_string (cx, &val);
157 } else {
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)
161 break;
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);
169 } else {
170 g_ptr_array_add (array_names, g_strdup (name));
171 g_ptr_array_add (array_values, g_strdup (value));
173 name = NULL;
176 // if there is uneven amount of elements, just ignore the last one
177 if (name != NULL)
178 SWFDEC_WARNING ("_customHeaders with uneven amount of elements");
180 end:
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)
191 void
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;
196 guint header_count;
197 char **header_names, **header_values;
198 SwfdecAsValue val;
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));
210 buffer = NULL;
211 } else {
212 // don't send the nul-byte
213 buffer = swfdec_buffer_new_for_data (g_memdup (data, strlen (data)),
214 strlen (data));
217 swfdec_load_object_as_get_headers (object, &header_count, &header_names,
218 &header_values);
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)
226 void
227 swfdec_load_object_as_sendAndLoad (SwfdecAsContext *cx, SwfdecAsObject *object,
228 guint argc, SwfdecAsValue *argv, SwfdecAsValue *rval)
230 const char *url, *data, *method = NULL;
231 guint header_count;
232 char **header_names, **header_values;
233 SwfdecAsObject *target;
234 SwfdecAsValue val;
235 SwfdecBuffer *buffer;
237 SWFDEC_AS_CHECK (SWFDEC_TYPE_AS_OBJECT, &object, "so|s", &url, &target,
238 &method);
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));
246 buffer = NULL;
247 } else {
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,
254 &header_values);
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);