diff options
Diffstat (limited to 'src/daq/s5proxy/src/s5proxy/proxy.go')
-rw-r--r-- | src/daq/s5proxy/src/s5proxy/proxy.go | 66 |
1 files changed, 57 insertions, 9 deletions
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 } |