1/*
2 * Copyright (C) 2011 Igalia S.L.
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 "WebKitURIResponse.h"
22
23#include "WebKitURIResponsePrivate.h"
24#include <WebCore/GUniquePtrSoup.h>
25#include <glib/gi18n-lib.h>
26#include <wtf/glib/WTFGType.h>
27#include <wtf/text/CString.h>
28
29using namespace WebCore;
30
31/**
32 * SECTION: WebKitURIResponse
33 * @Short_description: Represents a URI response
34 * @Title: WebKitURIResponse
35 *
36 * A #WebKitURIResponse contains information such as the URI, the
37 * status code, the content length, the mime type, the HTTP status or
38 * the suggested filename.
39 *
40 */
41
42enum {
43 PROP_0,
44
45 PROP_URI,
46 PROP_STATUS_CODE,
47 PROP_CONTENT_LENGTH,
48 PROP_MIME_TYPE,
49 PROP_SUGGESTED_FILENAME,
50 PROP_HTTP_HEADERS
51};
52
53struct _WebKitURIResponsePrivate {
54 ResourceResponse resourceResponse;
55 CString uri;
56 CString mimeType;
57 CString suggestedFilename;
58 GUniquePtr<SoupMessageHeaders> httpHeaders;
59};
60
61WEBKIT_DEFINE_TYPE(WebKitURIResponse, webkit_uri_response, G_TYPE_OBJECT)
62
63static void webkitURIResponseGetProperty(GObject* object, guint propId, GValue* value, GParamSpec* paramSpec)
64{
65 WebKitURIResponse* response = WEBKIT_URI_RESPONSE(object);
66
67 switch (propId) {
68 case PROP_URI:
69 g_value_set_string(value, webkit_uri_response_get_uri(response));
70 break;
71 case PROP_STATUS_CODE:
72 g_value_set_uint(value, webkit_uri_response_get_status_code(response));
73 break;
74 case PROP_CONTENT_LENGTH:
75 g_value_set_uint64(value, webkit_uri_response_get_content_length(response));
76 break;
77 case PROP_MIME_TYPE:
78 g_value_set_string(value, webkit_uri_response_get_mime_type(response));
79 break;
80 case PROP_SUGGESTED_FILENAME:
81 g_value_set_string(value, webkit_uri_response_get_suggested_filename(response));
82 break;
83 case PROP_HTTP_HEADERS:
84 g_value_set_boxed(value, webkit_uri_response_get_http_headers(response));
85 break;
86 default:
87 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec);
88 }
89}
90
91static void webkit_uri_response_class_init(WebKitURIResponseClass* responseClass)
92{
93 GObjectClass* objectClass = G_OBJECT_CLASS(responseClass);
94 objectClass->get_property = webkitURIResponseGetProperty;
95
96 /**
97 * WebKitURIResponse:uri:
98 *
99 * The URI for which the response was made.
100 */
101 g_object_class_install_property(objectClass,
102 PROP_URI,
103 g_param_spec_string("uri",
104 _("URI"),
105 _("The URI for which the response was made."),
106 0,
107 WEBKIT_PARAM_READABLE));
108 /**
109 * WebKitURIResponse:status-code:
110 *
111 * The status code of the response as returned by the server.
112 */
113 g_object_class_install_property(objectClass,
114 PROP_STATUS_CODE,
115 g_param_spec_uint("status-code",
116 _("Status Code"),
117 _("The status code of the response as returned by the server."),
118 0, G_MAXUINT, SOUP_STATUS_NONE,
119 WEBKIT_PARAM_READABLE));
120
121 /**
122 * WebKitURIResponse:content-length:
123 *
124 * The expected content length of the response.
125 */
126 g_object_class_install_property(objectClass,
127 PROP_CONTENT_LENGTH,
128 g_param_spec_uint64("content-length",
129 _("Content Length"),
130 _("The expected content length of the response."),
131 0, G_MAXUINT64, 0,
132 WEBKIT_PARAM_READABLE));
133
134 /**
135 * WebKitURIResponse:mime-type:
136 *
137 * The MIME type of the response.
138 */
139 g_object_class_install_property(objectClass,
140 PROP_MIME_TYPE,
141 g_param_spec_string("mime-type",
142 _("MIME Type"),
143 _("The MIME type of the response"),
144 0,
145 WEBKIT_PARAM_READABLE));
146
147 /**
148 * WebKitURIResponse:suggested-filename:
149 *
150 * The suggested filename for the URI response.
151 */
152 g_object_class_install_property(objectClass,
153 PROP_SUGGESTED_FILENAME,
154 g_param_spec_string("suggested-filename",
155 _("Suggested Filename"),
156 _("The suggested filename for the URI response"),
157 0,
158 WEBKIT_PARAM_READABLE));
159
160 /**
161 * WebKitURIResponse:http-headers:
162 *
163 * The HTTP headers of the response, or %NULL if the response is not an HTTP response.
164 *
165 * Since: 2.6
166 */
167 g_object_class_install_property(
168 objectClass,
169 PROP_HTTP_HEADERS,
170 g_param_spec_boxed(
171 "http-headers",
172 _("HTTP Headers"),
173 _("The The HTTP headers of the response"),
174 SOUP_TYPE_MESSAGE_HEADERS,
175 WEBKIT_PARAM_READABLE));
176}
177
178/**
179 * webkit_uri_response_get_uri:
180 * @response: a #WebKitURIResponse
181 *
182 * Returns: the uri of the #WebKitURIResponse
183 */
184const gchar* webkit_uri_response_get_uri(WebKitURIResponse* response)
185{
186 g_return_val_if_fail(WEBKIT_IS_URI_RESPONSE(response), 0);
187
188 response->priv->uri = response->priv->resourceResponse.url().string().utf8();
189 return response->priv->uri.data();
190}
191
192/**
193 * webkit_uri_response_get_status_code:
194 * @response: a #WebKitURIResponse
195 *
196 * Get the status code of the #WebKitURIResponse as returned by
197 * the server. It will normally be a #SoupKnownStatusCode, for
198 * example %SOUP_STATUS_OK, though the server can respond with any
199 * unsigned integer.
200 *
201 * Returns: the status code of @response
202 */
203guint webkit_uri_response_get_status_code(WebKitURIResponse* response)
204{
205 g_return_val_if_fail(WEBKIT_IS_URI_RESPONSE(response), SOUP_STATUS_NONE);
206
207 return response->priv->resourceResponse.httpStatusCode();
208}
209
210/**
211 * webkit_uri_response_get_content_length:
212 * @response: a #WebKitURIResponse
213 *
214 * Get the expected content length of the #WebKitURIResponse. It can
215 * be 0 if the server provided an incorrect or missing Content-Length.
216 *
217 * Returns: the expected content length of @response.
218 */
219guint64 webkit_uri_response_get_content_length(WebKitURIResponse* response)
220{
221 g_return_val_if_fail(WEBKIT_IS_URI_RESPONSE(response), 0);
222
223 return response->priv->resourceResponse.expectedContentLength();
224}
225
226/**
227 * webkit_uri_response_get_mime_type:
228 * @response: a #WebKitURIResponse
229 *
230 * Returns: the MIME type of the #WebKitURIResponse
231 */
232const gchar* webkit_uri_response_get_mime_type(WebKitURIResponse* response)
233{
234 g_return_val_if_fail(WEBKIT_IS_URI_RESPONSE(response), 0);
235
236 response->priv->mimeType = response->priv->resourceResponse.mimeType().utf8();
237 return response->priv->mimeType.data();
238}
239
240/**
241 * webkit_uri_response_get_suggested_filename:
242 * @response: a #WebKitURIResponse
243 *
244 * Get the suggested filename for @response, as specified by
245 * the 'Content-Disposition' HTTP header, or %NULL if it's not
246 * present.
247 *
248 * Returns: (transfer none): the suggested filename or %NULL if
249 * the 'Content-Disposition' HTTP header is not present.
250 */
251const gchar* webkit_uri_response_get_suggested_filename(WebKitURIResponse* response)
252{
253 g_return_val_if_fail(WEBKIT_IS_URI_RESPONSE(response), 0);
254
255 if (response->priv->resourceResponse.suggestedFilename().isEmpty())
256 return 0;
257
258 response->priv->suggestedFilename = response->priv->resourceResponse.suggestedFilename().utf8();
259 return response->priv->suggestedFilename.data();
260}
261
262/**
263 * webkit_uri_response_get_http_headers:
264 * @response: a #WebKitURIResponse
265 *
266 * Get the HTTP headers of a #WebKitURIResponse as a #SoupMessageHeaders.
267 *
268 * Returns: (transfer none): a #SoupMessageHeaders with the HTTP headers of @response
269 * or %NULL if @response is not an HTTP response.
270 * Since: 2.6
271 */
272SoupMessageHeaders* webkit_uri_response_get_http_headers(WebKitURIResponse* response)
273{
274 g_return_val_if_fail(WEBKIT_IS_URI_RESPONSE(response), nullptr);
275
276 if (response->priv->httpHeaders)
277 return response->priv->httpHeaders.get();
278
279 if (!response->priv->resourceResponse.url().protocolIsInHTTPFamily())
280 return nullptr;
281
282 response->priv->httpHeaders.reset(soup_message_headers_new(SOUP_MESSAGE_HEADERS_RESPONSE));
283 response->priv->resourceResponse.updateSoupMessageHeaders(response->priv->httpHeaders.get());
284 return response->priv->httpHeaders.get();
285}
286
287WebKitURIResponse* webkitURIResponseCreateForResourceResponse(const WebCore::ResourceResponse& resourceResponse)
288{
289 WebKitURIResponse* uriResponse = WEBKIT_URI_RESPONSE(g_object_new(WEBKIT_TYPE_URI_RESPONSE, NULL));
290 uriResponse->priv->resourceResponse = resourceResponse;
291 return uriResponse;
292}
293
294const WebCore::ResourceResponse& webkitURIResponseGetResourceResponse(WebKitURIResponse* uriResponse)
295{
296 return uriResponse->priv->resourceResponse;
297}
298
299