NetSurf
fetcher.c
Go to the documentation of this file.
1/*
2 * Copyright 2012 Vincent Sanders <vince@kyllikki.org>
3 *
4 * This file is part of NetSurf, http://www.netsurf-browser.org/
5 *
6 * NetSurf is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * NetSurf 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
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19/** \file
20 * implementation for javascript scheme fetcher
21 *
22 * This fetcher implements http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#javascript-protocol
23 */
24
25#include <stdbool.h>
26#include <stdlib.h>
27#include <libwapcaplet/libwapcaplet.h>
28
29#include "utils/nsurl.h"
30#include "utils/corestrings.h"
31#include "utils/ring.h"
32#include "content/fetch.h"
33#include "content/fetchers.h"
34
35#include "javascript/fetcher.h"
36
37/** Context for an resource fetch */
40
41 struct fetch *fetchh; /**< Handle for this fetch */
42
43 bool aborted; /**< Flag indicating fetch has been aborted */
44 bool locked; /**< Flag indicating entry is already entered */
45
46 nsurl *url; /**< The URL being fetched */
47};
48
49static struct fetch_javascript_context *ring = NULL;
50
51
52/** issue fetch callbacks with locking */
53static inline bool fetch_javascript_send_callback(const fetch_msg *msg,
54 struct fetch_javascript_context *ctx)
55{
56 ctx->locked = true;
57 fetch_send_callback(msg, ctx->fetchh);
58 ctx->locked = false;
59
60 return ctx->aborted;
61}
62
63
64/**
65 * called from poll to progress fetch.
66 *
67 * \todo This is currently completely unimplemented and just returns 204
68 */
70{
71 fetch_msg msg;
72 int code = 204;
73
74 /* content is going to return error code */
75 fetch_set_http_code(ctx->fetchh, code);
76
77 msg.type = FETCH_FINISHED;
79
80 return true;
81}
82
83
84
85/** callback to initialise the resource fetcher. */
86static bool fetch_javascript_initialise(lwc_string *scheme)
87{
88 return true;
89}
90
91/** callback to finalise the resource fetcher. */
92static void fetch_javascript_finalise(lwc_string *scheme)
93{
94}
95
97{
98 return true;
99}
100
101/** callback to set up a resource fetch context. */
102static void *
104 nsurl *url,
105 bool only_2xx,
106 bool downgrade_tls,
107 const char *post_urlenc,
108 const struct fetch_multipart_data *post_multipart,
109 const char **headers)
110{
111 struct fetch_javascript_context *ctx;
112
113 ctx = calloc(1, sizeof(*ctx));
114 if (ctx == NULL)
115 return NULL;
116
117 ctx->url = nsurl_ref(url);
118
119 ctx->fetchh = fetchh;
120
121 RING_INSERT(ring, ctx);
122
123 return ctx;
124}
125
126/** callback to free a resource fetch */
127static void fetch_javascript_free(void *ctx)
128{
129 struct fetch_javascript_context *c = ctx;
130 if (c->url != NULL) {
131 nsurl_unref(c->url);
132 }
133 RING_REMOVE(ring, c);
134 free(ctx);
135}
136
137/** callback to start a resource fetch */
138static bool fetch_javascript_start(void *ctx)
139{
140 return true;
141}
142
143/** callback to abort a resource fetch */
144static void fetch_javascript_abort(void *ctx)
145{
146 struct fetch_javascript_context *c = ctx;
147
148 /* To avoid the poll loop having to deal with the fetch context
149 * disappearing from under it, we simply flag the abort here.
150 * The poll loop itself will perform the appropriate cleanup.
151 */
152 c->aborted = true;
153}
154
155
156/** callback to poll for additional resource fetch contents */
157static void fetch_javascript_poll(lwc_string *scheme)
158{
159 struct fetch_javascript_context *c, *next;
160
161 if (ring == NULL) return;
162
163 /* Iterate over ring, processing each pending fetch */
164 c = ring;
165 do {
166 /* Ignore fetches that have been flagged as locked.
167 * This allows safe re-entrant calls to this function.
168 * Re-entrancy can occur if, as a result of a callback,
169 * the interested party causes fetch_poll() to be called
170 * again.
171 */
172 if (c->locked == true) {
173 next = c->r_next;
174 continue;
175 }
176
177 /* Only process non-aborted fetches */
178 if (c->aborted == false) {
179 /* resource fetches can be processed in one go */
181 }
182
183 /* Compute next fetch item at the last possible moment
184 * as processing this item may have added to the ring
185 */
186 next = c->r_next;
187
189 fetch_free(c->fetchh);
190
191 /* Advance to next ring entry, exiting if we've reached
192 * the start of the ring or the ring has become empty
193 */
194 } while ( (c = next) != ring && ring != NULL);
195}
196
197/**
198 * Register javascript scheme fetcher with fetcher factory.
199 *
200 * \return NSERROR_OK on success or appropriate error code on faliure.
201*/
203{
204 lwc_string *scheme = lwc_string_ref(corestring_lwc_javascript);
205 const struct fetcher_operation_table fetcher_ops = {
207 .acceptable = fetch_javascript_can_fetch,
208 .setup = fetch_javascript_setup,
209 .start = fetch_javascript_start,
210 .abort = fetch_javascript_abort,
211 .free = fetch_javascript_free,
212 .poll = fetch_javascript_poll,
213 .finalise = fetch_javascript_finalise
214 };
215
216 return fetcher_add(scheme, &fetcher_ops);
217}
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_FINISHED
Definition: fetch.h:46
Useful interned string pointers (interface).
nserror
Enumeration of error codes.
Definition: errors.h:29
static bool fetch_javascript_send_callback(const fetch_msg *msg, struct fetch_javascript_context *ctx)
issue fetch callbacks with locking
Definition: fetcher.c:53
static bool fetch_javascript_start(void *ctx)
callback to start a resource fetch
Definition: fetcher.c:138
static void fetch_javascript_free(void *ctx)
callback to free a resource fetch
Definition: fetcher.c:127
static bool fetch_javascript_can_fetch(const nsurl *url)
Definition: fetcher.c:96
static bool fetch_javascript_initialise(lwc_string *scheme)
callback to initialise the resource fetcher.
Definition: fetcher.c:86
static bool fetch_javascript_handler(struct fetch_javascript_context *ctx)
called from poll to progress fetch.
Definition: fetcher.c:69
nserror fetch_javascript_register(void)
Register javascript scheme fetcher with fetcher factory.
Definition: fetcher.c:202
static void fetch_javascript_finalise(lwc_string *scheme)
callback to finalise the resource fetcher.
Definition: fetcher.c:92
static void fetch_javascript_poll(lwc_string *scheme)
callback to poll for additional resource fetch contents
Definition: fetcher.c:157
static void * fetch_javascript_setup(struct fetch *fetchh, nsurl *url, bool only_2xx, bool downgrade_tls, const char *post_urlenc, const struct fetch_multipart_data *post_multipart, const char **headers)
callback to set up a resource fetch context.
Definition: fetcher.c:103
static void fetch_javascript_abort(void *ctx)
callback to abort a resource fetch
Definition: fetcher.c:144
static struct fetch_javascript_context * ring
Definition: fetcher.c:49
javascript scheme handler
Interface for fetchers factory.
NetSurf URL handling (interface).
void nsurl_unref(nsurl *url)
Drop a reference to a NetSurf URL object.
nsurl * nsurl_ref(nsurl *url)
Increment the reference count to a NetSurf URL object.
struct nsurl nsurl
NetSurf URL object.
Definition: nsurl.h:31
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
Context for an resource fetch.
Definition: fetcher.c:38
struct fetch_javascript_context * r_next
Definition: fetcher.c:39
struct fetch_javascript_context * r_prev
Definition: fetcher.c:39
bool locked
Flag indicating entry is already entered.
Definition: fetcher.c:44
bool aborted
Flag indicating fetch has been aborted.
Definition: fetcher.c:43
struct fetch * fetchh
Handle for this fetch.
Definition: fetcher.c:41
nsurl * url
The URL being fetched.
Definition: fetcher.c:46
Fetcher message data.
Definition: fetch.h:72
fetch_msg_type type
Definition: fetch.h:73
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