Resync oxy with original repository

This commit is contained in:
SALLEYRON Julien 2017-11-22 18:20:03 +01:00 committed by Traefiker
parent da5e4a13bf
commit bee8ebb00b
31 changed files with 650 additions and 808 deletions

View file

@ -2,19 +2,23 @@ package utils
import (
"bufio"
"fmt"
"io"
"mime"
"net"
"net/http"
"net/url"
"reflect"
log "github.com/Sirupsen/logrus"
)
// ProxyWriter helps to capture response headers and status code
// from the ServeHTTP. It can be safely passed to ServeHTTP handler,
// wrapping the real response writer.
type ProxyWriter struct {
W http.ResponseWriter
Code int
W http.ResponseWriter
Code int
Length int64
}
func (p *ProxyWriter) StatusCode() int {
@ -31,6 +35,7 @@ func (p *ProxyWriter) Header() http.Header {
}
func (p *ProxyWriter) Write(buf []byte) (int, error) {
p.Length = p.Length + int64(len(buf))
return p.W.Write(buf)
}
@ -45,8 +50,20 @@ func (p *ProxyWriter) Flush() {
}
}
func (p *ProxyWriter) CloseNotify() <-chan bool {
if cn, ok := p.W.(http.CloseNotifier); ok {
return cn.CloseNotify()
}
log.Warningf("Upstream ResponseWriter of type %v does not implement http.CloseNotifier. Returning dummy channel.", reflect.TypeOf(p.W))
return make(<-chan bool)
}
func (p *ProxyWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
return p.W.(http.Hijacker).Hijack()
if hi, ok := p.W.(http.Hijacker); ok {
return hi.Hijack()
}
log.Warningf("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))
}
func NewBufferWriter(w io.WriteCloser) *BufferWriter {
@ -79,8 +96,20 @@ func (b *BufferWriter) WriteHeader(code int) {
b.Code = code
}
func (b *BufferWriter) CloseNotify() <-chan bool {
if cn, ok := b.W.(http.CloseNotifier); ok {
return cn.CloseNotify()
}
log.Warningf("Upstream ResponseWriter of type %v does not implement http.CloseNotifier. Returning dummy channel.", reflect.TypeOf(b.W))
return make(<-chan bool)
}
func (b *BufferWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
return b.W.(http.Hijacker).Hijack()
if hi, ok := b.W.(http.Hijacker); ok {
return hi.Hijack()
}
log.Warningf("Upstream ResponseWriter of type %v does not implement http.Hijacker. Returning dummy channel.", reflect.TypeOf(b.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(b.W))
}
type nopWriteCloser struct {
@ -106,11 +135,9 @@ func CopyURL(i *url.URL) *url.URL {
// CopyHeaders copies http headers from source to destination, it
// does not overide, but adds multiple headers
func CopyHeaders(dst, src http.Header) {
func CopyHeaders(dst http.Header, src http.Header) {
for k, vv := range src {
for _, v := range vv {
dst.Add(k, v)
}
dst[k] = append(dst[k], vv...)
}
}
@ -130,9 +157,3 @@ func RemoveHeaders(headers http.Header, names ...string) {
headers.Del(h)
}
}
// Parse the MIME media type value of a header.
func GetHeaderMediaType(headers http.Header, name string) (string, error) {
mediatype, _, err := mime.ParseMediaType(headers.Get(name))
return mediatype, err
}