back to development
[swfdec.git] / swfdec / swfdec_load_object_as.c
bloba1a7956e39760f480f868e27c162ab28d961f128
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 (SwfdecAsObject *target, const char *text)
36 SwfdecAsValue val;
38 if (text != NULL) {
39 SWFDEC_AS_VALUE_SET_STRING (&val, text);
40 } else {
41 SWFDEC_AS_VALUE_SET_UNDEFINED (&val);
44 swfdec_as_object_call (target, SWFDEC_AS_STR_onData, 1, &val, NULL);
47 static void
48 swfdec_load_object_on_progress (SwfdecAsObject *target, glong size,
49 glong loaded)
51 SwfdecAsValue val;
53 SWFDEC_AS_VALUE_SET_NUMBER (&val, loaded);
54 swfdec_as_object_set_variable_and_flags (target, SWFDEC_AS_STR__bytesLoaded,
55 &val, SWFDEC_AS_VARIABLE_HIDDEN);
57 if (size >= 0) {
58 SWFDEC_AS_VALUE_SET_NUMBER (&val, size);
59 } else {
60 SWFDEC_AS_VALUE_SET_NUMBER (&val, loaded);
62 swfdec_as_object_set_variable_and_flags (target, SWFDEC_AS_STR__bytesTotal,
63 &val, SWFDEC_AS_VARIABLE_HIDDEN);
66 SWFDEC_AS_NATIVE (301, 0, swfdec_load_object_as_load)
67 void
68 swfdec_load_object_as_load (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc,
69 SwfdecAsValue *argv, SwfdecAsValue *rval)
71 SwfdecAsValue val;
72 const char *url;
74 SWFDEC_AS_VALUE_SET_BOOLEAN (rval, FALSE);
75 SWFDEC_AS_CHECK (SWFDEC_TYPE_AS_OBJECT, &object, "s", &url);
77 swfdec_load_object_create (object, url, NULL, 0, NULL, NULL,
78 swfdec_load_object_on_progress, swfdec_load_object_on_finish);
80 SWFDEC_AS_VALUE_SET_INT (&val, 0);
81 swfdec_as_object_set_variable_and_flags (object, SWFDEC_AS_STR__bytesLoaded,
82 &val, SWFDEC_AS_VARIABLE_HIDDEN);
83 SWFDEC_AS_VALUE_SET_UNDEFINED (&val);
84 swfdec_as_object_set_variable_and_flags (object, SWFDEC_AS_STR__bytesTotal,
85 &val, SWFDEC_AS_VARIABLE_HIDDEN);
87 SWFDEC_AS_VALUE_SET_BOOLEAN (&val, FALSE);
88 swfdec_as_object_set_variable_and_flags (object, SWFDEC_AS_STR_loaded, &val,
89 SWFDEC_AS_VARIABLE_HIDDEN);
91 SWFDEC_AS_VALUE_SET_BOOLEAN (rval, TRUE);
94 #define ALLOWED_CHARACTERS " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
95 static void
96 swfdec_load_object_as_get_headers (SwfdecAsObject *object, guint *header_count,
97 char ***header_names, char ***header_values)
99 // Should these be filtered at some other point instead?
100 static const char *disallowed_names[] = { "Accept-Ranges", "Age", "Allow",
101 "Allowed", "Connection", "Content-Length", "Content-Location",
102 "Content-Range", "ETag", "Host", "Last-Modified", "Location",
103 "Max-Forwards", "Proxy-Authenticate", "Proxy-Authorization", "Public",
104 "Range", "Referer", "Retry-After", "Server", "TE", "Trailer",
105 "Transfer-Encoding", "Upgrade", "URI", "Vary", "Via", "Warning",
106 "WWW-Authenticate", "x-flash-version" };
107 GPtrArray *array_names, *array_values;
108 SwfdecAsValue val;
109 SwfdecAsObject *list;
110 int i, length;
111 guint j;
112 const char *name;
113 SwfdecAsContext *cx;
115 cx = swfdec_gc_object_get_context (object);
117 array_names = g_ptr_array_new ();
118 array_values = g_ptr_array_new ();
120 if (swfdec_as_object_get_variable (object, SWFDEC_AS_STR_contentType, &val))
122 g_ptr_array_add (array_names, g_strdup (SWFDEC_AS_STR_Content_Type));
123 g_ptr_array_add (array_values,
124 g_strdup (swfdec_as_value_to_string (cx, &val)));
127 if (!swfdec_as_object_get_variable (object, SWFDEC_AS_STR__customHeaders,
128 &val))
129 goto end;
130 if (!SWFDEC_AS_VALUE_IS_OBJECT (&val)) {
131 SWFDEC_WARNING ("_customHeaders is not an object");
132 goto end;
134 list = SWFDEC_AS_VALUE_GET_OBJECT (&val);
136 swfdec_as_object_get_variable (list, SWFDEC_AS_STR_length, &val);
137 length = swfdec_as_value_to_integer (cx, &val);
139 /* FIXME: solve this with foreach, so it gets faster for weird cases */
140 name = NULL;
141 for (i = 0; i < length; i++) {
142 swfdec_as_object_get_variable (list, swfdec_as_integer_to_string (cx, i),
143 &val);
144 if (name == NULL) {
145 name = swfdec_as_value_to_string (cx, &val);
146 } else {
147 const char *value = swfdec_as_value_to_string (cx, &val);
148 for (j = 0; j < G_N_ELEMENTS (disallowed_names); j++) {
149 if (g_ascii_strcasecmp (name, disallowed_names[j]) == 0)
150 break;
152 if (j < G_N_ELEMENTS (disallowed_names)) {
153 SWFDEC_WARNING ("Custom header with name %s is not allowed", name);
154 } else if (strspn (name, ALLOWED_CHARACTERS) != strlen (name) || strchr (name, ':') != NULL || strchr (name, ' ') != NULL) {
155 SWFDEC_WARNING ("Custom header's name (%s) contains characters that are not allowed", name);
156 } else if (strspn (value, ALLOWED_CHARACTERS) != strlen (value)) {
157 SWFDEC_WARNING ("Custom header's value (%s) contains characters that are not allowed", value);
158 } else {
159 g_ptr_array_add (array_names, g_strdup (name));
160 g_ptr_array_add (array_values, g_strdup (value));
162 name = NULL;
165 // if there is uneven amount of elements, just ignore the last one
166 if (name != NULL)
167 SWFDEC_WARNING ("_customHeaders with uneven amount of elements");
169 end:
170 g_assert (array_names->len == array_values->len);
171 *header_count = array_names->len;
172 g_ptr_array_add (array_names, NULL);
173 g_ptr_array_add (array_values, NULL);
174 *header_names = (char **)g_ptr_array_free (array_names, FALSE);
175 *header_values = (char **)g_ptr_array_free (array_values, FALSE);
177 #undef ALLOWED_CHARACTERS
179 SWFDEC_AS_NATIVE (301, 1, swfdec_load_object_as_send)
180 void
181 swfdec_load_object_as_send (SwfdecAsContext *cx, SwfdecAsObject *object,
182 guint argc, SwfdecAsValue *argv, SwfdecAsValue *rval)
184 const char *url, *target = SWFDEC_AS_STR_EMPTY, *method = NULL, *data;
185 guint header_count;
186 char **header_names, **header_values;
187 SwfdecAsValue val;
188 SwfdecBuffer *buffer;
190 SWFDEC_AS_VALUE_SET_BOOLEAN (rval, FALSE);
191 SWFDEC_AS_CHECK (SWFDEC_TYPE_AS_OBJECT, &object, "s|ss", &url, &target, &method);
193 SWFDEC_AS_VALUE_SET_OBJECT (&val, object);
194 data = swfdec_as_value_to_string (cx, &val);
196 if (method == NULL || g_ascii_strcasecmp (method, "GET") == 0) {
197 url = swfdec_as_context_give_string (cx,
198 g_strjoin (NULL, url, "?", data, NULL));
199 buffer = NULL;
200 } else {
201 // don't send the nul-byte
202 buffer = swfdec_buffer_new_for_data (g_memdup (data, strlen (data)),
203 strlen (data));
206 swfdec_load_object_as_get_headers (object, &header_count, &header_names,
207 &header_values);
208 swfdec_player_launch_with_headers (SWFDEC_PLAYER (cx), url, target, buffer,
209 header_count, header_names, header_values);
211 SWFDEC_AS_VALUE_SET_BOOLEAN (rval, TRUE);
214 SWFDEC_AS_NATIVE (301, 2, swfdec_load_object_as_sendAndLoad)
215 void
216 swfdec_load_object_as_sendAndLoad (SwfdecAsContext *cx, SwfdecAsObject *object,
217 guint argc, SwfdecAsValue *argv, SwfdecAsValue *rval)
219 const char *url, *data, *method = NULL;
220 guint header_count;
221 char **header_names, **header_values;
222 SwfdecAsObject *target;
223 SwfdecAsValue val;
224 SwfdecBuffer *buffer;
226 SWFDEC_AS_CHECK (SWFDEC_TYPE_AS_OBJECT, &object, "so|s", &url, &target,
227 &method);
229 SWFDEC_AS_VALUE_SET_OBJECT (&val, object);
230 data = swfdec_as_value_to_string (cx, &val);
232 if (method == NULL || g_ascii_strcasecmp (method, "GET") == 0) {
233 url = swfdec_as_context_give_string (cx,
234 g_strjoin (NULL, url, "?", data, NULL));
235 buffer = NULL;
236 } else {
237 // don't send the nul-byte
238 buffer = swfdec_buffer_new_for_data (g_memdup (data, strlen (data)),
239 strlen (data));
242 swfdec_load_object_as_get_headers (object, &header_count, &header_names,
243 &header_values);
244 swfdec_load_object_create (target, url, buffer, header_count, header_names,
245 header_values, swfdec_load_object_on_progress,
246 swfdec_load_object_on_finish);
248 SWFDEC_AS_VALUE_SET_INT (&val, 0);
249 swfdec_as_object_set_variable_and_flags (target, SWFDEC_AS_STR__bytesLoaded,
250 &val, SWFDEC_AS_VARIABLE_HIDDEN);
251 SWFDEC_AS_VALUE_SET_UNDEFINED (&val);
252 swfdec_as_object_set_variable_and_flags (target, SWFDEC_AS_STR__bytesTotal,
253 &val, SWFDEC_AS_VARIABLE_HIDDEN);
255 SWFDEC_AS_VALUE_SET_BOOLEAN (&val, FALSE);
256 swfdec_as_object_set_variable_and_flags (target, SWFDEC_AS_STR_loaded, &val,
257 SWFDEC_AS_VARIABLE_HIDDEN);
259 SWFDEC_AS_VALUE_SET_BOOLEAN (rval, TRUE);