mirror of
https://github.com/caddyserver/caddy.git
synced 2026-04-01 14:52:20 -04:00
198 lines
4.7 KiB
Go
198 lines
4.7 KiB
Go
package caddyhttp
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"github.com/caddyserver/caddy/v2"
|
|
"github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
|
|
)
|
|
|
|
func TestStaticErrorCaddyModule(t *testing.T) {
|
|
se := StaticError{}
|
|
info := se.CaddyModule()
|
|
if info.ID != "http.handlers.error" {
|
|
t.Errorf("CaddyModule().ID = %q, want 'http.handlers.error'", info.ID)
|
|
}
|
|
}
|
|
|
|
func TestStaticErrorServeHTTP(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
staticErr StaticError
|
|
wantStatusCode int
|
|
wantMessage string
|
|
}{
|
|
{
|
|
name: "default status code 500",
|
|
staticErr: StaticError{},
|
|
wantStatusCode: 500,
|
|
},
|
|
{
|
|
name: "custom status code",
|
|
staticErr: StaticError{StatusCode: "404"},
|
|
wantStatusCode: 404,
|
|
},
|
|
{
|
|
name: "custom error message",
|
|
staticErr: StaticError{Error: "custom error", StatusCode: "503"},
|
|
wantStatusCode: 503,
|
|
wantMessage: "custom error",
|
|
},
|
|
{
|
|
name: "status code only",
|
|
staticErr: StaticError{StatusCode: "403"},
|
|
wantStatusCode: 403,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
repl := caddy.NewReplacer()
|
|
ctx := context.WithValue(context.Background(), caddy.ReplacerCtxKey, repl)
|
|
|
|
req, _ := http.NewRequest("GET", "http://example.com/", nil)
|
|
req = req.WithContext(ctx)
|
|
w := httptest.NewRecorder()
|
|
|
|
err := tt.staticErr.ServeHTTP(w, req, nil)
|
|
if err == nil {
|
|
t.Fatal("ServeHTTP() should return an error")
|
|
}
|
|
|
|
var he HandlerError
|
|
if !errors.As(err, &he) {
|
|
t.Fatal("ServeHTTP() error should be HandlerError")
|
|
}
|
|
|
|
if he.StatusCode != tt.wantStatusCode {
|
|
t.Errorf("StatusCode = %d, want %d", he.StatusCode, tt.wantStatusCode)
|
|
}
|
|
|
|
if tt.wantMessage != "" && he.Err != nil {
|
|
if he.Err.Error() != tt.wantMessage {
|
|
t.Errorf("Err.Error() = %q, want %q", he.Err.Error(), tt.wantMessage)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestStaticErrorServeHTTPInvalidStatusCode(t *testing.T) {
|
|
repl := caddy.NewReplacer()
|
|
ctx := context.WithValue(context.Background(), caddy.ReplacerCtxKey, repl)
|
|
|
|
req, _ := http.NewRequest("GET", "http://example.com/", nil)
|
|
req = req.WithContext(ctx)
|
|
w := httptest.NewRecorder()
|
|
|
|
se := StaticError{StatusCode: "not_a_number"}
|
|
err := se.ServeHTTP(w, req, nil)
|
|
if err == nil {
|
|
t.Fatal("ServeHTTP() should return error for invalid status code")
|
|
}
|
|
|
|
var he HandlerError
|
|
if !errors.As(err, &he) {
|
|
t.Fatal("error should be HandlerError")
|
|
}
|
|
// Invalid status code should return 500
|
|
if he.StatusCode != 500 {
|
|
t.Errorf("StatusCode = %d, want 500 for invalid status code", he.StatusCode)
|
|
}
|
|
}
|
|
|
|
func TestStaticErrorUnmarshalCaddyfile(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
input string
|
|
wantErr bool
|
|
wantStatus string
|
|
wantMsg string
|
|
}{
|
|
{
|
|
name: "status code only",
|
|
input: `error 404`,
|
|
wantStatus: "404",
|
|
},
|
|
{
|
|
name: "message only (non-3-digit)",
|
|
input: `error "Page not found"`,
|
|
wantMsg: "Page not found",
|
|
},
|
|
{
|
|
name: "message and status code",
|
|
input: `error "Page not found" 404`,
|
|
wantStatus: "404",
|
|
wantMsg: "Page not found",
|
|
},
|
|
{
|
|
name: "no args",
|
|
input: `error`,
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "too many args",
|
|
input: `error "msg" 404 extra`,
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "status in block",
|
|
input: "error 500 {\n message \"server error\"\n}",
|
|
wantStatus: "500",
|
|
wantMsg: "server error",
|
|
},
|
|
{
|
|
name: "two-digit number is treated as message",
|
|
input: `error 42`,
|
|
wantMsg: "42",
|
|
},
|
|
{
|
|
name: "four-digit number is treated as message",
|
|
input: `error 1234`,
|
|
wantMsg: "1234",
|
|
},
|
|
{
|
|
name: "three-digit is status code",
|
|
input: `error 503`,
|
|
wantStatus: "503",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
d := caddyfile.NewTestDispenser(tt.input)
|
|
se := &StaticError{}
|
|
err := se.UnmarshalCaddyfile(d)
|
|
|
|
if (err != nil) != tt.wantErr {
|
|
t.Errorf("UnmarshalCaddyfile() error = %v, wantErr %v", err, tt.wantErr)
|
|
return
|
|
}
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
if tt.wantStatus != "" && string(se.StatusCode) != tt.wantStatus {
|
|
t.Errorf("StatusCode = %q, want %q", se.StatusCode, tt.wantStatus)
|
|
}
|
|
if tt.wantMsg != "" && se.Error != tt.wantMsg {
|
|
t.Errorf("Error = %q, want %q", se.Error, tt.wantMsg)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestStaticErrorUnmarshalCaddyfileDuplicateMessage(t *testing.T) {
|
|
input := "error \"first message\" 500 {\n message \"second message\"\n}"
|
|
d := caddyfile.NewTestDispenser(input)
|
|
se := &StaticError{}
|
|
err := se.UnmarshalCaddyfile(d)
|
|
if err == nil {
|
|
t.Error("expected error when message is specified both inline and in block")
|
|
}
|
|
}
|