add header checker
Some checks failed
build container / build-container (push) Successful in 33m30s
run go test / test (push) Failing after 3s

This commit is contained in:
2025-04-01 14:09:43 +08:00
parent 85968bb5cf
commit 835045346d
3 changed files with 60 additions and 9 deletions

View File

@ -4,7 +4,6 @@ import (
"bytes"
"context"
"errors"
"fmt"
"io"
"log/slog"
"net"
@ -618,18 +617,54 @@ func (server *Server) tryUpstream(ctx context.Context, upstreamIdx, priority int
if err != nil {
return nil, nil, err
}
streaming := false
defer func() {
if !streaming {
response.Body.Close()
}
}()
if response.StatusCode == http.StatusNotModified {
return response, nil, nil
}
if response.StatusCode >= 400 && response.StatusCode < 500 {
return nil, nil, nil
responseCheckers := upstream.Checkers
if len(responseCheckers) == 0 {
responseCheckers = append(responseCheckers, Checker{})
}
if response.StatusCode < 200 || response.StatusCode >= 500 {
logger.With(
"url", newurl,
"status", response.StatusCode,
).Warn("unexpected status")
return response, nil, fmt.Errorf("unexpected status(url=%v): %v: %v", newurl, response.StatusCode, response)
for _, checker := range responseCheckers {
if len(checker.StatusCodes) == 0 {
checker.StatusCodes = append(checker.StatusCodes, http.StatusOK)
}
if !slices.Contains(checker.StatusCodes, response.StatusCode) {
return nil, nil, err
}
for _, headerChecker := range checker.Headers {
if headerChecker.Match == nil {
// check header exists
if _, ok := response.Header[headerChecker.Name]; !ok {
logger.Debug("missing header", "header", headerChecker.Name)
return nil, nil, nil
}
} else {
// check header match
value := response.Header.Get(headerChecker.Name)
if matched, err := regexp.MatchString(*headerChecker.Match, value); err != nil {
return nil, nil, err
} else if !matched {
logger.Debug("invalid header value",
"header", headerChecker.Name,
"value", value,
"matcher", *headerChecker.Match,
)
return nil, nil, nil
}
}
}
}
var currentOffset int64
@ -646,6 +681,7 @@ func (server *Server) tryUpstream(ctx context.Context, upstreamIdx, priority int
}
ch <- Chunk{buffer: buffer[:n]}
streaming = true
go func() {
defer close(ch)