Chromium Code Reviews| Index: server/prpc/server.go | 
| diff --git a/server/prpc/server.go b/server/prpc/server.go | 
| index df43971e712a79a6b1a1ac4ed34302ea92bf26fd..1079cb108b4e78571084632669914db70b8b76e3 100644 | 
| --- a/server/prpc/server.go | 
| +++ b/server/prpc/server.go | 
| @@ -5,6 +5,7 @@ | 
| package prpc | 
| import ( | 
| + "fmt" | 
| "net/http" | 
| "sort" | 
| "sync" | 
| @@ -12,7 +13,9 @@ import ( | 
| "github.com/julienschmidt/httprouter" | 
| "golang.org/x/net/context" | 
| "google.golang.org/grpc" | 
| + "google.golang.org/grpc/codes" | 
| + "github.com/luci/luci-go/common/logging" | 
| "github.com/luci/luci-go/server/auth" | 
| "github.com/luci/luci-go/server/middleware" | 
| ) | 
| @@ -55,7 +58,7 @@ func (s *Server) RegisterService(desc *grpc.ServiceDesc, impl interface{}) { | 
| if s.services == nil { | 
| s.services = map[string]*service{} | 
| } else if _, ok := s.services[desc.ServiceName]; ok { | 
| - panicf("service %q is already registered", desc.ServiceName) | 
| + panic(fmt.Errorf("service %q is already registered", desc.ServiceName)) | 
| } | 
| s.services[desc.ServiceName] = serv | 
| @@ -65,7 +68,7 @@ func (s *Server) RegisterService(desc *grpc.ServiceDesc, impl interface{}) { | 
| func (s *Server) authenticate(base middleware.Base) middleware.Base { | 
| a := GetDefaultAuth() | 
| if a == nil { | 
| - panicf("prpc: CustomAuthenticator is false, but default authenticator was not registered. " + | 
| + panic("prpc: CustomAuthenticator is false, but default authenticator was not registered. " + | 
| "Forgot to import appengine/gaeauth/server package?") | 
| } | 
| @@ -74,7 +77,8 @@ func (s *Server) authenticate(base middleware.Base) middleware.Base { | 
| c = auth.SetAuthenticator(c, a) | 
| c, err := a.Authenticate(c, r) | 
| if err != nil { | 
| - writeError(c, w, withStatus(err, http.StatusUnauthorized)) | 
| + res := errResponse(codes.Unauthenticated, http.StatusUnauthorized, err.Error()) | 
| + res.write(c, w) | 
| return | 
| } | 
| h(c, w, r, p) | 
| @@ -82,8 +86,9 @@ func (s *Server) authenticate(base middleware.Base) middleware.Base { | 
| } | 
| } | 
| -// InstallHandlers installs HTTP POST handlers at | 
| -// /prpc/{service_name}/{method_name} for all registered services. | 
| +// InstallHandlers installs HTTP handlers at /prpc/:service/:method. | 
| +// See https://godoc.org/github.com/luci/luci-go/common/prpc#hdr-Protocol | 
| +// for pRPC protocol. | 
| func (s *Server) InstallHandlers(r *httprouter.Router, base middleware.Base) { | 
| s.mu.Lock() | 
| defer s.mu.Unlock() | 
| @@ -92,11 +97,42 @@ func (s *Server) InstallHandlers(r *httprouter.Router, base middleware.Base) { | 
| base = s.authenticate(base) | 
| } | 
| - for _, service := range s.services { | 
| - for _, m := range service.methods { | 
| - m.InstallHandlers(r, base) | 
| - } | 
| + r.POST("/prpc/:service/:method", base(s.handle)) | 
| +} | 
| + | 
| +// handle handles RPCs. | 
| +// See https://godoc.org/github.com/luci/luci-go/common/prpc#hdr-Protocol | 
| +// for pRPC protocol. | 
| +func (s *Server) handle(c context.Context, w http.ResponseWriter, r *http.Request, p httprouter.Params) { | 
| + serviceName := p.ByName("service") | 
| + methodName := p.ByName("method") | 
| + res := s.respond(c, w, r, serviceName, methodName) | 
| + | 
| + c = logging.SetFields(c, logging.Fields{ | 
| + "service": serviceName, | 
| + "method": methodName, | 
| + }) | 
| + res.write(c, w) | 
| +} | 
| + | 
| +func (s *Server) respond(c context.Context, w http.ResponseWriter, r *http.Request, serviceName, methodName string) *response { | 
| + service := s.services[serviceName] | 
| + if service == nil { | 
| + return errResponse( | 
| + codes.Unimplemented, | 
| + http.StatusNotImplemented, | 
| + fmt.Sprintf("service %q is not implemented", serviceName)) | 
| 
 
Vadim Sh.
2016/01/27 00:21:10
errResponse does Sprintf inside, no need to call i
 
 | 
| + } | 
| + | 
| + method := service.methods[methodName] | 
| + if method == nil { | 
| + return errResponse( | 
| + codes.Unimplemented, | 
| + http.StatusNotImplemented, | 
| + fmt.Sprintf("method %q in service %q is not implemented", methodName, serviceName)) | 
| 
 
Vadim Sh.
2016/01/27 00:21:10
here too
(check other invocations too, just in ca
 
dnj
2016/01/27 00:39:59
Done.
 
 | 
| } | 
| + | 
| + return method.handle(c, w, r) | 
| } | 
| // ServiceNames returns a sorted list of full names of all registered services. |