[PATCH] Handle If-None-Match HTTP header in plain view
John Keeping
john at keeping.me.uk
Mon Aug 11 23:32:05 CEST 2014
On Mon, Aug 11, 2014 at 05:53:23PM -0300, Damián Nohales wrote:
> We are sending Etag to clients but this header is basically unusefulness
> if the server doesn't tell the client if the content has been changed or
> not for a given Path/Etag pair.
>
> Signed-off-by: Damián Nohales <damiannohales at gmail.com>
> ---
How does this interact with CGit's cache? What happens if the original
page expires from the cache and then a request comes in with a matching
Etag?
> cgit.c | 1 +
> cgit.h | 1 +
> ui-plain.c | 41 +++++++++++++++++++++--------------------
> ui-shared.c | 20 ++++++++++++++++++++
> ui-shared.h | 1 +
> 5 files changed, 44 insertions(+), 20 deletions(-)
>
> diff --git a/cgit.c b/cgit.c
> index 8c4517d..7af7712 100644
> --- a/cgit.c
> +++ b/cgit.c
> @@ -385,6 +385,7 @@ static void prepare_context(void)
> ctx.env.server_port = getenv("SERVER_PORT");
> ctx.env.http_cookie = getenv("HTTP_COOKIE");
> ctx.env.http_referer = getenv("HTTP_REFERER");
> + ctx.env.if_none_match = getenv("HTTP_IF_NONE_MATCH");
> ctx.env.content_length = getenv("CONTENT_LENGTH") ? strtoul(getenv("CONTENT_LENGTH"), NULL, 10) : 0;
> ctx.env.authenticated = 0;
> ctx.page.mimetype = "text/html";
> diff --git a/cgit.h b/cgit.h
> index 0badc64..eddd4c7 100644
> --- a/cgit.h
> +++ b/cgit.h
> @@ -282,6 +282,7 @@ struct cgit_environment {
> const char *server_port;
> const char *http_cookie;
> const char *http_referer;
> + const char *if_none_match;
> unsigned int content_length;
> int authenticated;
> };
> diff --git a/ui-plain.c b/ui-plain.c
> index 30fff89..a08dc5b 100644
> --- a/ui-plain.c
> +++ b/ui-plain.c
> @@ -103,8 +103,8 @@ static int print_object(const unsigned char *sha1, const char *path)
> ctx.page.filename = path;
> ctx.page.size = size;
> ctx.page.etag = sha1_to_hex(sha1);
> - cgit_print_http_headers();
> - html_raw(buf, size);
> + if (!cgit_print_http_headers_matching_etag())
> + html_raw(buf, size);
> /* If we allocated this, then casting away const is safe. */
> if (freemime)
> free((char*) ctx.page.mimetype);
> @@ -128,24 +128,25 @@ static void print_dir(const unsigned char *sha1, const char *base,
> fullpath = buildpath(base, baselen, path);
> slash = (fullpath[0] == '/' ? "" : "/");
> ctx.page.etag = sha1_to_hex(sha1);
> - cgit_print_http_headers();
> - htmlf("<html><head><title>%s", slash);
> - html_txt(fullpath);
> - htmlf("</title></head>\n<body>\n<h2>%s", slash);
> - html_txt(fullpath);
> - html("</h2>\n<ul>\n");
> - len = strlen(fullpath);
> - if (len > 1) {
> - fullpath[len - 1] = 0;
> - slash = strrchr(fullpath, '/');
> - if (slash)
> - *(slash + 1) = 0;
> - else
> - fullpath = NULL;
> - html("<li>");
> - cgit_plain_link("../", NULL, NULL, ctx.qry.head, ctx.qry.sha1,
> - fullpath);
> - html("</li>\n");
> + if (!cgit_print_http_headers_matching_etag()) {
> + htmlf("<html><head><title>%s", slash);
> + html_txt(fullpath);
> + htmlf("</title></head>\n<body>\n<h2>%s", slash);
> + html_txt(fullpath);
> + html("</h2>\n<ul>\n");
> + len = strlen(fullpath);
> + if (len > 1) {
> + fullpath[len - 1] = 0;
> + slash = strrchr(fullpath, '/');
> + if (slash)
> + *(slash + 1) = 0;
> + else
> + fullpath = NULL;
> + html("<li>");
> + cgit_plain_link("../", NULL, NULL, ctx.qry.head, ctx.qry.sha1,
> + fullpath);
> + html("</li>\n");
> + }
> }
> free(fullpath);
> }
> diff --git a/ui-shared.c b/ui-shared.c
> index 9dde0a3..84c7efd 100644
> --- a/ui-shared.c
> +++ b/ui-shared.c
> @@ -661,6 +661,26 @@ void cgit_print_http_headers(void)
> exit(0);
> }
>
> +int cgit_print_http_headers_matching_etag(void)
> +{
> + int match = 0;
> + char *etag;
> + if (ctx.page.etag && ctx.env.if_none_match) {
> + etag = fmtalloc("\"%s\"", ctx.page.etag);
> + if (!strcmp(etag, ctx.env.if_none_match)) {
> + ctx.page.status = 304;
> + ctx.page.statusmsg = "Not Modified";
> + ctx.page.mimetype = NULL;
> + ctx.page.size = 0;
> + ctx.page.filename = NULL;
> + match = 1;
> + }
> + free(etag);
> + }
> + cgit_print_http_headers();
> + return match;
> +}
> +
> void cgit_print_docstart(void)
> {
> if (ctx.cfg.embedded) {
> diff --git a/ui-shared.h b/ui-shared.h
> index 3e7a91b..e279f42 100644
> --- a/ui-shared.h
> +++ b/ui-shared.h
> @@ -60,6 +60,7 @@ extern void cgit_vprint_error(const char *fmt, va_list ap);
> extern void cgit_print_date(time_t secs, const char *format, int local_time);
> extern void cgit_print_age(time_t t, time_t max_relative, const char *format);
> extern void cgit_print_http_headers(void);
> +extern int cgit_print_http_headers_matching_etag(void);
> extern void cgit_print_docstart(void);
> extern void cgit_print_docend();
> extern void cgit_print_pageheader(void);
> --
> 2.0.4
>
> _______________________________________________
> CGit mailing list
> CGit at lists.zx2c4.com
> http://lists.zx2c4.com/mailman/listinfo/cgit
More information about the CGit
mailing list