Update oxy dependency
This commit is contained in:
parent
d81c4e6d1a
commit
07be89d6e9
31 changed files with 636 additions and 195 deletions
2
vendor/github.com/vulcand/oxy/utils/auth.go
generated
vendored
2
vendor/github.com/vulcand/oxy/utils/auth.go
generated
vendored
|
@ -6,6 +6,7 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
// BasicAuth basic auth information
|
||||
type BasicAuth struct {
|
||||
Username string
|
||||
Password string
|
||||
|
@ -16,6 +17,7 @@ func (ba *BasicAuth) String() string {
|
|||
return fmt.Sprintf("Basic %s", encoded)
|
||||
}
|
||||
|
||||
// ParseAuthHeader creates a new BasicAuth from header values
|
||||
func ParseAuthHeader(header string) (*BasicAuth, error) {
|
||||
values := strings.Fields(header)
|
||||
if len(values) != 2 {
|
||||
|
|
14
vendor/github.com/vulcand/oxy/utils/dumpreq.go
generated
vendored
14
vendor/github.com/vulcand/oxy/utils/dumpreq.go
generated
vendored
|
@ -9,6 +9,7 @@ import (
|
|||
"net/url"
|
||||
)
|
||||
|
||||
// SerializableHttpRequest serializable HTTP request
|
||||
type SerializableHttpRequest struct {
|
||||
Method string
|
||||
URL *url.URL
|
||||
|
@ -28,6 +29,7 @@ type SerializableHttpRequest struct {
|
|||
TLS *tls.ConnectionState
|
||||
}
|
||||
|
||||
// Clone clone a request
|
||||
func Clone(r *http.Request) *SerializableHttpRequest {
|
||||
if r == nil {
|
||||
return nil
|
||||
|
@ -47,14 +49,16 @@ func Clone(r *http.Request) *SerializableHttpRequest {
|
|||
return rc
|
||||
}
|
||||
|
||||
// ToJson serializes to JSON
|
||||
func (s *SerializableHttpRequest) ToJson() string {
|
||||
if jsonVal, err := json.Marshal(s); err != nil || jsonVal == nil {
|
||||
return fmt.Sprintf("Error marshalling SerializableHttpRequest to json: %s", err.Error())
|
||||
} else {
|
||||
return string(jsonVal)
|
||||
jsonVal, err := json.Marshal(s)
|
||||
if err != nil || jsonVal == nil {
|
||||
return fmt.Sprintf("Error marshalling SerializableHttpRequest to json: %s", err)
|
||||
}
|
||||
return string(jsonVal)
|
||||
}
|
||||
|
||||
// DumpHttpRequest dump a HTTP request to JSON
|
||||
func DumpHttpRequest(req *http.Request) string {
|
||||
return fmt.Sprintf("%v", Clone(req).ToJson())
|
||||
return Clone(req).ToJson()
|
||||
}
|
||||
|
|
30
vendor/github.com/vulcand/oxy/utils/handler.go
generated
vendored
30
vendor/github.com/vulcand/oxy/utils/handler.go
generated
vendored
|
@ -1,22 +1,34 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// StatusClientClosedRequest non-standard HTTP status code for client disconnection
|
||||
const StatusClientClosedRequest = 499
|
||||
|
||||
// StatusClientClosedRequestText non-standard HTTP status for client disconnection
|
||||
const StatusClientClosedRequestText = "Client Closed Request"
|
||||
|
||||
// ErrorHandler error handler
|
||||
type ErrorHandler interface {
|
||||
ServeHTTP(w http.ResponseWriter, req *http.Request, err error)
|
||||
}
|
||||
|
||||
// DefaultHandler default error handler
|
||||
var DefaultHandler ErrorHandler = &StdHandler{}
|
||||
|
||||
type StdHandler struct {
|
||||
}
|
||||
// StdHandler Standard error handler
|
||||
type StdHandler struct{}
|
||||
|
||||
func (e *StdHandler) ServeHTTP(w http.ResponseWriter, req *http.Request, err error) {
|
||||
statusCode := http.StatusInternalServerError
|
||||
|
||||
if e, ok := err.(net.Error); ok {
|
||||
if e.Timeout() {
|
||||
statusCode = http.StatusGatewayTimeout
|
||||
|
@ -25,11 +37,23 @@ func (e *StdHandler) ServeHTTP(w http.ResponseWriter, req *http.Request, err err
|
|||
}
|
||||
} else if err == io.EOF {
|
||||
statusCode = http.StatusBadGateway
|
||||
} else if err == context.Canceled {
|
||||
statusCode = StatusClientClosedRequest
|
||||
}
|
||||
|
||||
w.WriteHeader(statusCode)
|
||||
w.Write([]byte(http.StatusText(statusCode)))
|
||||
w.Write([]byte(statusText(statusCode)))
|
||||
log.Debugf("'%d %s' caused by: %v", statusCode, statusText(statusCode), err)
|
||||
}
|
||||
|
||||
func statusText(statusCode int) string {
|
||||
if statusCode == StatusClientClosedRequest {
|
||||
return StatusClientClosedRequestText
|
||||
}
|
||||
return http.StatusText(statusCode)
|
||||
}
|
||||
|
||||
// ErrorHandlerFunc error handler function type
|
||||
type ErrorHandlerFunc func(http.ResponseWriter, *http.Request, error)
|
||||
|
||||
// ServeHTTP calls f(w, r).
|
||||
|
|
55
vendor/github.com/vulcand/oxy/utils/netutils.go
generated
vendored
55
vendor/github.com/vulcand/oxy/utils/netutils.go
generated
vendored
|
@ -12,18 +12,29 @@ import (
|
|||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// ProxyWriter calls recorder, used to debug logs
|
||||
type ProxyWriter struct {
|
||||
W http.ResponseWriter
|
||||
w http.ResponseWriter
|
||||
code int
|
||||
length int64
|
||||
|
||||
log *log.Logger
|
||||
}
|
||||
|
||||
func NewProxyWriter(writer http.ResponseWriter) *ProxyWriter {
|
||||
// NewProxyWriter creates a new ProxyWriter
|
||||
func NewProxyWriter(w http.ResponseWriter) *ProxyWriter {
|
||||
return NewProxyWriterWithLogger(w, log.StandardLogger())
|
||||
}
|
||||
|
||||
// NewProxyWriterWithLogger creates a new ProxyWriter
|
||||
func NewProxyWriterWithLogger(w http.ResponseWriter, l *log.Logger) *ProxyWriter {
|
||||
return &ProxyWriter{
|
||||
W: writer,
|
||||
w: w,
|
||||
log: l,
|
||||
}
|
||||
}
|
||||
|
||||
// StatusCode gets status code
|
||||
func (p *ProxyWriter) StatusCode() int {
|
||||
if p.code == 0 {
|
||||
// per contract standard lib will set this to http.StatusOK if not set
|
||||
|
@ -33,46 +44,54 @@ func (p *ProxyWriter) StatusCode() int {
|
|||
return p.code
|
||||
}
|
||||
|
||||
// GetLength gets content length
|
||||
func (p *ProxyWriter) GetLength() int64 {
|
||||
return p.length
|
||||
}
|
||||
|
||||
// Header gets response header
|
||||
func (p *ProxyWriter) Header() http.Header {
|
||||
return p.W.Header()
|
||||
return p.w.Header()
|
||||
}
|
||||
|
||||
func (p *ProxyWriter) Write(buf []byte) (int, error) {
|
||||
p.length = p.length + int64(len(buf))
|
||||
return p.W.Write(buf)
|
||||
return p.w.Write(buf)
|
||||
}
|
||||
|
||||
// WriteHeader writes status code
|
||||
func (p *ProxyWriter) WriteHeader(code int) {
|
||||
p.code = code
|
||||
p.W.WriteHeader(code)
|
||||
p.w.WriteHeader(code)
|
||||
}
|
||||
|
||||
// Flush flush the writer
|
||||
func (p *ProxyWriter) Flush() {
|
||||
if f, ok := p.W.(http.Flusher); ok {
|
||||
if f, ok := p.w.(http.Flusher); ok {
|
||||
f.Flush()
|
||||
}
|
||||
}
|
||||
|
||||
// CloseNotify returns a channel that receives at most a single value (true)
|
||||
// when the client connection has gone away.
|
||||
func (p *ProxyWriter) CloseNotify() <-chan bool {
|
||||
if cn, ok := p.W.(http.CloseNotifier); ok {
|
||||
if cn, ok := p.w.(http.CloseNotifier); ok {
|
||||
return cn.CloseNotify()
|
||||
}
|
||||
log.Debugf("Upstream ResponseWriter of type %v does not implement http.CloseNotifier. Returning dummy channel.", reflect.TypeOf(p.W))
|
||||
p.log.Debugf("Upstream ResponseWriter of type %v does not implement http.CloseNotifier. Returning dummy channel.", reflect.TypeOf(p.w))
|
||||
return make(<-chan bool)
|
||||
}
|
||||
|
||||
// Hijack lets the caller take over the connection.
|
||||
func (p *ProxyWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
|
||||
if hi, ok := p.W.(http.Hijacker); ok {
|
||||
if hi, ok := p.w.(http.Hijacker); ok {
|
||||
return hi.Hijack()
|
||||
}
|
||||
log.Debugf("Upstream ResponseWriter of type %v does not implement http.Hijacker. Returning dummy channel.", reflect.TypeOf(p.W))
|
||||
return nil, nil, fmt.Errorf("the response writer that was wrapped in this proxy, does not implement http.Hijacker. It is of type: %v", reflect.TypeOf(p.W))
|
||||
p.log.Debugf("Upstream ResponseWriter of type %v does not implement http.Hijacker. Returning dummy channel.", reflect.TypeOf(p.w))
|
||||
return nil, nil, fmt.Errorf("the response writer that was wrapped in this proxy, does not implement http.Hijacker. It is of type: %v", reflect.TypeOf(p.w))
|
||||
}
|
||||
|
||||
// NewBufferWriter creates a new BufferWriter
|
||||
func NewBufferWriter(w io.WriteCloser) *BufferWriter {
|
||||
return &BufferWriter{
|
||||
W: w,
|
||||
|
@ -80,16 +99,19 @@ func NewBufferWriter(w io.WriteCloser) *BufferWriter {
|
|||
}
|
||||
}
|
||||
|
||||
// BufferWriter buffer writer
|
||||
type BufferWriter struct {
|
||||
H http.Header
|
||||
Code int
|
||||
W io.WriteCloser
|
||||
}
|
||||
|
||||
// Close close the writer
|
||||
func (b *BufferWriter) Close() error {
|
||||
return b.W.Close()
|
||||
}
|
||||
|
||||
// Header gets response header
|
||||
func (b *BufferWriter) Header() http.Header {
|
||||
return b.H
|
||||
}
|
||||
|
@ -98,11 +120,13 @@ func (b *BufferWriter) Write(buf []byte) (int, error) {
|
|||
return b.W.Write(buf)
|
||||
}
|
||||
|
||||
// WriteHeader sets rw.Code.
|
||||
// WriteHeader writes status code
|
||||
func (b *BufferWriter) WriteHeader(code int) {
|
||||
b.Code = code
|
||||
}
|
||||
|
||||
// CloseNotify returns a channel that receives at most a single value (true)
|
||||
// when the client connection has gone away.
|
||||
func (b *BufferWriter) CloseNotify() <-chan bool {
|
||||
if cn, ok := b.W.(http.CloseNotifier); ok {
|
||||
return cn.CloseNotify()
|
||||
|
@ -111,6 +135,7 @@ func (b *BufferWriter) CloseNotify() <-chan bool {
|
|||
return make(<-chan bool)
|
||||
}
|
||||
|
||||
// Hijack lets the caller take over the connection.
|
||||
func (b *BufferWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
|
||||
if hi, ok := b.W.(http.Hijacker); ok {
|
||||
return hi.Hijack()
|
||||
|
@ -125,10 +150,10 @@ type nopWriteCloser struct {
|
|||
|
||||
func (*nopWriteCloser) Close() error { return nil }
|
||||
|
||||
// NopCloser returns a WriteCloser with a no-op Close method wrapping
|
||||
// NopWriteCloser returns a WriteCloser with a no-op Close method wrapping
|
||||
// the provided Writer w.
|
||||
func NopWriteCloser(w io.Writer) io.WriteCloser {
|
||||
return &nopWriteCloser{w}
|
||||
return &nopWriteCloser{Writer: w}
|
||||
}
|
||||
|
||||
// CopyURL provides update safe copy by avoiding shallow copying User field
|
||||
|
|
12
vendor/github.com/vulcand/oxy/utils/source.go
generated
vendored
12
vendor/github.com/vulcand/oxy/utils/source.go
generated
vendored
|
@ -6,21 +6,25 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
// ExtractSource extracts the source from the request, e.g. that may be client ip, or particular header that
|
||||
// SourceExtractor extracts the source from the request, e.g. that may be client ip, or particular header that
|
||||
// identifies the source. amount stands for amount of connections the source consumes, usually 1 for connection limiters
|
||||
// error should be returned when source can not be identified
|
||||
type SourceExtractor interface {
|
||||
Extract(req *http.Request) (token string, amount int64, err error)
|
||||
}
|
||||
|
||||
// ExtractorFunc extractor function type
|
||||
type ExtractorFunc func(req *http.Request) (token string, amount int64, err error)
|
||||
|
||||
// Extract extract from request
|
||||
func (f ExtractorFunc) Extract(req *http.Request) (string, int64, error) {
|
||||
return f(req)
|
||||
}
|
||||
|
||||
// ExtractSource extract source function type
|
||||
type ExtractSource func(req *http.Request)
|
||||
|
||||
// NewExtractor creates a new SourceExtractor
|
||||
func NewExtractor(variable string) (SourceExtractor, error) {
|
||||
if variable == "client.ip" {
|
||||
return ExtractorFunc(extractClientIP), nil
|
||||
|
@ -31,17 +35,17 @@ func NewExtractor(variable string) (SourceExtractor, error) {
|
|||
if strings.HasPrefix(variable, "request.header.") {
|
||||
header := strings.TrimPrefix(variable, "request.header.")
|
||||
if len(header) == 0 {
|
||||
return nil, fmt.Errorf("Wrong header: %s", header)
|
||||
return nil, fmt.Errorf("wrong header: %s", header)
|
||||
}
|
||||
return makeHeaderExtractor(header), nil
|
||||
}
|
||||
return nil, fmt.Errorf("Unsupported limiting variable: '%s'", variable)
|
||||
return nil, fmt.Errorf("unsupported limiting variable: '%s'", variable)
|
||||
}
|
||||
|
||||
func extractClientIP(req *http.Request) (string, int64, error) {
|
||||
vals := strings.SplitN(req.RemoteAddr, ":", 2)
|
||||
if len(vals[0]) == 0 {
|
||||
return "", 0, fmt.Errorf("Failed to parse client IP: %v", req.RemoteAddr)
|
||||
return "", 0, fmt.Errorf("failed to parse client IP: %v", req.RemoteAddr)
|
||||
}
|
||||
return vals[0], 1, nil
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue