vole
Clone
Read only, no credentials:
https://rodent.software/git/vole.git
Write over SSH with a registered key:
git clone ssh://git@0.0.0.0:2222/vole.git
A free and open-source forge that lives in your Git repo.
|
26c9be33
Keenan Nemetz
9d ago
|
1 | package web |
| 2 | ||
| 3 | import "testing" | |
| 4 | ||
| 5 | // TestParseByteRange pins the decisions a Range header can ask for: serve a | |
| 6 | // part, refuse because it starts past the end, or ignore it and serve the whole | |
| 7 | // file. The last case is the one that must not surprise a client: an | |
| 8 | // unparsable header is not an error, it is "no range". | |
| 9 | func TestParseByteRange(t *testing.T) { | |
| 10 | cases := []struct { | |
| 11 | name string | |
| 12 | header string | |
| 13 | size int64 | |
| 14 | start, length int64 | |
| 15 | partial bool | |
| 16 | unsatisfiable bool | |
| 17 | }{ | |
| 18 | {name: "no header", size: 20}, | |
| 19 | {name: "other unit", header: "items=0-1", size: 20}, | |
| 20 | {name: "prefix", header: "bytes=0-9", size: 20, start: 0, length: 10, partial: true}, | |
| 21 | {name: "middle", header: "bytes=5-9", size: 20, start: 5, length: 5, partial: true}, | |
| 22 | {name: "open ended", header: "bytes=15-", size: 20, start: 15, length: 5, partial: true}, | |
| 23 | {name: "end past size", header: "bytes=15-99", size: 20, start: 15, length: 5, partial: true}, | |
| 24 | {name: "whole file", header: "bytes=0-", size: 20, start: 0, length: 20, partial: true}, | |
| 25 | {name: "suffix", header: "bytes=-5", size: 20, start: 15, length: 5, partial: true}, | |
| 26 | {name: "suffix larger than the file", header: "bytes=-99", size: 20, start: 0, length: 20, partial: true}, | |
| 27 | {name: "start past the end", header: "bytes=20-", size: 20, unsatisfiable: true}, | |
| 28 | {name: "range past the end", header: "bytes=25-30", size: 20, unsatisfiable: true}, | |
| 29 | {name: "zero suffix", header: "bytes=-0", size: 20, unsatisfiable: true}, | |
| 30 | {name: "empty file", header: "bytes=0-", size: 0, unsatisfiable: true}, | |
| 31 | {name: "multiple ranges", header: "bytes=0-1,3-4", size: 20}, | |
| 32 | {name: "not a number", header: "bytes=abc", size: 20}, | |
| 33 | {name: "reversed", header: "bytes=5-3", size: 20}, | |
| 34 | {name: "no dash", header: "bytes=5", size: 20}, | |
| 35 | } | |
| 36 | for _, c := range cases { | |
| 37 | t.Run(c.name, func(t *testing.T) { | |
| 38 | br, partial, unsatisfiable := parseByteRange(c.header, c.size) | |
| 39 | if partial != c.partial || unsatisfiable != c.unsatisfiable { | |
| 40 | t.Fatalf("parseByteRange(%q, %d) = partial %t, unsatisfiable %t; want %t, %t", | |
| 41 | c.header, c.size, partial, unsatisfiable, c.partial, c.unsatisfiable) | |
| 42 | } | |
| 43 | if c.partial && (br.start != c.start || br.length != c.length) { | |
| 44 | t.Fatalf("range = %+v; want start %d length %d", br, c.start, c.length) | |
| 45 | } | |
| 46 | }) | |
| 47 | } | |
| 48 | } |