diff --git a/go.mod b/go.mod index 612118c..5c01ae4 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,3 @@ module github.com/darren/pacroxy -require github.com/darren/gpac v0.0.0-20190205064832-63757178eeaa +require github.com/darren/gpac v0.0.0-20190205154740-ac48ff1eaf41 diff --git a/go.sum b/go.sum index 510639d..eea16b1 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ github.com/darren/gpac v0.0.0-20190205064832-63757178eeaa h1:vjvetKH0/jVzRp+/8TA2cc/7NW5Md19v/VPabcx0THs= github.com/darren/gpac v0.0.0-20190205064832-63757178eeaa/go.mod h1:fK76ZiaaM0f4rW2A3sTomlo/wlY9jRV07KJ66DbOAXs= +github.com/darren/gpac v0.0.0-20190205154740-ac48ff1eaf41 h1:xkADc3wb+Zb9diEuPy+Ib3DEJ0GzMDKuQDm370m/cxw= +github.com/darren/gpac v0.0.0-20190205154740-ac48ff1eaf41/go.mod h1:fK76ZiaaM0f4rW2A3sTomlo/wlY9jRV07KJ66DbOAXs= github.com/robertkrimen/otto v0.0.0-20180617131154-15f95af6e78d h1:1VUlQbCfkoSGv7qP7Y+ro3ap1P1pPZxgdGVqiTVy5C4= github.com/robertkrimen/otto v0.0.0-20180617131154-15f95af6e78d/go.mod h1:xvqspoSXJTIpemEonrMDFq6XzwHYYgToXWj5eRX1OtY= gopkg.in/sourcemap.v1 v1.0.5 h1:inv58fC9f9J3TK2Y2R1NPntXEn3/wjWHkonhIUODNTI= diff --git a/main.go b/main.go index 34e838a..0b419da 100644 --- a/main.go +++ b/main.go @@ -9,17 +9,24 @@ import ( "net" "net/http" "strings" + "sync" + "time" "github.com/darren/gpac" ) var pacfile = flag.String("p", "wpad.dat", "pac file to load") var addr = flag.String("l", "127.0.0.1:8080", "Listening address") +var refresh = flag.Duration("r", 0, "Time duration to refresh pac file") // Server the proxy server type Server struct { http.Server - pac *gpac.Parser + sync.Mutex + + pacfile string + pac *gpac.Parser + refreshDuration time.Duration } func (s *Server) handle(w http.ResponseWriter, r *http.Request) { @@ -197,6 +204,57 @@ func (s *Server) handleHTTP(w http.ResponseWriter, req *http.Request) { http.Error(w, "No Proxy Available", http.StatusServiceUnavailable) } +func (s *Server) watch() { + for { + time.Sleep(s.refreshDuration) + log.Printf("Try reloading from %s", s.pacfile) + pac, err := gpac.From(s.pacfile) + + if pac.Source() == s.pac.Source() { + log.Println("Pac file not changed") + continue + } + + if err != nil { + log.Println("Refresh pac failed: %v", err) + } else { + log.Println("Refresh pac succeeded") + } + + s.Lock() + s.pac = pac + s.Unlock() + } +} + +// Start starts the proxy server +func (s *Server) Start() error { + log.Printf("Start proxy on %s", s.Server.Addr) + if s.refreshDuration > 0 { + log.Printf("Start pac file watcher on: %s, refresh time: %v", s.pacfile, s.refreshDuration) + go s.watch() + } + s.Handler = http.HandlerFunc(s.handle) + return s.ListenAndServe() +} + +// New create the proxy server +func New(addr string, pacf string, rintval time.Duration) (*Server, error) { + pac, err := gpac.From(pacf) + if err != nil { + return nil, err + } + + return &Server{ + Server: http.Server{ + Addr: addr, + }, + pac: pac, + pacfile: pacf, + refreshDuration: rintval, + }, nil +} + func cloneHeader(dst, src http.Header) { for k, vv := range src { for _, v := range vv { @@ -209,20 +267,10 @@ func main() { log.SetFlags(log.LstdFlags | log.Lshortfile) flag.Parse() - log.Printf("Loading pac from %s", *pacfile) - pac, err := gpac.From(*pacfile) + server, err := New(*addr, *pacfile, *refresh) if err != nil { log.Fatal(err) } - log.Printf("Start proxy on %s", *addr) - server := Server{ - Server: http.Server{ - Addr: *addr, - }, - pac: pac, - } - - server.Handler = http.HandlerFunc(server.handle) - log.Fatal(server.ListenAndServe()) + log.Fatal(server.Start()) }