Skip to content

Commit

Permalink
Refactor listener and server code
Browse files Browse the repository at this point in the history
Create a common function to create a listening socket which supports TLS
from a CertSource and the PROXY protocol which can then be used for all
TCP based servers.

Pronounce the difference between listeners which hold the socket for
incoming connections, servers which manage connections and configuration
and handlers which handle individual requests.

Introduce a separate TCP server which is similar to the HTTP server and
unify the ListenAndServe code across both servers. This allows using
both the TCP and HTTP server to be used for (test-)servers and proxy
servers depending on the handler they use.

Drop the custom graceful shutdown logic in favor of the context based
shutdown introduced with Go 1.8. This makes Go 1.8 the minimum
requirement.

Drop the legacy and unused websocket handler which uses
golang.org/x/net/websocket.

Move the server and listening code into the proxy package. The HTTP
related code remains under the proxy package instead of an http package
to avoid naming conflicts with the standard http library. Instead, the
files are prefixed with http_.
  • Loading branch information
magiconair committed Mar 23, 2017
1 parent d1021b3 commit 726eb51
Show file tree
Hide file tree
Showing 16 changed files with 409 additions and 302 deletions.
16 changes: 0 additions & 16 deletions exit/shutdown.go

This file was deleted.

148 changes: 0 additions & 148 deletions listen.go

This file was deleted.

47 changes: 32 additions & 15 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@ import (
"runtime/debug"
"strings"
"sync"
"sync/atomic"
"time"

"github.com/eBay/fabio/admin"
"github.com/eBay/fabio/config"
"github.com/eBay/fabio/exit"
"github.com/eBay/fabio/metrics"
"github.com/eBay/fabio/proxy"
"github.com/eBay/fabio/proxy/tcp"
"github.com/eBay/fabio/registry"
"github.com/eBay/fabio/registry/consul"
"github.com/eBay/fabio/registry/file"
Expand All @@ -37,6 +39,8 @@ import (
// script to ensure the correct version nubmer
var version = "1.3.8"

var shuttingDown int32

func main() {
cfg, err := config.Load(os.Args, os.Environ())
if err != nil {
Expand All @@ -52,7 +56,8 @@ func main() {
log.Printf("[INFO] Go runtime is %s", runtime.Version())

exit.Listen(func(s os.Signal) {
exit.Shutdown()
atomic.StoreInt32(&shuttingDown, 1)
proxy.Shutdown(cfg.Proxy.ShutdownWait)
if registry.Default == nil {
return
}
Expand All @@ -72,14 +77,14 @@ func main() {
<-first

// create proxies after metrics since they use the metrics registry.
httpProxy := newHTTPProxy(cfg)
tcpProxy := newTCPSNIProxy(cfg)
startListeners(cfg.Listen, cfg.Proxy.ShutdownWait, httpProxy, tcpProxy)
startServers(cfg)
exit.Wait()
log.Print("[INFO] Down")
}

func newHTTPProxy(cfg *config.Config) http.Handler {
pick, match := route.Picker[cfg.Proxy.Strategy], route.Matcher[cfg.Proxy.Matcher]
pick := route.Picker[cfg.Proxy.Strategy]
match := route.Matcher[cfg.Proxy.Matcher]
log.Printf("[INFO] Using routing strategy %q", cfg.Proxy.Strategy)
log.Printf("[INFO] Using route matching %q", cfg.Proxy.Matcher)

Expand All @@ -100,23 +105,22 @@ func newHTTPProxy(cfg *config.Config) http.Handler {
}
return t
},
ShuttingDown: exit.ShuttingDown,
Requests: metrics.DefaultRegistry.GetTimer("requests"),
Noroute: metrics.DefaultRegistry.GetCounter("notfound"),
Requests: metrics.DefaultRegistry.GetTimer("requests"),
Noroute: metrics.DefaultRegistry.GetCounter("notfound"),
}
}

func newTCPSNIProxy(cfg *config.Config) *proxy.TCPSNIProxy {
return &proxy.TCPSNIProxy{
func newTCPSNIProxy(cfg *config.Config) *tcp.SNIProxy {
pick := route.Picker[cfg.Proxy.Strategy]
return &tcp.SNIProxy{
Config: cfg.Proxy,
Lookup: func(serverName string) *route.Target {
t := route.GetTable().LookupHost(serverName, route.Picker[cfg.Proxy.Strategy])
Lookup: func(host string) *route.Target {
t := route.GetTable().LookupHost(host, pick)
if t == nil {
log.Print("[WARN] No route for ", serverName)
log.Print("[WARN] No route for ", host)
}
return t
},
ShuttingDown: exit.ShuttingDown,
}
}

Expand All @@ -136,6 +140,19 @@ func startAdmin(cfg *config.Config) {
}()
}

func startServers(cfg *config.Config) {
for _, l := range cfg.Listen {
switch l.Proto {
case "http", "https":
go proxy.ListenAndServeHTTP(l, newHTTPProxy(cfg))
case "tcp+sni":
go proxy.ListenAndServeTCP(l, newTCPSNIProxy(cfg))
default:
exit.Fatal("[FATAL] Invalid protocol ", l.Proto)
}
}
}

func initMetrics(cfg *config.Config) {
if cfg.Metrics.Target == "" {
log.Printf("[INFO] Metrics disabled")
Expand Down Expand Up @@ -195,7 +212,7 @@ func initBackend(cfg *config.Config) {
}

time.Sleep(cfg.Registry.Retry)
if exit.ShuttingDown() {
if atomic.LoadInt32(&shuttingDown) > 0 {
exit.Exit(1)
}
}
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
13 changes: 0 additions & 13 deletions proxy/proxy.go → proxy/http_proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,6 @@ type HTTPProxy struct {
// The proxy will panic if this value is nil.
Lookup func(*http.Request) *route.Target

// ShuttingDown returns true if the server should no longer
// handle new requests. ShuttingDown can be nil which is equivalent
// to a function that returns always false.
ShuttingDown func() bool

// Requests is a timer metric which is updated for every request.
Requests metrics.Timer

Expand All @@ -38,11 +33,6 @@ type HTTPProxy struct {
}

func (p *HTTPProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if p.ShuttingDown != nil && p.ShuttingDown() {
http.Error(w, "shutting down", http.StatusServiceUnavailable)
return
}

if p.Lookup == nil {
panic("no lookup function")
}
Expand Down Expand Up @@ -76,9 +66,6 @@ func (p *HTTPProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
case upgrade == "websocket" || upgrade == "Websocket":
h = newRawProxy(t.URL)

// To use the filtered proxy use
// h = newWSProxy(t.URL)

case accept == "text/event-stream":
// use the flush interval for SSE (server-sent events)
// must be > 0s to be effective
Expand Down
File renamed without changes.
Loading

0 comments on commit 726eb51

Please sign in to comment.