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)) |
+ } |
+ |
+ 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)) |
} |
+ |
+ return method.handle(c, w, r) |
} |
// ServiceNames returns a sorted list of full names of all registered services. |