fix application bug

This commit is contained in:
Jeff
2019-05-13 11:19:18 +08:00
committed by zryfish
parent 996d6fe4c5
commit 5462f51e65
717 changed files with 87703 additions and 53426 deletions

View File

@@ -21,10 +21,13 @@ import (
"fmt"
"io"
"io/ioutil"
"log"
"net"
"net/http"
"net/textproto"
"net/url"
"path"
"regexp"
"strconv"
"strings"
"sync"
@@ -65,18 +68,39 @@ type staticUpstream struct {
Port string
ContentString string
}
WithoutPathPrefix string
IgnoredSubPaths []string
insecureSkipVerify bool
MaxFails int32
resolver srvResolver
CaCertPool *x509.CertPool
WithoutPathPrefix string
IgnoredSubPaths []string
insecureSkipVerify bool
MaxFails int32
resolver srvResolver
CaCertPool *x509.CertPool
upstreamHeaderReplacements headerReplacements
downstreamHeaderReplacements headerReplacements
}
type srvResolver interface {
LookupSRV(context.Context, string, string, string) (string, []*net.SRV, error)
}
// headerReplacement stores a compiled regex matcher and a string replacer, for replacement rules
type headerReplacement struct {
regexp *regexp.Regexp
to string
}
// headerReplacements stores a mapping of canonical MIME header to headerReplacement
// Implements a subset of http.Header functions, to allow convenient addition and deletion of rules
type headerReplacements map[string][]headerReplacement
func (h headerReplacements) Add(key string, value headerReplacement) {
key = textproto.CanonicalMIMEHeaderKey(key)
h[key] = append(h[key], value)
}
func (h headerReplacements) Del(key string) {
delete(h, textproto.CanonicalMIMEHeaderKey(key))
}
// NewStaticUpstreams parses the configuration input and sets up
// static upstreams for the proxy middleware. The host string parameter,
// if not empty, is used for setting the upstream Host header for the
@@ -86,18 +110,20 @@ func NewStaticUpstreams(c caddyfile.Dispenser, host string) ([]Upstream, error)
for c.Next() {
upstream := &staticUpstream{
from: "",
stop: make(chan struct{}),
upstreamHeaders: make(http.Header),
downstreamHeaders: make(http.Header),
Hosts: nil,
Policy: &Random{},
MaxFails: 1,
TryInterval: 250 * time.Millisecond,
MaxConns: 0,
KeepAlive: http.DefaultMaxIdleConnsPerHost,
Timeout: 30 * time.Second,
resolver: net.DefaultResolver,
from: "",
stop: make(chan struct{}),
upstreamHeaders: make(http.Header),
downstreamHeaders: make(http.Header),
Hosts: nil,
Policy: &Random{},
MaxFails: 1,
TryInterval: 250 * time.Millisecond,
MaxConns: 0,
KeepAlive: http.DefaultMaxIdleConnsPerHost,
Timeout: 30 * time.Second,
resolver: net.DefaultResolver,
upstreamHeaderReplacements: make(headerReplacements),
downstreamHeaderReplacements: make(headerReplacements),
}
if !c.Args(&upstream.from) {
@@ -220,9 +246,11 @@ func (u *staticUpstream) NewHost(host string) (*UpstreamHost, error) {
return false
}
}(u),
WithoutPathPrefix: u.WithoutPathPrefix,
MaxConns: u.MaxConns,
HealthCheckResult: atomic.Value{},
WithoutPathPrefix: u.WithoutPathPrefix,
MaxConns: u.MaxConns,
HealthCheckResult: atomic.Value{},
UpstreamHeaderReplacements: u.upstreamHeaderReplacements,
DownstreamHeaderReplacements: u.downstreamHeaderReplacements,
}
baseURL, err := url.Parse(uh.Name)
@@ -302,6 +330,8 @@ func parseUpstream(u string) ([]string, error) {
}
func parseBlock(c *caddyfile.Dispenser, u *staticUpstream, hasSrv bool) error {
var isUpstream bool
switch c.Val() {
case "policy":
if !c.NextArg() {
@@ -431,23 +461,37 @@ func parseBlock(c *caddyfile.Dispenser, u *staticUpstream, hasSrv bool) error {
}
u.HealthCheck.ContentString = c.Val()
case "header_upstream":
var header, value string
if !c.Args(&header, &value) {
// When removing a header, the value can be optional.
if !strings.HasPrefix(header, "-") {
return c.ArgErr()
}
}
u.upstreamHeaders.Add(header, value)
isUpstream = true
fallthrough
case "header_downstream":
var header, value string
if !c.Args(&header, &value) {
// When removing a header, the value can be optional.
if !strings.HasPrefix(header, "-") {
var header, value, replaced string
if c.Args(&header, &value, &replaced) {
// Don't allow - or + in replacements
if strings.HasPrefix(header, "-") || strings.HasPrefix(header, "+") {
return c.ArgErr()
}
r, err := regexp.Compile(value)
if err != nil {
return err
}
if isUpstream {
u.upstreamHeaderReplacements.Add(header, headerReplacement{r, replaced})
} else {
u.downstreamHeaderReplacements.Add(header, headerReplacement{r, replaced})
}
} else {
if len(value) == 0 {
// When removing a header, the value can be optional.
if !strings.HasPrefix(header, "-") {
return c.ArgErr()
}
}
if isUpstream {
u.upstreamHeaders.Add(header, value)
} else {
u.downstreamHeaders.Add(header, value)
}
}
u.downstreamHeaders.Add(header, value)
case "transparent":
// Note: X-Forwarded-For header is always being appended for proxy connections
// See implementation of createUpstreamRequest in proxy.go
@@ -589,8 +633,10 @@ func (u *staticUpstream) healthCheck() {
return true
}
defer func() {
io.Copy(ioutil.Discard, r.Body)
r.Body.Close()
if _, err := io.Copy(ioutil.Discard, r.Body); err != nil {
log.Println("[ERROR] failed to copy: ", err)
}
_ = r.Body.Close()
}()
if r.StatusCode < 200 || r.StatusCode >= 400 {
return true