1
0
Fork 0

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

@ -22,18 +22,18 @@ func ParseAuthHeader(header string) (*BasicAuth, error) {
return nil, fmt.Errorf(fmt.Sprintf("Failed to parse header '%s'", header))
}
auth_type := strings.ToLower(values[0])
if auth_type != "basic" {
return nil, fmt.Errorf("Expected basic auth type, got '%s'", auth_type)
authType := strings.ToLower(values[0])
if authType != "basic" {
return nil, fmt.Errorf("Expected basic auth type, got '%s'", authType)
}
encoded_string := values[1]
decoded_string, err := base64.StdEncoding.DecodeString(encoded_string)
encodedString := values[1]
decodedString, err := base64.StdEncoding.DecodeString(encodedString)
if err != nil {
return nil, fmt.Errorf("Failed to parse header '%s', base64 failed: %s", header, err)
}
values = strings.SplitN(string(decoded_string), ":", 2)
values = strings.SplitN(string(decodedString), ":", 2)
if len(values) != 2 {
return nil, fmt.Errorf("Failed to parse header '%s', expected separator ':'", header)
}

60
vendor/github.com/vulcand/oxy/utils/dumpreq.go generated vendored Normal file
View file

@ -0,0 +1,60 @@
package utils
import (
"crypto/tls"
"encoding/json"
"fmt"
"mime/multipart"
"net/http"
"net/url"
)
type SerializableHttpRequest struct {
Method string
URL *url.URL
Proto string // "HTTP/1.0"
ProtoMajor int // 1
ProtoMinor int // 0
Header http.Header
ContentLength int64
TransferEncoding []string
Host string
Form url.Values
PostForm url.Values
MultipartForm *multipart.Form
Trailer http.Header
RemoteAddr string
RequestURI string
TLS *tls.ConnectionState
}
func Clone(r *http.Request) *SerializableHttpRequest {
if r == nil {
return nil
}
rc := new(SerializableHttpRequest)
rc.Method = r.Method
rc.URL = r.URL
rc.Proto = r.Proto
rc.ProtoMajor = r.ProtoMajor
rc.ProtoMinor = r.ProtoMinor
rc.Header = r.Header
rc.ContentLength = r.ContentLength
rc.Host = r.Host
rc.RemoteAddr = r.RemoteAddr
rc.RequestURI = r.RequestURI
return rc
}
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)
}
}
func DumpHttpRequest(req *http.Request) string {
return fmt.Sprintf("%v", Clone(req).ToJson())
}

View file

@ -1,86 +0,0 @@
package utils
import (
"io"
"log"
)
var NullLogger Logger = &NOPLogger{}
// Logger defines a simple logging interface
type Logger interface {
Infof(format string, args ...interface{})
Warningf(format string, args ...interface{})
Errorf(format string, args ...interface{})
}
type FileLogger struct {
info *log.Logger
warn *log.Logger
error *log.Logger
}
func NewFileLogger(w io.Writer, lvl LogLevel) *FileLogger {
l := &FileLogger{}
flag := log.Ldate | log.Ltime | log.Lmicroseconds
if lvl <= INFO {
l.info = log.New(w, "INFO: ", flag)
}
if lvl <= WARN {
l.warn = log.New(w, "WARN: ", flag)
}
if lvl <= ERROR {
l.error = log.New(w, "ERR: ", flag)
}
return l
}
func (f *FileLogger) Infof(format string, args ...interface{}) {
if f.info == nil {
return
}
f.info.Printf(format, args...)
}
func (f *FileLogger) Warningf(format string, args ...interface{}) {
if f.warn == nil {
return
}
f.warn.Printf(format, args...)
}
func (f *FileLogger) Errorf(format string, args ...interface{}) {
if f.error == nil {
return
}
f.error.Printf(format, args...)
}
type NOPLogger struct {
}
func (*NOPLogger) Infof(format string, args ...interface{}) {
}
func (*NOPLogger) Warningf(format string, args ...interface{}) {
}
func (*NOPLogger) Errorf(format string, args ...interface{}) {
}
func (*NOPLogger) Info(string) {
}
func (*NOPLogger) Warning(string) {
}
func (*NOPLogger) Error(string) {
}
type LogLevel int
const (
INFO = iota
WARN
ERROR
)

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
}