pip compatible server to serve Python packages out of GitHub
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

107 lines
3.2 KiB

/*
Package graceful implements graceful shutdown for HTTP servers by closing idle
connections after receiving a signal. By default, this package listens for
interrupts (i.e., SIGINT), but when it detects that it is running under Einhorn
it will additionally listen for SIGUSR2 as well, giving your application
automatic support for graceful restarts/code upgrades.
*/
package graceful
import (
"crypto/tls"
"net"
"net/http"
"github.com/zenazn/goji/graceful/listener"
)
// Most of the code here is lifted straight from net/http
// Type Server is exactly the same as an http.Server, but provides more graceful
// implementations of its methods.
type Server http.Server
func (srv *Server) ListenAndServe() error {
addr := srv.Addr
if addr == "" {
addr = ":http"
}
l, e := net.Listen("tcp", addr)
if e != nil {
return e
}
return srv.Serve(l)
}
// Unlike the method of the same name on http.Server, this function defaults to
// enforcing TLS 1.0 or higher in order to address the POODLE vulnerability.
// Users who wish to enable SSLv3 must do so by supplying a TLSConfig
// explicitly.
func (srv *Server) ListenAndServeTLS(certFile, keyFile string) error {
addr := srv.Addr
if addr == "" {
addr = ":https"
}
config := &tls.Config{
MinVersion: tls.VersionTLS10,
}
if srv.TLSConfig != nil {
*config = *srv.TLSConfig
}
if config.NextProtos == nil {
config.NextProtos = []string{"http/1.1"}
}
var err error
config.Certificates = make([]tls.Certificate, 1)
config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
if err != nil {
return err
}
conn, err := net.Listen("tcp", addr)
if err != nil {
return err
}
tlsListener := tls.NewListener(conn, config)
return srv.Serve(tlsListener)
}
// ListenAndServe behaves exactly like the net/http function of the same name.
func ListenAndServe(addr string, handler http.Handler) error {
server := &Server{Addr: addr, Handler: handler}
return server.ListenAndServe()
}
// ListenAndServeTLS behaves almost exactly like the net/http function of the
// same name. Unlike net/http, however, this function defaults to enforcing TLS
// 1.0 or higher in order to address the POODLE vulnerability. Users who wish to
// enable SSLv3 must do so by explicitly instantiating a server with an
// appropriately configured TLSConfig property.
func ListenAndServeTLS(addr, certfile, keyfile string, handler http.Handler) error {
server := &Server{Addr: addr, Handler: handler}
return server.ListenAndServeTLS(certfile, keyfile)
}
// Serve behaves exactly like the net/http function of the same name.
func Serve(l net.Listener, handler http.Handler) error {
server := &Server{Handler: handler}
return server.Serve(l)
}
// WrapListener wraps an arbitrary net.Listener for use with graceful shutdowns.
// In the background, it uses the listener sub-package to Wrap the listener in
// Deadline mode. If another mode of operation is desired, you should call
// listener.Wrap yourself: this function is smart enough to not double-wrap
// listeners.
func WrapListener(l net.Listener) net.Listener {
if lt, ok := l.(*listener.T); ok {
appendListener(lt)
return lt
}
lt := listener.Wrap(l, listener.Deadline)
appendListener(lt)
return lt
}