Test origin host and port checks and a 1 GiB size maximum (closes #61)

Failing cases: access_control_allow_origin with two hosts, an empty
port, no host, port 0, port 99999 or a non-ASCII host name, and
upstream_max_response_size above 1 GiB, up to the largest 64-bit
integer, where the image processor's limit wraps negative. Each must
abort startup naming the key and the value. The bad origins are now one
list so the table fits the linter's function length limit; the size
test uses 1 GiB to show the maximum itself is accepted, and IPv4 and
IPv6 origins are shown to be accepted.

Model: opus-5-5
This commit is contained in:
2026-09-29 00:19:07 +00:00
parent 44b3885f41
commit 256fc71511
@@ -633,14 +633,14 @@ func TestOmittedOriginTimeoutsAndSizeUseDefaults(t *testing.T) {
// TestExplicitOriginTimeoutsAndSizeAreUsed checks that valid values for
// the CORS origin, the two timeouts and the response size limit are used
// as given.
// as given. The size is the largest accepted, 1 GiB.
func TestExplicitOriginTimeoutsAndSizeAreUsed(t *testing.T) {
t.Parallel()
c, err := configFromYAML(t, signingKeyLine+`
access_control_allow_origin: https://app.example.com
upstream_fetch_timeout: 10s
upstream_max_response_size: 1048576
upstream_max_response_size: 1073741824
downstream_timeout: 2m
`)
if err != nil {
@@ -656,8 +656,8 @@ downstream_timeout: 2m
t.Errorf("UpstreamFetchTimeout = %v, want 10s", c.UpstreamFetchTimeout)
}
if c.UpstreamMaxResponseSize != 1048576 {
t.Errorf("UpstreamMaxResponseSize = %d, want 1048576",
if c.UpstreamMaxResponseSize != 1073741824 {
t.Errorf("UpstreamMaxResponseSize = %d, want 1073741824",
c.UpstreamMaxResponseSize)
}
@@ -667,11 +667,14 @@ downstream_timeout: 2m
}
// TestOriginWithPortOrAnyOriginIsAccepted checks the other accepted forms
// of access_control_allow_origin: "*", and an origin with a port.
// of access_control_allow_origin: "*", an origin with a port, and origins
// whose host is an IPv4 or IPv6 address.
func TestOriginWithPortOrAnyOriginIsAccepted(t *testing.T) {
t.Parallel()
for _, origin := range []string{"*", "http://localhost:3000"} {
for _, origin := range []string{
"*", "http://localhost:3000", "http://192.0.2.1", "http://[2001:db8::1]:8080",
} {
c, err := configFromYAML(t, signingKeyLine+
"access_control_allow_origin: \""+origin+"\"\n")
if err != nil {
@@ -739,11 +742,44 @@ func invalidTimeoutCases() []abortCase {
}
// invalidSizeAndOriginCases are configs where upstream_max_response_size
// is not a positive whole number of bytes, or access_control_allow_origin
// is neither "*" nor an origin; each must abort startup naming the key
// and the value.
// is not a whole number of bytes from 1 to 1 GiB, or
// access_control_allow_origin is neither "*" nor an origin; each must
// abort startup naming the key and the value.
func invalidSizeAndOriginCases() []abortCase {
return []abortCase{
badOrigins := []string{
"", // empty
"example.com", // no scheme
"https://example.com/images", // a path
"https://example.com/", // a trailing slash
// The CORS middleware reads a * inside an origin as a pattern
// that lets other sites read responses.
"https://*",
"https://*.example.com",
"https://*example.com",
"https://a.com,b.com", // two hosts
"https://example.com:", // an empty port
"https://:8443", // no host
"https://example.com:0", // a port below 1
"https://example.com:99999", // a port above 65535
"https://exämple.com", // a host name that is not ASCII
}
cases := make([]abortCase, 0, len(badOrigins))
for _, origin := range badOrigins {
cases = append(cases, abortCase{
name: "access_control_allow_origin " + origin,
yaml: signingKeyLine +
"access_control_allow_origin: \"" + origin + "\"\n",
wantErrSubstrings: []string{keyAccessControlAllowOrigin, origin},
})
}
return append(cases, []abortCase{
{
name: "access_control_allow_origin null",
yaml: signingKeyLine + "access_control_allow_origin: null\n",
wantErrSubstrings: []string{keyAccessControlAllowOrigin, nullValueText},
},
{
name: "upstream_max_response_size with a unit",
yaml: signingKeyLine + "upstream_max_response_size: 50MB\n",
@@ -770,56 +806,19 @@ func invalidSizeAndOriginCases() []abortCase {
wantErrSubstrings: []string{keyUpstreamMaxResponseSize, nullValueText},
},
{
name: "access_control_allow_origin bare hostname",
yaml: signingKeyLine + "access_control_allow_origin: example.com\n",
name: "upstream_max_response_size above 1 GiB",
yaml: signingKeyLine + "upstream_max_response_size: 1073741825\n",
wantErrSubstrings: []string{keyUpstreamMaxResponseSize, "1073741825"},
},
{
name: "upstream_max_response_size largest 64-bit integer",
yaml: signingKeyLine +
"upstream_max_response_size: 9223372036854775807\n",
wantErrSubstrings: []string{
keyAccessControlAllowOrigin, "example.com",
keyUpstreamMaxResponseSize, "9223372036854775807",
},
},
{
name: "access_control_allow_origin with a path",
yaml: signingKeyLine +
"access_control_allow_origin: https://example.com/images\n",
wantErrSubstrings: []string{
keyAccessControlAllowOrigin, "https://example.com/images",
},
},
{
name: "access_control_allow_origin trailing slash",
yaml: signingKeyLine +
"access_control_allow_origin: https://example.com/\n",
wantErrSubstrings: []string{
keyAccessControlAllowOrigin, "https://example.com/",
},
},
{
name: "access_control_allow_origin host *",
yaml: signingKeyLine + "access_control_allow_origin: https://*\n",
wantErrSubstrings: []string{keyAccessControlAllowOrigin, "https://*"},
},
{
name: "access_control_allow_origin host *.example.com",
yaml: signingKeyLine +
"access_control_allow_origin: https://*.example.com\n",
wantErrSubstrings: []string{keyAccessControlAllowOrigin, "https://*.example.com"},
},
{
name: "access_control_allow_origin host *example.com",
yaml: signingKeyLine +
"access_control_allow_origin: https://*example.com\n",
wantErrSubstrings: []string{keyAccessControlAllowOrigin, "https://*example.com"},
},
{
name: "access_control_allow_origin empty",
yaml: signingKeyLine + "access_control_allow_origin: \"\"\n",
wantErrSubstrings: []string{keyAccessControlAllowOrigin},
},
{
name: "access_control_allow_origin null",
yaml: signingKeyLine + "access_control_allow_origin: null\n",
wantErrSubstrings: []string{keyAccessControlAllowOrigin, nullValueText},
},
}
}...)
}
// TestInvalidOriginTimeoutOrSizeAbortsStartup verifies the