mirror of
https://github.com/netsurf-browser/netsurf
synced 2024-12-22 12:12:35 +03:00
Clean up fetch callback API. Inject some long-needed type safety.
svn path=/trunk/netsurf/; revision=13137
This commit is contained in:
parent
91bdfbd172
commit
dcbafe6b87
@ -662,12 +662,9 @@ void fetch_multipart_data_destroy(struct fetch_multipart_data *list)
|
||||
}
|
||||
|
||||
void
|
||||
fetch_send_callback(fetch_msg msg, struct fetch *fetch, const void *data,
|
||||
unsigned long size, fetch_error_code errorcode)
|
||||
fetch_send_callback(const fetch_msg *msg, struct fetch *fetch)
|
||||
{
|
||||
/*LOG(("Fetcher sending callback. Fetch %p, fetcher %p data %p size %lu",
|
||||
fetch, fetch->fetcher_handle, data, size)); */
|
||||
fetch->callback(msg, fetch->p, data, size, errorcode);
|
||||
fetch->callback(msg, fetch->p);
|
||||
}
|
||||
|
||||
|
||||
|
@ -30,33 +30,48 @@
|
||||
#include "utils/config.h"
|
||||
#include "utils/nsurl.h"
|
||||
|
||||
typedef enum {
|
||||
FETCH_PROGRESS,
|
||||
FETCH_HEADER,
|
||||
FETCH_DATA,
|
||||
FETCH_FINISHED,
|
||||
FETCH_ERROR,
|
||||
FETCH_REDIRECT,
|
||||
FETCH_NOTMODIFIED,
|
||||
FETCH_AUTH,
|
||||
FETCH_CERT_ERR,
|
||||
} fetch_msg;
|
||||
|
||||
typedef enum {
|
||||
FETCH_ERROR_NO_ERROR,
|
||||
FETCH_ERROR_CERT,
|
||||
FETCH_ERROR_AUTHENTICATION,
|
||||
FETCH_ERROR_HTTP_NOT2,
|
||||
FETCH_ERROR_COULDNT_RESOLVE_HOST,
|
||||
FETCH_ERROR_PARTIAL_FILE,
|
||||
FETCH_ERROR_MEMORY,
|
||||
FETCH_ERROR_URL,
|
||||
FETCH_ERROR_ENCODING,
|
||||
FETCH_ERROR_MISC
|
||||
} fetch_error_code;
|
||||
|
||||
struct content;
|
||||
struct fetch;
|
||||
struct ssl_cert_info;
|
||||
|
||||
typedef enum {
|
||||
FETCH_PROGRESS,
|
||||
FETCH_HEADER,
|
||||
FETCH_DATA,
|
||||
FETCH_FINISHED,
|
||||
FETCH_ERROR,
|
||||
FETCH_REDIRECT,
|
||||
FETCH_NOTMODIFIED,
|
||||
FETCH_AUTH,
|
||||
FETCH_CERT_ERR
|
||||
} fetch_msg_type;
|
||||
|
||||
typedef struct fetch_msg {
|
||||
fetch_msg_type type;
|
||||
|
||||
union {
|
||||
const char *progress;
|
||||
|
||||
struct {
|
||||
const uint8_t *buf;
|
||||
size_t len;
|
||||
} header_or_data;
|
||||
|
||||
const char *error;
|
||||
|
||||
/** \todo Use nsurl */
|
||||
const char *redirect;
|
||||
|
||||
struct {
|
||||
const char *realm;
|
||||
} auth;
|
||||
|
||||
struct {
|
||||
const struct ssl_cert_info *certs;
|
||||
size_t num_certs;
|
||||
} cert_err;
|
||||
} data;
|
||||
} fetch_msg;
|
||||
|
||||
/** Fetch POST multipart data */
|
||||
struct fetch_multipart_data {
|
||||
@ -80,8 +95,7 @@ struct ssl_cert_info {
|
||||
|
||||
extern bool fetch_active;
|
||||
|
||||
typedef void (*fetch_callback)(fetch_msg msg, void *p, const void *data,
|
||||
unsigned long size, fetch_error_code errorcode);
|
||||
typedef void (*fetch_callback)(const fetch_msg *msg, void *p);
|
||||
|
||||
|
||||
void fetch_init(void);
|
||||
@ -141,12 +155,11 @@ bool fetch_add_fetcher(lwc_string *scheme,
|
||||
fetcher_poll_fetcher poll_fetcher,
|
||||
fetcher_finalise finaliser);
|
||||
|
||||
void fetch_send_callback(fetch_msg msg, struct fetch *fetch,
|
||||
const void *data, unsigned long size,
|
||||
fetch_error_code errorcode);
|
||||
void fetch_send_callback(const fetch_msg *msg, struct fetch *fetch);
|
||||
void fetch_remove_from_queues(struct fetch *fetch);
|
||||
void fetch_free(struct fetch *f);
|
||||
void fetch_set_http_code(struct fetch *fetch, long http_code);
|
||||
const char *fetch_get_referer_to_send(struct fetch *fetch);
|
||||
void fetch_set_cookie(struct fetch *fetch, const char *data);
|
||||
|
||||
#endif
|
||||
|
@ -77,12 +77,11 @@ struct fetch_about_context {
|
||||
static struct fetch_about_context *ring = NULL;
|
||||
|
||||
/** issue fetch callbacks with locking */
|
||||
static inline bool fetch_about_send_callback(fetch_msg msg,
|
||||
struct fetch_about_context *ctx, const void *data,
|
||||
unsigned long size, fetch_error_code errorcode)
|
||||
static inline bool fetch_about_send_callback(const fetch_msg *msg,
|
||||
struct fetch_about_context *ctx)
|
||||
{
|
||||
ctx->locked = true;
|
||||
fetch_send_callback(msg, ctx->fetchh, data, size, errorcode);
|
||||
fetch_send_callback(msg, ctx->fetchh);
|
||||
ctx->locked = false;
|
||||
|
||||
return ctx->aborted;
|
||||
@ -92,6 +91,7 @@ static bool fetch_about_send_header(struct fetch_about_context *ctx,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
char header[64];
|
||||
fetch_msg msg;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
@ -100,8 +100,11 @@ static bool fetch_about_send_header(struct fetch_about_context *ctx,
|
||||
|
||||
va_end(ap);
|
||||
|
||||
fetch_about_send_callback(FETCH_HEADER, ctx, header, strlen(header),
|
||||
FETCH_ERROR_NO_ERROR);
|
||||
msg.type = FETCH_HEADER;
|
||||
msg.data.header_or_data.buf = (const uint8_t *) header;
|
||||
msg.data.header_or_data.len = strlen(header);
|
||||
|
||||
fetch_about_send_callback(&msg, ctx);
|
||||
|
||||
return ctx->aborted;
|
||||
}
|
||||
@ -111,24 +114,26 @@ static bool fetch_about_send_header(struct fetch_about_context *ctx,
|
||||
|
||||
static bool fetch_about_blank_handler(struct fetch_about_context *ctx)
|
||||
{
|
||||
char buffer[2];
|
||||
int code = 200;
|
||||
fetch_msg msg;
|
||||
const char buffer[2] = { ' ', '\0' };
|
||||
|
||||
/* content is going to return ok */
|
||||
fetch_set_http_code(ctx->fetchh, code);
|
||||
fetch_set_http_code(ctx->fetchh, 200);
|
||||
|
||||
/* content type */
|
||||
if (fetch_about_send_header(ctx, "Content-Type: text/html"))
|
||||
goto fetch_about_blank_handler_aborted;
|
||||
|
||||
buffer[0] = ' ';
|
||||
buffer[1] = 0;
|
||||
if (fetch_about_send_callback(FETCH_DATA, ctx, buffer, strlen(buffer),
|
||||
FETCH_ERROR_NO_ERROR))
|
||||
msg.type = FETCH_DATA;
|
||||
msg.data.header_or_data.buf = (const uint8_t *) buffer;
|
||||
msg.data.header_or_data.len = strlen(buffer);
|
||||
|
||||
if (fetch_about_send_callback(&msg, ctx))
|
||||
goto fetch_about_blank_handler_aborted;
|
||||
|
||||
fetch_about_send_callback(FETCH_FINISHED, ctx, 0, 0,
|
||||
FETCH_ERROR_NO_ERROR);
|
||||
msg.type = FETCH_FINISHED;
|
||||
|
||||
fetch_about_send_callback(&msg, ctx);
|
||||
|
||||
return true;
|
||||
|
||||
@ -139,11 +144,15 @@ fetch_about_blank_handler_aborted:
|
||||
|
||||
static bool fetch_about_credits_handler(struct fetch_about_context *ctx)
|
||||
{
|
||||
fetch_msg msg;
|
||||
|
||||
/* content is going to return redirect */
|
||||
fetch_set_http_code(ctx->fetchh, 302);
|
||||
|
||||
fetch_about_send_callback(FETCH_REDIRECT, ctx, "resource:credits.html",
|
||||
0, FETCH_ERROR_NO_ERROR);
|
||||
msg.type = FETCH_REDIRECT;
|
||||
msg.data.redirect = "resource:credits.html";
|
||||
|
||||
fetch_about_send_callback(&msg, ctx);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -151,11 +160,15 @@ static bool fetch_about_credits_handler(struct fetch_about_context *ctx)
|
||||
|
||||
static bool fetch_about_licence_handler(struct fetch_about_context *ctx)
|
||||
{
|
||||
fetch_msg msg;
|
||||
|
||||
/* content is going to return redirect */
|
||||
fetch_set_http_code(ctx->fetchh, 302);
|
||||
|
||||
fetch_about_send_callback(FETCH_REDIRECT, ctx, "resource:licence.html",
|
||||
0, FETCH_ERROR_NO_ERROR);
|
||||
msg.type = FETCH_REDIRECT;
|
||||
msg.data.redirect = "resource:licence.html";
|
||||
|
||||
fetch_about_send_callback(&msg, ctx);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -167,6 +180,7 @@ static bool fetch_about_licence_handler(struct fetch_about_context *ctx)
|
||||
*/
|
||||
static bool fetch_about_imagecache_handler(struct fetch_about_context *ctx)
|
||||
{
|
||||
fetch_msg msg;
|
||||
char buffer[1024]; /* output buffer */
|
||||
int code = 200;
|
||||
int slen;
|
||||
@ -180,6 +194,9 @@ static bool fetch_about_imagecache_handler(struct fetch_about_context *ctx)
|
||||
if (fetch_about_send_header(ctx, "Content-Type: text/html"))
|
||||
goto fetch_about_imagecache_handler_aborted;
|
||||
|
||||
msg.type = FETCH_DATA;
|
||||
msg.data.header_or_data.buf = (const uint8_t *) buffer;
|
||||
|
||||
/* page head */
|
||||
slen = snprintf(buffer, sizeof buffer,
|
||||
"<html>\n<head>\n"
|
||||
@ -193,8 +210,8 @@ static bool fetch_about_imagecache_handler(struct fetch_about_context *ctx)
|
||||
"<img src=\"resource:netsurf.png\" alt=\"NetSurf\"></a>"
|
||||
"</p>\n"
|
||||
"<h1>NetSurf Browser Image Cache Status</h1>\n" );
|
||||
if (fetch_about_send_callback(FETCH_DATA, ctx, buffer,
|
||||
slen, FETCH_ERROR_NO_ERROR))
|
||||
msg.data.header_or_data.len = slen;
|
||||
if (fetch_about_send_callback(&msg, ctx))
|
||||
goto fetch_about_imagecache_handler_aborted;
|
||||
|
||||
/* image cache summary */
|
||||
@ -216,8 +233,8 @@ static bool fetch_about_imagecache_handler(struct fetch_about_context *ctx)
|
||||
if (slen >= (int) (sizeof(buffer)))
|
||||
goto fetch_about_imagecache_handler_aborted; /* overflow */
|
||||
|
||||
if (fetch_about_send_callback(FETCH_DATA, ctx, buffer,
|
||||
slen, FETCH_ERROR_NO_ERROR))
|
||||
msg.data.header_or_data.len = slen;
|
||||
if (fetch_about_send_callback(&msg, ctx))
|
||||
goto fetch_about_imagecache_handler_aborted;
|
||||
|
||||
|
||||
@ -240,8 +257,8 @@ static bool fetch_about_imagecache_handler(struct fetch_about_context *ctx)
|
||||
|
||||
if (res >= (int) (sizeof buffer - slen)) {
|
||||
/* last entry would not fit in buffer, submit buffer */
|
||||
if (fetch_about_send_callback(FETCH_DATA, ctx, buffer,
|
||||
slen, FETCH_ERROR_NO_ERROR))
|
||||
msg.data.header_or_data.len = slen;
|
||||
if (fetch_about_send_callback(&msg, ctx))
|
||||
goto fetch_about_imagecache_handler_aborted;
|
||||
slen = 0;
|
||||
} else {
|
||||
@ -254,12 +271,12 @@ static bool fetch_about_imagecache_handler(struct fetch_about_context *ctx)
|
||||
slen += snprintf(buffer + slen, sizeof buffer - slen,
|
||||
"</table>\n</body>\n</html>\n");
|
||||
|
||||
if (fetch_about_send_callback(FETCH_DATA, ctx, buffer, slen,
|
||||
FETCH_ERROR_NO_ERROR))
|
||||
msg.data.header_or_data.len = slen;
|
||||
if (fetch_about_send_callback(&msg, ctx))
|
||||
goto fetch_about_imagecache_handler_aborted;
|
||||
|
||||
fetch_about_send_callback(FETCH_FINISHED, ctx, 0, 0,
|
||||
FETCH_ERROR_NO_ERROR);
|
||||
msg.type = FETCH_FINISHED;
|
||||
fetch_about_send_callback(&msg, ctx);
|
||||
|
||||
return true;
|
||||
|
||||
@ -270,6 +287,7 @@ fetch_about_imagecache_handler_aborted:
|
||||
/** Handler to generate about:config page */
|
||||
static bool fetch_about_config_handler(struct fetch_about_context *ctx)
|
||||
{
|
||||
fetch_msg msg;
|
||||
char buffer[1024];
|
||||
int code = 200;
|
||||
int slen;
|
||||
@ -283,6 +301,9 @@ static bool fetch_about_config_handler(struct fetch_about_context *ctx)
|
||||
if (fetch_about_send_header(ctx, "Content-Type: text/html"))
|
||||
goto fetch_about_config_handler_aborted;
|
||||
|
||||
msg.type = FETCH_DATA;
|
||||
msg.data.header_or_data.buf = (const uint8_t *) buffer;
|
||||
|
||||
slen = snprintf(buffer, sizeof buffer,
|
||||
"<html>\n<head>\n"
|
||||
"<title>NetSurf Browser Config</title>\n"
|
||||
@ -307,8 +328,8 @@ static bool fetch_about_config_handler(struct fetch_about_context *ctx)
|
||||
|
||||
if (res >= (int) (sizeof buffer - slen)) {
|
||||
/* last entry would not fit in buffer, submit buffer */
|
||||
if (fetch_about_send_callback(FETCH_DATA, ctx, buffer,
|
||||
slen, FETCH_ERROR_NO_ERROR))
|
||||
msg.data.header_or_data.len = slen;
|
||||
if (fetch_about_send_callback(&msg, ctx))
|
||||
goto fetch_about_config_handler_aborted;
|
||||
slen = 0;
|
||||
} else {
|
||||
@ -321,12 +342,12 @@ static bool fetch_about_config_handler(struct fetch_about_context *ctx)
|
||||
slen += snprintf(buffer + slen, sizeof buffer - slen,
|
||||
"</table>\n</body>\n</html>\n");
|
||||
|
||||
if (fetch_about_send_callback(FETCH_DATA, ctx, buffer, slen,
|
||||
FETCH_ERROR_NO_ERROR))
|
||||
msg.data.header_or_data.len = slen;
|
||||
if (fetch_about_send_callback(&msg, ctx))
|
||||
goto fetch_about_config_handler_aborted;
|
||||
|
||||
fetch_about_send_callback(FETCH_FINISHED, ctx, 0, 0,
|
||||
FETCH_ERROR_NO_ERROR);
|
||||
msg.type = FETCH_FINISHED;
|
||||
fetch_about_send_callback(&msg, ctx);
|
||||
|
||||
return true;
|
||||
|
||||
@ -340,6 +361,7 @@ fetch_about_config_handler_aborted:
|
||||
*/
|
||||
static bool fetch_about_choices_handler(struct fetch_about_context *ctx)
|
||||
{
|
||||
fetch_msg msg;
|
||||
char buffer[1024];
|
||||
int code = 200;
|
||||
int slen;
|
||||
@ -353,6 +375,9 @@ static bool fetch_about_choices_handler(struct fetch_about_context *ctx)
|
||||
if (fetch_about_send_header(ctx, "Content-Type: text/plain"))
|
||||
goto fetch_about_choices_handler_aborted;
|
||||
|
||||
msg.type = FETCH_DATA;
|
||||
msg.data.header_or_data.buf = (const uint8_t *) buffer;
|
||||
|
||||
slen = snprintf(buffer, sizeof buffer,
|
||||
"# Automatically generated current NetSurf browser Choices\n");
|
||||
|
||||
@ -366,8 +391,8 @@ static bool fetch_about_choices_handler(struct fetch_about_context *ctx)
|
||||
|
||||
if (res >= (int) (sizeof buffer - slen)) {
|
||||
/* last entry would not fit in buffer, submit buffer */
|
||||
if (fetch_about_send_callback(FETCH_DATA, ctx, buffer,
|
||||
slen, FETCH_ERROR_NO_ERROR))
|
||||
msg.data.header_or_data.len = slen;
|
||||
if (fetch_about_send_callback(&msg, ctx))
|
||||
goto fetch_about_choices_handler_aborted;
|
||||
slen = 0;
|
||||
} else {
|
||||
@ -377,12 +402,12 @@ static bool fetch_about_choices_handler(struct fetch_about_context *ctx)
|
||||
}
|
||||
} while (res > 0);
|
||||
|
||||
if (fetch_about_send_callback(FETCH_DATA, ctx, buffer, slen,
|
||||
FETCH_ERROR_NO_ERROR))
|
||||
msg.data.header_or_data.len = slen;
|
||||
if (fetch_about_send_callback(&msg, ctx))
|
||||
goto fetch_about_choices_handler_aborted;
|
||||
|
||||
fetch_about_send_callback(FETCH_FINISHED, ctx, 0, 0,
|
||||
FETCH_ERROR_NO_ERROR);
|
||||
msg.type = FETCH_FINISHED;
|
||||
fetch_about_send_callback(&msg, ctx);
|
||||
|
||||
return true;
|
||||
|
||||
@ -397,6 +422,7 @@ typedef struct { const char *leaf; const char modtype; } modification_t;
|
||||
static bool fetch_about_testament_handler(struct fetch_about_context *ctx)
|
||||
{
|
||||
static modification_t modifications[] = WT_MODIFICATIONS;
|
||||
fetch_msg msg;
|
||||
char buffer[1024];
|
||||
int code = 200;
|
||||
int slen;
|
||||
@ -410,11 +436,14 @@ static bool fetch_about_testament_handler(struct fetch_about_context *ctx)
|
||||
if (fetch_about_send_header(ctx, "Content-Type: text/plain"))
|
||||
goto fetch_about_testament_handler_aborted;
|
||||
|
||||
msg.type = FETCH_DATA;
|
||||
msg.data.header_or_data.buf = (const uint8_t *) buffer;
|
||||
|
||||
slen = snprintf(buffer, sizeof buffer,
|
||||
"# Automatically generated by NetSurf build system\n\n");
|
||||
|
||||
if (fetch_about_send_callback(FETCH_DATA, ctx, buffer, slen,
|
||||
FETCH_ERROR_NO_ERROR))
|
||||
msg.data.header_or_data.len = slen;
|
||||
if (fetch_about_send_callback(&msg, ctx))
|
||||
goto fetch_about_testament_handler_aborted;
|
||||
|
||||
slen = snprintf(buffer, sizeof buffer,
|
||||
@ -430,9 +459,9 @@ static bool fetch_about_testament_handler(struct fetch_about_context *ctx)
|
||||
"# This NetSurf was built from a branch.\n\n"
|
||||
#endif
|
||||
);
|
||||
|
||||
if (fetch_about_send_callback(FETCH_DATA, ctx, buffer, slen,
|
||||
FETCH_ERROR_NO_ERROR))
|
||||
|
||||
msg.data.header_or_data.len = slen;
|
||||
if (fetch_about_send_callback(&msg, ctx))
|
||||
goto fetch_about_testament_handler_aborted;
|
||||
|
||||
|
||||
@ -440,16 +469,16 @@ static bool fetch_about_testament_handler(struct fetch_about_context *ctx)
|
||||
"Built by %s (%s) from %s at revision %s\n\n",
|
||||
GECOS, USERNAME, WT_BRANCHPATH, WT_REVID);
|
||||
|
||||
if (fetch_about_send_callback(FETCH_DATA, ctx, buffer, slen,
|
||||
FETCH_ERROR_NO_ERROR))
|
||||
msg.data.header_or_data.len = slen;
|
||||
if (fetch_about_send_callback(&msg, ctx))
|
||||
goto fetch_about_testament_handler_aborted;
|
||||
|
||||
slen = snprintf(buffer, sizeof buffer,
|
||||
"Built on %s in %s\n\n",
|
||||
WT_HOSTNAME, WT_ROOT);
|
||||
|
||||
if (fetch_about_send_callback(FETCH_DATA, ctx, buffer, slen,
|
||||
FETCH_ERROR_NO_ERROR))
|
||||
msg.data.header_or_data.len = slen;
|
||||
if (fetch_about_send_callback(&msg, ctx))
|
||||
goto fetch_about_testament_handler_aborted;
|
||||
|
||||
if (WT_MODIFIED > 0) {
|
||||
@ -461,8 +490,8 @@ static bool fetch_about_testament_handler(struct fetch_about_context *ctx)
|
||||
"Working tree is not modified.\n");
|
||||
}
|
||||
|
||||
if (fetch_about_send_callback(FETCH_DATA, ctx, buffer, slen,
|
||||
FETCH_ERROR_NO_ERROR))
|
||||
msg.data.header_or_data.len = slen;
|
||||
if (fetch_about_send_callback(&msg, ctx))
|
||||
goto fetch_about_testament_handler_aborted;
|
||||
|
||||
for (i = 0; i < WT_MODIFIED; ++i) {
|
||||
@ -470,14 +499,14 @@ static bool fetch_about_testament_handler(struct fetch_about_context *ctx)
|
||||
" %c %s\n",
|
||||
modifications[i].modtype,
|
||||
modifications[i].leaf);
|
||||
if (fetch_about_send_callback(FETCH_DATA, ctx, buffer, slen,
|
||||
FETCH_ERROR_NO_ERROR))
|
||||
msg.data.header_or_data.len = slen;
|
||||
if (fetch_about_send_callback(&msg, ctx))
|
||||
goto fetch_about_testament_handler_aborted;
|
||||
|
||||
}
|
||||
|
||||
fetch_about_send_callback(FETCH_FINISHED, ctx, 0, 0,
|
||||
FETCH_ERROR_NO_ERROR);
|
||||
|
||||
msg.type = FETCH_FINISHED;
|
||||
fetch_about_send_callback(&msg, ctx);
|
||||
|
||||
return true;
|
||||
|
||||
@ -487,11 +516,15 @@ fetch_about_testament_handler_aborted:
|
||||
|
||||
static bool fetch_about_logo_handler(struct fetch_about_context *ctx)
|
||||
{
|
||||
fetch_msg msg;
|
||||
|
||||
/* content is going to return redirect */
|
||||
fetch_set_http_code(ctx->fetchh, 302);
|
||||
|
||||
fetch_about_send_callback(FETCH_REDIRECT, ctx, "resource:netsurf.png",
|
||||
0, FETCH_ERROR_NO_ERROR);
|
||||
msg.type = FETCH_REDIRECT;
|
||||
msg.data.redirect = "resource:netsurf.png";
|
||||
|
||||
fetch_about_send_callback(&msg, ctx);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -533,6 +566,7 @@ struct about_handlers about_handler_list[] = {
|
||||
*/
|
||||
static bool fetch_about_about_handler(struct fetch_about_context *ctx)
|
||||
{
|
||||
fetch_msg msg;
|
||||
char buffer[1024];
|
||||
int code = 200;
|
||||
int slen;
|
||||
@ -546,6 +580,9 @@ static bool fetch_about_about_handler(struct fetch_about_context *ctx)
|
||||
if (fetch_about_send_header(ctx, "Content-Type: text/html"))
|
||||
goto fetch_about_config_handler_aborted;
|
||||
|
||||
msg.type = FETCH_DATA;
|
||||
msg.data.header_or_data.buf = (const uint8_t *) buffer;
|
||||
|
||||
slen = snprintf(buffer, sizeof buffer,
|
||||
"<html>\n<head>\n"
|
||||
"<title>NetSurf List of About pages</title>\n"
|
||||
@ -575,8 +612,8 @@ static bool fetch_about_about_handler(struct fetch_about_context *ctx)
|
||||
|
||||
if (res >= (int)(sizeof buffer - slen)) {
|
||||
/* last entry would not fit in buffer, submit buffer */
|
||||
if (fetch_about_send_callback(FETCH_DATA, ctx, buffer,
|
||||
slen, FETCH_ERROR_NO_ERROR))
|
||||
msg.data.header_or_data.len = slen;
|
||||
if (fetch_about_send_callback(&msg, ctx))
|
||||
goto fetch_about_config_handler_aborted;
|
||||
slen = 0;
|
||||
} else {
|
||||
@ -588,12 +625,12 @@ static bool fetch_about_about_handler(struct fetch_about_context *ctx)
|
||||
slen += snprintf(buffer + slen, sizeof buffer - slen,
|
||||
"</ul>\n</body>\n</html>\n");
|
||||
|
||||
if (fetch_about_send_callback(FETCH_DATA, ctx, buffer, slen,
|
||||
FETCH_ERROR_NO_ERROR))
|
||||
msg.data.header_or_data.len = slen;
|
||||
if (fetch_about_send_callback(&msg, ctx))
|
||||
goto fetch_about_config_handler_aborted;
|
||||
|
||||
fetch_about_send_callback(FETCH_FINISHED, ctx, 0, 0,
|
||||
FETCH_ERROR_NO_ERROR);
|
||||
msg.type = FETCH_FINISHED;
|
||||
fetch_about_send_callback(&msg, ctx);
|
||||
|
||||
return true;
|
||||
|
||||
|
@ -787,9 +787,9 @@ void fetch_curl_poll(lwc_string *scheme_ignored)
|
||||
|
||||
void fetch_curl_done(CURL *curl_handle, CURLcode result)
|
||||
{
|
||||
fetch_msg msg;
|
||||
bool finished = false;
|
||||
bool error = false;
|
||||
fetch_error_code errorcode = FETCH_ERROR_NO_ERROR;
|
||||
bool cert = false;
|
||||
bool abort_fetch;
|
||||
struct curl_fetch_info *f;
|
||||
@ -830,7 +830,6 @@ void fetch_curl_done(CURL *curl_handle, CURLcode result)
|
||||
; /* redirect with partial body, or similar */
|
||||
else {
|
||||
error = true;
|
||||
errorcode = FETCH_ERROR_PARTIAL_FILE;
|
||||
}
|
||||
} else if (result == CURLE_WRITE_ERROR && f->stopped)
|
||||
/* CURLE_WRITE_ERROR occurs when fetch_curl_data
|
||||
@ -842,23 +841,19 @@ void fetch_curl_done(CURL *curl_handle, CURLcode result)
|
||||
memset(f->cert_data, 0, sizeof(f->cert_data));
|
||||
cert = true;
|
||||
}
|
||||
else if (result == CURLE_COULDNT_RESOLVE_HOST) {
|
||||
error = true;
|
||||
errorcode = FETCH_ERROR_COULDNT_RESOLVE_HOST;
|
||||
}
|
||||
else {
|
||||
LOG(("Unknown cURL response code %d", result));
|
||||
error = true;
|
||||
errorcode = FETCH_ERROR_MISC;
|
||||
}
|
||||
|
||||
fetch_curl_stop(f);
|
||||
|
||||
if (abort_fetch)
|
||||
; /* fetch was aborted: no callback */
|
||||
else if (finished)
|
||||
fetch_send_callback(FETCH_FINISHED, f->fetch_handle, 0, 0, errorcode);
|
||||
else if (cert) {
|
||||
else if (finished) {
|
||||
msg.type = FETCH_FINISHED;
|
||||
fetch_send_callback(&msg, f->fetch_handle);
|
||||
} else if (cert) {
|
||||
int i;
|
||||
BIO *mem;
|
||||
BUF_MEM *buf;
|
||||
@ -934,14 +929,17 @@ void fetch_curl_done(CURL *curl_handle, CURLcode result)
|
||||
if (certs[i].cert->references == 0)
|
||||
X509_free(certs[i].cert);
|
||||
}
|
||||
errorcode = FETCH_ERROR_CERT;
|
||||
fetch_send_callback(FETCH_CERT_ERR, f->fetch_handle,
|
||||
&ssl_certs, i, errorcode);
|
||||
|
||||
msg.type = FETCH_CERT_ERR;
|
||||
msg.data.cert_err.certs = ssl_certs;
|
||||
msg.data.cert_err.num_certs = i;
|
||||
fetch_send_callback(&msg, f->fetch_handle);
|
||||
} else if (error) {
|
||||
msg.type = FETCH_ERROR;
|
||||
msg.data.error = fetch_error_buffer;
|
||||
|
||||
fetch_send_callback(&msg, f->fetch_handle);
|
||||
}
|
||||
else if (error)
|
||||
fetch_send_callback(FETCH_ERROR, f->fetch_handle,
|
||||
fetch_error_buffer, 0, errorcode);
|
||||
|
||||
fetch_free(f->fetch_handle);
|
||||
}
|
||||
@ -957,11 +955,14 @@ int fetch_curl_progress(void *clientp, double dltotal, double dlnow,
|
||||
static char fetch_progress_buffer[256]; /**< Progress buffer for cURL */
|
||||
struct curl_fetch_info *f = (struct curl_fetch_info *) clientp;
|
||||
unsigned int time_now_cs;
|
||||
double percent;
|
||||
fetch_msg msg;
|
||||
|
||||
if (f->abort)
|
||||
return 0;
|
||||
|
||||
msg.type = FETCH_PROGRESS;
|
||||
msg.data.progress = fetch_progress_buffer;
|
||||
|
||||
/* Rate limit each fetch's progress notifications to 2 a second */
|
||||
#define UPDATES_PER_SECOND 2
|
||||
#define UPDATE_DELAY_CS (100 / UPDATES_PER_SECOND)
|
||||
@ -973,22 +974,16 @@ int fetch_curl_progress(void *clientp, double dltotal, double dlnow,
|
||||
#undef UPDATES_PERS_SECOND
|
||||
|
||||
if (dltotal > 0) {
|
||||
percent = dlnow * 100.0f / dltotal;
|
||||
snprintf(fetch_progress_buffer, 255,
|
||||
messages_get("Progress"),
|
||||
human_friendly_bytesize(dlnow),
|
||||
human_friendly_bytesize(dltotal));
|
||||
fetch_send_callback(FETCH_PROGRESS, f->fetch_handle,
|
||||
fetch_progress_buffer,
|
||||
(unsigned long) percent,
|
||||
FETCH_ERROR_NO_ERROR);
|
||||
fetch_send_callback(&msg, f->fetch_handle);
|
||||
} else {
|
||||
snprintf(fetch_progress_buffer, 255,
|
||||
messages_get("ProgressU"),
|
||||
human_friendly_bytesize(dlnow));
|
||||
fetch_send_callback(FETCH_PROGRESS, f->fetch_handle,
|
||||
fetch_progress_buffer, 0,
|
||||
FETCH_ERROR_NO_ERROR);
|
||||
fetch_send_callback(&msg, f->fetch_handle);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1021,6 +1016,7 @@ size_t fetch_curl_data(char *data, size_t size, size_t nmemb,
|
||||
{
|
||||
struct curl_fetch_info *f = _f;
|
||||
CURLcode code;
|
||||
fetch_msg msg;
|
||||
|
||||
/* ensure we only have to get this information once */
|
||||
if (!f->http_code)
|
||||
@ -1039,17 +1035,16 @@ size_t fetch_curl_data(char *data, size_t size, size_t nmemb,
|
||||
return size * nmemb;
|
||||
}
|
||||
|
||||
/*LOG(("fetch %p, size %lu", f, size * nmemb));*/
|
||||
|
||||
if (f->abort || (!f->had_headers && fetch_curl_process_headers(f))) {
|
||||
f->stopped = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* send data to the caller */
|
||||
/*LOG(("FETCH_DATA"));*/
|
||||
fetch_send_callback(FETCH_DATA, f->fetch_handle, data, size * nmemb,
|
||||
FETCH_ERROR_NO_ERROR);
|
||||
msg.type = FETCH_DATA;
|
||||
msg.data.header_or_data.buf = (const uint8_t *) data;
|
||||
msg.data.header_or_data.len = size * nmemb;
|
||||
fetch_send_callback(&msg, f->fetch_handle);
|
||||
|
||||
if (f->abort) {
|
||||
f->stopped = true;
|
||||
@ -1071,6 +1066,7 @@ size_t fetch_curl_header(char *data, size_t size, size_t nmemb,
|
||||
{
|
||||
struct curl_fetch_info *f = _f;
|
||||
int i;
|
||||
fetch_msg msg;
|
||||
size *= nmemb;
|
||||
|
||||
if (f->abort) {
|
||||
@ -1078,8 +1074,10 @@ size_t fetch_curl_header(char *data, size_t size, size_t nmemb,
|
||||
return 0;
|
||||
}
|
||||
|
||||
fetch_send_callback(FETCH_HEADER, f->fetch_handle, data, size,
|
||||
FETCH_ERROR_NO_ERROR);
|
||||
msg.type = FETCH_HEADER;
|
||||
msg.data.header_or_data.buf = (const uint8_t *) data;
|
||||
msg.data.header_or_data.len = size;
|
||||
fetch_send_callback(&msg, f->fetch_handle);
|
||||
|
||||
#define SKIP_ST(o) for (i = (o); i < (int) size && (data[i] == ' ' || data[i] == '\t'); i++)
|
||||
|
||||
@ -1152,6 +1150,7 @@ bool fetch_curl_process_headers(struct curl_fetch_info *f)
|
||||
{
|
||||
long http_code;
|
||||
CURLcode code;
|
||||
fetch_msg msg;
|
||||
|
||||
f->had_headers = true;
|
||||
|
||||
@ -1167,32 +1166,34 @@ bool fetch_curl_process_headers(struct curl_fetch_info *f)
|
||||
|
||||
if (http_code == 304 && !f->post_urlenc && !f->post_multipart) {
|
||||
/* Not Modified && GET request */
|
||||
fetch_send_callback(FETCH_NOTMODIFIED, f->fetch_handle, 0, 0,
|
||||
FETCH_ERROR_NO_ERROR);
|
||||
msg.type = FETCH_NOTMODIFIED;
|
||||
fetch_send_callback(&msg, f->fetch_handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* handle HTTP redirects (3xx response codes) */
|
||||
if (300 <= http_code && http_code < 400 && f->location != 0) {
|
||||
LOG(("FETCH_REDIRECT, '%s'", f->location));
|
||||
fetch_send_callback(FETCH_REDIRECT, f->fetch_handle,
|
||||
f->location, 0, FETCH_ERROR_NO_ERROR);
|
||||
msg.type = FETCH_REDIRECT;
|
||||
msg.data.redirect = f->location;
|
||||
fetch_send_callback(&msg, f->fetch_handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* handle HTTP 401 (Authentication errors) */
|
||||
if (http_code == 401) {
|
||||
fetch_send_callback(FETCH_AUTH, f->fetch_handle, f->realm, 0,
|
||||
FETCH_ERROR_AUTHENTICATION);
|
||||
msg.type = FETCH_AUTH;
|
||||
msg.data.auth.realm = f->realm;
|
||||
fetch_send_callback(&msg, f->fetch_handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* handle HTTP errors (non 2xx response codes) */
|
||||
if (f->only_2xx && strncmp(nsurl_access(f->url), "http", 4) == 0 &&
|
||||
(http_code < 200 || 299 < http_code)) {
|
||||
fetch_send_callback(FETCH_ERROR, f->fetch_handle,
|
||||
messages_get("Not2xx"), 0,
|
||||
FETCH_ERROR_HTTP_NOT2);
|
||||
msg.type = FETCH_ERROR;
|
||||
msg.data.error = messages_get("Not2xx");
|
||||
fetch_send_callback(&msg, f->fetch_handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -127,17 +127,17 @@ static void fetch_data_abort(void *ctx)
|
||||
c->aborted = true;
|
||||
}
|
||||
|
||||
static void fetch_data_send_callback(fetch_msg msg,
|
||||
struct fetch_data_context *c, const void *data,
|
||||
unsigned long size, fetch_error_code errorcode)
|
||||
static void fetch_data_send_callback(const fetch_msg *msg,
|
||||
struct fetch_data_context *c)
|
||||
{
|
||||
c->locked = true;
|
||||
fetch_send_callback(msg, c->parent_fetch, data, size, errorcode);
|
||||
fetch_send_callback(msg, c->parent_fetch);
|
||||
c->locked = false;
|
||||
}
|
||||
|
||||
static bool fetch_data_process(struct fetch_data_context *c)
|
||||
{
|
||||
fetch_msg msg;
|
||||
char *params;
|
||||
char *comma;
|
||||
char *unescaped;
|
||||
@ -153,8 +153,9 @@ static bool fetch_data_process(struct fetch_data_context *c)
|
||||
|
||||
if (strlen(c->url) < 6) {
|
||||
/* 6 is the minimum possible length (data:,) */
|
||||
fetch_data_send_callback(FETCH_ERROR, c,
|
||||
"Malformed data: URL", 0, FETCH_ERROR_URL);
|
||||
msg.type = FETCH_ERROR;
|
||||
msg.data.error = "Malformed data: URL";
|
||||
fetch_data_send_callback(&msg, c);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -163,8 +164,9 @@ static bool fetch_data_process(struct fetch_data_context *c)
|
||||
|
||||
/* find the comma */
|
||||
if ( (comma = strchr(params, ',')) == NULL) {
|
||||
fetch_data_send_callback(FETCH_ERROR, c,
|
||||
"Malformed data: URL", 0, FETCH_ERROR_URL);
|
||||
msg.type = FETCH_ERROR;
|
||||
msg.data.error = "Malformed data: URL";
|
||||
fetch_data_send_callback(&msg, c);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -177,9 +179,10 @@ static bool fetch_data_process(struct fetch_data_context *c)
|
||||
}
|
||||
|
||||
if (c->mimetype == NULL) {
|
||||
fetch_data_send_callback(FETCH_ERROR, c,
|
||||
"Unable to allocate memory for mimetype in data: URL",
|
||||
0, FETCH_ERROR_MEMORY);
|
||||
msg.type = FETCH_ERROR;
|
||||
msg.data.error =
|
||||
"Unable to allocate memory for mimetype in data: URL";
|
||||
fetch_data_send_callback(&msg, c);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -197,9 +200,9 @@ static bool fetch_data_process(struct fetch_data_context *c)
|
||||
unescaped = curl_easy_unescape(curl, comma + 1, 0, &templen);
|
||||
c->datalen = templen;
|
||||
if (unescaped == NULL) {
|
||||
fetch_data_send_callback(FETCH_ERROR, c,
|
||||
"Unable to URL decode data: URL", 0,
|
||||
FETCH_ERROR_ENCODING);
|
||||
msg.type = FETCH_ERROR;
|
||||
msg.data.error = "Unable to URL decode data: URL";
|
||||
fetch_data_send_callback(&msg, c);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -207,18 +210,19 @@ static bool fetch_data_process(struct fetch_data_context *c)
|
||||
c->data = malloc(c->datalen); /* safe: always gets smaller */
|
||||
if (base64_decode(unescaped, c->datalen, c->data,
|
||||
&(c->datalen)) == false) {
|
||||
fetch_data_send_callback(FETCH_ERROR, c,
|
||||
"Unable to Base64 decode data: URL", 0,
|
||||
FETCH_ERROR_ENCODING);
|
||||
msg.type = FETCH_ERROR;
|
||||
msg.data.error = "Unable to Base64 decode data: URL";
|
||||
fetch_data_send_callback(&msg, c);
|
||||
curl_free(unescaped);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
c->data = malloc(c->datalen);
|
||||
if (c->data == NULL) {
|
||||
fetch_data_send_callback(FETCH_ERROR, c,
|
||||
"Unable to allocate memory for data: URL", 0,
|
||||
FETCH_ERROR_MEMORY);
|
||||
msg.type = FETCH_ERROR;
|
||||
msg.data.error =
|
||||
"Unable to allocate memory for data: URL";
|
||||
fetch_data_send_callback(&msg, c);
|
||||
curl_free(unescaped);
|
||||
return false;
|
||||
}
|
||||
@ -232,6 +236,7 @@ static bool fetch_data_process(struct fetch_data_context *c)
|
||||
|
||||
static void fetch_data_poll(lwc_string *scheme)
|
||||
{
|
||||
fetch_msg msg;
|
||||
struct fetch_data_context *c, *next;
|
||||
|
||||
if (ring == NULL) return;
|
||||
@ -263,27 +268,33 @@ static void fetch_data_poll(lwc_string *scheme)
|
||||
*/
|
||||
snprintf(header, sizeof header, "Content-Type: %s",
|
||||
c->mimetype);
|
||||
fetch_data_send_callback(FETCH_HEADER, c, header,
|
||||
strlen(header), FETCH_ERROR_NO_ERROR);
|
||||
msg.type = FETCH_HEADER;
|
||||
msg.data.header_or_data.buf = (const uint8_t *) header;
|
||||
msg.data.header_or_data.len = strlen(header);
|
||||
fetch_data_send_callback(&msg, c);
|
||||
|
||||
if (c->aborted == false) {
|
||||
snprintf(header, sizeof header,
|
||||
"Content-Length: %zd",
|
||||
c->datalen);
|
||||
fetch_data_send_callback(FETCH_HEADER, c,
|
||||
header, strlen(header),
|
||||
FETCH_ERROR_NO_ERROR);
|
||||
msg.type = FETCH_HEADER;
|
||||
msg.data.header_or_data.buf =
|
||||
(const uint8_t *) header;
|
||||
msg.data.header_or_data.len = strlen(header);
|
||||
fetch_data_send_callback(&msg, c);
|
||||
}
|
||||
|
||||
if (c->aborted == false) {
|
||||
fetch_data_send_callback(FETCH_DATA,
|
||||
c, c->data, c->datalen,
|
||||
FETCH_ERROR_NO_ERROR);
|
||||
msg.type = FETCH_DATA;
|
||||
msg.data.header_or_data.buf =
|
||||
(const uint8_t *) c->data;
|
||||
msg.data.header_or_data.len = c->datalen;
|
||||
fetch_data_send_callback(&msg, c);
|
||||
}
|
||||
|
||||
if (c->aborted == false) {
|
||||
fetch_data_send_callback(FETCH_FINISHED,
|
||||
c, 0, 0, FETCH_ERROR_NO_ERROR);
|
||||
msg.type = FETCH_FINISHED;
|
||||
fetch_data_send_callback(&msg, c);
|
||||
}
|
||||
} else {
|
||||
LOG(("Processing of %s failed!", c->url));
|
||||
|
@ -70,12 +70,11 @@ struct fetch_file_context {
|
||||
static struct fetch_file_context *ring = NULL;
|
||||
|
||||
/** issue fetch callbacks with locking */
|
||||
static inline bool fetch_file_send_callback(fetch_msg msg,
|
||||
struct fetch_file_context *ctx, const void *data,
|
||||
unsigned long size, fetch_error_code errorcode)
|
||||
static inline bool fetch_file_send_callback(const fetch_msg *msg,
|
||||
struct fetch_file_context *ctx)
|
||||
{
|
||||
ctx->locked = true;
|
||||
fetch_send_callback(msg, ctx->fetchh, data, size, errorcode);
|
||||
fetch_send_callback(msg, ctx->fetchh);
|
||||
ctx->locked = false;
|
||||
|
||||
return ctx->aborted;
|
||||
@ -84,6 +83,7 @@ static inline bool fetch_file_send_callback(fetch_msg msg,
|
||||
static bool fetch_file_send_header(struct fetch_file_context *ctx,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
fetch_msg msg;
|
||||
char header[64];
|
||||
va_list ap;
|
||||
|
||||
@ -93,8 +93,10 @@ static bool fetch_file_send_header(struct fetch_file_context *ctx,
|
||||
|
||||
va_end(ap);
|
||||
|
||||
fetch_file_send_callback(FETCH_HEADER, ctx, header, strlen(header),
|
||||
FETCH_ERROR_NO_ERROR);
|
||||
msg.type = FETCH_HEADER;
|
||||
msg.data.header_or_data.buf = (const uint8_t *) header;
|
||||
msg.data.header_or_data.len = strlen(header);
|
||||
fetch_file_send_callback(&msg, ctx);
|
||||
|
||||
return ctx->aborted;
|
||||
}
|
||||
@ -204,6 +206,7 @@ static int fetch_file_errno_to_http_code(int error_no)
|
||||
|
||||
static void fetch_file_process_error(struct fetch_file_context *ctx, int code)
|
||||
{
|
||||
fetch_msg msg;
|
||||
char buffer[1024];
|
||||
const char *title;
|
||||
char key[8];
|
||||
@ -223,12 +226,14 @@ static void fetch_file_process_error(struct fetch_file_context *ctx, int code)
|
||||
"<p>Error %d while fetching file %s</p></body></html>",
|
||||
title, title, code, nsurl_access(ctx->url));
|
||||
|
||||
if (fetch_file_send_callback(FETCH_DATA, ctx, buffer, strlen(buffer),
|
||||
FETCH_ERROR_NO_ERROR))
|
||||
msg.type = FETCH_DATA;
|
||||
msg.data.header_or_data.buf = (const uint8_t *) buffer;
|
||||
msg.data.header_or_data.len = strlen(buffer);
|
||||
if (fetch_file_send_callback(&msg, ctx))
|
||||
goto fetch_file_process_error_aborted;
|
||||
|
||||
fetch_file_send_callback(FETCH_FINISHED, ctx, 0, 0,
|
||||
FETCH_ERROR_NO_ERROR);
|
||||
msg.type = FETCH_FINISHED;
|
||||
fetch_file_send_callback(&msg, ctx);
|
||||
|
||||
fetch_file_process_error_aborted:
|
||||
return;
|
||||
@ -239,6 +244,7 @@ fetch_file_process_error_aborted:
|
||||
static void fetch_file_process_plain(struct fetch_file_context *ctx,
|
||||
struct stat *fdstat)
|
||||
{
|
||||
fetch_msg msg;
|
||||
char *buf;
|
||||
size_t buf_size;
|
||||
|
||||
@ -250,8 +256,8 @@ static void fetch_file_process_plain(struct fetch_file_context *ctx,
|
||||
/* Check if we can just return not modified */
|
||||
if (ctx->file_etag != 0 && ctx->file_etag == fdstat->st_mtime) {
|
||||
fetch_set_http_code(ctx->fetchh, 304);
|
||||
fetch_file_send_callback(FETCH_NOTMODIFIED, ctx, 0, 0,
|
||||
FETCH_ERROR_NO_ERROR);
|
||||
msg.type = FETCH_NOTMODIFIED;
|
||||
fetch_file_send_callback(&msg, ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -271,9 +277,10 @@ static void fetch_file_process_plain(struct fetch_file_context *ctx,
|
||||
/* allocate the buffer storage */
|
||||
buf = malloc(buf_size);
|
||||
if (buf == NULL) {
|
||||
fetch_file_send_callback(FETCH_ERROR, ctx,
|
||||
"Unable to allocate memory for file data buffer",
|
||||
0, FETCH_ERROR_MEMORY);
|
||||
msg.type = FETCH_ERROR;
|
||||
msg.data.error =
|
||||
"Unable to allocate memory for file data buffer";
|
||||
fetch_file_send_callback(&msg, ctx);
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
@ -304,29 +311,32 @@ static void fetch_file_process_plain(struct fetch_file_context *ctx,
|
||||
while (tot_read < fdstat->st_size) {
|
||||
res = read(fd, buf, buf_size);
|
||||
if (res == -1) {
|
||||
fetch_file_send_callback(FETCH_ERROR, ctx,
|
||||
"Error reading file", 0,
|
||||
FETCH_ERROR_PARTIAL_FILE);
|
||||
msg.type = FETCH_ERROR;
|
||||
msg.data.error = "Error reading file";
|
||||
fetch_file_send_callback(&msg, ctx);
|
||||
goto fetch_file_process_aborted;
|
||||
}
|
||||
|
||||
if (res == 0) {
|
||||
fetch_file_send_callback(FETCH_ERROR, ctx,
|
||||
"Unexpected EOF reading file", 0,
|
||||
FETCH_ERROR_PARTIAL_FILE);
|
||||
msg.type = FETCH_ERROR;
|
||||
msg.data.error = "Unexpected EOF reading file";
|
||||
fetch_file_send_callback(&msg, ctx);
|
||||
goto fetch_file_process_aborted;
|
||||
}
|
||||
|
||||
tot_read += res;
|
||||
|
||||
if (fetch_file_send_callback(FETCH_DATA, ctx, buf, res,
|
||||
FETCH_ERROR_NO_ERROR))
|
||||
msg.type = FETCH_DATA;
|
||||
msg.data.header_or_data.buf = (const uint8_t *) buf;
|
||||
msg.data.header_or_data.len = res;
|
||||
if (fetch_file_send_callback(&msg, ctx))
|
||||
break;
|
||||
}
|
||||
|
||||
if (ctx->aborted == false)
|
||||
fetch_file_send_callback(FETCH_FINISHED, ctx, 0, 0,
|
||||
FETCH_ERROR_NO_ERROR);
|
||||
if (ctx->aborted == false) {
|
||||
msg.type = FETCH_FINISHED;
|
||||
fetch_file_send_callback(&msg, ctx);
|
||||
}
|
||||
|
||||
fetch_file_process_aborted:
|
||||
|
||||
@ -392,6 +402,7 @@ static char *gen_nice_title(char *path)
|
||||
static void fetch_file_process_dir(struct fetch_file_context *ctx,
|
||||
struct stat *fdstat)
|
||||
{
|
||||
fetch_msg msg;
|
||||
char buffer[1024]; /* Output buffer */
|
||||
bool even = false; /* formatting flag */
|
||||
char *title; /* pretty printed title */
|
||||
@ -425,18 +436,21 @@ static void fetch_file_process_dir(struct fetch_file_context *ctx,
|
||||
if (fetch_file_send_header(ctx, "Content-Type: text/html"))
|
||||
goto fetch_file_process_dir_aborted;
|
||||
|
||||
msg.type = FETCH_DATA;
|
||||
msg.data.header_or_data.buf = (const uint8_t *) buffer;
|
||||
|
||||
/* directory listing top */
|
||||
dirlist_generate_top(buffer, sizeof buffer);
|
||||
if (fetch_file_send_callback(FETCH_DATA, ctx, buffer, strlen(buffer),
|
||||
FETCH_ERROR_NO_ERROR))
|
||||
msg.data.header_or_data.len = strlen(buffer);
|
||||
if (fetch_file_send_callback(&msg, ctx))
|
||||
goto fetch_file_process_dir_aborted;
|
||||
|
||||
/* directory listing title */
|
||||
title = gen_nice_title(ctx->path);
|
||||
dirlist_generate_title(title, buffer, sizeof buffer);
|
||||
free(title);
|
||||
if (fetch_file_send_callback(FETCH_DATA, ctx, buffer, strlen(buffer),
|
||||
FETCH_ERROR_NO_ERROR))
|
||||
msg.data.header_or_data.len = strlen(buffer);
|
||||
if (fetch_file_send_callback(&msg, ctx))
|
||||
goto fetch_file_process_dir_aborted;
|
||||
|
||||
/* Print parent directory link */
|
||||
@ -446,11 +460,8 @@ static void fetch_file_process_dir(struct fetch_file_context *ctx,
|
||||
if ((res == URL_FUNC_OK) && compare == false) {
|
||||
dirlist_generate_parent_link(up, buffer, sizeof buffer);
|
||||
|
||||
fetch_file_send_callback(FETCH_DATA, ctx,
|
||||
buffer,
|
||||
strlen(buffer),
|
||||
FETCH_ERROR_NO_ERROR);
|
||||
|
||||
msg.data.header_or_data.len = strlen(buffer);
|
||||
fetch_file_send_callback(&msg, ctx);
|
||||
}
|
||||
free(up);
|
||||
|
||||
@ -461,8 +472,8 @@ static void fetch_file_process_dir(struct fetch_file_context *ctx,
|
||||
|
||||
/* directory list headings */
|
||||
dirlist_generate_headings(buffer, sizeof buffer);
|
||||
if (fetch_file_send_callback(FETCH_DATA, ctx, buffer, strlen(buffer),
|
||||
FETCH_ERROR_NO_ERROR))
|
||||
msg.data.header_or_data.len = strlen(buffer);
|
||||
if (fetch_file_send_callback(&msg, ctx))
|
||||
goto fetch_file_process_dir_aborted;
|
||||
|
||||
while ((ent = readdir(scandir)) != NULL) {
|
||||
@ -532,10 +543,8 @@ static void fetch_file_process_dir(struct fetch_file_context *ctx,
|
||||
|
||||
free(path);
|
||||
|
||||
if (fetch_file_send_callback(FETCH_DATA, ctx,
|
||||
buffer,
|
||||
strlen(buffer),
|
||||
FETCH_ERROR_NO_ERROR))
|
||||
msg.data.header_or_data.len = strlen(buffer);
|
||||
if (fetch_file_send_callback(&msg, ctx))
|
||||
goto fetch_file_process_dir_aborted;
|
||||
|
||||
even = !even;
|
||||
@ -543,13 +552,12 @@ static void fetch_file_process_dir(struct fetch_file_context *ctx,
|
||||
|
||||
/* directory listing bottom */
|
||||
dirlist_generate_bottom(buffer, sizeof buffer);
|
||||
if (fetch_file_send_callback(FETCH_DATA, ctx, buffer, strlen(buffer),
|
||||
FETCH_ERROR_NO_ERROR))
|
||||
msg.data.header_or_data.len = strlen(buffer);
|
||||
if (fetch_file_send_callback(&msg, ctx))
|
||||
goto fetch_file_process_dir_aborted;
|
||||
|
||||
|
||||
fetch_file_send_callback(FETCH_FINISHED, ctx, 0, 0,
|
||||
FETCH_ERROR_NO_ERROR);
|
||||
msg.type = FETCH_FINISHED;
|
||||
fetch_file_send_callback(&msg, ctx);
|
||||
|
||||
fetch_file_process_dir_aborted:
|
||||
|
||||
|
@ -89,12 +89,11 @@ static struct fetch_resource_map_entry {
|
||||
static uint32_t fetch_resource_path_count;
|
||||
|
||||
/** issue fetch callbacks with locking */
|
||||
static inline bool fetch_resource_send_callback(fetch_msg msg,
|
||||
struct fetch_resource_context *ctx, const void *data,
|
||||
unsigned long size, fetch_error_code errorcode)
|
||||
static inline bool fetch_resource_send_callback(const fetch_msg *msg,
|
||||
struct fetch_resource_context *ctx)
|
||||
{
|
||||
ctx->locked = true;
|
||||
fetch_send_callback(msg, ctx->fetchh, data, size, errorcode);
|
||||
fetch_send_callback(msg, ctx->fetchh);
|
||||
ctx->locked = false;
|
||||
|
||||
return ctx->aborted;
|
||||
@ -103,6 +102,7 @@ static inline bool fetch_resource_send_callback(fetch_msg msg,
|
||||
static bool fetch_resource_send_header(struct fetch_resource_context *ctx,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
fetch_msg msg;
|
||||
char header[64];
|
||||
va_list ap;
|
||||
|
||||
@ -112,8 +112,10 @@ static bool fetch_resource_send_header(struct fetch_resource_context *ctx,
|
||||
|
||||
va_end(ap);
|
||||
|
||||
fetch_resource_send_callback(FETCH_HEADER, ctx, header, strlen(header),
|
||||
FETCH_ERROR_NO_ERROR);
|
||||
msg.type = FETCH_HEADER;
|
||||
msg.data.header_or_data.buf = (const uint8_t *) header;
|
||||
msg.data.header_or_data.len = strlen(header);
|
||||
fetch_resource_send_callback(&msg, ctx);
|
||||
|
||||
return ctx->aborted;
|
||||
}
|
||||
@ -123,12 +125,14 @@ static bool fetch_resource_send_header(struct fetch_resource_context *ctx,
|
||||
|
||||
static bool fetch_resource_redirect_handler(struct fetch_resource_context *ctx)
|
||||
{
|
||||
fetch_msg msg;
|
||||
|
||||
/* content is going to return redirect */
|
||||
fetch_set_http_code(ctx->fetchh, 302);
|
||||
|
||||
fetch_resource_send_callback(FETCH_REDIRECT, ctx,
|
||||
nsurl_access(ctx->redirect_url), 0,
|
||||
FETCH_ERROR_NO_ERROR);
|
||||
msg.type = FETCH_REDIRECT;
|
||||
msg.data.redirect = nsurl_access(ctx->redirect_url);
|
||||
fetch_resource_send_callback(&msg, ctx);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -136,6 +140,7 @@ static bool fetch_resource_redirect_handler(struct fetch_resource_context *ctx)
|
||||
|
||||
static bool fetch_resource_notfound_handler(struct fetch_resource_context *ctx)
|
||||
{
|
||||
fetch_msg msg;
|
||||
int code = 404;
|
||||
char buffer[1024];
|
||||
const char *title;
|
||||
@ -156,12 +161,14 @@ static bool fetch_resource_notfound_handler(struct fetch_resource_context *ctx)
|
||||
"<p>Error %d while fetching file %s</p></body></html>",
|
||||
title, title, code, nsurl_access(ctx->url));
|
||||
|
||||
if (fetch_resource_send_callback(FETCH_DATA, ctx, buffer, strlen(buffer),
|
||||
FETCH_ERROR_NO_ERROR))
|
||||
msg.type = FETCH_DATA;
|
||||
msg.data.header_or_data.buf = (const uint8_t *) buffer;
|
||||
msg.data.header_or_data.len = strlen(buffer);
|
||||
if (fetch_resource_send_callback(&msg, ctx))
|
||||
goto fetch_resource_notfound_handler_aborted;
|
||||
|
||||
fetch_resource_send_callback(FETCH_FINISHED, ctx, 0, 0,
|
||||
FETCH_ERROR_NO_ERROR);
|
||||
msg.type = FETCH_FINISHED;
|
||||
fetch_resource_send_callback(&msg, ctx);
|
||||
|
||||
fetch_resource_notfound_handler_aborted:
|
||||
return false;
|
||||
|
@ -211,18 +211,17 @@ static nserror llcache_post_data_clone(const llcache_post_data *orig,
|
||||
|
||||
static nserror llcache_query_handle_response(bool proceed, void *cbpw);
|
||||
|
||||
static void llcache_fetch_callback(fetch_msg msg, void *p, const void *data,
|
||||
unsigned long size, fetch_error_code errorcode);
|
||||
static void llcache_fetch_callback(const fetch_msg *msg, void *p);
|
||||
static nserror llcache_fetch_redirect(llcache_object *object,
|
||||
const char *target, llcache_object **replacement);
|
||||
static nserror llcache_fetch_notmodified(llcache_object *object,
|
||||
llcache_object **replacement);
|
||||
static nserror llcache_fetch_split_header(const char *data, size_t len,
|
||||
static nserror llcache_fetch_split_header(const uint8_t *data, size_t len,
|
||||
char **name, char **value);
|
||||
static nserror llcache_fetch_parse_header(llcache_object *object,
|
||||
const char *data, size_t len, char **name, char **value);
|
||||
const uint8_t *data, size_t len, char **name, char **value);
|
||||
static nserror llcache_fetch_process_header(llcache_object *object,
|
||||
const char *data, size_t len);
|
||||
const uint8_t *data, size_t len);
|
||||
static nserror llcache_fetch_process_data(llcache_object *object,
|
||||
const uint8_t *data, size_t len);
|
||||
static nserror llcache_fetch_auth(llcache_object *object,
|
||||
@ -1814,29 +1813,27 @@ nserror llcache_query_handle_response(bool proceed, void *cbpw)
|
||||
/**
|
||||
* Handler for fetch events
|
||||
*
|
||||
* \param msg Type of fetch event
|
||||
* \param msg Fetch event
|
||||
* \param p Our private data
|
||||
* \param data Event data
|
||||
* \param size Length of data in bytes
|
||||
* \param errorcode Reason for fetch error
|
||||
*/
|
||||
void llcache_fetch_callback(fetch_msg msg, void *p, const void *data,
|
||||
unsigned long size, fetch_error_code errorcode)
|
||||
void llcache_fetch_callback(const fetch_msg *msg, void *p)
|
||||
{
|
||||
nserror error = NSERROR_OK;
|
||||
llcache_object *object = p;
|
||||
llcache_event event;
|
||||
|
||||
#ifdef LLCACHE_TRACE
|
||||
LOG(("Fetch event %d for %p", msg, object));
|
||||
LOG(("Fetch event %d for %p", msg->type, object));
|
||||
#endif
|
||||
|
||||
switch (msg) {
|
||||
switch (msg->type) {
|
||||
case FETCH_HEADER:
|
||||
/* Received a fetch header */
|
||||
object->fetch.state = LLCACHE_FETCH_HEADERS;
|
||||
|
||||
error = llcache_fetch_process_header(object, data, size);
|
||||
error = llcache_fetch_process_header(object,
|
||||
msg->data.header_or_data.buf,
|
||||
msg->data.header_or_data.len);
|
||||
break;
|
||||
|
||||
/* 3xx responses */
|
||||
@ -1849,7 +1846,8 @@ void llcache_fetch_callback(fetch_msg msg, void *p, const void *data,
|
||||
object->candidate = NULL;
|
||||
}
|
||||
|
||||
error = llcache_fetch_redirect(object, data, &object);
|
||||
error = llcache_fetch_redirect(object,
|
||||
msg->data.redirect, &object);
|
||||
break;
|
||||
case FETCH_NOTMODIFIED:
|
||||
/* Conditional request determined that cached object is fresh */
|
||||
@ -1891,7 +1889,9 @@ void llcache_fetch_callback(fetch_msg msg, void *p, const void *data,
|
||||
|
||||
object->fetch.state = LLCACHE_FETCH_DATA;
|
||||
|
||||
error = llcache_fetch_process_data(object, data, size);
|
||||
error = llcache_fetch_process_data(object,
|
||||
msg->data.header_or_data.buf,
|
||||
msg->data.header_or_data.len);
|
||||
break;
|
||||
case FETCH_FINISHED:
|
||||
/* Finished fetching */
|
||||
@ -1933,7 +1933,7 @@ void llcache_fetch_callback(fetch_msg msg, void *p, const void *data,
|
||||
/** \todo Consider using errorcode for something */
|
||||
|
||||
event.type = LLCACHE_EVENT_ERROR;
|
||||
event.data.msg = data;
|
||||
event.data.msg = msg->data.error;
|
||||
|
||||
error = llcache_send_event_to_users(object, &event);
|
||||
|
||||
@ -1941,8 +1941,8 @@ void llcache_fetch_callback(fetch_msg msg, void *p, const void *data,
|
||||
case FETCH_PROGRESS:
|
||||
/* Progress update */
|
||||
event.type = LLCACHE_EVENT_PROGRESS;
|
||||
event.data.msg = data;
|
||||
|
||||
event.data.msg = msg->data.progress;
|
||||
|
||||
error = llcache_send_event_to_users(object, &event);
|
||||
|
||||
break;
|
||||
@ -1957,7 +1957,7 @@ void llcache_fetch_callback(fetch_msg msg, void *p, const void *data,
|
||||
object->candidate = NULL;
|
||||
}
|
||||
|
||||
error = llcache_fetch_auth(object, data);
|
||||
error = llcache_fetch_auth(object, msg->data.auth.realm);
|
||||
break;
|
||||
case FETCH_CERT_ERR:
|
||||
/* Something went wrong when validating TLS certificates */
|
||||
@ -1968,7 +1968,9 @@ void llcache_fetch_callback(fetch_msg msg, void *p, const void *data,
|
||||
object->candidate = NULL;
|
||||
}
|
||||
|
||||
error = llcache_fetch_cert_error(object, data, size);
|
||||
error = llcache_fetch_cert_error(object,
|
||||
msg->data.cert_err.certs,
|
||||
msg->data.cert_err.num_certs);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2179,17 +2181,17 @@ nserror llcache_fetch_notmodified(llcache_object *object,
|
||||
* \param value Pointer to location to receive header value
|
||||
* \return NSERROR_OK on success, appropriate error otherwise
|
||||
*/
|
||||
nserror llcache_fetch_split_header(const char *data, size_t len, char **name,
|
||||
char **value)
|
||||
nserror llcache_fetch_split_header(const uint8_t *data, size_t len,
|
||||
char **name, char **value)
|
||||
{
|
||||
char *n, *v;
|
||||
const char *colon;
|
||||
const uint8_t *colon;
|
||||
|
||||
/* Find colon */
|
||||
colon = strchr(data, ':');
|
||||
colon = (const uint8_t *) strchr((const char *) data, ':');
|
||||
if (colon == NULL) {
|
||||
/* Failed, assume a key with no value */
|
||||
n = strdup(data);
|
||||
n = strdup((const char *) data);
|
||||
if (n == NULL)
|
||||
return NSERROR_NOMEM;
|
||||
|
||||
@ -2213,7 +2215,7 @@ nserror llcache_fetch_split_header(const char *data, size_t len, char **name,
|
||||
colon[-1] == '\n'))
|
||||
colon--;
|
||||
|
||||
n = strndup(data, colon - data);
|
||||
n = strndup((const char *) data, colon - data);
|
||||
if (n == NULL)
|
||||
return NSERROR_NOMEM;
|
||||
|
||||
@ -2236,7 +2238,7 @@ nserror llcache_fetch_split_header(const char *data, size_t len, char **name,
|
||||
len--;
|
||||
}
|
||||
|
||||
v = strndup(colon, len - (colon - data));
|
||||
v = strndup((const char *) colon, len - (colon - data));
|
||||
if (v == NULL) {
|
||||
free(n);
|
||||
return NSERROR_NOMEM;
|
||||
@ -2263,8 +2265,8 @@ nserror llcache_fetch_split_header(const char *data, size_t len, char **name,
|
||||
* the cache control data for the object if an interesting
|
||||
* header is encountered
|
||||
*/
|
||||
nserror llcache_fetch_parse_header(llcache_object *object, const char *data,
|
||||
size_t len, char **name, char **value)
|
||||
nserror llcache_fetch_parse_header(llcache_object *object,
|
||||
const uint8_t *data, size_t len, char **name, char **value)
|
||||
{
|
||||
nserror error;
|
||||
|
||||
@ -2355,8 +2357,8 @@ nserror llcache_fetch_parse_header(llcache_object *object, const char *data,
|
||||
* \param len Byte length of header
|
||||
* \return NSERROR_OK on success, appropriate error otherwise
|
||||
*/
|
||||
nserror llcache_fetch_process_header(llcache_object *object, const char *data,
|
||||
size_t len)
|
||||
nserror llcache_fetch_process_header(llcache_object *object,
|
||||
const uint8_t *data, size_t len)
|
||||
{
|
||||
nserror error;
|
||||
char *name, *value;
|
||||
@ -2374,7 +2376,7 @@ nserror llcache_fetch_process_header(llcache_object *object, const char *data,
|
||||
* that we might have computed, and start again.
|
||||
*/
|
||||
/** \todo Properly parse the response line */
|
||||
if (strncmp(data, "HTTP/", SLEN("HTTP/")) == 0) {
|
||||
if (strncmp((const char *) data, "HTTP/", SLEN("HTTP/")) == 0) {
|
||||
time_t req_time = object->cache.req_time;
|
||||
|
||||
llcache_invalidate_cache_control_data(object);
|
||||
|
Loading…
Reference in New Issue
Block a user