netsurf/test/llcache.c
Michael Drake fa2e3b7784 URL unescape: return the new length to the caller.
The avoids situations were we threw away the length, only for
the caller to have to strlen the returned string.

Note, there seems to be a case of the amiga front end writing
beyond end of allocation.  Added a TODO for now.
2016-07-24 14:03:16 +01:00

362 lines
7.9 KiB
C

/*
* Copyright 2011 John Mark Bell <jmb@netsurf-browser.org>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "content/fetch.h"
#include "content/llcache.h"
#include "utils/ring.h"
#include "utils/nsurl.h"
#include "utils/url.h"
#include "utils/corestrings.h"
#include "utils/utils.h"
/******************************************************************************
* Things that we'd reasonably expect to have to implement *
******************************************************************************/
bool verbose_log;
/* utils/utils.h */
char *filename_from_path(char *path)
{
char *leafname;
leafname = strrchr(path, '/');
if (!leafname)
leafname = path;
else
leafname += 1;
return strdup(leafname);
}
/* utils/schedule.h */
void schedule(int t, schedule_callback_fn cb, void *pw)
{
}
/* utils/schedule.h */
void schedule_remove(schedule_callback_fn cb, void *pw)
{
}
/* content/fetch.h */
const char *fetch_filetype(const char *unix_path)
{
return NULL;
}
/* content/fetch.h */
char *fetch_mimetype(const char *ro_path)
{
return NULL;
}
/* utils/url.h */
char *path_to_url(const char *path)
{
int urllen = strlen(path) + FILE_SCHEME_PREFIX_LEN + 1;
char *url = malloc(urllen);
if (url == NULL) {
return NULL;
}
if (*path == '/') {
path++; /* file: paths are already absolute */
}
snprintf(url, urllen, "%s%s", FILE_SCHEME_PREFIX, path);
return url;
}
/* utils/url.h */
char *url_to_path(const char *url)
{
char *url_path;
char *path = NULL;
if (url_unescape(url, 0, NULL, &url_path) == NSERROR_OK) {
/* return the absolute path including leading / */
path = strdup(url_path + (FILE_SCHEME_PREFIX_LEN - 1));
free(url_path);
}
return path;
}
/******************************************************************************
* Things that are absolutely not reasonable, and should disappear *
******************************************************************************/
#include "desktop/cookie_manager.h"
#include "desktop/tree.h"
/* desktop/cookie_manager.h -- used by urldb
*
* URLdb should have a cookies update event + handler registration
*/
bool cookie_manager_add(const struct cookie_data *data)
{
return true;
}
/* desktop/cookie_manager.h -- used by urldb
*
* URLdb should have a cookies removal handler registration
*/
void cookie_manager_remove(const struct cookie_data *data)
{
}
/* image/bitmap.h -- used by urldb
*
* URLdb shouldn't care about bitmaps.
* This is because the legacy RO thumbnail stuff was hacked in and must die.
*/
void bitmap_destroy(void *bitmap)
{
}
/* image/image.h -- used by urldb
*
* URLdb shouldn't care about bitmaps.
* This is because the legacy RO thumbnail stuff was hacked in and must die.
*/
bool image_bitmap_plot(struct bitmap *bitmap, struct content_redraw_data *data,
const struct rect *clip, const struct redraw_context *ctx)
{
return true;
}
/* content/fetchers/fetch_file.h -- used by fetcher core
*
* Simpler to stub this than haul in all the file fetcher's dependencies
*/
void fetch_file_register(void)
{
}
/******************************************************************************
* test: protocol handler *
******************************************************************************/
typedef struct test_context {
struct fetch *parent;
bool aborted;
bool locked;
struct test_context *r_prev;
struct test_context *r_next;
} test_context;
static test_context *ring;
bool test_initialise(lwc_string *scheme)
{
/* Nothing to do */
return true;
}
bool test_can_fetch(const nsurl *url)
{
/* Nothing to do */
return true;
}
void test_finalise(lwc_string *scheme)
{
/* Nothing to do */
}
void *test_setup_fetch(struct fetch *parent, nsurl *url, bool only_2xx,
bool downgrade_tls, const char *post_urlenc,
const struct fetch_multipart_data *post_multipart,
const char **headers)
{
test_context *ctx = calloc(1, sizeof(test_context));
if (ctx == NULL)
return NULL;
ctx->parent = parent;
RING_INSERT(ring, ctx);
return ctx;
}
bool test_start_fetch(void *handle)
{
/* Nothing to do */
return true;
}
void test_abort_fetch(void *handle)
{
test_context *ctx = handle;
ctx->aborted = true;
}
void test_free_fetch(void *handle)
{
test_context *ctx = handle;
RING_REMOVE(ring, ctx);
free(ctx);
}
void test_process(test_context *ctx)
{
/** \todo Implement */
}
void test_poll(lwc_string *scheme)
{
test_context *ctx, *next;
if (ring == NULL)
return;
ctx = ring;
do {
next = ctx->r_next;
if (ctx->locked)
continue;
if (ctx->aborted == false) {
test_process(ctx);
}
fetch_remove_from_queues(ctx->parent);
fetch_free(ctx->parent);
} while ((ctx = next) != ring && ring != NULL);
}
/******************************************************************************
* The actual test code *
******************************************************************************/
nserror query_handler(const llcache_query *query, void *pw,
llcache_query_response cb, void *cbpw)
{
/* I'm too lazy to actually implement this. It should queue the query,
* then deliver the response from main(). */
return NSERROR_OK;
}
nserror event_handler(llcache_handle *handle,
const llcache_event *event, void *pw)
{
static char *event_names[] = {
"HAD_HEADERS", "HAD_DATA", "DONE", "ERROR", "PROGRESS"
};
bool *done = pw;
if (event->type != LLCACHE_EVENT_PROGRESS)
fprintf(stdout, "%p : %s\n", handle, event_names[event->type]);
/* Inform main() that the fetch completed */
if (event->type == LLCACHE_EVENT_DONE)
*done = true;
return NSERROR_OK;
}
int main(int argc, char **argv)
{
nserror error;
llcache_handle *handle;
llcache_handle *handle2;
lwc_string *scheme;
nsurl *url;
bool done = false;
/* Initialise subsystems */
fetch_init();
if (lwc_intern_string("test", SLEN("test"), &scheme) != lwc_error_ok) {
fprintf(stderr, "Failed to intern \"test\"\n");
return 1;
}
fetch_add_fetcher(scheme, test_initialise, test_can_fetch,
test_setup_fetch, test_start_fetch, test_abort_fetch,
test_free_fetch, test_poll, test_finalise);
/* Initialise low-level cache */
error = llcache_initialise(query_handler, NULL, 1024 * 1024);
if (error != NSERROR_OK) {
fprintf(stderr, "llcache_initialise: %d\n", error);
return 1;
}
if (nsurl_create("http://www.netsurf-browser.org", &url) != NSERROR_OK) {
fprintf(stderr, "Failed creating url\n");
return 1;
}
/* Retrieve an URL from the low-level cache (may trigger fetch) */
error = llcache_handle_retrieve(url,
LLCACHE_RETRIEVE_VERIFIABLE, NULL, NULL,
event_handler, &done, &handle);
if (error != NSERROR_OK) {
fprintf(stderr, "llcache_handle_retrieve: %d\n", error);
return 1;
}
/* Poll relevant components */
while (done == false) {
llcache_poll();
}
done = false;
error = llcache_handle_retrieve(url,
LLCACHE_RETRIEVE_VERIFIABLE, NULL, NULL,
event_handler, &done, &handle2);
if (error != NSERROR_OK) {
fprintf(stderr, "llcache_handle_retrieve: %d\n", error);
return 1;
}
while (done == false) {
llcache_poll();
}
fprintf(stdout, "%p, %p -> %d\n", handle, handle2,
llcache_handle_references_same_object(handle, handle2));
/* Cleanup */
llcache_handle_release(handle2);
llcache_handle_release(handle);
fetch_quit();
return 0;
}