Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 // Package info exposes /auth/api/v1/server/info URL and allows to query it. | |
| 6 // | |
| 7 // This endpoint is used by luci services to advertise service account names | |
| 8 // they use (among other things). | |
| 9 package info | |
| 10 | |
| 11 import ( | |
| 12 "encoding/json" | |
| 13 "net/http" | |
| 14 "time" | |
| 15 | |
| 16 "github.com/julienschmidt/httprouter" | |
| 17 "golang.org/x/net/context" | |
| 18 | |
| 19 "github.com/luci/luci-go/server/auth/internal" | |
| 20 "github.com/luci/luci-go/server/middleware" | |
| 21 "github.com/luci/luci-go/server/proccache" | |
| 22 ) | |
| 23 | |
| 24 // ServiceInfo describes JSON format of /auth/api/v1/server/info response. | |
| 25 type ServiceInfo struct { | |
| 26 AppID string `json:"app_id,omitempty"` | |
| 27 AppRuntime string `json:"app_runtime,omitempty"` | |
| 28 AppVersion string `json:"app_version,omitempty"` | |
| 29 ServiceAccountName string `json:"service_account_name,omitempty"` | |
| 30 } | |
| 31 | |
| 32 type proccacheKey string | |
| 33 | |
| 34 // FetchServiceInfo fetches information about the service at given URL. | |
|
M-A Ruel
2015/11/24 13:47:59
Err, why not just do a HTTP 301 ?
Vadim Sh.
2015/11/24 19:27:29
What? Why? I don't understand.
This function will
M-A Ruel
2015/11/24 19:31:34
I mean, chromium-swarm-dev could redirect this API
| |
| 35 // | |
| 36 // Uses proccache to cache it locally for 1 hour. | |
| 37 func FetchServiceInfo(c context.Context, serviceURL string) (*ServiceInfo, error ) { | |
| 38 info, err := proccache.GetOrMake(c, proccacheKey(serviceURL), func() (in terface{}, time.Duration, error) { | |
| 39 info := &ServiceInfo{} | |
| 40 err := internal.FetchJSON(c, info, func() (*http.Request, error) { | |
| 41 return http.NewRequest("GET", serviceURL+"/auth/api/v1/s erver/info", nil) | |
| 42 }) | |
| 43 if err != nil { | |
| 44 return nil, 0, err | |
| 45 } | |
| 46 return info, time.Hour, nil | |
| 47 }) | |
| 48 if err != nil { | |
| 49 return nil, err | |
| 50 } | |
| 51 return info.(*ServiceInfo), nil | |
| 52 } | |
| 53 | |
| 54 // ServiceInfoCallback is called by /auth/api/v1/server/info handler. | |
| 55 type ServiceInfoCallback func(context.Context) (ServiceInfo, error) | |
| 56 | |
| 57 // InstallHandlers installs handler that serves info provided by the callback. | |
| 58 func InstallHandlers(r *httprouter.Router, base middleware.Base, cb ServiceInfoC allback) { | |
| 59 handler := func(c context.Context, w http.ResponseWriter, r *http.Reques t, p httprouter.Params) { | |
| 60 var response struct { | |
| 61 ServiceInfo | |
| 62 Error string `json:"error,omitempty"` | |
| 63 } | |
| 64 info, err := cb(c) | |
| 65 w.Header().Set("Content-Type", "application/json; charset=utf-8" ) | |
| 66 if err != nil { | |
| 67 w.WriteHeader(http.StatusInternalServerError) | |
| 68 response.Error = err.Error() | |
| 69 } else { | |
| 70 w.WriteHeader(http.StatusOK) | |
| 71 response.ServiceInfo = info | |
| 72 } | |
| 73 json.NewEncoder(w).Encode(response) | |
| 74 } | |
| 75 r.GET("/auth/api/v1/server/info", base(handler)) | |
| 76 } | |
| OLD | NEW |