From b04cc02c97d2648b3faa1fc6126c61a4eab4e15d Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Wed, 28 Jun 2017 01:39:11 +0200 Subject: added initial support for http/https connection multiplexing --- src/daq/s5proxy/Makefile | 6 ++-- src/daq/s5proxy/src/s5proxy/proxy.go | 66 +++++++++++++++++++++++++++++++----- 2 files changed, 60 insertions(+), 12 deletions(-) diff --git a/src/daq/s5proxy/Makefile b/src/daq/s5proxy/Makefile index db0c259..091717f 100644 --- a/src/daq/s5proxy/Makefile +++ b/src/daq/s5proxy/Makefile @@ -38,7 +38,7 @@ endif EXECUTEABLE := s5proxy -#LIBS := "" +LIBS := "github.com/soheilhy/cmux" .PHONY: getlibs updatelibs vet format build clean distclean @@ -46,10 +46,10 @@ all: build getlibs: -# @$(foreach lib,$(LIBS), echo "fetching lib: $(lib)"; $(GOCMD) get $(lib);) + @$(foreach lib,$(LIBS), echo "fetching lib: $(lib)"; $(GOCMD) get $(lib);) updatelibs: -# @$(foreach lib,$(LIBS), echo "updating lib: $(lib)"; $(GOCMD) get -u $(lib);) + @$(foreach lib,$(LIBS), echo "updating lib: $(lib)"; $(GOCMD) get -u $(lib);) vet: @echo "vetting: $(EXECUTEABLE)" diff --git a/src/daq/s5proxy/src/s5proxy/proxy.go b/src/daq/s5proxy/src/s5proxy/proxy.go index 6ef1742..3f5ec89 100644 --- a/src/daq/s5proxy/src/s5proxy/proxy.go +++ b/src/daq/s5proxy/src/s5proxy/proxy.go @@ -38,7 +38,10 @@ import ( "net/http" "net/http/httputil" "net/url" + "strings" "time" + + "github.com/soheilhy/cmux" ) func generateTime(input string) string { @@ -157,8 +160,43 @@ func NewProxy(conf *Config, stats *Stats) (p *Proxy, err error) { proxyHandler(p, w, r) }) + p.srv = &http.Server{ + Handler: p.mux, + } + return +} + +type httpsRedirectHandler struct { + code int +} + +func (h *httpsRedirectHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + uri := *r.URL + uri.Scheme = "https" + uri.Host = r.Host + http.Redirect(w, r, uri.String(), h.code) +} + +func (p *Proxy) RunHTTP(l net.Listener) error { + mux := http.NewServeMux() + mux.Handle("/", &httpsRedirectHandler{http.StatusTemporaryRedirect}) // TODO: make redirect code configurable + + srv := &http.Server{ + Handler: mux, + } + + return srv.Serve(l) +} + +func (p *Proxy) RunHTTPS(l net.Listener) error { + cert, err := tls.LoadX509KeyPair(p.conf.CertFile, p.conf.KeyFile) + if err != nil { + return err + } + // TODO: make this configurable cfg := &tls.Config{ + Certificates: []tls.Certificate{cert}, MinVersion: tls.VersionTLS10, CurvePreferences: []tls.CurveID{tls.CurveP521, tls.CurveP384, tls.CurveP256}, PreferServerCipherSuites: true, @@ -170,16 +208,26 @@ func NewProxy(conf *Config, stats *Stats) (p *Proxy, err error) { }, } - p.srv = &http.Server{ - Addr: conf.ListenAddr, - Handler: p.mux, - TLSConfig: cfg, - TLSNextProto: make(map[string]func(*http.Server, *tls.Conn, http.Handler), 0), - } - return + tlsL := tls.NewListener(l, cfg) + return p.srv.Serve(tlsL) } func (p *Proxy) Run() error { - s5l.Printf("PROXY: listening on '%s'", p.srv.Addr) - return p.srv.ListenAndServeTLS(p.conf.CertFile, p.conf.KeyFile) + s5l.Printf("PROXY: listening on '%s'", p.conf.ListenAddr) + + l, err := net.Listen("tcp", p.conf.ListenAddr) + if err != nil { + return err + } + m := cmux.New(l) + httpL := m.Match(cmux.HTTP1Fast()) + httpsL := m.Match(cmux.Any()) + + go p.RunHTTP(httpL) + go p.RunHTTPS(httpsL) + + if err := m.Serve(); !strings.Contains(err.Error(), "use of closed network connection") { + return err + } + return nil } -- cgit v1.2.3