From 5207ecf3083fdf9e28fbc775426e415ff4a08f5d Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Sun, 20 Sep 2020 16:36:01 +0100 Subject: split out the about scheme imagecache page generator --- content/fetchers/about/Makefile | 2 +- content/fetchers/about/about.c | 361 ++++++++++++------------------------ content/fetchers/about/about.h | 9 +- content/fetchers/about/imagecache.c | 174 +++++++++++++++++ content/fetchers/about/imagecache.h | 37 ++++ content/fetchers/about/private.h | 59 ++++++ 6 files changed, 396 insertions(+), 246 deletions(-) create mode 100644 content/fetchers/about/imagecache.c create mode 100644 content/fetchers/about/imagecache.h create mode 100644 content/fetchers/about/private.h (limited to 'content/fetchers/about') diff --git a/content/fetchers/about/Makefile b/content/fetchers/about/Makefile index 88786ec5b..3a96d03bd 100644 --- a/content/fetchers/about/Makefile +++ b/content/fetchers/about/Makefile @@ -1,6 +1,6 @@ # about fetcher sources -S_FETCHER_ABOUT := about.c +S_FETCHER_ABOUT := about.c imagecache.c # The following files depend on the testament content/fetchers/about/about.c: testament $(OBJROOT)/testament.h diff --git a/content/fetchers/about/about.c b/content/fetchers/about/about.c index e2fbd4d85..3e645cd30 100644 --- a/content/fetchers/about/about.c +++ b/content/fetchers/about/about.c @@ -45,14 +45,13 @@ #include "content/fetch.h" #include "content/fetchers.h" -#include "image/image_cache.h" #include "desktop/system_colour.h" +#include "private.h" +#include "imagecache.h" #include "about.h" -struct fetch_about_context; - typedef bool (*fetch_about_handler)(struct fetch_about_context *); /** @@ -87,10 +86,11 @@ struct about_handlers { }; + /** * issue fetch callbacks with locking */ -static inline bool +static bool fetch_about_send_callback(const fetch_msg *msg, struct fetch_about_context *ctx) { ctx->locked = true; @@ -100,7 +100,8 @@ fetch_about_send_callback(const fetch_msg *msg, struct fetch_about_context *ctx) return ctx->aborted; } -static inline bool +/* exported interface documented in about/private.h */ +bool fetch_about_send_finished(struct fetch_about_context *ctx) { fetch_msg msg; @@ -108,7 +109,16 @@ fetch_about_send_finished(struct fetch_about_context *ctx) return fetch_about_send_callback(&msg, ctx); } -static bool +/* exported interface documented in about/private.h */ +bool fetch_about_set_http_code(struct fetch_about_context *ctx, long code) +{ + fetch_set_http_code(ctx->fetchh, code); + + return ctx->aborted; +} + +/* exported interface documented in about/private.h */ +bool fetch_about_send_header(struct fetch_about_context *ctx, const char *fmt, ...) { char header[64]; @@ -128,10 +138,26 @@ fetch_about_send_header(struct fetch_about_context *ctx, const char *fmt, ...) return fetch_about_send_callback(&msg, ctx); } -/** - * send formatted data on a fetch - */ -static nserror ssenddataf(struct fetch_about_context *ctx, const char *fmt, ...) +/* exported interface documented in about/private.h */ +nserror +fetch_about_senddata(struct fetch_about_context *ctx, const uint8_t *data, size_t data_len) +{ + fetch_msg msg; + + msg.type = FETCH_DATA; + msg.data.header_or_data.buf = data; + msg.data.header_or_data.len = data_len; + + if (fetch_about_send_callback(&msg, ctx)) { + return NSERROR_INVALID; + } + + return NSERROR_OK; +} + +/* exported interface documented in about/private.h */ +nserror +fetch_about_ssenddataf(struct fetch_about_context *ctx, const char *fmt, ...) { char buffer[1024]; char *dbuff; @@ -198,7 +224,7 @@ static bool fetch_about_srverror(struct fetch_about_context *ctx) if (fetch_about_send_header(ctx, "Content-Type: text/plain")) return false; - res = ssenddataf(ctx, "Server error 500"); + res = fetch_about_ssenddataf(ctx, "Server error 500"); if (res != NSERROR_OK) { return false; } @@ -289,153 +315,6 @@ static bool fetch_about_licence_handler(struct fetch_about_context *ctx) } -/** - * Handler to generate about:imagecache page. - * - * Shows details of current image cache. - * - * \param ctx The fetcher context. - * \return true if handled false if aborted. - */ -static bool fetch_about_imagecache_handler(struct fetch_about_context *ctx) -{ - fetch_msg msg; - char buffer[2048]; /* output buffer */ - int code = 200; - int slen; - unsigned int cent_loop = 0; - int elen = 0; /* entry length */ - nserror res; - bool even = false; - - /* content is going to return ok */ - fetch_set_http_code(ctx->fetchh, code); - - /* content type */ - if (fetch_about_send_header(ctx, "Content-Type: text/html")) - goto fetch_about_imagecache_handler_aborted; - - /* page head */ - res = ssenddataf(ctx, - "\n\n" - "Image Cache Status\n" - "\n" - "\n" - "\n" - "

Image Cache Status

\n"); - if (res != NSERROR_OK) { - goto fetch_about_imagecache_handler_aborted; - } - - /* image cache summary */ - slen = image_cache_snsummaryf(buffer, sizeof(buffer), - "

Configured limit of %a hysteresis of %b

\n" - "

Total bitmap size in use %c (in %d)

\n" - "

Age %es

\n" - "

Peak size %f (in %g)

\n" - "

Peak image count %h (size %i)

\n" - "

Cache total/hit/miss/fail (counts) %j/%k/%l/%m " - "(%pj%%/%pk%%/%pl%%/%pm%%)

\n" - "

Cache total/hit/miss/fail (size) %n/%o/%q/%r " - "(%pn%%/%po%%/%pq%%/%pr%%)

\n" - "

Total images never rendered: %s " - "(includes %t that were converted)

\n" - "

Total number of excessive conversions: %u " - "(from %v images converted more than once)" - "

\n" - "

Bitmap of size %w had most (%x) conversions

\n" - "

Current contents

\n"); - if (slen >= (int) (sizeof(buffer))) { - goto fetch_about_imagecache_handler_aborted; /* overflow */ - } - - /* send image cache summary */ - msg.type = FETCH_DATA; - msg.data.header_or_data.buf = (const uint8_t *) buffer; - msg.data.header_or_data.len = slen; - if (fetch_about_send_callback(&msg, ctx)) { - goto fetch_about_imagecache_handler_aborted; - } - - /* image cache entry table */ - res = ssenddataf(ctx, "

\n" - "" - "Entry" - "Content Key" - "Redraw Count" - "Conversion Count" - "Last Redraw" - "Bitmap Age" - "Bitmap Size" - "Source" - "\n"); - if (res != NSERROR_OK) { - goto fetch_about_imagecache_handler_aborted; - } - - slen = 0; - do { - if (even) { - elen = image_cache_snentryf(buffer + slen, - sizeof buffer - slen, - cent_loop, - "" - "%e" - "%k" - "%r" - "%c" - "%a" - "%g" - "%s" - "%o" - "\n"); - } else { - elen = image_cache_snentryf(buffer + slen, - sizeof buffer - slen, - cent_loop, - "" - "%e" - "%k" - "%r" - "%c" - "%a" - "%g" - "%s" - "%o" - "\n"); - } - if (elen <= 0) - break; /* last option */ - - if (elen >= (int) (sizeof buffer - slen)) { - /* last entry would not fit in buffer, submit buffer */ - msg.data.header_or_data.len = slen; - if (fetch_about_send_callback(&msg, ctx)) - goto fetch_about_imagecache_handler_aborted; - slen = 0; - } else { - /* normal addition */ - slen += elen; - cent_loop++; - even = !even; - } - } while (elen > 0); - - slen += snprintf(buffer + slen, sizeof buffer - slen, - "

\n\n\n"); - - msg.data.header_or_data.len = slen; - if (fetch_about_send_callback(&msg, ctx)) - goto fetch_about_imagecache_handler_aborted; - - fetch_about_send_finished(ctx); - - return true; - -fetch_about_imagecache_handler_aborted: - return false; -} /** * certificate name parameters @@ -1155,7 +1034,7 @@ format_certificate_name(struct fetch_about_context *ctx, struct ns_cert_name *cert_name) { nserror res; - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "Common Name%s\n", cert_name->common_name); if (res != NSERROR_OK) { @@ -1163,7 +1042,7 @@ format_certificate_name(struct fetch_about_context *ctx, } if (cert_name->organisation != NULL) { - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "Organisation%s\n", cert_name->organisation); if (res != NSERROR_OK) { @@ -1172,7 +1051,7 @@ format_certificate_name(struct fetch_about_context *ctx, } if (cert_name->organisation_unit != NULL) { - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "Organisation Unit%s\n", cert_name->organisation_unit); if (res != NSERROR_OK) { @@ -1181,7 +1060,7 @@ format_certificate_name(struct fetch_about_context *ctx, } if (cert_name->locality != NULL) { - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "Locality%s\n", cert_name->locality); if (res != NSERROR_OK) { @@ -1190,7 +1069,7 @@ format_certificate_name(struct fetch_about_context *ctx, } if (cert_name->province != NULL) { - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "Privince%s\n", cert_name->province); if (res != NSERROR_OK) { @@ -1199,7 +1078,7 @@ format_certificate_name(struct fetch_about_context *ctx, } if (cert_name->country != NULL) { - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "Country%s\n", cert_name->country); if (res != NSERROR_OK) { @@ -1223,7 +1102,7 @@ format_certificate_san(struct fetch_about_context *ctx, return NSERROR_OK; } - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "\n" "\n"); if (res != NSERROR_OK) { @@ -1231,7 +1110,7 @@ format_certificate_san(struct fetch_about_context *ctx, } while (san != NULL) { - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "\n", san->name); if (res != NSERROR_OK) { @@ -1241,7 +1120,7 @@ format_certificate_san(struct fetch_about_context *ctx, san = san->next; } - res = ssenddataf(ctx, "
Alternative Names
DNS Name%s
\n"); + res = fetch_about_ssenddataf(ctx, "\n"); return res; @@ -1259,7 +1138,7 @@ format_certificate_public_key(struct fetch_about_context *ctx, return NSERROR_OK; } - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "\n" "\n" "\n" @@ -1272,7 +1151,7 @@ format_certificate_public_key(struct fetch_about_context *ctx, if (public_key->exponent != NULL) { - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "\n", public_key->exponent); if (res != NSERROR_OK) { @@ -1281,7 +1160,7 @@ format_certificate_public_key(struct fetch_about_context *ctx, } if (public_key->modulus != NULL) { - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "\n", public_key->modulus); if (res != NSERROR_OK) { @@ -1290,7 +1169,7 @@ format_certificate_public_key(struct fetch_about_context *ctx, } if (public_key->curve != NULL) { - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "\n", public_key->curve); if (res != NSERROR_OK) { @@ -1299,7 +1178,7 @@ format_certificate_public_key(struct fetch_about_context *ctx, } if (public_key->public != NULL) { - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "\n", public_key->public); if (res != NSERROR_OK) { @@ -1307,7 +1186,7 @@ format_certificate_public_key(struct fetch_about_context *ctx, } } - res = ssenddataf(ctx, "
Public Key
Algorithm%s
Exponent%s
Modulus%s
Curve%s
Public Value%s
\n"); + res = fetch_about_ssenddataf(ctx, "\n"); return res; } @@ -1325,7 +1204,7 @@ format_certificate_fingerprint(struct fetch_about_context *ctx, } - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "\n" "\n"); if (res != NSERROR_OK) { @@ -1333,7 +1212,7 @@ format_certificate_fingerprint(struct fetch_about_context *ctx, } if (cert_info->sha256fingerprint != NULL) { - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "\n", cert_info->sha256fingerprint); if (res != NSERROR_OK) { @@ -1342,7 +1221,7 @@ format_certificate_fingerprint(struct fetch_about_context *ctx, } if (cert_info->sha1fingerprint != NULL) { - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "\n", cert_info->sha1fingerprint); if (res != NSERROR_OK) { @@ -1350,7 +1229,7 @@ format_certificate_fingerprint(struct fetch_about_context *ctx, } } - res = ssenddataf(ctx, "
Fingerprints
SHA-256%s
SHA-1%s
\n"); + res = fetch_about_ssenddataf(ctx, "\n"); return res; } @@ -1362,7 +1241,7 @@ format_certificate(struct fetch_about_context *ctx, { nserror res; - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "

%s

\n", depth, cert_info->subject_name.common_name); if (res != NSERROR_OK) { @@ -1370,7 +1249,7 @@ format_certificate(struct fetch_about_context *ctx, } if (cert_info->err != SSL_CERT_ERR_OK) { - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "\n" "" "" @@ -1383,7 +1262,7 @@ format_certificate(struct fetch_about_context *ctx, } } - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "
Fault
\n" "\n"); if (res != NSERROR_OK) { @@ -1395,13 +1274,13 @@ format_certificate(struct fetch_about_context *ctx, return res; } - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "
Issued To
\n"); if (res != NSERROR_OK) { return res; } - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "\n" "\n"); if (res != NSERROR_OK) { @@ -1413,13 +1292,13 @@ format_certificate(struct fetch_about_context *ctx, return res; } - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "
Issued By
\n"); if (res != NSERROR_OK) { return res; } - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "\n" "\n" "\n" @@ -1441,7 +1320,7 @@ format_certificate(struct fetch_about_context *ctx, return res; } - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "
Validity
Valid From%s
\n" "\n"); if (res != NSERROR_OK) { @@ -1449,7 +1328,7 @@ format_certificate(struct fetch_about_context *ctx, } if (cert_info->serialnum != NULL) { - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "\n", cert_info->serialnum); if (res != NSERROR_OK) { @@ -1458,7 +1337,7 @@ format_certificate(struct fetch_about_context *ctx, } if (cert_info->sig_algor != NULL) { - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "" "\n", cert_info->sig_algor); @@ -1467,7 +1346,7 @@ format_certificate(struct fetch_about_context *ctx, } } - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "\n" "
Miscellaneous
Serial Number%s
Signature Algorithm%s
Version%ld
\n", cert_info->version); @@ -1505,7 +1384,7 @@ static bool fetch_about_certificate_handler(struct fetch_about_context *ctx) goto fetch_about_certificate_handler_aborted; /* page head */ - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "\n\n" "NetSurf Browser Certificate Viewer\n" "url, &chain); if (res != NSERROR_OK) { - res = ssenddataf(ctx, "

Could not process that

\n"); + res = fetch_about_ssenddataf(ctx, "

Could not process that

\n"); if (res != NSERROR_OK) { goto fetch_about_certificate_handler_aborted; } @@ -1528,14 +1407,14 @@ static bool fetch_about_certificate_handler(struct fetch_about_context *ctx) res = convert_chain_to_cert_info(chain, &cert_info); if (res == NSERROR_OK) { size_t depth; - res = ssenddataf(ctx, "\n"); if (res != NSERROR_OK) { free_ns_cert_info(cert_info); goto fetch_about_certificate_handler_aborted; @@ -1564,7 +1443,7 @@ static bool fetch_about_certificate_handler(struct fetch_about_context *ctx) free_ns_cert_info(cert_info); } else { - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "

Invalid certificate data

\n"); if (res != NSERROR_OK) { goto fetch_about_certificate_handler_aborted; @@ -1574,7 +1453,7 @@ static bool fetch_about_certificate_handler(struct fetch_about_context *ctx) /* page footer */ - res = ssenddataf(ctx, "\n\n"); + res = fetch_about_ssenddataf(ctx, "\n\n"); if (res != NSERROR_OK) { goto fetch_about_certificate_handler_aborted; } @@ -1615,7 +1494,7 @@ static bool fetch_about_config_handler(struct fetch_about_context *ctx) goto fetch_about_config_handler_aborted; } - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "\n\n" "NetSurf Browser Config\n" " 0) { - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "Working tree has %d modification%s\n\n", WT_MODIFIED, WT_MODIFIED == 1 ? "" : "s"); } else { - res = ssenddataf(ctx, "Working tree is not modified.\n"); + res = fetch_about_ssenddataf(ctx, "Working tree is not modified.\n"); } if (res != NSERROR_OK) { goto fetch_about_testament_handler_aborted; } for (modidx = 0; modidx < WT_MODIFIED; ++modidx) { - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, " %s %s\n", modifications[modidx].modtype, modifications[modidx].leaf); @@ -2069,7 +1948,7 @@ static bool fetch_about_query_auth_handler(struct fetch_about_context *ctx) } title = messages_get("LoginTitle"); - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "\n\n" "%s\n" ""); if (res != NSERROR_OK) { @@ -2095,19 +1974,19 @@ static bool fetch_about_query_auth_handler(struct fetch_about_context *ctx) password, &description); if (res == NSERROR_OK) { - res = ssenddataf(ctx, "

%s

", description); + res = fetch_about_ssenddataf(ctx, "

%s

", description); free(description); if (res != NSERROR_OK) { goto fetch_about_query_auth_handler_aborted; } } - res = ssenddataf(ctx, ""); + res = fetch_about_ssenddataf(ctx, "
"); if (res != NSERROR_OK) { goto fetch_about_query_auth_handler_aborted; } - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "" "" "" "
" ""); + res = fetch_about_ssenddataf(ctx, "
"); if (res != NSERROR_OK) { goto fetch_about_query_auth_handler_aborted; } - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "
" "" @@ -2151,7 +2030,7 @@ static bool fetch_about_query_auth_handler(struct fetch_about_context *ctx) if (res != NSERROR_OK) { url_s = strdup(""); } - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "", url_s); free(url_s); @@ -2159,14 +2038,14 @@ static bool fetch_about_query_auth_handler(struct fetch_about_context *ctx) goto fetch_about_query_auth_handler_aborted; } - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "", realm); if (res != NSERROR_OK) { goto fetch_about_query_auth_handler_aborted; } - res = ssenddataf(ctx, "\n\n"); + res = fetch_about_ssenddataf(ctx, "\n\n"); if (res != NSERROR_OK) { goto fetch_about_query_auth_handler_aborted; } @@ -2232,7 +2111,7 @@ static bool fetch_about_query_privacy_handler(struct fetch_about_context *ctx) } title = messages_get("PrivacyTitle"); - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "\n\n" "%s\n" ""); if (res != NSERROR_OK) { @@ -2256,7 +2135,7 @@ static bool fetch_about_query_privacy_handler(struct fetch_about_context *ctx) "PrivacyDescription", &description); if (res == NSERROR_OK) { - res = ssenddataf(ctx, "

%s

", description); + res = fetch_about_ssenddataf(ctx, "

%s

", description); free(description); if (res != NSERROR_OK) { goto fetch_about_query_ssl_handler_aborted; @@ -2264,13 +2143,13 @@ static bool fetch_about_query_privacy_handler(struct fetch_about_context *ctx) } if (chainurl == NULL) { - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "

%s

" "

%s

", reason, messages_get("ViewCertificatesNotPossible")); } else { - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "

%s

" "

%s

", reason, @@ -2280,7 +2159,7 @@ static bool fetch_about_query_privacy_handler(struct fetch_about_context *ctx) if (res != NSERROR_OK) { goto fetch_about_query_ssl_handler_aborted; } - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "
" "" @@ -2297,7 +2176,7 @@ static bool fetch_about_query_privacy_handler(struct fetch_about_context *ctx) if (res != NSERROR_OK) { url_s = strdup(""); } - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "", url_s); free(url_s); @@ -2305,7 +2184,7 @@ static bool fetch_about_query_privacy_handler(struct fetch_about_context *ctx) goto fetch_about_query_ssl_handler_aborted; } - res = ssenddataf(ctx, "\n\n"); + res = fetch_about_ssenddataf(ctx, "\n\n"); if (res != NSERROR_OK) { goto fetch_about_query_ssl_handler_aborted; } @@ -2367,7 +2246,7 @@ static bool fetch_about_query_timeout_handler(struct fetch_about_context *ctx) } title = messages_get("TimeoutTitle"); - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "\n\n" "%s\n" ""); if (res != NSERROR_OK) { @@ -2391,18 +2270,18 @@ static bool fetch_about_query_timeout_handler(struct fetch_about_context *ctx) "TimeoutDescription", &description); if (res == NSERROR_OK) { - res = ssenddataf(ctx, "

%s

", description); + res = fetch_about_ssenddataf(ctx, "

%s

", description); free(description); if (res != NSERROR_OK) { goto fetch_about_query_timeout_handler_aborted; } } - res = ssenddataf(ctx, "

%s

", reason); + res = fetch_about_ssenddataf(ctx, "

%s

", reason); if (res != NSERROR_OK) { goto fetch_about_query_timeout_handler_aborted; } - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "
" "" @@ -2419,7 +2298,7 @@ static bool fetch_about_query_timeout_handler(struct fetch_about_context *ctx) if (res != NSERROR_OK) { url_s = strdup(""); } - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "", url_s); free(url_s); @@ -2427,7 +2306,7 @@ static bool fetch_about_query_timeout_handler(struct fetch_about_context *ctx) goto fetch_about_query_timeout_handler_aborted; } - res = ssenddataf(ctx, "\n\n"); + res = fetch_about_ssenddataf(ctx, "\n\n"); if (res != NSERROR_OK) { goto fetch_about_query_timeout_handler_aborted; } @@ -2490,7 +2369,7 @@ fetch_about_query_fetcherror_handler(struct fetch_about_context *ctx) } title = messages_get("FetchErrorTitle"); - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "\n\n" "%s\n" ""); if (res != NSERROR_OK) { @@ -2514,18 +2393,18 @@ fetch_about_query_fetcherror_handler(struct fetch_about_context *ctx) "FetchErrorDescription", &description); if (res == NSERROR_OK) { - res = ssenddataf(ctx, "

%s

", description); + res = fetch_about_ssenddataf(ctx, "

%s

", description); free(description); if (res != NSERROR_OK) { goto fetch_about_query_fetcherror_handler_aborted; } } - res = ssenddataf(ctx, "

%s

", reason); + res = fetch_about_ssenddataf(ctx, "

%s

", reason); if (res != NSERROR_OK) { goto fetch_about_query_fetcherror_handler_aborted; } - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "
" "" @@ -2542,7 +2421,7 @@ fetch_about_query_fetcherror_handler(struct fetch_about_context *ctx) if (res != NSERROR_OK) { url_s = strdup(""); } - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "", url_s); free(url_s); @@ -2550,7 +2429,7 @@ fetch_about_query_fetcherror_handler(struct fetch_about_context *ctx) goto fetch_about_query_fetcherror_handler_aborted; } - res = ssenddataf(ctx, "\n\n"); + res = fetch_about_ssenddataf(ctx, "\n\n"); if (res != NSERROR_OK) { goto fetch_about_query_fetcherror_handler_aborted; } @@ -2720,7 +2599,7 @@ 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; - res = ssenddataf(ctx, + res = fetch_about_ssenddataf(ctx, "\n\n" "List of NetSurf pages\n" "about:%s\n", about_handler_list[abt_loop].name, about_handler_list[abt_loop].name); @@ -2748,7 +2627,7 @@ static bool fetch_about_about_handler(struct fetch_about_context *ctx) } } - res = ssenddataf(ctx, "\n\n\n"); + res = fetch_about_ssenddataf(ctx, "\n\n\n"); if (res != NSERROR_OK) { goto fetch_about_config_handler_aborted; } @@ -2774,7 +2653,7 @@ fetch_about_404_handler(struct fetch_about_context *ctx) return false; } - res = ssenddataf(ctx, "Unknown page: %s", nsurl_access(ctx->url)); + res = fetch_about_ssenddataf(ctx, "Unknown page: %s", nsurl_access(ctx->url)); if (res != NSERROR_OK) { return false; } diff --git a/content/fetchers/about/about.h b/content/fetchers/about/about.h index 944f84a59..bf6379709 100644 --- a/content/fetchers/about/about.h +++ b/content/fetchers/about/about.h @@ -16,12 +16,13 @@ * along with this program. If not, see . */ -/** \file - * about: URL method handler +/** + * \file + * about scheme URL method handler */ -#ifndef NETSURF_CONTENT_FETCHERS_FETCH_ABOUT_H -#define NETSURF_CONTENT_FETCHERS_FETCH_ABOUT_H +#ifndef NETSURF_CONTENT_FETCHERS_ABOUT_ABOUT_H +#define NETSURF_CONTENT_FETCHERS_ABOUT_ABOUT_H /** * Register about scheme handler. diff --git a/content/fetchers/about/imagecache.c b/content/fetchers/about/imagecache.c new file mode 100644 index 000000000..5e2abcb1e --- /dev/null +++ b/content/fetchers/about/imagecache.c @@ -0,0 +1,174 @@ +/* + * Copyright 2020 Vincent Sanders + * + * This file is part of NetSurf. + * + * 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 . + */ + +/** + * \file + * content generator for the about scheme imagecache page + */ + +#include +#include + +#include "netsurf/types.h" + +#include "image/image_cache.h" + +#include "private.h" +#include "imagecache.h" + +/* exported interface documented in about/imagecache.h */ +bool fetch_about_imagecache_handler(struct fetch_about_context *ctx) +{ + char buffer[2048]; /* output buffer */ + int code = 200; + int slen; + unsigned int cent_loop = 0; + int elen = 0; /* entry length */ + nserror res; + bool even = false; + + /* content is going to return ok */ + fetch_about_set_http_code(ctx, code); + + /* content type */ + if (fetch_about_send_header(ctx, "Content-Type: text/html")) + goto fetch_about_imagecache_handler_aborted; + + /* page head */ + res = fetch_about_ssenddataf(ctx, + "\n\n" + "Image Cache Status\n" + "\n" + "\n" + "\n" + "

Image Cache Status

\n"); + if (res != NSERROR_OK) { + goto fetch_about_imagecache_handler_aborted; + } + + /* image cache summary */ + slen = image_cache_snsummaryf(buffer, sizeof(buffer), + "

Configured limit of %a hysteresis of %b

\n" + "

Total bitmap size in use %c (in %d)

\n" + "

Age %es

\n" + "

Peak size %f (in %g)

\n" + "

Peak image count %h (size %i)

\n" + "

Cache total/hit/miss/fail (counts) %j/%k/%l/%m " + "(%pj%%/%pk%%/%pl%%/%pm%%)

\n" + "

Cache total/hit/miss/fail (size) %n/%o/%q/%r " + "(%pn%%/%po%%/%pq%%/%pr%%)

\n" + "

Total images never rendered: %s " + "(includes %t that were converted)

\n" + "

Total number of excessive conversions: %u " + "(from %v images converted more than once)" + "

\n" + "

Bitmap of size %w had most (%x) conversions

\n" + "

Current contents

\n"); + if (slen >= (int) (sizeof(buffer))) { + goto fetch_about_imagecache_handler_aborted; /* overflow */ + } + + res = fetch_about_senddata(ctx, (const uint8_t *)buffer, slen); + if (res != NSERROR_OK) { + goto fetch_about_imagecache_handler_aborted; + } + + /* image cache entry table */ + res = fetch_about_ssenddataf(ctx, "

\n" + "" + "Entry" + "Content Key" + "Redraw Count" + "Conversion Count" + "Last Redraw" + "Bitmap Age" + "Bitmap Size" + "Source" + "\n"); + if (res != NSERROR_OK) { + goto fetch_about_imagecache_handler_aborted; + } + + slen = 0; + do { + if (even) { + elen = image_cache_snentryf(buffer + slen, + sizeof buffer - slen, + cent_loop, + "" + "%e" + "%k" + "%r" + "%c" + "%a" + "%g" + "%s" + "%o" + "\n"); + } else { + elen = image_cache_snentryf(buffer + slen, + sizeof buffer - slen, + cent_loop, + "" + "%e" + "%k" + "%r" + "%c" + "%a" + "%g" + "%s" + "%o" + "\n"); + } + if (elen <= 0) + break; /* last option */ + + if (elen >= (int) (sizeof buffer - slen)) { + /* last entry would not fit in buffer, submit buffer */ + res = fetch_about_senddata(ctx, + (const uint8_t *)buffer, + slen); + if (res != NSERROR_OK) { + goto fetch_about_imagecache_handler_aborted; + } + + slen = 0; + } else { + /* normal addition */ + slen += elen; + cent_loop++; + even = !even; + } + } while (elen > 0); + + slen += snprintf(buffer + slen, sizeof buffer - slen, + "

\n\n\n"); + + res = fetch_about_senddata(ctx, (const uint8_t *)buffer, slen); + if (res != NSERROR_OK) { + goto fetch_about_imagecache_handler_aborted; + } + + fetch_about_send_finished(ctx); + + return true; + +fetch_about_imagecache_handler_aborted: + return false; +} diff --git a/content/fetchers/about/imagecache.h b/content/fetchers/about/imagecache.h new file mode 100644 index 000000000..d1419cea7 --- /dev/null +++ b/content/fetchers/about/imagecache.h @@ -0,0 +1,37 @@ +/* + * Copyright 2020 Vincent Sanders + * + * This file is part of NetSurf. + * + * 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 . + */ + +/** + * \file + * about scheme imagecache handler interface + */ + +#ifndef NETSURF_CONTENT_FETCHERS_ABOUT_IMAGECACHE_H +#define NETSURF_CONTENT_FETCHERS_ABOUT_IMAGECACHE_H + +/** + * Handler to generate about scheme imagecache page. + * + * Shows details of current image cache. + * + * \param ctx The fetcher context. + * \return true if handled false if aborted. + */ +bool fetch_about_imagecache_handler(struct fetch_about_context *ctx); + +#endif diff --git a/content/fetchers/about/private.h b/content/fetchers/about/private.h new file mode 100644 index 000000000..d877ac5e8 --- /dev/null +++ b/content/fetchers/about/private.h @@ -0,0 +1,59 @@ +/* + * Copyright 2020 Vincent Sanders + * + * 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 . + */ + +/** + * \file + * Private interfaces for the about scheme fetcher. + */ + +#ifndef NETSURF_CONTENT_FETCHERS_ABOUT_PRIVATE_H +#define NETSURF_CONTENT_FETCHERS_ABOUT_PRIVATE_H + +struct fetch_about_context; + +/** + * set http response code on about response + */ +bool fetch_about_set_http_code(struct fetch_about_context *ctx, long code); + +/** + * Send a header on the about response + * + * \param ctx The about fetch context + * \param fmt The format specifier of the header + * \return true if the fetch has been aborted else false + */ +bool fetch_about_send_header(struct fetch_about_context *ctx, const char *fmt, ...); + +/** + * send data on the about response + */ +nserror +fetch_about_senddata(struct fetch_about_context *ctx, const uint8_t *data, size_t data_len); + +/** + * send formatted data on the about response + */ +nserror fetch_about_ssenddataf(struct fetch_about_context *ctx, const char *fmt, ...); + +/** + * complete the about fetch response + */ +bool fetch_about_send_finished(struct fetch_about_context *ctx); + +#endif -- cgit v1.2.3