Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(117)

Side by Side Diff: appengine/cmd/tokenserver/frontend/main.go

Issue 2043423004: Make HTTP middleware easier to use (Closed) Base URL: https://github.com/luci/luci-go@master
Patch Set: gaemiddleware: add middleware func for WithProd Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « appengine/cmd/milo/settings/themes.go ('k') | appengine/gaeauth/server/default.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The LUCI Authors. All rights reserved. 1 // Copyright 2016 The LUCI Authors. All rights reserved.
2 // Use of this source code is governed under the Apache License, Version 2.0 2 // Use of this source code is governed under the Apache License, Version 2.0
3 // that can be found in the LICENSE file. 3 // that can be found in the LICENSE file.
4 4
5 // Package frontend implements HTTP server that handles requests to default 5 // Package frontend implements HTTP server that handles requests to default
6 // module. 6 // module.
7 // 7 //
8 // It stitches together all the code. 8 // It stitches together all the code.
9 package frontend 9 package frontend
10 10
11 import ( 11 import (
12 "net/http" 12 "net/http"
13 "sync" 13 "sync"
14 14
15 "github.com/golang/protobuf/proto" 15 "github.com/golang/protobuf/proto"
16 "github.com/julienschmidt/httprouter"
17 "golang.org/x/net/context" 16 "golang.org/x/net/context"
18 "google.golang.org/grpc" 17 "google.golang.org/grpc"
19 "google.golang.org/grpc/codes" 18 "google.golang.org/grpc/codes"
20 19
21 "github.com/luci/gae/service/info" 20 "github.com/luci/gae/service/info"
22 "github.com/luci/luci-go/appengine/gaeauth/server" 21 "github.com/luci/luci-go/appengine/gaeauth/server"
23 "github.com/luci/luci-go/appengine/gaemiddleware" 22 "github.com/luci/luci-go/appengine/gaemiddleware"
24 "github.com/luci/luci-go/appengine/tsmon" 23 "github.com/luci/luci-go/appengine/tsmon"
25 "github.com/luci/luci-go/common/logging" 24 "github.com/luci/luci-go/common/logging"
26 "github.com/luci/luci-go/server/auth" 25 "github.com/luci/luci-go/server/auth"
27 "github.com/luci/luci-go/server/auth/machine" 26 "github.com/luci/luci-go/server/auth/machine"
28 "github.com/luci/luci-go/server/discovery" 27 "github.com/luci/luci-go/server/discovery"
29 "github.com/luci/luci-go/server/prpc" 28 "github.com/luci/luci-go/server/prpc"
29 "github.com/luci/luci-go/server/router"
30 30
31 "github.com/luci/luci-go/common/api/tokenserver/admin/v1" 31 "github.com/luci/luci-go/common/api/tokenserver/admin/v1"
32 "github.com/luci/luci-go/common/api/tokenserver/identity/v1" 32 "github.com/luci/luci-go/common/api/tokenserver/identity/v1"
33 "github.com/luci/luci-go/common/api/tokenserver/minter/v1" 33 "github.com/luci/luci-go/common/api/tokenserver/minter/v1"
34 34
35 "github.com/luci/luci-go/appengine/cmd/tokenserver/services/admin/certau thorities" 35 "github.com/luci/luci-go/appengine/cmd/tokenserver/services/admin/certau thorities"
36 "github.com/luci/luci-go/appengine/cmd/tokenserver/services/admin/servic eaccounts" 36 "github.com/luci/luci-go/appengine/cmd/tokenserver/services/admin/servic eaccounts"
37 "github.com/luci/luci-go/appengine/cmd/tokenserver/services/identity/ide ntityfetcher" 37 "github.com/luci/luci-go/appengine/cmd/tokenserver/services/identity/ide ntityfetcher"
38 "github.com/luci/luci-go/appengine/cmd/tokenserver/services/minter/token minter" 38 "github.com/luci/luci-go/appengine/cmd/tokenserver/services/minter/token minter"
39 ) 39 )
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 case err != nil: 75 case err != nil:
76 return nil, grpc.Errorf(codes.Internal, "can't check ACL - %s", err) 76 return nil, grpc.Errorf(codes.Internal, "can't check ACL - %s", err)
77 case !admin: 77 case !admin:
78 return nil, grpc.Errorf(codes.PermissionDenied, "not an admin") 78 return nil, grpc.Errorf(codes.PermissionDenied, "not an admin")
79 } 79 }
80 return c, nil 80 return c, nil
81 } 81 }
82 } 82 }
83 83
84 func init() { 84 func init() {
85 » router := httprouter.New() 85 » r := router.New()
86 » base := gaemiddleware.BaseProd 86 » basemw := gaemiddleware.BaseProd()
87 87
88 // Install auth, config and tsmon handlers. 88 // Install auth, config and tsmon handlers.
89 » gaemiddleware.InstallHandlers(router, base) 89 » gaemiddleware.InstallHandlers(r, basemw)
90 90
91 // The service has no UI, so just redirect to stock RPC explorer. 91 // The service has no UI, so just redirect to stock RPC explorer.
92 » router.GET("/", func(w http.ResponseWriter, r *http.Request, _ httproute r.Params) { 92 » r.GET("/", nil, func(c *router.Context) {
93 » » http.Redirect(w, r, "/rpcexplorer/", http.StatusFound) 93 » » http.Redirect(c.Writer, c.Request, "/rpcexplorer/", http.StatusF ound)
94 }) 94 })
95 95
96 // Optional warmup routes. 96 // Optional warmup routes.
97 » router.GET("/_ah/warmup", base(warmupHandler)) 97 » r.GET("/_ah/warmup", basemw, warmupHandler)
98 » router.GET("/_ah/start", base(warmupHandler)) 98 » r.GET("/_ah/start", basemw, warmupHandler)
99 99
100 // Backend routes used for cron and task queues. 100 // Backend routes used for cron and task queues.
101 » router.GET("/internal/cron/read-config", base(gaemiddleware.RequireCron( readConfigCron))) 101 » r.GET("/internal/cron/read-config", append(basemw, gaemiddleware.Require Cron), readConfigCron)
102 » router.GET("/internal/cron/fetch-crl", base(gaemiddleware.RequireCron(fe tchCRLCron))) 102 » r.GET("/internal/cron/fetch-crl", append(basemw, gaemiddleware.RequireCr on), fetchCRLCron)
103 103
104 // Install all RPC servers. 104 // Install all RPC servers.
105 api := prpc.Server{ 105 api := prpc.Server{
106 Authenticator: auth.Authenticator{ 106 Authenticator: auth.Authenticator{
107 &server.OAuth2Method{Scopes: []string{server.EmailScope} }, 107 &server.OAuth2Method{Scopes: []string{server.EmailScope} },
108 &machine.MachineTokenAuthMethod{}, 108 &machine.MachineTokenAuthMethod{},
109 }, 109 },
110 UnaryServerInterceptor: tsmon.NewGrpcUnaryInterceptor(nil), 110 UnaryServerInterceptor: tsmon.NewGrpcUnaryInterceptor(nil),
111 } 111 }
112 admin.RegisterCertificateAuthoritiesServer(&api, caServerWithAuth) 112 admin.RegisterCertificateAuthoritiesServer(&api, caServerWithAuth)
113 admin.RegisterServiceAccountsServer(&api, serviceAccountsServerWithAuth) 113 admin.RegisterServiceAccountsServer(&api, serviceAccountsServerWithAuth)
114 identity.RegisterIdentityFetcherServer(&api, identityFetcher) 114 identity.RegisterIdentityFetcherServer(&api, identityFetcher)
115 minter.RegisterTokenMinterServer(&api, tokenMinterServerWithoutAuth) // auth inside 115 minter.RegisterTokenMinterServer(&api, tokenMinterServerWithoutAuth) // auth inside
116 discovery.Enable(&api) 116 discovery.Enable(&api)
117 » api.InstallHandlers(router, base) 117 » api.InstallHandlers(r, basemw)
118 118
119 // Expose all this stuff. 119 // Expose all this stuff.
120 » http.DefaultServeMux.Handle("/", router) 120 » http.DefaultServeMux.Handle("/", r)
121 } 121 }
122 122
123 /// Routes. 123 /// Routes.
124 124
125 // warmupHandler warms in-memory caches. 125 // warmupHandler warms in-memory caches.
126 func warmupHandler(c context.Context, w http.ResponseWriter, r *http.Request, _ httprouter.Params) { 126 func warmupHandler(c *router.Context) {
127 » if err := server.Warmup(c); err != nil { 127 » if err := server.Warmup(c.Context); err != nil {
128 panic(err) // let panic catcher deal with it 128 panic(err) // let panic catcher deal with it
129 } 129 }
130 » w.WriteHeader(http.StatusOK) 130 » c.Writer.WriteHeader(http.StatusOK)
131 } 131 }
132 132
133 // readConfigCron is handler for /internal/cron/read-config GAE cron task. 133 // readConfigCron is handler for /internal/cron/read-config GAE cron task.
134 func readConfigCron(c context.Context, w http.ResponseWriter, r *http.Request, _ httprouter.Params) { 134 func readConfigCron(c *router.Context) {
135 // Don't override manually imported configs with 'nil' on devserver. 135 // Don't override manually imported configs with 'nil' on devserver.
136 » if info.Get(c).IsDevAppServer() { 136 » if info.Get(c.Context).IsDevAppServer() {
137 » » w.WriteHeader(http.StatusOK) 137 » » c.Writer.WriteHeader(http.StatusOK)
138 return 138 return
139 } 139 }
140 » if _, err := caServerWithoutAuth.ImportConfig(c, nil); err != nil { 140 » if _, err := caServerWithoutAuth.ImportConfig(c.Context, nil); err != ni l {
141 panic(err) // let panic catcher deal with it 141 panic(err) // let panic catcher deal with it
142 } 142 }
143 » w.WriteHeader(http.StatusOK) 143 » c.Writer.WriteHeader(http.StatusOK)
144 } 144 }
145 145
146 // fetchCRLCron is handler for /internal/cron/fetch-crl GAE cron task. 146 // fetchCRLCron is handler for /internal/cron/fetch-crl GAE cron task.
147 func fetchCRLCron(c context.Context, w http.ResponseWriter, r *http.Request, _ h ttprouter.Params) { 147 func fetchCRLCron(c *router.Context) {
148 » list, err := caServerWithoutAuth.ListCAs(c, nil) 148 » list, err := caServerWithoutAuth.ListCAs(c.Context, nil)
149 if err != nil { 149 if err != nil {
150 panic(err) // let panic catcher deal with it 150 panic(err) // let panic catcher deal with it
151 } 151 }
152 152
153 // Fetch CRL of each active CA in parallel. In practice there are very f ew 153 // Fetch CRL of each active CA in parallel. In practice there are very f ew
154 // CAs there (~= 1), so the risk of OOM is small. 154 // CAs there (~= 1), so the risk of OOM is small.
155 wg := sync.WaitGroup{} 155 wg := sync.WaitGroup{}
156 errs := make([]error, len(list.Cn)) 156 errs := make([]error, len(list.Cn))
157 for i, cn := range list.Cn { 157 for i, cn := range list.Cn {
158 wg.Add(1) 158 wg.Add(1)
159 go func(i int, cn string) { 159 go func(i int, cn string) {
160 defer wg.Done() 160 defer wg.Done()
161 » » » _, err := caServerWithoutAuth.FetchCRL(c, &admin.FetchCR LRequest{Cn: cn}) 161 » » » _, err := caServerWithoutAuth.FetchCRL(c.Context, &admin .FetchCRLRequest{Cn: cn})
162 if err != nil { 162 if err != nil {
163 » » » » logging.Errorf(c, "FetchCRL(%q) failed - %s", cn , err) 163 » » » » logging.Errorf(c.Context, "FetchCRL(%q) failed - %s", cn, err)
164 errs[i] = err 164 errs[i] = err
165 } 165 }
166 }(i, cn) 166 }(i, cn)
167 } 167 }
168 wg.Wait() 168 wg.Wait()
169 169
170 // Retry cron job only on transient errors. On fatal errors let it rerun one 170 // Retry cron job only on transient errors. On fatal errors let it rerun one
171 // minute later, as usual, to avoid spamming logs with errors. 171 // minute later, as usual, to avoid spamming logs with errors.
172 status := http.StatusOK 172 status := http.StatusOK
173 for _, err = range errs { 173 for _, err = range errs {
174 if grpc.Code(err) == codes.Internal { 174 if grpc.Code(err) == codes.Internal {
175 status = http.StatusInternalServerError 175 status = http.StatusInternalServerError
176 break 176 break
177 } 177 }
178 } 178 }
179 » w.WriteHeader(status) 179 » c.Writer.WriteHeader(status)
180 } 180 }
OLDNEW
« no previous file with comments | « appengine/cmd/milo/settings/themes.go ('k') | appengine/gaeauth/server/default.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698