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 |