2760: Merge branch '2760-folder-hierarchy' refs #2760
[arvados.git] / services / keep / src / arvados.org / keepproxy / keepproxy.go
index 9e0b2ff90c29fe070ec30e3bd11f96f1038f9a87..38e14fd2832f10d01d2997b6b66dd70f02585459 100644 (file)
@@ -29,7 +29,9 @@ func main() {
                pidfile          string
        )
 
-       flag.StringVar(
+       flagset := flag.NewFlagSet("default", flag.ExitOnError)
+
+       flagset.StringVar(
                &listen,
                "listen",
                DEFAULT_ADDR,
@@ -37,35 +39,35 @@ func main() {
                        "ipaddr:port. e.g. -listen=10.0.1.24:8000. Use -listen=:port "+
                        "to listen on all network interfaces.")
 
-       flag.BoolVar(
+       flagset.BoolVar(
                &no_get,
                "no-get",
                false,
                "If set, disable GET operations")
 
-       flag.BoolVar(
-               &no_get,
+       flagset.BoolVar(
+               &no_put,
                "no-put",
                false,
                "If set, disable PUT operations")
 
-       flag.IntVar(
+       flagset.IntVar(
                &default_replicas,
                "default-replicas",
                2,
                "Default number of replicas to write if not specified by the client.")
 
-       flag.StringVar(
+       flagset.StringVar(
                &pidfile,
                "pid",
                "",
                "Path to write pid file")
 
-       flag.Parse()
+       flagset.Parse(os.Args[1:])
 
        kc, err := keepclient.MakeKeepClient()
        if err != nil {
-               log.Fatal(err)
+               log.Fatalf("Error setting up keep client %s", err.Error())
        }
 
        if pidfile != "" {
@@ -87,6 +89,8 @@ func main() {
 
        go RefreshServicesList(&kc)
 
+       log.Printf("Arvados Keep proxy started listening on %v with server list %v", listener.Addr(), kc.ServiceRoots())
+
        // Start listening for requests.
        http.Serve(listener, MakeRESTRouter(!no_get, !no_put, &kc))
 }
@@ -101,7 +105,14 @@ type ApiTokenCache struct {
 func RefreshServicesList(kc *keepclient.KeepClient) {
        for {
                time.Sleep(300 * time.Second)
+               oldservices := kc.ServiceRoots()
                kc.DiscoverKeepServers()
+               newservices := kc.ServiceRoots()
+               s1 := fmt.Sprint(oldservices)
+               s2 := fmt.Sprint(newservices)
+               if s1 != s2 {
+                       log.Printf("Updated server list to %v", s2)
+               }
        }
 }
 
@@ -167,7 +178,7 @@ func CheckAuthorizationHeader(kc keepclient.KeepClient, cache *ApiTokenCache, re
 
        var usersreq *http.Request
 
-       if usersreq, err = http.NewRequest("GET", fmt.Sprintf("https://%s/arvados/v1/users/current", kc.ApiServer), nil); err != nil {
+       if usersreq, err = http.NewRequest("HEAD", fmt.Sprintf("https://%s/arvados/v1/users/current", kc.ApiServer), nil); err != nil {
                // Can't construct the request
                log.Printf("%s: CheckAuthorizationHeader error: %v", GetRemoteAddress(req), err)
                return false
@@ -206,6 +217,8 @@ type PutBlockHandler struct {
        *ApiTokenCache
 }
 
+type InvalidPathHandler struct{}
+
 // MakeRESTRouter
 //     Returns a mux.Router that passes GET and PUT requests to the
 //     appropriate handlers.
@@ -218,24 +231,31 @@ func MakeRESTRouter(
        t := &ApiTokenCache{tokens: make(map[string]int64), expireTime: 300}
 
        rest := mux.NewRouter()
-       gh := rest.Handle(`/{hash:[0-9a-f]{32}}`, GetBlockHandler{kc, t})
-       ghsig := rest.Handle(
-               `/{hash:[0-9a-f]{32}}+A{signature:[0-9a-f]+}@{timestamp:[0-9a-f]+}`,
-               GetBlockHandler{kc, t})
-       ph := rest.Handle(`/{hash:[0-9a-f]{32}}`, PutBlockHandler{kc, t})
 
        if enable_get {
+               gh := rest.Handle(`/{hash:[0-9a-f]{32}}`, GetBlockHandler{kc, t})
+               ghsig := rest.Handle(
+                       `/{hash:[0-9a-f]{32}}+A{signature:[0-9a-f]+}@{timestamp:[0-9a-f]+}`,
+                       GetBlockHandler{kc, t})
+
                gh.Methods("GET", "HEAD")
                ghsig.Methods("GET", "HEAD")
        }
 
        if enable_put {
-               ph.Methods("PUT")
+               rest.Handle(`/{hash:[0-9a-f]{32}}`, PutBlockHandler{kc, t}).Methods("PUT")
        }
 
+       rest.NotFoundHandler = InvalidPathHandler{}
+
        return rest
 }
 
+func (this InvalidPathHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
+       log.Printf("%s: %s %s unroutable", GetRemoteAddress(req), req.Method, req.URL.Path)
+       http.Error(resp, "Bad request", http.StatusBadRequest)
+}
+
 func (this GetBlockHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
 
        kc := *this.KeepClient