add header checker
This commit is contained in:
54
server.go
54
server.go
@ -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)
|
||||
|
||||
|
Reference in New Issue
Block a user