blob: 4615dc577b985b3c7b012079d554d570b24a5f9e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#!/bin/sh

# The plain page hands over a repository's own bytes. A file with no better
# guess is served as text unless its bytes look binary, a directory answers
# with a bare listing of links, and a path that names nothing comes back as
# a 404 rather than an empty document.

test_description='Check content on plain page'
. ./setup.sh

test_expect_success 'generate foo/plain/file-1' '
	cgit_url "foo/plain/file-1" >tmp
'

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; charset=UTF-8$"
'

test_expect_success 'the body carries the blob byte for byte' '
	strip_headers <tmp >body &&
	git -C repos/foo show master:file-1 >expect &&
	test_cmp expect body
'

test_expect_success 'a missing path is a 404' '
	cgit_url "foo/plain/no-such-file" >tmp &&
	head -n 1 tmp | grep "Status: 404"
'

test_expect_success 'a directory answers with a listing of links' '
	cgit_url "foo/plain" >tmp &&
	grep "<li><a href=" tmp &&
	grep "file-1" tmp &&
	grep "file-5" tmp
'

test_expect_success 'a blob whose bytes look binary is served as octet-stream' '
	(
		cd repos/foo &&
		printf "\000\001\002" >blob.bin &&
		git add blob.bin &&
		git commit -m binary
	) &&
	cgit_url "foo/plain/blob.bin" >tmp &&
	sed "/^$/q" tmp | grep "^Content-Type: application/octet-stream$"
'

# RFC 7303 names the XML types by an xml subtype or a +xml suffix, and those
# take a charset like text does. A type that only spells xml inside a word,
# as the Office formats do, is binary and gets none.
test_expect_success 'only text and xml types carry a charset' '
	(
		cd repos/foo &&
		printf "PK" >doc.docx &&
		printf "<svg/>" >pic.svg &&
		git add doc.docx pic.svg &&
		git commit -m types
	) &&
	docx=application/vnd.openxmlformats-officedocument. &&
	docx=${docx}wordprocessingml.document &&
	{
		echo "enable-html-serving=1" &&
		echo "mimetype.docx=$docx" &&
		echo "mimetype.svg=image/svg+xml" &&
		cat cgitrc
	} >typesrc &&
	CGIT_CONFIG="$PWD/typesrc" QUERY_STRING="url=foo/plain/doc.docx" cgit >tmp &&
	sed "/^$/q" tmp | grep "^Content-Type: $docx$" &&
	CGIT_CONFIG="$PWD/typesrc" QUERY_STRING="url=foo/plain/pic.svg" cgit >tmp &&
	sed "/^$/q" tmp | grep "^Content-Type: image/svg+xml; charset=UTF-8$"
'

# A tree can carry two entries of one name, which only a repository with
# fsck off accepts, and the plain view answers the first alone.
test_expect_success 'plain answers once for duplicate tree entries' '
	test_create_repo repos/dup &&
	(
		cd repos/dup &&
		blob=$(printf PNGDATA | git hash-object -w --stdin) &&
		inner=$(printf "100644 blob %s\\tinside\\n" $blob | git mktree) &&
		top=$(printf "100644 blob %s\\tx.png\\n040000 tree %s\\tx.png\\n" $blob $inner | git mktree --missing) &&
		c=$(echo dup | git commit-tree $top) &&
		git update-ref refs/heads/master $c
	) &&
	{
		echo "virtual-root=/" &&
		echo "cache-size=0" &&
		echo "mimetype.png=image/png" &&
		echo "repo.url=dup" &&
		echo "repo.path=$PWD/repos/dup/.git"
	} >duprc &&
	CGIT_CONFIG="$PWD/duprc" QUERY_STRING="url=dup/plain/x.png" cgit >tmp &&
	test $(grep -c "^Status:" tmp) = 1 &&
	test $(grep -c "^Content-Type:" tmp) = 1 &&
	grep "^Content-Type: image/png" tmp
'

# A header line cannot carry a control byte, and a web server refuses the
# whole response over one, so a file name holding one is sent with a stand-in.
test_expect_success 'a control character in a file name stays out of the headers' '
	(
		cd repos/dup &&
		blob=$(printf x | git hash-object -w --stdin) &&
		top=$(printf "100644 blob %s\\tctl\\001name.txt\\n" $blob | git mktree) &&
		c=$(echo ctl | git commit-tree $top) &&
		git update-ref refs/heads/ctl $c
	) &&
	CGIT_CONFIG="$PWD/duprc" QUERY_STRING="url=dup/plain/ctl%01name.txt&h=ctl" cgit >tmp &&
	grep "^Content-Disposition: inline; filename=.ctl?name.txt.$" tmp
'

test_done