diff --git a/.gitignore b/.gitignore index 190fab662..03aa43689 100644 --- a/.gitignore +++ b/.gitignore @@ -7,5 +7,4 @@ traefik traefik.toml *.test vendor/ -static/ -glide.lock \ No newline at end of file +static/ \ No newline at end of file diff --git a/build.Dockerfile b/build.Dockerfile index 6cedd3b85..5711a8778 100644 --- a/build.Dockerfile +++ b/build.Dockerfile @@ -24,6 +24,7 @@ RUN ln -s /usr/local/bin/docker-${DOCKER_VERSION} /usr/local/bin/docker WORKDIR /go/src/github.com/containous/traefik COPY glide.yaml glide.yaml -RUN glide up --quick +COPY glide.lock glide.lock +RUN glide install COPY . /go/src/github.com/containous/traefik diff --git a/glide.lock b/glide.lock new file mode 100644 index 000000000..a74d445ea --- /dev/null +++ b/glide.lock @@ -0,0 +1,256 @@ +hash: 2a18c9cab231b5e108c666641c2436da3d9a1a0d9d1c586948af94271a47b317 +updated: 2016-03-15T23:01:22.853471291+01:00 +imports: +- name: github.com/alecthomas/template + version: b867cc6ab45cece8143cfcc6fc9c77cf3f2c23c0 +- name: github.com/alecthomas/units + version: 6b4e7dc5e3143b85ea77909c72caf89416fc2915 +- name: github.com/boltdb/bolt + version: 51f99c862475898df9773747d3accd05a7ca33c1 +- name: github.com/BurntSushi/toml + version: bd2bdf7f18f849530ef7a1c29a4290217cab32a1 +- name: github.com/BurntSushi/ty + version: 6add9cd6ad42d389d6ead1dde60b4ad71e46fd74 + subpackages: + - fun +- name: github.com/cenkalti/backoff + version: 4dc77674aceaabba2c7e3da25d4c823edfb73f99 +- name: github.com/codahale/hdrhistogram + version: 954f16e8b9ef0e5d5189456aa4c1202758e04f17 +- name: github.com/codegangsta/cli + version: bf4a526f48af7badd25d2cb02d587e1b01be3b50 +- name: github.com/codegangsta/negroni + version: c7477ad8e330bef55bf1ebe300cf8aa67c492d1b +- name: github.com/containous/oxy + version: 0b5b371bce661385d35439204298fa6fb5db5463 + subpackages: + - cbreaker + - forward + - memmetrics + - roundrobin + - utils +- name: github.com/coreos/go-etcd + version: cc90c7b091275e606ad0ca7102a23fb2072f3f5e + subpackages: + - etcd +- name: github.com/davecgh/go-spew + version: 5215b55f46b2b919f50a1df0eaa5886afe4e3b3d + subpackages: + - spew +- name: github.com/docker/distribution + version: 9038e48c3b982f8e82281ea486f078a73731ac4e +- name: github.com/docker/docker + version: f39987afe8d611407887b3094c03d6ba6a766a67 + subpackages: + - autogen + - api + - cliconfig + - daemon/network + - graph/tags + - image + - opts + - pkg/archive + - pkg/fileutils + - pkg/homedir + - pkg/httputils + - pkg/ioutils + - pkg/jsonmessage + - pkg/mflag + - pkg/nat + - pkg/parsers + - pkg/pools + - pkg/promise + - pkg/random + - pkg/stdcopy + - pkg/stringid + - pkg/symlink + - pkg/system + - pkg/tarsum + - pkg/term + - pkg/timeutils + - pkg/tlsconfig + - pkg/ulimit + - pkg/units + - pkg/urlutil + - pkg/useragent + - pkg/version + - registry + - runconfig + - utils + - volume +- name: github.com/docker/libcompose + version: d3089811c119a211469a9cc93caea684d937e5d3 + subpackages: + - docker + - logger + - lookup + - project + - utils +- name: github.com/docker/libkv + version: 3732f7ff1b56057c3158f10bceb1e79133025373 + subpackages: + - store + - store/boltdb + - store/consul + - store/etcd + - store/zookeeper +- name: github.com/docker/libtrust + version: 9cbd2a1374f46905c68a4eb3694a130610adc62a +- name: github.com/donovanhide/eventsource + version: d8a3071799b98cacd30b6da92f536050ccfe6da4 +- name: github.com/elazarl/go-bindata-assetfs + version: d5cac425555ca5cf00694df246e04f05e6a55150 +- name: github.com/flynn/go-shlex + version: 3f9db97f856818214da2e1057f8ad84803971cff +- name: github.com/fsouza/go-dockerclient + version: a49c8269a6899cae30da1f8a4b82e0ce945f9967 + subpackages: + - external/github.com/docker/docker/opts + - external/github.com/docker/docker/pkg/archive + - external/github.com/docker/docker/pkg/fileutils + - external/github.com/docker/docker/pkg/homedir + - external/github.com/docker/docker/pkg/stdcopy + - external/github.com/hashicorp/go-cleanhttp + - external/github.com/Sirupsen/logrus + - external/github.com/docker/docker/pkg/idtools + - external/github.com/docker/docker/pkg/ioutils + - external/github.com/docker/docker/pkg/pools + - external/github.com/docker/docker/pkg/promise + - external/github.com/docker/docker/pkg/system + - external/github.com/docker/docker/pkg/longpath + - external/github.com/opencontainers/runc/libcontainer/user + - external/golang.org/x/sys/unix + - external/golang.org/x/net/context + - external/github.com/docker/go-units +- name: github.com/gambol99/go-marathon + version: ade11d1dc2884ee1f387078fc28509559b6235d1 +- name: github.com/golang/glog + version: fca8c8854093a154ff1eb580aae10276ad6b1b5f +- name: github.com/google/go-querystring + version: 6bb77fe6f42b85397288d4f6f67ac72f8f400ee7 + subpackages: + - query +- name: github.com/gorilla/context + version: 215affda49addc4c8ef7e2534915df2c8c35c6cd +- name: github.com/gorilla/handlers + version: 40694b40f4a928c062f56849989d3e9cd0570e5f +- name: github.com/gorilla/mux + version: f15e0c49460fd49eebe2bcc8486b05d1bef68d3a +- name: github.com/gorilla/websocket + version: e2e3d8414d0fbae04004f151979f4e27c6747fe7 +- name: github.com/hashicorp/consul + version: de080672fee9e6104572eeea89eccdca135bb918 + subpackages: + - api +- name: github.com/hashicorp/hcl + version: 567a5d1c4878a4ac8c198c730fd15f978b0529c7 + subpackages: + - hcl/ast + - hcl/parser + - hcl/token + - json/parser + - hcl/scanner + - hcl/strconv + - json/scanner + - json/token +- name: github.com/inconshreveable/mousetrap + version: 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75 +- name: github.com/kr/pretty + version: e6ac2fc51e89a3249e82157fa0bb7a18ef9dd5bb +- name: github.com/kr/text + version: bb797dc4fb8320488f47bf11de07a733d7233e1f +- name: github.com/magiconair/properties + version: 497d0afefddf378f9ffb3c89db6a326985908519 +- name: github.com/mailgun/log + version: 44874009257d4d47ba9806f1b7f72a32a015e4d8 +- name: github.com/mailgun/manners + version: fada45142db3f93097ca917da107aa3fad0ffcb5 +- name: github.com/mailgun/oxy + version: 8aaf36279137ac04ace3792a4f86098631b27d5a + subpackages: + - cbreaker +- name: github.com/mailgun/predicate + version: cb0bff91a7ab7cf7571e661ff883fc997bc554a3 +- name: github.com/mailgun/timetools + version: fd192d755b00c968d312d23f521eb0cdc6f66bd0 +- name: github.com/mitchellh/mapstructure + version: d2dd0262208475919e1a362f675cfc0e7c10e905 +- name: github.com/opencontainers/runc + version: 4ab132458fc3e9dbeea624153e0331952dc4c8d5 + subpackages: + - libcontainer/user +- name: github.com/pmezard/go-difflib + version: d8ed2627bdf02c080bf22230dbb337003b7aba2d + subpackages: + - difflib +- name: github.com/samalba/dockerclient + version: cfb489c624b635251a93e74e1e90eb0959c5367f +- name: github.com/samuel/go-zookeeper + version: fa6674abf3f4580b946a01bf7a1ce4ba8766205b + subpackages: + - zk +- name: github.com/Sirupsen/logrus + version: 418b41d23a1bf978c06faea5313ba194650ac088 +- name: github.com/spf13/cast + version: ee7b3e0353166ab1f3a605294ac8cd2b77953778 +- name: github.com/spf13/cobra + version: 1bacefc9a216c93293e670067bd159a64b4d72c3 + subpackages: + - cobra +- name: github.com/spf13/jwalterweatherman + version: 33c24e77fb80341fe7130ee7c594256ff08ccc46 +- name: github.com/spf13/pflag + version: 7f60f83a2c81bc3c3c0d5297f61ddfa68da9d3b7 +- name: github.com/spf13/viper + version: a212099cbe6fbe8d07476bfda8d2d39b6ff8f325 +- name: github.com/stretchr/objx + version: cbeaeb16a013161a98496fad62933b1d21786672 +- name: github.com/stretchr/testify + version: 6fe211e493929a8aac0469b93f28b1d0688a9a3a + subpackages: + - mock + - assert +- name: github.com/thoas/stats + version: 54ed61c2b47e263ae2f01b86837b0c4bd1da28e8 +- name: github.com/unrolled/render + version: 26b4e3aac686940fe29521545afad9966ddfc80c +- name: github.com/vdemeester/shakers + version: 8fe734f75f3a70b651cbfbf8a55a009da09e8dc5 +- name: github.com/vulcand/oxy + version: 8aaf36279137ac04ace3792a4f86098631b27d5a + subpackages: + - memmetrics + - utils +- name: github.com/vulcand/predicate + version: cb0bff91a7ab7cf7571e661ff883fc997bc554a3 +- name: github.com/vulcand/route + version: cb89d787ddbb1c5849a7ac9f79004c1fd12a4a32 +- name: github.com/vulcand/vulcand + version: 475540bb016702d5b7cc4674e37f48ee3e144a69 + subpackages: + - plugin/rewrite + - plugin + - router +- name: github.com/wendal/errors + version: f66c77a7882b399795a8987ebf87ef64a427417e +- name: golang.org/x/net + version: d9558e5c97f85372afee28cf2b6059d7d3818919 + subpackages: + - context +- name: golang.org/x/sys + version: eb2c74142fd19a79b3f237334c7384d5167b1b46 + subpackages: + - unix +- name: gopkg.in/alecthomas/kingpin.v2 + version: 639879d6110b1b0409410c7b737ef0bb18325038 +- name: gopkg.in/check.v1 + version: 11d3bc7aa68e238947792f30573146a3231fc0f1 +- name: gopkg.in/fsnotify.v1 + version: 96c060f6a6b7e0d6f75fddd10efeaca3e5d1bcb0 +- name: gopkg.in/mgo.v2 + version: 22287bab4379e1fbf6002fb4eb769888f3fb224c + subpackages: + - bson +- name: gopkg.in/yaml.v2 + version: 7ad95dd0798a40da1ccdff6dff35fd177b5edf40 +devImports: [] diff --git a/glide.yaml b/glide.yaml index 91fa94889..caa66c296 100644 --- a/glide.yaml +++ b/glide.yaml @@ -8,8 +8,8 @@ import: ref: 9038e48c3b982f8e82281ea486f078a73731ac4e - package: github.com/mailgun/log ref: 44874009257d4d47ba9806f1b7f72a32a015e4d8 - - package: github.com/mailgun/oxy - ref: 547c334d658398c05b346c0b79d8f47ba2e1473b + - package: github.com/containous/oxy + ref: 0b5b371bce661385d35439204298fa6fb5db5463 subpackages: - cbreaker - forward diff --git a/middlewares/cbreaker.go b/middlewares/cbreaker.go index 7a059809b..6b875aa52 100644 --- a/middlewares/cbreaker.go +++ b/middlewares/cbreaker.go @@ -3,7 +3,7 @@ package middlewares import ( "net/http" - "github.com/mailgun/oxy/cbreaker" + "github.com/containous/oxy/cbreaker" ) // CircuitBreaker holds the oxy circuit breaker. diff --git a/middlewares/websocket.go b/middlewares/websocket.go deleted file mode 100644 index 6dfff2f01..000000000 --- a/middlewares/websocket.go +++ /dev/null @@ -1,52 +0,0 @@ -package middlewares - -import ( - "net/http" - "strings" - "time" - - log "github.com/Sirupsen/logrus" - "github.com/mailgun/oxy/roundrobin" -) - -// WebsocketUpgrader holds Websocket configuration. -type WebsocketUpgrader struct { - rr *roundrobin.RoundRobin -} - -// NewWebsocketUpgrader returns a new WebsocketUpgrader. -func NewWebsocketUpgrader(rr *roundrobin.RoundRobin) *WebsocketUpgrader { - wu := WebsocketUpgrader{ - rr: rr, - } - return &wu -} - -func (u *WebsocketUpgrader) ServeHTTP(w http.ResponseWriter, req *http.Request) { - // If request is websocket, serve with golang websocket server to do protocol handshake - if strings.Join(req.Header["Upgrade"], "") == "websocket" { - start := time.Now().UTC() - url, err := u.rr.NextServer() - if err != nil { - log.Errorf("Can't round robin in websocket middleware") - return - } - log.Debugf("Websocket forward to %s", url.String()) - NewProxy(url).ServeHTTP(w, req) - - if req.TLS != nil { - log.Debugf("Round trip: %v, duration: %v tls:version: %x, tls:resume:%t, tls:csuite:%x, tls:server:%v", - req.URL, time.Now().UTC().Sub(start), - req.TLS.Version, - req.TLS.DidResume, - req.TLS.CipherSuite, - req.TLS.ServerName) - } else { - log.Debugf("Round trip: %v, duration: %v", - req.URL, time.Now().UTC().Sub(start)) - } - - return - } - u.rr.ServeHTTP(w, req) -} diff --git a/middlewares/websocketproxy.go b/middlewares/websocketproxy.go deleted file mode 100644 index ebec3ea61..000000000 --- a/middlewares/websocketproxy.go +++ /dev/null @@ -1,179 +0,0 @@ -package middlewares - -import ( - "io" - "net" - "net/http" - "net/url" - "strings" - - log "github.com/Sirupsen/logrus" - "github.com/gorilla/websocket" -) - -// Original developpement made by https://github.com/koding/websocketproxy -var ( - // DefaultUpgrader specifies the parameters for upgrading an HTTP - // connection to a WebSocket connection. - DefaultUpgrader = &websocket.Upgrader{ - ReadBufferSize: 1024, - WriteBufferSize: 1024, - } - - // DefaultDialer is a dialer with all fields set to the default zero values. - DefaultDialer = websocket.DefaultDialer -) - -// WebsocketProxy is an HTTP Handler that takes an incoming WebSocket -// connection and proxies it to another server. -type WebsocketProxy struct { - // Backend returns the backend URL which the proxy uses to reverse proxy - // the incoming WebSocket connection. Request is the initial incoming and - // unmodified request. - Backend func(*http.Request) *url.URL - - // Upgrader specifies the parameters for upgrading a incoming HTTP - // connection to a WebSocket connection. If nil, DefaultUpgrader is used. - Upgrader *websocket.Upgrader - - // Dialer contains options for connecting to the backend WebSocket server. - // If nil, DefaultDialer is used. - Dialer *websocket.Dialer -} - -// ProxyHandler returns a new http.Handler interface that reverse proxies the -// request to the given target. -func ProxyHandler(target *url.URL) http.Handler { - return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { - NewProxy(target).ServeHTTP(rw, req) - }) -} - -// NewProxy returns a new Websocket reverse proxy that rewrites the -// URL's to the scheme, host and base path provider in target. -func NewProxy(target *url.URL) *WebsocketProxy { - backend := func(r *http.Request) *url.URL { - // Shallow copy - u := *target - u.Fragment = r.URL.Fragment - u.Path = r.URL.Path - u.RawQuery = r.URL.RawQuery - rurl := u.String() - if strings.HasPrefix(rurl, "http") { - u.Scheme = "ws" - } - if strings.HasPrefix(rurl, "https") { - u.Scheme = "wss" - } - return &u - } - return &WebsocketProxy{Backend: backend} -} - -// ServeHTTP implements the http.Handler that proxies WebSocket connections. -func (w *WebsocketProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) { - if w.Backend == nil { - log.Errorf("Websocketproxy: backend function is not defined") - http.Error(rw, "Backend not found", http.StatusInternalServerError) - http.NotFound(rw, req) - return - } - - backendURL := w.Backend(req) - if backendURL == nil { - log.Errorf("Websocketproxy: backend URL is nil") - http.Error(rw, "Backend URL is nil", http.StatusInternalServerError) - return - } - - dialer := w.Dialer - if w.Dialer == nil { - dialer = DefaultDialer - } - - // Pass headers from the incoming request to the dialer to forward them to - // the final destinations. - requestHeader := http.Header{} - requestHeader.Add("Origin", req.Header.Get("Origin")) - for _, prot := range req.Header[http.CanonicalHeaderKey("Sec-WebSocket-Protocol")] { - requestHeader.Add("Sec-WebSocket-Protocol", prot) - } - for _, cookie := range req.Header[http.CanonicalHeaderKey("Cookie")] { - requestHeader.Add("Cookie", cookie) - } - for _, auth := range req.Header[http.CanonicalHeaderKey("Authorization")] { - requestHeader.Add("Authorization", auth) - } - - // Pass X-Forwarded-For headers too, code below is a part of - // httputil.ReverseProxy. See http://en.wikipedia.org/wiki/X-Forwarded-For - // for more information - // TODO: use RFC7239 http://tools.ietf.org/html/rfc7239 - if clientIP, _, err := net.SplitHostPort(req.RemoteAddr); err == nil { - // If we aren't the first proxy retain prior - // X-Forwarded-For information as a comma+space - // separated list and fold multiple headers into one. - if prior, ok := req.Header["X-Forwarded-For"]; ok { - clientIP = strings.Join(prior, ", ") + ", " + clientIP - } - requestHeader.Set("X-Forwarded-For", clientIP) - } - - // Set the originating protocol of the incoming HTTP request. The SSL might - // be terminated on our site and because we doing proxy adding this would - // be helpful for applications on the backend. - requestHeader.Set("X-Forwarded-Proto", "http") - if req.TLS != nil { - requestHeader.Set("X-Forwarded-Proto", "https") - } - - //frontend Origin != backend Origin - requestHeader.Del("Origin") - - // Connect to the backend URL, also pass the headers we get from the requst - // together with the Forwarded headers we prepared above. - // TODO: support multiplexing on the same backend connection instead of - // opening a new TCP connection time for each request. This should be - // optional: - // http://tools.ietf.org/html/draft-ietf-hybi-websocket-multiplexing-01 - connBackend, resp, err := dialer.Dial(backendURL.String(), requestHeader) - if err != nil { - log.Errorf("Websocketproxy: couldn't dial to remote backend url %s, %s, %+v", backendURL.String(), err, resp) - http.Error(rw, "Remote backend unreachable", http.StatusBadGateway) - return - } - defer connBackend.Close() - - upgrader := w.Upgrader - if w.Upgrader == nil { - upgrader = DefaultUpgrader - } - - // Only pass those headers to the upgrader. - upgradeHeader := http.Header{} - upgradeHeader.Set("Sec-WebSocket-Protocol", - resp.Header.Get(http.CanonicalHeaderKey("Sec-WebSocket-Protocol"))) - upgradeHeader.Set("Set-Cookie", - resp.Header.Get(http.CanonicalHeaderKey("Set-Cookie"))) - - // Now upgrade the existing incoming request to a WebSocket connection. - // Also pass the header that we gathered from the Dial handshake. - connPub, err := upgrader.Upgrade(rw, req, upgradeHeader) - if err != nil { - log.Errorf("Websocketproxy: couldn't upgrade %s", err) - http.NotFound(rw, req) - return - } - defer connPub.Close() - - errc := make(chan error, 2) - cp := func(dst io.Writer, src io.Reader) { - _, err := io.Copy(dst, src) - errc <- err - } - - // Start our proxy now, everything is ready... - go cp(connBackend.UnderlyingConn(), connPub.UnderlyingConn()) - go cp(connPub.UnderlyingConn(), connBackend.UnderlyingConn()) - <-errc -} diff --git a/server.go b/server.go index 863810f14..a85eccbde 100644 --- a/server.go +++ b/server.go @@ -20,14 +20,14 @@ import ( log "github.com/Sirupsen/logrus" "github.com/codegangsta/negroni" + "github.com/containous/oxy/cbreaker" + "github.com/containous/oxy/forward" + "github.com/containous/oxy/roundrobin" "github.com/containous/traefik/middlewares" "github.com/containous/traefik/provider" "github.com/containous/traefik/types" "github.com/gorilla/mux" "github.com/mailgun/manners" - "github.com/mailgun/oxy/cbreaker" - "github.com/mailgun/oxy/forward" - "github.com/mailgun/oxy/roundrobin" ) var oxyLogger = &OxyLogger{} @@ -379,7 +379,7 @@ func (server *Server) loadConfig(configurations configs, globalConfiguration Glo } case types.Wrr: log.Debugf("Creating load-balancer wrr") - lb = middlewares.NewWebsocketUpgrader(rr) + lb = rr for serverName, server := range configuration.Backends[frontend.Backend].Servers { url, err := url.Parse(server.URL) if err != nil {