NetSurf
css_fetcher.c
Go to the documentation of this file.
1/*
2 * Copyright 2008 Rob Kendrick <rjek@netsurf-browser.org>
3 * Copyright 2013 John-Mark Bell <jmb@netsurf-browser.org>
4 *
5 * This file is part of NetSurf.
6 *
7 * NetSurf is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * NetSurf is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20/**
21 * \file
22 * HTML fetcher for CSS objects
23 */
24
25#include <assert.h>
26#include <stdbool.h>
27#include <stdlib.h>
28#include <string.h>
29#include <dom/dom.h>
30#include <libwapcaplet/libwapcaplet.h>
31
32#include "netsurf/inttypes.h"
33#include "utils/config.h"
34#include "utils/corestrings.h"
35#include "utils/log.h"
36#include "utils/ring.h"
37#include "utils/nsurl.h"
38#include "utils/utils.h"
39#include "content/fetch.h"
40#include "content/fetchers.h"
41
42#include "html/private.h"
43
44typedef struct html_css_fetcher_item {
45 uint32_t key;
46 dom_string *data;
48
51
54
57
58 bool aborted;
59 bool locked;
60
63
64static uint32_t current_key = 0;
67
68static bool html_css_fetcher_initialise(lwc_string *scheme)
69{
70 NSLOG(netsurf, INFO, "html_css_fetcher_initialise called for %s",
71 lwc_string_data(scheme));
72 return true;
73}
74
75static void html_css_fetcher_finalise(lwc_string *scheme)
76{
77 NSLOG(netsurf, INFO, "html_css_fetcher_finalise called for %s",
78 lwc_string_data(scheme));
79}
80
82{
83 return true;
84}
85
87 bool only_2xx, bool downgrade_tls, const char *post_urlenc,
88 const struct fetch_multipart_data *post_multipart,
89 const char **headers)
90{
92 lwc_string *path;
93 uint32_t key;
94 html_css_fetcher_item *item, *found = NULL;
95
96 /* format of a x-ns-css URL is:
97 * x-ns-url:<key>
98 * Where key is an unsigned 32bit integer
99 */
100
102 /* The path must exist */
103 if (path == NULL) {
104 return NULL;
105 }
106
107 key = strtoul(lwc_string_data(path), NULL, 10);
108
109 lwc_string_unref(path);
110
111 /* There must be at least one item */
112 if (items == NULL) {
113 return NULL;
114 }
115
116 item = items;
117 do {
118 if (item->key == key) {
119 found = item;
120 break;
121 }
122
123 item = item->r_next;
124 } while (item != items);
125
126 /* We must have found the item */
127 if (found == NULL) {
128 return NULL;
129 }
130
131 ctx = calloc(1, sizeof(*ctx));
132 if (ctx == NULL)
133 return NULL;
134
136 ctx->url = nsurl_ref(url);
137 ctx->item = found;
138
139 RING_INSERT(ring, ctx);
140
141 return ctx;
142}
143
144static bool html_css_fetcher_start(void *ctx)
145{
146 return true;
147}
148
149static void html_css_fetcher_free(void *ctx)
150{
152
153 nsurl_unref(c->url);
154 if (c->item != NULL) {
156 dom_string_unref(c->item->data);
158 free(c->item);
159 }
160 RING_REMOVE(ring, c);
161 free(ctx);
162}
163
164static void html_css_fetcher_abort(void *ctx)
165{
167
168 /* To avoid the poll loop having to deal with the fetch context
169 * disappearing from under it, we simply flag the abort here.
170 * The poll loop itself will perform the appropriate cleanup.
171 */
172 c->aborted = true;
173}
174
177{
178 c->locked = true;
180 c->locked = false;
181}
182
183static void html_css_fetcher_poll(lwc_string *scheme)
184{
185 fetch_msg msg;
186 html_css_fetcher_context *c, *next;
187
188 if (ring == NULL) return;
189
190 /* Iterate over ring, processing each pending fetch */
191 c = ring;
192 do {
193 /* Ignore fetches that have been flagged as locked.
194 * This allows safe re-entrant calls to this function.
195 * Re-entrancy can occur if, as a result of a callback,
196 * the interested party causes fetch_poll() to be called
197 * again.
198 */
199 if (c->locked == true) {
200 next = c->r_next;
201 continue;
202 }
203
204 /* Only process non-aborted fetches */
205 if (c->aborted) {
206 /* Nothing to do */
207 assert(c->locked == false);
208 } else if (c->item != NULL) {
209 char header[4096];
210
212
213 /* Any callback can result in the fetch being aborted.
214 * Therefore, we _must_ check for this after _every_
215 * call to html_css_fetcher_send_callback().
216 */
217 snprintf(header, sizeof header,
218 "Content-Type: text/css; charset=utf-8");
219 msg.type = FETCH_HEADER;
220 msg.data.header_or_data.buf = (const uint8_t *) header;
221 msg.data.header_or_data.len = strlen(header);
223
224 if (c->aborted == false) {
225 snprintf(header, sizeof header,
226 "Content-Length: %"PRIsizet,
227 dom_string_byte_length(c->item->data));
228 msg.type = FETCH_HEADER;
230 (const uint8_t *) header;
231 msg.data.header_or_data.len = strlen(header);
233 }
234
235 if (c->aborted == false) {
236 snprintf(header, sizeof header,
237 "X-NS-Base: %.*s",
238 (int) nsurl_length(c->item->base_url),
240 msg.type = FETCH_HEADER;
242 (const uint8_t *) header;
243 msg.data.header_or_data.len = strlen(header);
245 }
246
247 if (c->aborted == false) {
248 msg.type = FETCH_DATA;
250 (const uint8_t *)
251 dom_string_data(c->item->data);
253 dom_string_byte_length(c->item->data);
255 }
256
257 if (c->aborted == false) {
258 msg.type = FETCH_FINISHED;
260 }
261 } else {
262 NSLOG(netsurf, INFO, "Processing of %s failed!",
263 nsurl_access(c->url));
264
265 /* Ensure that we're unlocked here. If we aren't,
266 * then html_css_fetcher_process() is broken.
267 */
268 assert(c->locked == false);
269 }
270
271 /* Compute next fetch item at the last possible moment as
272 * processing this item may have added to the ring.
273 */
274 next = c->r_next;
275
278
279 /* Advance to next ring entry, exiting if we've reached
280 * the start of the ring or the ring has become empty
281 */
282 } while ( (c = next) != ring && ring != NULL);
283}
284
285/* exported interface documented in html_internal.h */
287{
288 const struct fetcher_operation_table html_css_fetcher_ops = {
290 .acceptable = html_css_fetcher_can_fetch,
291 .setup = html_css_fetcher_setup,
292 .start = html_css_fetcher_start,
293 .abort = html_css_fetcher_abort,
294 .free = html_css_fetcher_free,
295 .poll = html_css_fetcher_poll,
296 .finalise = html_css_fetcher_finalise
297 };
298
299 return fetcher_add(lwc_string_ref(corestring_lwc_x_ns_css),
300 &html_css_fetcher_ops);
301}
302
303/* exported interface documented in html_internal.h */
305html_css_fetcher_add_item(dom_string *data, nsurl *base_url, uint32_t *key)
306{
307 html_css_fetcher_item *item = malloc(sizeof(*item));
308
309 if (item == NULL) {
310 return NSERROR_NOMEM;
311 }
312
313 *key = item->key = current_key++;
314 item->data = dom_string_ref(data);
315 item->base_url = nsurl_ref(base_url);
316
317 RING_INSERT(items, item);
318
319 return NSERROR_OK;
320}
void fetch_set_http_code(struct fetch *fetch, long http_code)
set the http code of a fetch
Definition: fetch.c:794
nserror fetcher_add(lwc_string *scheme, const struct fetcher_operation_table *ops)
Register a fetcher for a scheme.
Definition: fetch.c:357
void fetch_send_callback(const fetch_msg *msg, struct fetch *fetch)
send message to fetch
Definition: fetch.c:757
void fetch_free(struct fetch *f)
Free a fetch structure and associated resources.
Definition: fetch.c:548
void fetch_remove_from_queues(struct fetch *fetch)
remove a queued fetch
Definition: fetch.c:767
Fetching of data from a URL (interface).
@ FETCH_DATA
Definition: fetch.h:44
@ FETCH_HEADER
Definition: fetch.h:43
@ FETCH_FINISHED
Definition: fetch.h:46
Useful interned string pointers (interface).
static html_css_fetcher_item * items
Definition: css_fetcher.c:65
struct html_css_fetcher_context html_css_fetcher_context
static uint32_t current_key
Definition: css_fetcher.c:64
static bool html_css_fetcher_initialise(lwc_string *scheme)
Definition: css_fetcher.c:68
static void html_css_fetcher_finalise(lwc_string *scheme)
Definition: css_fetcher.c:75
static void html_css_fetcher_poll(lwc_string *scheme)
Definition: css_fetcher.c:183
nserror html_css_fetcher_register(void)
Register the fetcher for the pseudo x-ns-css scheme.
Definition: css_fetcher.c:286
static void * html_css_fetcher_setup(struct fetch *parent_fetch, nsurl *url, bool only_2xx, bool downgrade_tls, const char *post_urlenc, const struct fetch_multipart_data *post_multipart, const char **headers)
Definition: css_fetcher.c:86
static void html_css_fetcher_free(void *ctx)
Definition: css_fetcher.c:149
static bool html_css_fetcher_start(void *ctx)
Definition: css_fetcher.c:144
static bool html_css_fetcher_can_fetch(const nsurl *url)
Definition: css_fetcher.c:81
static void html_css_fetcher_send_callback(const fetch_msg *msg, html_css_fetcher_context *c)
Definition: css_fetcher.c:175
struct html_css_fetcher_item html_css_fetcher_item
static html_css_fetcher_context * ring
Definition: css_fetcher.c:66
static void html_css_fetcher_abort(void *ctx)
Definition: css_fetcher.c:164
nserror html_css_fetcher_add_item(dom_string *data, nsurl *base_url, uint32_t *key)
Definition: css_fetcher.c:305
nserror
Enumeration of error codes.
Definition: errors.h:29
@ NSERROR_NOMEM
Memory exhaustion.
Definition: errors.h:32
@ NSERROR_OK
No error.
Definition: errors.h:30
Interface for fetchers factory.
Netsurf additional integer type formatting macros.
#define PRIsizet
c99 standard printf formatting for size_t type
Definition: inttypes.h:53
#define NSLOG(catname, level, logmsg, args...)
Definition: log.h:116
NetSurf URL handling (interface).
void nsurl_unref(nsurl *url)
Drop a reference to a NetSurf URL object.
const char * nsurl_access(const nsurl *url)
Access a NetSurf URL object as a string.
size_t nsurl_length(const nsurl *url)
Find the length of a NetSurf URL object's URL, as returned by nsurl_access.
nsurl * nsurl_ref(nsurl *url)
Increment the reference count to a NetSurf URL object.
lwc_string * nsurl_get_component(const nsurl *url, nsurl_component part)
Get part of a URL as a lwc_string, from a NetSurf URL object.
@ NSURL_PATH
Definition: nsurl.h:52
struct nsurl nsurl
NetSurf URL object.
Definition: nsurl.h:31
Private data for text/html content.
Ring list structure.
#define RING_REMOVE(ring, element)
Remove the given element from the specified ring.
Definition: ring.h:53
#define RING_INSERT(ring, element)
Insert the given item into the specified ring.
Definition: ring.h:40
Interface to utility string handling.
Fetcher message data.
Definition: fetch.h:72
const uint8_t * buf
Definition: fetch.h:79
fetch_msg_type type
Definition: fetch.h:73
struct fetch_msg::@118::@119 header_or_data
size_t len
Definition: fetch.h:80
union fetch_msg::@118 data
Fetch POST multipart data.
Definition: fetch.h:109
Information for a single fetch.
Definition: fetch.c:89
Fetcher operations API.
Definition: fetchers.h:49
bool(* initialise)(lwc_string *scheme)
The initialiser for the fetcher.
Definition: fetchers.h:55
struct html_css_fetcher_context * r_prev
Definition: css_fetcher.c:61
struct fetch * parent_fetch
Definition: css_fetcher.c:53
html_css_fetcher_item * item
Definition: css_fetcher.c:56
struct html_css_fetcher_context * r_next
Definition: css_fetcher.c:61
struct html_css_fetcher_item * r_prev
Definition: css_fetcher.c:49
struct html_css_fetcher_item * r_next
Definition: css_fetcher.c:49
dom_string * data
Definition: css_fetcher.c:46
Interface to a number of general purpose functionality.
static nserror path(const struct redraw_context *ctx, const plot_style_t *pstyle, const float *p, unsigned int n, const float transform[6])
Plots a path.
Definition: plot.c:821