1/*
2 * Copyright (C) 2009 Jan Michael C. Alonzo
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
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 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB.  If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20#include "config.h"
21#include "webkitwebresource.h"
22
23#include "ArchiveResource.h"
24#include "KURL.h"
25#include "PlatformString.h"
26#include "SharedBuffer.h"
27#include "webkitenumtypes.h"
28#include "webkitglobalsprivate.h"
29#include "webkitmarshal.h"
30#include "webkitwebresourceprivate.h"
31#include <glib.h>
32#include <glib/gi18n-lib.h>
33#include <wtf/Assertions.h>
34#include <wtf/text/CString.h>
35
36/**
37 * SECTION:webkitwebresource
38 * @short_description: Represents a downloaded URI.
39 * @see_also: #WebKitWebDataSource
40 *
41 * A web resource encapsulates the data of the download as well as the URI,
42 * MIME type and frame name of the resource.
43 */
44
45using namespace WebCore;
46
47enum {
48    PROP_0,
49
50    PROP_URI,
51    PROP_MIME_TYPE,
52    PROP_ENCODING,
53    PROP_FRAME_NAME
54};
55
56G_DEFINE_TYPE(WebKitWebResource, webkit_web_resource, G_TYPE_OBJECT);
57
58static void webkit_web_resource_get_property(GObject* object, guint prop_id, GValue* value, GParamSpec* pspec);
59static void webkit_web_resource_set_property(GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec);
60
61static void webkit_web_resource_cleanup(WebKitWebResource* webResource)
62{
63    WebKitWebResourcePrivate* priv = webResource->priv;
64
65    g_free(priv->uri);
66    priv->uri = NULL;
67
68    g_free(priv->mimeType);
69    priv->mimeType = NULL;
70
71    g_free(priv->textEncoding);
72    priv->textEncoding = NULL;
73
74    g_free(priv->frameName);
75    priv->frameName = NULL;
76
77    if (priv->data)
78        g_string_free(priv->data, TRUE);
79    priv->data = NULL;
80}
81
82static void webkit_web_resource_dispose(GObject* object)
83{
84    WebKitWebResource* webResource = WEBKIT_WEB_RESOURCE(object);
85    WebKitWebResourcePrivate* priv = webResource->priv;
86
87    if (priv->resource) {
88        priv->resource->deref();
89        priv->resource = 0;
90    }
91
92    G_OBJECT_CLASS(webkit_web_resource_parent_class)->dispose(object);
93}
94
95static void webkit_web_resource_finalize(GObject* object)
96{
97    WebKitWebResource* webResource = WEBKIT_WEB_RESOURCE(object);
98
99    webkit_web_resource_cleanup(webResource);
100
101    G_OBJECT_CLASS(webkit_web_resource_parent_class)->finalize(object);
102}
103
104static void webkit_web_resource_class_init(WebKitWebResourceClass* klass)
105{
106    GObjectClass* gobject_class = G_OBJECT_CLASS(klass);
107
108    gobject_class->dispose = webkit_web_resource_dispose;
109    gobject_class->finalize = webkit_web_resource_finalize;
110    gobject_class->get_property = webkit_web_resource_get_property;
111    gobject_class->set_property = webkit_web_resource_set_property;
112
113    /**
114     * WebKitWebResource:uri:
115     *
116     * The URI of the web resource
117     *
118     * Since: 1.1.14
119     */
120    g_object_class_install_property(gobject_class,
121                                    PROP_URI,
122                                    g_param_spec_string(
123                                    "uri",
124                                    _("URI"),
125                                    _("The uri of the resource"),
126                                    NULL,
127                                    (GParamFlags)(WEBKIT_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)));
128    /**
129     * WebKitWebResource:mime-type:
130     *
131     * The MIME type of the web resource.
132     *
133     * Since: 1.1.14
134     */
135    g_object_class_install_property(gobject_class,
136                                    PROP_MIME_TYPE,
137                                    g_param_spec_string(
138                                    "mime-type",
139                                    _("MIME Type"),
140                                    _("The MIME type of the resource"),
141                                    NULL,
142                                    WEBKIT_PARAM_READABLE));
143    /**
144     * WebKitWebResource:encoding:
145     *
146     * The encoding name to which the web resource was encoded in.
147     *
148     * Since: 1.1.14
149     */
150    g_object_class_install_property(gobject_class,
151                                    PROP_ENCODING,
152                                    g_param_spec_string(
153                                    "encoding",
154                                    _("Encoding"),
155                                    _("The text encoding name of the resource"),
156                                    NULL,
157                                    WEBKIT_PARAM_READABLE));
158
159    /**
160     * WebKitWebResource:frame-name:
161     *
162     * The frame name for the web resource.
163     *
164     * Since: 1.1.14
165     */
166    g_object_class_install_property(gobject_class,
167                                    PROP_FRAME_NAME,
168                                    g_param_spec_string(
169                                    "frame-name",
170                                    _("Frame Name"),
171                                    _("The frame name of the resource"),
172                                    NULL,
173                                    WEBKIT_PARAM_READABLE));
174
175    g_type_class_add_private(gobject_class, sizeof(WebKitWebResourcePrivate));
176}
177
178static void webkit_web_resource_get_property(GObject* object, guint prop_id, GValue* value, GParamSpec* pspec)
179{
180    WebKitWebResource* webResource = WEBKIT_WEB_RESOURCE(object);
181
182    switch (prop_id) {
183    case PROP_URI:
184        g_value_set_string(value, webkit_web_resource_get_uri(webResource));
185        break;
186    case PROP_MIME_TYPE:
187        g_value_set_string(value, webkit_web_resource_get_mime_type(webResource));
188        break;
189    case PROP_ENCODING:
190        g_value_set_string(value, webkit_web_resource_get_encoding(webResource));
191        break;
192    case PROP_FRAME_NAME:
193        g_value_set_string(value, webkit_web_resource_get_frame_name(webResource));
194        break;
195    default:
196        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
197        break;
198    }
199}
200
201static void webkit_web_resource_set_property(GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec)
202{
203    WebKitWebResource* webResource = WEBKIT_WEB_RESOURCE(object);
204
205    switch (prop_id) {
206    case PROP_URI:
207        g_free(webResource->priv->uri);
208        webResource->priv->uri = g_value_dup_string(value);
209        break;
210    default:
211        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
212        break;
213    }
214}
215
216static void webkit_web_resource_init(WebKitWebResource* webResource)
217{
218    webResource->priv = G_TYPE_INSTANCE_GET_PRIVATE(webResource, WEBKIT_TYPE_WEB_RESOURCE, WebKitWebResourcePrivate);
219}
220
221// internal use only
222WebKitWebResource* webkit_web_resource_new_with_core_resource(PassRefPtr<ArchiveResource> resource)
223{
224    WebKitWebResource* webResource = WEBKIT_WEB_RESOURCE(g_object_new(WEBKIT_TYPE_WEB_RESOURCE, NULL));
225    WebKitWebResourcePrivate* priv = webResource->priv;
226    priv->resource = resource.releaseRef();
227
228    return webResource;
229}
230
231void webkit_web_resource_init_with_core_resource(WebKitWebResource* webResource, PassRefPtr<ArchiveResource> resource)
232{
233    ASSERT(resource);
234
235    WebKitWebResourcePrivate* priv = webResource->priv;
236
237    if (priv->resource)
238        priv->resource->deref();
239
240    priv->resource = resource.releaseRef();
241}
242
243/**
244 * webkit_web_resource_new:
245 * @data: the data to initialize the #WebKitWebResource
246 * @size: the length of @data
247 * @uri: the uri of the #WebKitWebResource
248 * @mime_type: the MIME type of the #WebKitWebResource
249 * @encoding: the text encoding name of the #WebKitWebResource
250 * @frame_name: the frame name of the #WebKitWebResource
251 *
252 * Returns a new #WebKitWebResource. The @encoding can be %NULL. The
253 * @frame_name argument can be used if the resource represents contents of an
254 * entire HTML frame, otherwise pass %NULL.
255 *
256 * Return value: a new #WebKitWebResource
257 *
258 * Since: 1.1.14
259 */
260WebKitWebResource* webkit_web_resource_new(const gchar* data,
261                                           gssize size,
262                                           const gchar* uri,
263                                           const gchar* mimeType,
264                                           const gchar* encoding,
265                                           const gchar* frameName)
266{
267    g_return_val_if_fail(data, NULL);
268    g_return_val_if_fail(uri, NULL);
269    g_return_val_if_fail(mimeType, NULL);
270
271    if (size < 0)
272        size = strlen(data);
273
274    RefPtr<SharedBuffer> buffer = SharedBuffer::create(data, size);
275    WebKitWebResource* webResource = webkit_web_resource_new_with_core_resource(ArchiveResource::create(buffer, KURL(KURL(), String::fromUTF8(uri)), String::fromUTF8(mimeType), String::fromUTF8(encoding), String::fromUTF8(frameName)));
276
277    return webResource;
278}
279
280/**
281 * webkit_web_resource_get_data:
282 * @web_resource: a #WebKitWebResource
283 *
284 * Returns the data of the @webResource.
285 *
286 * Return value: (transfer none): a #GString containing the character
287 * data of the @webResource.  The string is owned by WebKit and should
288 * not be freed or destroyed.
289 *
290 * Since: 1.1.14
291 */
292GString* webkit_web_resource_get_data(WebKitWebResource* webResource)
293{
294    g_return_val_if_fail(WEBKIT_IS_WEB_RESOURCE(webResource), NULL);
295
296    WebKitWebResourcePrivate* priv = webResource->priv;
297
298    if (!priv->resource)
299        return NULL;
300
301    if (!priv->data)
302        priv->data = g_string_new_len(priv->resource->data()->data(), priv->resource->data()->size());
303
304    return priv->data;
305}
306
307/**
308 * webkit_web_resource_get_uri:
309 * @web_resource: a #WebKitWebResource
310 *
311 * Return value: the URI of the resource
312 *
313 * Since: 1.1.14
314 */
315G_CONST_RETURN gchar* webkit_web_resource_get_uri(WebKitWebResource* webResource)
316{
317    g_return_val_if_fail(WEBKIT_IS_WEB_RESOURCE(webResource), NULL);
318
319    WebKitWebResourcePrivate* priv = webResource->priv;
320
321
322    // We may have an URI without having a resource assigned to us (e.g., if the
323    // FrameLoaderClient only had a ResourceRequest when we got created
324    if (priv->uri)
325        return priv->uri;
326
327    if (!priv->resource)
328        return NULL;
329
330    priv->uri = g_strdup(priv->resource->url().string().utf8().data());
331
332    return priv->uri;
333}
334
335/**
336 * webkit_web_resource_get_mime_type:
337 * @web_resource: a #WebKitWebResource
338 *
339 * Return value: the MIME type of the resource
340 *
341 * Since: 1.1.14
342 */
343G_CONST_RETURN gchar* webkit_web_resource_get_mime_type(WebKitWebResource* webResource)
344{
345    g_return_val_if_fail(WEBKIT_IS_WEB_RESOURCE(webResource), NULL);
346
347    WebKitWebResourcePrivate* priv = webResource->priv;
348    if (!priv->resource)
349        return NULL;
350
351    if (!priv->mimeType)
352        priv->mimeType = g_strdup(priv->resource->mimeType().utf8().data());
353
354    return priv->mimeType;
355}
356
357/**
358 * webkit_web_resource_get_encoding:
359 * @web_resource: a #WebKitWebResource
360 *
361 * Return value: the encoding name of the resource
362 *
363 * Since: 1.1.14
364 */
365G_CONST_RETURN gchar* webkit_web_resource_get_encoding(WebKitWebResource* webResource)
366{
367    g_return_val_if_fail(WEBKIT_IS_WEB_RESOURCE(webResource), NULL);
368
369    WebKitWebResourcePrivate* priv = webResource->priv;
370    if (!priv->resource)
371        return NULL;
372
373    if (!priv->textEncoding)
374        priv->textEncoding = g_strdup(priv->resource->textEncoding().utf8().data());
375
376    return priv->textEncoding;
377}
378
379/**
380 * webkit_web_resource_get_frame_name:
381 * @web_resource: a #WebKitWebResource
382 *
383 * Return value: the frame name of the resource.
384 *
385 * Since: 1.1.14
386 */
387G_CONST_RETURN gchar* webkit_web_resource_get_frame_name(WebKitWebResource* webResource)
388{
389    g_return_val_if_fail(WEBKIT_IS_WEB_RESOURCE(webResource), NULL);
390
391    WebKitWebResourcePrivate* priv = webResource->priv;
392    if (!priv->resource)
393        return NULL;
394
395    if (!priv->frameName)
396        priv->frameName = g_strdup(priv->resource->frameName().utf8().data());
397
398    return priv->frameName;
399}
400
401