about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--cgit.c6
-rw-r--r--cgit.h3
-rw-r--r--ui-atom.c6
-rw-r--r--ui-blob.c8
-rw-r--r--ui-plain.c6
-rw-r--r--ui-shared.c22
-rw-r--r--ui-shared.h1
7 files changed, 47 insertions, 5 deletions
diff --git a/cgit.c b/cgit.c
index 2afc598..513ea12 100644
--- a/cgit.c
+++ b/cgit.c
@@ -208,6 +208,7 @@ static void prepare_context(struct cgit_context *ctx)
 	ctx->page.size = 0;
 	ctx->page.modified = time(NULL);
 	ctx->page.expires = ctx->page.modified;
+	ctx->page.etag = NULL;
 }
 
 struct refmatch {
@@ -287,6 +288,8 @@ static int prepare_repo_cmd(struct cgit_context *ctx)
 	if (get_sha1(ctx->qry.head, sha1)) {
 		tmp = xstrdup(ctx->qry.head);
 		ctx->qry.head = ctx->repo->defbranch;
+		ctx->page.status = 404;
+		ctx->page.statusmsg = "not found";
 		cgit_print_http_headers(ctx);
 		cgit_print_docstart(ctx);
 		cgit_print_pageheader(ctx);
@@ -431,6 +434,7 @@ static int calc_ttl()
 int main(int argc, const char **argv)
 {
 	const char *cgit_config_env = getenv("CGIT_CONFIG");
+	const char *method = getenv("REQUEST_METHOD");
 	const char *path;
 	char *qry;
 	int err, ttl;
@@ -477,6 +481,8 @@ int main(int argc, const char **argv)
 
 	ttl = calc_ttl();
 	ctx.page.expires += ttl*60;
+	if (method && !strcmp(method, "HEAD"))
+		ctx.cfg.nocache = 1;
 	if (ctx.cfg.nocache)
 		ctx.cfg.cache_size = 0;
 	err = cache_process(ctx.cfg.cache_size, ctx.cfg.cache_root,
diff --git a/cgit.h b/cgit.h
index aed826a..78b30ba 100644
--- a/cgit.h
+++ b/cgit.h
@@ -181,7 +181,10 @@ struct cgit_page {
 	char *mimetype;
 	char *charset;
 	char *filename;
+	char *etag;
 	char *title;
+	int status;
+	char *statusmsg;
 };
 
 struct cgit_context {
diff --git a/ui-atom.c b/ui-atom.c
index a6ea3ee..e5c31d9 100644
--- a/ui-atom.c
+++ b/ui-atom.c
@@ -52,7 +52,8 @@ void add_entry(struct commit *commit, char *host)
 	cgit_print_date(info->author_date, FMT_ATOMDATE, ctx.cfg.local_time);
 	html("</published>\n");
 	if (host) {
-		html("<link rel='alternate' type='text/html' href='http://");
+		html("<link rel='alternate' type='text/html' href='");
+		html(cgit_httpscheme());
 		html_attr(host);
 		html_attr(cgit_pageurl(ctx.repo->url, "commit", NULL));
 		if (ctx.cfg.virtual_root)
@@ -113,7 +114,8 @@ void cgit_print_atom(char *tip, char *path, int max_count)
 	html_txt(ctx.repo->desc);
 	html("</subtitle>\n");
 	if (host) {
-		html("<link rel='alternate' type='text/html' href='http://");
+		html("<link rel='alternate' type='text/html' href='");
+		html(cgit_httpscheme());
 		html_attr(host);
 		html_attr(cgit_repourl(ctx.repo->url));
 		html("'/>\n");
diff --git a/ui-blob.c b/ui-blob.c
index 3cda03d..2ccd31d 100644
--- a/ui-blob.c
+++ b/ui-blob.c
@@ -27,7 +27,7 @@ void cgit_print_blob(const char *hex, char *path, const char *head)
 
 	unsigned char sha1[20];
 	enum object_type type;
-	unsigned char *buf;
+	char *buf;
 	unsigned long size;
 	struct commit *commit;
 	const char *paths[] = {path, NULL};
@@ -67,6 +67,12 @@ void cgit_print_blob(const char *hex, char *path, const char *head)
 
 	buf[size] = '\0';
 	ctx.page.mimetype = ctx.qry.mimetype;
+	if (!ctx.page.mimetype) {
+		if (buffer_is_binary(buf, size))
+			ctx.page.mimetype = "application/octet-stream";
+		else
+			ctx.page.mimetype = "text/plain";
+	}
 	ctx.page.filename = path;
 	cgit_print_http_headers(&ctx);
 	write(htmlfd, buf, size);
diff --git a/ui-plain.c b/ui-plain.c
index 5addd9e..93a3a05 100644
--- a/ui-plain.c
+++ b/ui-plain.c
@@ -31,9 +31,13 @@ static void print_object(const unsigned char *sha1, const char *path)
 		html_status(404, "Not found", 0);
 		return;
 	}
-	ctx.page.mimetype = "text/plain";
+	if (buffer_is_binary(buf, size))
+		ctx.page.mimetype = "application/octet-stream";
+	else
+		ctx.page.mimetype = "text/plain";
 	ctx.page.filename = fmt("%s", path);
 	ctx.page.size = size;
+	ctx.page.etag = sha1_to_hex(sha1);
 	cgit_print_http_headers(&ctx);
 	html_raw(buf, size);
 	match = 1;
diff --git a/ui-shared.c b/ui-shared.c
index fea2c40..66d5b82 100644
--- a/ui-shared.c
+++ b/ui-shared.c
@@ -34,6 +34,17 @@ void cgit_print_error(char *msg)
 	html("</div>\n");
 }
 
+char *cgit_httpscheme()
+{
+	char *https;
+
+	https = getenv("HTTPS");
+	if (https != NULL && strcmp(https, "on") == 0)
+		return "https://";
+	else
+		return "http://";
+}
+
 char *cgit_hosturl()
 {
 	char *host, *port;
@@ -456,6 +467,10 @@ void cgit_print_age(time_t t, time_t max_relative, char *format)
 
 void cgit_print_http_headers(struct cgit_context *ctx)
 {
+	const char *method = getenv("REQUEST_METHOD");
+
+	if (ctx->page.status)
+		htmlf("Status: %d %s\n", ctx->page.status, ctx->page.statusmsg);
 	if (ctx->page.mimetype && ctx->page.charset)
 		htmlf("Content-Type: %s; charset=%s\n", ctx->page.mimetype,
 		      ctx->page.charset);
@@ -468,7 +483,11 @@ void cgit_print_http_headers(struct cgit_context *ctx)
 		      ctx->page.filename);
 	htmlf("Last-Modified: %s\n", http_date(ctx->page.modified));
 	htmlf("Expires: %s\n", http_date(ctx->page.expires));
+	if (ctx->page.etag)
+		htmlf("ETag: \"%s\"\n", ctx->page.etag);
 	html("\n");
+	if (method && !strcmp(method, "HEAD"))
+		exit(0);
 }
 
 void cgit_print_docstart(struct cgit_context *ctx)
@@ -492,7 +511,8 @@ void cgit_print_docstart(struct cgit_context *ctx)
 		html("'/>\n");
 	}
 	if (host && ctx->repo) {
-		html("<link rel='alternate' title='Atom feed' href='http://");
+		html("<link rel='alternate' title='Atom feed' href='");
+		html(cgit_httpscheme());
 		html_attr(cgit_hosturl());
 		html_attr(cgit_fileurl(ctx->repo->url, "atom", ctx->qry.path,
 				       fmt("h=%s", ctx->qry.head)));
diff --git a/ui-shared.h b/ui-shared.h
index 5a3821f..bff4826 100644
--- a/ui-shared.h
+++ b/ui-shared.h
@@ -1,6 +1,7 @@
 #ifndef UI_SHARED_H
 #define UI_SHARED_H
 
+extern char *cgit_httpscheme();
 extern char *cgit_hosturl();
 extern char *cgit_repourl(const char *reponame);
 extern char *cgit_fileurl(const char *reponame, const char *pagename,