NetSurf
fetch.c
Go to the documentation of this file.
1/*
2 * Copyright 2006,2007 Daniel Silverstone <dsilvers@digital-scurf.org>
3 * Copyright 2007 James Bursa <bursa@users.sourceforge.net>
4 * Copyright 2003 Phil Mellor <monkeyson@users.sourceforge.net>
5 *
6 * This file is part of NetSurf, http://www.netsurf-browser.org/
7 *
8 * NetSurf is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
11 *
12 * NetSurf is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21/**
22 * \file
23 * Implementation of fetching of data from a URL.
24 *
25 * The implementation is the fetch factory and the generic operations
26 * around the fetcher specific methods.
27 *
28 * Active fetches are held in the circular linked list ::fetch_ring. There may
29 * be at most nsoption max_fetchers_per_host active requests per Host: header.
30 * There may be at most nsoption max_fetchers active requests overall. Inactive
31 * fetches are stored in the ::queue_ring waiting for use.
32 */
33
34#include <stdlib.h>
35#include <assert.h>
36#include <errno.h>
37#include <stdbool.h>
38#include <string.h>
39#include <strings.h>
40#include <time.h>
41#include <libwapcaplet/libwapcaplet.h>
42
43#include "utils/config.h"
44#include "utils/corestrings.h"
45#include "utils/nsoption.h"
46#include "utils/log.h"
47#include "utils/messages.h"
48#include "utils/nsurl.h"
49#include "utils/ring.h"
50#include "netsurf/misc.h"
52
53#include "content/fetch.h"
54#include "content/fetchers.h"
56#include "content/fetchers/about/about.h"
60#include "javascript/fetcher.h"
61#include "content/urldb.h"
62
63/** The maximum number of fetchers that can be added */
64#define MAX_FETCHERS 10
65
66/** The time in ms between polling the fetchers.
67 *
68 * \todo The schedule timeout should be profiled to see if there is a
69 * better value or even if it needs to be dynamic.
70 */
71#define SCHEDULE_TIME 10
72
73/** The fdset timeout in ms */
74#define FDSET_TIMEOUT 1000
75
76/**
77 * Information about a fetcher for a given scheme.
78 */
79typedef struct scheme_fetcher_s {
80 lwc_string *scheme; /**< The scheme. */
81
82 struct fetcher_operation_table ops; /**< The fetchers operations. */
83 int refcount; /**< When zero the fetcher is no longer in use. */
85
87
88/** Information for a single fetch. */
89struct fetch {
90 fetch_callback callback;/**< Callback function. */
91 nsurl *url; /**< URL. */
92 nsurl *referer; /**< Referer URL. */
93 bool verifiable; /**< Transaction is verifiable */
94 void *p; /**< Private data for callback. */
95 lwc_string *host; /**< Host part of URL, interned */
96 long http_code; /**< HTTP response code, or 0. */
97 int fetcherd; /**< Fetcher descriptor for this fetch */
98 void *fetcher_handle; /**< The handle for the fetcher. */
99 bool fetch_is_active; /**< This fetch is active. */
100 fetch_msg_type last_msg;/**< The last message sent for this fetch */
101 struct fetch *r_prev; /**< Previous active fetch in ::fetch_ring. */
102 struct fetch *r_next; /**< Next active fetch in ::fetch_ring. */
103};
104
105static struct fetch *fetch_ring = NULL; /**< Ring of active fetches. */
106static struct fetch *queue_ring = NULL; /**< Ring of queued fetches */
107
108/******************************************************************************
109 * fetch internals *
110 ******************************************************************************/
111
112static inline void fetch_ref_fetcher(int fetcherd)
113{
115}
116
117static inline void fetch_unref_fetcher(int fetcherd)
118{
120 if (fetchers[fetcherd].refcount == 0) {
122 lwc_string_unref(fetchers[fetcherd].scheme);
123 }
124}
125
126/**
127 * Find a suitable fetcher for a scheme.
128 */
129static int get_fetcher_for_scheme(lwc_string *scheme)
130{
131 int fetcherd;
132 bool match;
133
134 for (fetcherd = 0; fetcherd < MAX_FETCHERS; fetcherd++) {
135 if ((fetchers[fetcherd].refcount > 0) &&
136 (lwc_string_isequal(fetchers[fetcherd].scheme,
137 scheme, &match) == lwc_error_ok) &&
138 (match == true)) {
139 return fetcherd;
140 }
141 }
142 return -1;
143}
144
145/**
146 * Dispatch a single job
147 */
148static bool fetch_dispatch_job(struct fetch *fetch)
149{
151 NSLOG(fetch, DEBUG,
152 "Attempting to start fetch %p, fetcher %p, url %s", fetch,
155
157 RING_INSERT(queue_ring, fetch); /* Put it back on the end of the queue */
158 return false;
159 } else {
161 fetch->fetch_is_active = true;
162 return true;
163 }
164}
165
166/**
167 * Choose and dispatch a single job. Return false if we failed to dispatch
168 * anything.
169 *
170 * We don't check the overall dispatch size here because we're not called unless
171 * there is room in the fetch queue for us.
172 */
174{
175 bool same_host;
176 struct fetch *queueitem;
177 queueitem = queue_ring;
178 do {
179 /* We can dispatch the selected item if there is room in the
180 * fetch ring
181 */
182 int countbyhost;
183 RING_COUNTBYLWCHOST(struct fetch, fetch_ring, countbyhost,
184 queueitem->host);
185 if (countbyhost < nsoption_int(max_fetchers_per_host)) {
186 /* We can dispatch this item in theory */
187 return fetch_dispatch_job(queueitem);
188 }
189 /* skip over other items with the same host */
190 same_host = true;
191 while (same_host == true && queueitem->r_next != queue_ring) {
192 if (lwc_string_isequal(queueitem->host,
193 queueitem->r_next->host, &same_host) ==
194 lwc_error_ok && same_host == true) {
195 queueitem = queueitem->r_next;
196 }
197 }
198 queueitem = queueitem->r_next;
199 } while (queueitem != queue_ring);
200 return false;
201}
202
203static void dump_rings(void)
204{
205 struct fetch *q;
206 struct fetch *f;
207
208 q = queue_ring;
209 if (q) {
210 do {
211 NSLOG(fetch, DEBUG, "queue_ring: %s",
212 nsurl_access(q->url));
213 q = q->r_next;
214 } while (q != queue_ring);
215 }
216 f = fetch_ring;
217 if (f) {
218 do {
219 NSLOG(fetch, DEBUG, "fetch_ring: %s",
220 nsurl_access(f->url));
221 f = f->r_next;
222 } while (f != fetch_ring);
223 }
224}
225
226/**
227 * Dispatch as many jobs as we have room to dispatch.
228 *
229 * @return true if there are active fetchers that require polling else false.
230 */
231static bool fetch_dispatch_jobs(void)
232{
233 int all_active;
234 int all_queued;
235
236 RING_GETSIZE(struct fetch, queue_ring, all_queued);
237 RING_GETSIZE(struct fetch, fetch_ring, all_active);
238
239 NSLOG(fetch, DEBUG,
240 "queue_ring %i, fetch_ring %i",
241 all_queued,
242 all_active);
243 dump_rings();
244
245 while ((all_queued != 0) &&
246 (all_active < nsoption_int(max_fetchers)) &&
248 all_queued--;
249 all_active++;
250 NSLOG(fetch, DEBUG,
251 "%d queued, %d fetching",
252 all_queued,
253 all_active);
254 }
255
256 NSLOG(fetch, DEBUG, "Fetch ring is now %d elements.", all_active);
257 NSLOG(fetch, DEBUG, "Queue ring is now %d elements.", all_queued);
258
259 return (all_active > 0);
260}
261
262static void fetcher_poll(void *unused)
263{
264 int fetcherd;
265
266 if (fetch_dispatch_jobs()) {
267 NSLOG(fetch, DEBUG, "Polling fetchers");
268 for (fetcherd = 0; fetcherd < MAX_FETCHERS; fetcherd++) {
269 if (fetchers[fetcherd].refcount > 0) {
270 /* fetcher present */
272 }
273 }
274
275 /* schedule active fetchers to run again in 10ms */
277 }
278}
279
280/******************************************************************************
281 * Public API *
282 ******************************************************************************/
283
284/* exported interface documented in content/fetch.h */
286{
287 nserror ret;
288
289#ifdef WITH_CURL
290 ret = fetch_curl_register();
291 if (ret != NSERROR_OK) {
292 return ret;
293 }
294#endif
295
296 ret = fetch_data_register();
297 if (ret != NSERROR_OK) {
298 return ret;
299 }
300
301 ret = fetch_file_register();
302 if (ret != NSERROR_OK) {
303 return ret;
304 }
305
307 if (ret != NSERROR_OK) {
308 return ret;
309 }
310
311 ret = fetch_about_register();
312 if (ret != NSERROR_OK) {
313 return ret;
314 }
315
317
318 return ret;
319}
320
321/* exported interface documented in content/fetchers.h */
322void fetcher_quit(void)
323{
324 int fetcherd; /* fetcher index */
325 for (fetcherd = 0; fetcherd < MAX_FETCHERS; fetcherd++) {
326 if (fetchers[fetcherd].refcount > 1) {
327 /* fetcher still has reference at quit. This
328 * should not happen as the fetch should have
329 * been aborted in llcache shutdown.
330 *
331 * This appears to be normal behaviour if a
332 * curl operation is still in progress at exit
333 * as the abort waits for curl to complete.
334 *
335 * We could make the user wait for curl to
336 * complete but we are exiting anyway so thats
337 * unhelpful. Instead we just log it and force
338 * the reference count to allow the fetcher to
339 * be stopped.
340 */
341 NSLOG(fetch, INFO,
342 "Fetcher for scheme %s still has %d active users at quit.",
343 lwc_string_data(fetchers[fetcherd].scheme),
344 fetchers[fetcherd].refcount);
345
347 }
348 if (fetchers[fetcherd].refcount == 1) {
349
351 }
352 }
353}
354
355/* exported interface documented in content/fetchers.h */
357fetcher_add(lwc_string *scheme, const struct fetcher_operation_table *ops)
358{
359 int fetcherd;
360
361 /* find unused fetcher descriptor */
362 for (fetcherd = 0; fetcherd < MAX_FETCHERS; fetcherd++) {
363 if (fetchers[fetcherd].refcount == 0) {
364 break;
365 }
366 }
367 if (fetcherd == MAX_FETCHERS) {
368 return NSERROR_INIT_FAILED;
369 }
370
371 if (!ops->initialise(scheme)) {
372 return NSERROR_INIT_FAILED;
373 }
374
375 fetchers[fetcherd].scheme = scheme;
376 fetchers[fetcherd].ops = *ops;
377
379
380 return NSERROR_OK;
381}
382
383/* exported interface documented in content/fetch.h */
385fetch_fdset(fd_set *read_fd_set,
386 fd_set *write_fd_set,
387 fd_set *except_fd_set,
388 int *maxfd_out)
389{
390 int maxfd = -1;
391 int fetcherd; /* fetcher index */
392
393 if (!fetch_dispatch_jobs()) {
394 NSLOG(fetch, DEBUG, "No jobs");
395 *maxfd_out = -1;
396 return NSERROR_OK;
397 }
398
399 NSLOG(fetch, DEBUG, "Polling fetchers");
400
401 for (fetcherd = 0; fetcherd < MAX_FETCHERS; fetcherd++) {
402 if (fetchers[fetcherd].refcount > 0) {
403 /* fetcher present */
405 }
406 }
407
408 FD_ZERO(read_fd_set);
409 FD_ZERO(write_fd_set);
410 FD_ZERO(except_fd_set);
411
412 for (fetcherd = 0; fetcherd < MAX_FETCHERS; fetcherd++) {
413 if ((fetchers[fetcherd].refcount > 0) &&
414 (fetchers[fetcherd].ops.fdset != NULL)) {
415 /* fetcher present */
416 int fetcher_maxfd;
417 fetcher_maxfd = fetchers[fetcherd].ops.fdset(
418 fetchers[fetcherd].scheme, read_fd_set,
419 write_fd_set, except_fd_set);
420 if (fetcher_maxfd > maxfd)
421 maxfd = fetcher_maxfd;
422 }
423 }
424
425 if (maxfd >= 0) {
426 /* change the scheduled poll to happen is a 1000ms as
427 * we assume fetching an fdset means the fetchers will
428 * be run by the client waking up on data available on
429 * the fd and re-calling fetcher_fdset() if this does
430 * not happen the fetch polling will continue as
431 * usual.
432 */
433 /** @note adjusting the schedule time is only done for
434 * curl currently. This is because as it is assumed to
435 * be the only fetcher that can possibly have fd to
436 * select on. All the other fetchers continue to need
437 * polling frequently.
438 */
440 }
441
442 *maxfd_out = maxfd;
443
444 return NSERROR_OK;
445}
446
447/* exported interface documented in content/fetch.h */
450 nsurl *referer,
452 void *p,
453 bool only_2xx,
454 const char *post_urlenc,
455 const struct fetch_multipart_data *post_multipart,
456 bool verifiable,
457 bool downgrade_tls,
458 const char *headers[],
459 struct fetch **fetch_out)
460{
461 struct fetch *fetch;
462 lwc_string *scheme;
463
464 fetch = calloc(1, sizeof (*fetch));
465 if (fetch == NULL) {
466 return NSERROR_NOMEM;
467 }
468
469 /* The URL we're fetching must have a scheme */
471 assert(scheme != NULL);
472
473 /* try and obtain a fetcher for this scheme */
475 lwc_string_unref(scheme);
476 if (fetch->fetcherd == -1) {
477 free(fetch);
479 }
480
481 NSLOG(fetch, DEBUG, "fetch %p, url '%s'", fetch, nsurl_access(url));
482
483 /* construct a new fetch structure */
487 fetch->p = p;
489
490 if (referer != NULL) {
492 }
493
494 /* try and set up the fetch */
496 only_2xx, downgrade_tls,
497 post_urlenc, post_multipart,
498 headers);
499 if (fetch->fetcher_handle == NULL) {
500
501 if (fetch->host != NULL)
502 lwc_string_unref(fetch->host);
503
504 if (fetch->url != NULL)
506
507 if (fetch->referer != NULL)
509
510 free(fetch);
511
512
513 /** \todo The fetchers setup should return nserror and that be
514 * passed back rather than assuming a bad url
515 */
516 return NSERROR_BAD_URL;
517 }
518
519 /* Rah, got it, so ref the fetcher. */
521
522 /* Dump new fetch in the queue. */
524
525 /* Ask the queue to run. */
526 if (fetch_dispatch_jobs()) {
527 NSLOG(fetch, DEBUG, "scheduling poll");
528 /* schedule active fetchers to run again in 10ms */
529 guit->misc->schedule(10, fetcher_poll, NULL);
530 }
531
532 *fetch_out = fetch;
533 return NSERROR_OK;
534}
535
536/* exported interface documented in content/fetch.h */
537void fetch_abort(struct fetch *f)
538{
539 assert(f);
541 NSLOG(fetch, DEBUG,
542 "fetch %p, fetcher %p, url '%s'", f, f->fetcher_handle,
543 nsurl_access(f->url));
545}
546
547/* exported interface documented in content/fetch.h */
548void fetch_free(struct fetch *f)
549{
551 /* We didn't finish, so tell our user that an error occurred */
552 fetch_msg msg;
553
554 msg.type = FETCH_ERROR;
555 msg.data.error = "FetchFailedToFinish";
556
557 NSLOG(fetch, CRITICAL,
558 "During the fetch of %s, the fetcher did not finish.",
559 nsurl_access(f->url));
560
561 fetch_send_callback(&msg, f);
562 }
563
564 NSLOG(fetch, DEBUG,
565 "Freeing fetch %p, fetcher %p",
566 f,
567 f->fetcher_handle);
568
570
572
573 nsurl_unref(f->url);
574 if (f->referer != NULL) {
576 }
577 if (f->host != NULL) {
578 lwc_string_unref(f->host);
579 }
580 free(f);
581}
582
583
584
585/* exported interface documented in content/fetch.h */
587{
588 lwc_string *scheme = nsurl_get_component(url, NSURL_SCHEME);
589 int fetcherd;
590
592 lwc_string_unref(scheme);
593
594 if (fetcherd == -1) {
595 return false;
596 }
597
599}
600
601/* exported interface documented in content/fetch.h */
604 void *p)
605{
606 assert(fetch);
608 fetch->p = p;
609}
610
611/* exported interface documented in content/fetch.h */
613{
614 return fetch->http_code;
615}
616
617
618/* exported interface documented in content/fetch.h */
621{
622 struct fetch_multipart_data *clone, *last = NULL;
623 struct fetch_multipart_data *result = NULL;
624
625 for (; list != NULL; list = list->next) {
626 clone = malloc(sizeof(struct fetch_multipart_data));
627 if (clone == NULL) {
628 if (result != NULL)
630
631 return NULL;
632 }
633
634 clone->file = list->file;
635
636 clone->name = strdup(list->name);
637 if (clone->name == NULL) {
638 free(clone);
639 if (result != NULL)
641
642 return NULL;
643 }
644
645 clone->value = strdup(list->value);
646 if (clone->value == NULL) {
647 free(clone->name);
648 free(clone);
649 if (result != NULL)
651
652 return NULL;
653 }
654
655 if (clone->file) {
656 clone->rawfile = strdup(list->rawfile);
657 if (clone->rawfile == NULL) {
658 free(clone->value);
659 free(clone->name);
660 free(clone);
661 if (result != NULL)
663
664 return NULL;
665 }
666 } else {
667 clone->rawfile = NULL;
668 }
669
670 clone->next = NULL;
671
672 if (result == NULL)
673 result = clone;
674 else
675 last->next = clone;
676
677 last = clone;
678 }
679
680 return result;
681}
682
683
684/* exported interface documented in content/fetch.h */
685const char *
687 const char *name)
688{
689 while (list != NULL) {
690 if (strcmp(list->name, name) == 0) {
691 return list->value;
692 }
693 list = list->next;
694 }
695
696 return NULL;
697}
698
699
700/* exported interface documented in content/fetch.h */
702{
704
705 for (; list != NULL; list = next) {
706 next = list->next;
707 free(list->name);
708 free(list->value);
709 if (list->file) {
710 NSLOG(fetch, DEBUG,
711 "Freeing rawfile: %s", list->rawfile);
712 free(list->rawfile);
713 }
714 free(list);
715 }
716}
717
718
719/* exported interface documented in content/fetch.h */
722 const char *name,
723 const char *value)
724{
725 struct fetch_multipart_data *newdata;
726
727 assert(list);
728
729 newdata = calloc(sizeof(*newdata), 1);
730
731 if (newdata == NULL) {
732 return NSERROR_NOMEM;
733 }
734
735 newdata->name = strdup(name);
736 if (newdata->name == NULL) {
737 free(newdata);
738 return NSERROR_NOMEM;
739 }
740
741 newdata->value = strdup(value);
742 if (newdata->value == NULL) {
743 free(newdata->name);
744 free(newdata);
745 return NSERROR_NOMEM;
746 }
747
748 newdata->next = *list;
749 *list = newdata;
750
751 return NSERROR_OK;
752}
753
754
755/* exported interface documented in content/fetch.h */
756void
758{
759 /* Bump the last_msg to the greatest seen msg */
760 if (msg->type > fetch->last_msg)
761 fetch->last_msg = msg->type;
762 fetch->callback(msg, fetch->p);
763}
764
765
766/* exported interface documented in content/fetch.h */
768{
769 int all_active;
770 int all_queued;
771
772 NSLOG(fetch, DEBUG,
773 "Fetch %p, fetcher %p can be freed",
774 fetch,
776
777 /* Go ahead and free the fetch properly now */
778 if (fetch->fetch_is_active) {
780 } else {
782 }
783
784
785 RING_GETSIZE(struct fetch, fetch_ring, all_active);
786 RING_GETSIZE(struct fetch, queue_ring, all_queued);
787
788 NSLOG(fetch, DEBUG, "Fetch ring is now %d elements.", all_active);
789 NSLOG(fetch, DEBUG, "Queue ring is now %d elements.", all_queued);
790}
791
792
793/* exported interface documented in content/fetch.h */
794void fetch_set_http_code(struct fetch *fetch, long http_code)
795{
796 NSLOG(fetch, DEBUG, "Setting HTTP code to %ld", http_code);
797
798 fetch->http_code = http_code;
799}
800
801
802/* exported interface documented in content/fetch.h */
803void fetch_set_cookie(struct fetch *fetch, const char *data)
804{
805 assert(fetch && data);
806
807 /* If the fetch is unverifiable err on the side of caution and
808 * do not set the cookie */
809
810 if (fetch->verifiable) {
811 /* If the transaction's verifiable, we don't require
812 * that the request uri and the parent domain match,
813 * so don't pass in any referer/parent in this case. */
814 urldb_set_cookie(data, fetch->url, NULL);
815 } else if (fetch->referer != NULL) {
816 /* Permit the cookie to be set if the fetch is unverifiable
817 * and the fetch URI domain matches the referer. */
818 /** \todo Long-term, this needs to be replaced with a
819 * comparison against the origin fetch URI. In the case
820 * where a nested object requests a fetch, the origin URI
821 * is the nested object's parent URI, whereas the referer
822 * for the fetch will be the nested object's URI. */
824 }
825}
STATIC char result[100]
Definition: arexx.c:77
static void fetch_unref_fetcher(int fetcherd)
Definition: fetch.c:117
nserror fetch_multipart_data_new_kv(struct fetch_multipart_data **list, const char *name, const char *value)
Create an entry for a fetch_multipart_data.
Definition: fetch.c:721
static struct fetch * fetch_ring
Ring of active fetches.
Definition: fetch.c:105
void fetch_set_http_code(struct fetch *fetch, long http_code)
set the http code of a fetch
Definition: fetch.c:794
void fetcher_quit(void)
Clean up for quit.
Definition: fetch.c:322
static void dump_rings(void)
Definition: fetch.c:203
static struct fetch * queue_ring
Ring of queued fetches.
Definition: fetch.c:106
bool fetch_can_fetch(const nsurl *url)
Check if a URL's scheme can be fetched.
Definition: fetch.c:586
static bool fetch_dispatch_jobs(void)
Dispatch as many jobs as we have room to dispatch.
Definition: fetch.c:231
static bool fetch_dispatch_job(struct fetch *fetch)
Dispatch a single job.
Definition: fetch.c:148
void fetch_set_cookie(struct fetch *fetch, const char *data)
set cookie data on a fetch
Definition: fetch.c:803
static void fetch_ref_fetcher(int fetcherd)
Definition: fetch.c:112
const char * fetch_multipart_data_find(const struct fetch_multipart_data *list, const char *name)
Find an entry in a fetch_multipart_data.
Definition: fetch.c:686
static scheme_fetcher fetchers[MAX_FETCHERS]
Definition: fetch.c:86
long fetch_http_code(struct fetch *fetch)
Get the HTTP response code.
Definition: fetch.c:612
nserror fetch_start(nsurl *url, nsurl *referer, fetch_callback callback, void *p, bool only_2xx, const char *post_urlenc, const struct fetch_multipart_data *post_multipart, bool verifiable, bool downgrade_tls, const char *headers[], struct fetch **fetch_out)
Start fetching data for the given URL.
Definition: fetch.c:449
void fetch_abort(struct fetch *f)
Abort a fetch.
Definition: fetch.c:537
nserror fetcher_add(lwc_string *scheme, const struct fetcher_operation_table *ops)
Register a fetcher for a scheme.
Definition: fetch.c:357
struct scheme_fetcher_s scheme_fetcher
Information about a fetcher for a given scheme.
nserror fetch_fdset(fd_set *read_fd_set, fd_set *write_fd_set, fd_set *except_fd_set, int *maxfd_out)
Get the set of file descriptors the fetchers are currently using.
Definition: fetch.c:385
static int get_fetcher_for_scheme(lwc_string *scheme)
Find a suitable fetcher for a scheme.
Definition: fetch.c:129
#define MAX_FETCHERS
The maximum number of fetchers that can be added.
Definition: fetch.c:64
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
static void fetcher_poll(void *unused)
Definition: fetch.c:262
#define FDSET_TIMEOUT
The fdset timeout in ms.
Definition: fetch.c:74
static bool fetch_choose_and_dispatch(void)
Choose and dispatch a single job.
Definition: fetch.c:173
struct fetch_multipart_data * fetch_multipart_data_clone(const struct fetch_multipart_data *list)
Clone a linked list of fetch_multipart_data.
Definition: fetch.c:620
void fetch_remove_from_queues(struct fetch *fetch)
remove a queued fetch
Definition: fetch.c:767
void fetch_change_callback(struct fetch *fetch, fetch_callback callback, void *p)
Change the callback function for a fetch.
Definition: fetch.c:602
void fetch_multipart_data_destroy(struct fetch_multipart_data *list)
Free a linked list of fetch_multipart_data.
Definition: fetch.c:701
#define SCHEDULE_TIME
The time in ms between polling the fetchers.
Definition: fetch.c:71
nserror fetcher_init(void)
Initialise all registered fetchers.
Definition: fetch.c:285
Fetching of data from a URL (interface).
#define FETCH__INTERNAL_ABORTED
This message is actually an internal message used to indicate that a fetch was aborted.
Definition: fetch.h:67
#define FETCH_MIN_FINISHED_MSG
Minimum finished message type.
Definition: fetch.h:61
void(* fetch_callback)(const fetch_msg *msg, void *p)
Definition: fetch.h:133
fetch_msg_type
Fetcher message types.
Definition: fetch.h:40
@ FETCH_ERROR
Definition: fetch.h:48
nserror fetch_file_register(void)
Register file scheme handler.
Definition: file.c:829
file scheme fetcher handler interface.
Useful interned string pointers (interface).
nserror fetch_curl_register(void)
Register curl scheme handler.
Definition: curl.c:1965
Fetching of data from a URL (Registration).
nserror fetch_data_register(void)
Register data scheme handler.
Definition: data.c:324
data scheme fetch handler interface.
nserror
Enumeration of error codes.
Definition: errors.h:29
@ NSERROR_INIT_FAILED
Initialisation failed.
Definition: errors.h:38
@ NSERROR_BAD_URL
Bad URL.
Definition: errors.h:55
@ NSERROR_NO_FETCH_HANDLER
No fetch handler for URL scheme.
Definition: errors.h:33
@ NSERROR_NOMEM
Memory exhaustion.
Definition: errors.h:32
@ NSERROR_OK
No error.
Definition: errors.h:30
nserror fetch_javascript_register(void)
Register javascript scheme fetcher with fetcher factory.
Definition: fetcher.c:202
javascript scheme handler
Interface for fetchers factory.
static nserror fetch(nsurl *url, enum backing_store_flags bsflags, uint8_t **data_out, size_t *datalen_out)
Retrieve an object from the backing store.
struct netsurf_table * guit
The global interface table.
Definition: gui_factory.c:49
Interface to core interface table.
Interface to platform-specific miscellaneous browser operation table.
#define NSLOG(catname, level, logmsg, args...)
Definition: log.h:116
Localised message support (interface).
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.
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_SCHEME
Definition: nsurl.h:45
@ NSURL_HOST
Definition: nsurl.h:49
struct nsurl nsurl
NetSurf URL object.
Definition: nsurl.h:31
nserror fetch_resource_register(void)
Register the resource scheme.
Definition: resource.c:469
resource URL scheme handler interface.
Ring list structure.
#define RING_GETSIZE(ringtype, ring, sizevar)
Measure the size of a ring and put it in the supplied variable.
Definition: ring.h:86
#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
#define RING_COUNTBYLWCHOST(ringtype, ring, sizevar, lwc_hostname)
Count the number of elements in the ring which match the provided lwc_hostname.
Definition: ring.h:98
Interface to utility string handling.
Fetcher message data.
Definition: fetch.h:72
fetch_msg_type type
Definition: fetch.h:73
union fetch_msg::@118 data
const char * error
Definition: fetch.h:83
Fetch POST multipart data.
Definition: fetch.h:109
char * rawfile
Raw filename if file is true.
Definition: fetch.h:115
char * value
Item value.
Definition: fetch.h:113
struct fetch_multipart_data * next
Next in linked list.
Definition: fetch.h:110
char * name
Name of item.
Definition: fetch.h:112
bool file
Item is a file.
Definition: fetch.h:116
Information for a single fetch.
Definition: fetch.c:89
fetch_callback callback
Callback function.
Definition: fetch.c:90
void * p
Private data for callback.
Definition: fetch.c:94
nsurl * referer
Referer URL.
Definition: fetch.c:92
long http_code
HTTP response code, or 0.
Definition: fetch.c:96
void * fetcher_handle
The handle for the fetcher.
Definition: fetch.c:98
nsurl * url
URL.
Definition: fetch.c:91
fetch_msg_type last_msg
The last message sent for this fetch.
Definition: fetch.c:100
bool fetch_is_active
This fetch is active.
Definition: fetch.c:99
lwc_string * host
Host part of URL, interned.
Definition: fetch.c:95
struct fetch * r_next
Next active fetch in fetch_ring.
Definition: fetch.c:102
int fetcherd
Fetcher descriptor for this fetch.
Definition: fetch.c:97
bool verifiable
Transaction is verifiable.
Definition: fetch.c:93
struct fetch * r_prev
Previous active fetch in fetch_ring.
Definition: fetch.c:101
Fetcher operations API.
Definition: fetchers.h:49
bool(* start)(void *fetch)
start a fetch.
Definition: fetchers.h:76
void(* free)(void *fetch)
free a fetch allocated through the setup method.
Definition: fetchers.h:86
void *(* setup)(struct fetch *parent_fetch, struct nsurl *url, bool only_2xx, bool downgrade_tls, const char *post_urlenc, const struct fetch_multipart_data *post_multipart, const char **headers)
Setup a fetch.
Definition: fetchers.h:68
void(* finalise)(lwc_string *scheme)
Finalise the fetcher.
Definition: fetchers.h:102
int(* fdset)(lwc_string *scheme, fd_set *read_set, fd_set *write_set, fd_set *error_set)
update an fdset with the FDs needed to poll cleanly
Definition: fetchers.h:96
void(* abort)(void *fetch)
abort a fetch.
Definition: fetchers.h:81
bool(* initialise)(lwc_string *scheme)
The initialiser for the fetcher.
Definition: fetchers.h:55
void(* poll)(lwc_string *scheme)
poll a fetcher to let it make progress.
Definition: fetchers.h:91
bool(* acceptable)(const struct nsurl *url)
Can this fetcher accept a url.
Definition: fetchers.h:63
nserror(* schedule)(int t, void(*callback)(void *p), void *p)
Schedule a callback.
Definition: misc.h:58
struct gui_misc_table * misc
Browser table.
Definition: gui_table.h:57
Information about a fetcher for a given scheme.
Definition: fetch.c:79
int refcount
When zero the fetcher is no longer in use.
Definition: fetch.c:83
lwc_string * scheme
The scheme.
Definition: fetch.c:80
struct fetcher_operation_table ops
The fetchers operations.
Definition: fetch.c:82
Interface to time operations.
bool urldb_set_cookie(const char *header, nsurl *url, nsurl *referer)
Parse Set-Cookie header and insert cookie(s) into database.
Definition: urldb.c:3734
Unified URL information database internal interface.
Option reading and saving interface.
#define nsoption_int(OPTION)
Get the value of an integer option.
Definition: nsoption.h:279