diff options
context:
space:
mode:
-rw-r--r--source/ui-plain.c10
-rw-r--r--source/ui-shared.c13
-rw-r--r--source/ui-summary.c1
-rwxr-xr-xtests/t0105-plain.sh4
-rwxr-xr-xtests/t0110-snapshot.sh6
5 files changed, 19 insertions, 15 deletions
diff --git a/source/ui-plain.c b/source/ui-plain.c
index 7db6e07..6d02051 100644
--- a/source/ui-plain.c
+++ b/source/ui-plain.c
@@ -81,14 +81,8 @@ static void print_object(const struct object_id *oid, const char *path)
ctx.page.mimetype = NULL;
}
- if (!ctx.page.mimetype) {
- if (buffer_is_binary(buf, size)) {
- ctx.page.mimetype = "application/octet-stream";
- ctx.page.charset = NULL;
- } else {
- ctx.page.mimetype = "text/plain";
- }
- }
+ if (!ctx.page.mimetype)
+ ctx.page.mimetype = buffer_is_binary(buf, size) ? "application/octet-stream" : "text/plain";
ctx.page.filename = path;
ctx.page.size = size;
cgit_print_http_headers();
diff --git a/source/ui-shared.c b/source/ui-shared.c
index 3970c58..a112fb2 100644
--- a/source/ui-shared.c
+++ b/source/ui-shared.c
@@ -1424,6 +1424,15 @@ void cgit_print_age(time_t t, int tz, time_t max_relative)
print_rel_date(t, tz, secs * 1.0 / SECONDS_PER_YEAR, "age-years", "years");
}
+/*
+ * Whether a content type carries text a charset applies to, which is every
+ * text type and the XML ones, the atom feed among them.
+ */
+static int type_has_charset(const char *mimetype)
+{
+ return starts_with(mimetype, "text/") || strstr(mimetype, "xml");
+}
+
void cgit_print_http_headers(void)
{
ctx.page.headers_sent = 1;
@@ -1436,7 +1445,9 @@ void cgit_print_http_headers(void)
htmlf("Status: %d %s\n", ctx.page.status, ctx.page.statusmsg);
else
html("Status: 200 OK\n");
- if (ctx.page.mimetype && ctx.page.charset)
+ // A charset only means something for text, so an archive or a pack
+ // is sent without one.
+ if (ctx.page.mimetype && ctx.page.charset && type_has_charset(ctx.page.mimetype))
htmlf("Content-Type: %s; charset=%s\n", ctx.page.mimetype, ctx.page.charset);
else if (ctx.page.mimetype)
htmlf("Content-Type: %s\n", ctx.page.mimetype);
diff --git a/source/ui-summary.c b/source/ui-summary.c
index eb04ecd..61cd6ac 100644
--- a/source/ui-summary.c
+++ b/source/ui-summary.c
@@ -138,7 +138,6 @@ void cgit_print_repo_readme(const char *path)
mimetype = cgit_get_mimetype_for_filename(path);
if (mimetype && (starts_with(mimetype, "image/") || starts_with(mimetype, "video/"))) {
ctx.page.mimetype = mimetype;
- ctx.page.charset = NULL;
cgit_print_plain();
free(mimetype);
return;
diff --git a/tests/t0105-plain.sh b/tests/t0105-plain.sh
index 2fbe87f..4041d98 100755
--- a/tests/t0105-plain.sh
+++ b/tests/t0105-plain.sh
@@ -14,7 +14,7 @@ test_expect_success 'generate foo/plain/file-1' '
test_expect_success 'a text file is served as text/plain' '
head -n 1 tmp | grep "Status: 200 OK" &&
- sed "/^$/q" tmp | grep "Content-Type: text/plain"
+ sed "/^$/q" tmp | grep "^Content-Type: text/plain; charset=UTF-8$"
'
test_expect_success 'the body carries the blob byte for byte' '
@@ -43,7 +43,7 @@ test_expect_success 'a blob whose bytes look binary is served as octet-stream' '
git commit -m binary
) &&
cgit_url "foo/plain/blob.bin" >tmp &&
- sed "/^$/q" tmp | grep "Content-Type: application/octet-stream"
+ sed "/^$/q" tmp | grep "^Content-Type: application/octet-stream$"
'
test_done
diff --git a/tests/t0110-snapshot.sh b/tests/t0110-snapshot.sh
index ba38b82..4852e7b 100755
--- a/tests/t0110-snapshot.sh
+++ b/tests/t0110-snapshot.sh
@@ -31,7 +31,7 @@ test_tar_snapshot() {
test_expect_success $prereq "check $ext response headers" "
head -n 1 tmp | grep 'Status: 200 OK' &&
- head -n 2 tmp | grep 'Content-Type: $type' &&
+ head -n 2 tmp | grep '^Content-Type: $type\$' &&
head -n 3 tmp | grep 'Content-Disposition: inline; filename=.master.$ext.'
"
@@ -58,7 +58,7 @@ test_expect_success 'get foo/snapshot/master.tar' '
test_expect_success 'check tar response headers' '
head -n 1 tmp | grep "Status: 200 OK" &&
- head -n 2 tmp | grep "Content-Type: application/x-tar" &&
+ head -n 2 tmp | grep "^Content-Type: application/x-tar$" &&
head -n 3 tmp | grep "Content-Disposition: inline; filename=.master.tar."
'
@@ -91,7 +91,7 @@ test_expect_success 'get foo/snapshot/master.zip' '
test_expect_success 'check zip response headers' '
head -n 1 tmp | grep "Status: 200 OK" &&
- head -n 2 tmp | grep "Content-Type: application/zip" &&
+ head -n 2 tmp | grep "^Content-Type: application/zip$" &&
head -n 3 tmp | grep "Content-Disposition: inline; filename=.master.zip."
'