mirror of
				https://github.com/caddyserver/caddy.git
				synced 2025-10-30 18:22:49 -04:00 
			
		
		
		
	
		
			Some checks are pending
		
		
	
	Tests / test (./cmd/caddy/caddy, ~1.22.3, macos-14, 0, 1.22, mac) (push) Waiting to run
				
			Tests / test (./cmd/caddy/caddy, ~1.22.3, ubuntu-latest, 0, 1.22, linux) (push) Waiting to run
				
			Tests / test (./cmd/caddy/caddy, ~1.23.0, macos-14, 0, 1.23, mac) (push) Waiting to run
				
			Tests / test (./cmd/caddy/caddy, ~1.23.0, ubuntu-latest, 0, 1.23, linux) (push) Waiting to run
				
			Tests / test (./cmd/caddy/caddy.exe, ~1.22.3, windows-latest, True, 1.22, windows) (push) Waiting to run
				
			Tests / test (./cmd/caddy/caddy.exe, ~1.23.0, windows-latest, True, 1.23, windows) (push) Waiting to run
				
			Tests / test (s390x on IBM Z) (push) Waiting to run
				
			Tests / goreleaser-check (push) Waiting to run
				
			Cross-Build / build (~1.22.3, 1.22, aix) (push) Waiting to run
				
			Cross-Build / build (~1.22.3, 1.22, darwin) (push) Waiting to run
				
			Cross-Build / build (~1.22.3, 1.22, dragonfly) (push) Waiting to run
				
			Cross-Build / build (~1.22.3, 1.22, freebsd) (push) Waiting to run
				
			Cross-Build / build (~1.22.3, 1.22, illumos) (push) Waiting to run
				
			Cross-Build / build (~1.22.3, 1.22, linux) (push) Waiting to run
				
			Cross-Build / build (~1.22.3, 1.22, netbsd) (push) Waiting to run
				
			Cross-Build / build (~1.22.3, 1.22, openbsd) (push) Waiting to run
				
			Cross-Build / build (~1.22.3, 1.22, solaris) (push) Waiting to run
				
			Cross-Build / build (~1.22.3, 1.22, windows) (push) Waiting to run
				
			Cross-Build / build (~1.23.0, 1.23, aix) (push) Waiting to run
				
			Cross-Build / build (~1.23.0, 1.23, darwin) (push) Waiting to run
				
			Cross-Build / build (~1.23.0, 1.23, dragonfly) (push) Waiting to run
				
			Cross-Build / build (~1.23.0, 1.23, freebsd) (push) Waiting to run
				
			Cross-Build / build (~1.23.0, 1.23, illumos) (push) Waiting to run
				
			Cross-Build / build (~1.23.0, 1.23, linux) (push) Waiting to run
				
			Cross-Build / build (~1.23.0, 1.23, netbsd) (push) Waiting to run
				
			Cross-Build / build (~1.23.0, 1.23, openbsd) (push) Waiting to run
				
			Cross-Build / build (~1.23.0, 1.23, solaris) (push) Waiting to run
				
			Cross-Build / build (~1.23.0, 1.23, windows) (push) Waiting to run
				
			Lint / lint (macos-14, mac) (push) Waiting to run
				
			Lint / lint (ubuntu-latest, linux) (push) Waiting to run
				
			Lint / lint (windows-latest, windows) (push) Waiting to run
				
			Lint / govulncheck (push) Waiting to run
				
			* caddyhttp: Allow matching Transfer-Encoding * Log transfer_encoding on the request --------- Co-authored-by: Matt Holt <mholt@users.noreply.github.com>
		
			
				
	
	
		
			120 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			120 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright 2015 Matthew Holt and The Caddy Authors
 | |
| //
 | |
| // Licensed under the Apache License, Version 2.0 (the "License");
 | |
| // you may not use this file except in compliance with the License.
 | |
| // You may obtain a copy of the License at
 | |
| //
 | |
| //     http://www.apache.org/licenses/LICENSE-2.0
 | |
| //
 | |
| // Unless required by applicable law or agreed to in writing, software
 | |
| // distributed under the License is distributed on an "AS IS" BASIS,
 | |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
| // See the License for the specific language governing permissions and
 | |
| // limitations under the License.
 | |
| 
 | |
| package caddyhttp
 | |
| 
 | |
| import (
 | |
| 	"net/http"
 | |
| 	"strconv"
 | |
| 	"strings"
 | |
| 
 | |
| 	"github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
 | |
| )
 | |
| 
 | |
| // ResponseMatcher is a type which can determine if an
 | |
| // HTTP response matches some criteria.
 | |
| type ResponseMatcher struct {
 | |
| 	// If set, one of these status codes would be required.
 | |
| 	// A one-digit status can be used to represent all codes
 | |
| 	// in that class (e.g. 3 for all 3xx codes).
 | |
| 	StatusCode []int `json:"status_code,omitempty"`
 | |
| 
 | |
| 	// If set, each header specified must be one of the
 | |
| 	// specified values, with the same logic used by the
 | |
| 	// [request header matcher](/docs/json/apps/http/servers/routes/match/header/).
 | |
| 	Headers http.Header `json:"headers,omitempty"`
 | |
| }
 | |
| 
 | |
| // Match returns true if the given statusCode and hdr match rm.
 | |
| func (rm ResponseMatcher) Match(statusCode int, hdr http.Header) bool {
 | |
| 	if !rm.matchStatusCode(statusCode) {
 | |
| 		return false
 | |
| 	}
 | |
| 	return matchHeaders(hdr, rm.Headers, "", []string{}, nil)
 | |
| }
 | |
| 
 | |
| func (rm ResponseMatcher) matchStatusCode(statusCode int) bool {
 | |
| 	if rm.StatusCode == nil {
 | |
| 		return true
 | |
| 	}
 | |
| 	for _, code := range rm.StatusCode {
 | |
| 		if StatusCodeMatches(statusCode, code) {
 | |
| 			return true
 | |
| 		}
 | |
| 	}
 | |
| 	return false
 | |
| }
 | |
| 
 | |
| // ParseNamedResponseMatcher parses the tokens of a named response matcher.
 | |
| //
 | |
| //	@name {
 | |
| //	    header <field> [<value>]
 | |
| //	    status <code...>
 | |
| //	}
 | |
| //
 | |
| // Or, single line syntax:
 | |
| //
 | |
| //	@name [header <field> [<value>]] | [status <code...>]
 | |
| func ParseNamedResponseMatcher(d *caddyfile.Dispenser, matchers map[string]ResponseMatcher) error {
 | |
| 	d.Next() // consume matcher name
 | |
| 	definitionName := d.Val()
 | |
| 
 | |
| 	if _, ok := matchers[definitionName]; ok {
 | |
| 		return d.Errf("matcher is defined more than once: %s", definitionName)
 | |
| 	}
 | |
| 
 | |
| 	matcher := ResponseMatcher{}
 | |
| 	for nesting := d.Nesting(); d.NextArg() || d.NextBlock(nesting); {
 | |
| 		switch d.Val() {
 | |
| 		case "header":
 | |
| 			if matcher.Headers == nil {
 | |
| 				matcher.Headers = http.Header{}
 | |
| 			}
 | |
| 
 | |
| 			// reuse the header request matcher's unmarshaler
 | |
| 			headerMatcher := MatchHeader(matcher.Headers)
 | |
| 			err := headerMatcher.UnmarshalCaddyfile(d.NewFromNextSegment())
 | |
| 			if err != nil {
 | |
| 				return err
 | |
| 			}
 | |
| 
 | |
| 			matcher.Headers = http.Header(headerMatcher)
 | |
| 		case "status":
 | |
| 			if matcher.StatusCode == nil {
 | |
| 				matcher.StatusCode = []int{}
 | |
| 			}
 | |
| 
 | |
| 			args := d.RemainingArgs()
 | |
| 			if len(args) == 0 {
 | |
| 				return d.ArgErr()
 | |
| 			}
 | |
| 
 | |
| 			for _, arg := range args {
 | |
| 				if len(arg) == 3 && strings.HasSuffix(arg, "xx") {
 | |
| 					arg = arg[:1]
 | |
| 				}
 | |
| 				statusNum, err := strconv.Atoi(arg)
 | |
| 				if err != nil {
 | |
| 					return d.Errf("bad status value '%s': %v", arg, err)
 | |
| 				}
 | |
| 				matcher.StatusCode = append(matcher.StatusCode, statusNum)
 | |
| 			}
 | |
| 		default:
 | |
| 			return d.Errf("unrecognized response matcher %s", d.Val())
 | |
| 		}
 | |
| 	}
 | |
| 	matchers[definitionName] = matcher
 | |
| 	return nil
 | |
| }
 |