Chromium Code Reviews| Index: server/prpc/server.go |
| diff --git a/server/prpc/server.go b/server/prpc/server.go |
| index df43971e712a79a6b1a1ac4ed34302ea92bf26fd..0732adea009e79bb6bbaf18ded97519de2fffb62 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" |
| ) |
| @@ -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,52 @@ 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) |
| - } |
| + const path = "/prpc/:service/:method" |
| + handle := base(s.handle) |
| + r.POST(path, handle) |
|
dnj (Google)
2016/01/26 16:13:57
Do we need to support all of these methods? I thou
nodir
2016/01/26 18:01:07
We had this discussion and decided to handle all m
dnj
2016/01/26 18:50:27
Seems pointless, but OK. IMO either a client knows
nodir
2016/01/26 19:06:09
ah, Server.handle was exported at some point, that
|
| + r.GET(path, handle) |
| + r.PUT(path, handle) |
| + r.DELETE(path, handle) |
| + r.PATCH(path, 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) { |
| + res := s.respond(c, w, r, p) |
|
dnj (Google)
2016/01/26 16:13:57
nit: pull service/method out of params up front, t
nodir
2016/01/26 18:01:07
Done.
|
| + |
| + c = logging.SetFields(c, logging.Fields{ |
| + "Service": p.ByName("service"), |
| + "Method": p.ByName("method"), |
| + }) |
| + res.write(c, w) |
| +} |
| + |
| +func (s *Server) respond(c context.Context, w http.ResponseWriter, r *http.Request, p httprouter.Params) *response { |
| + if r.Method != "POST" { |
| + return errResponse(codes.Unimplemented, http.StatusMethodNotAllowed, "HTTP method must be POST") |
| } |
| + |
| + serviceName := p.ByName("service") |
| + service := s.services[serviceName] |
| + if service == nil { |
| + return errResponse( |
| + codes.Unimplemented, |
| + http.StatusNotImplemented, |
| + fmt.Sprintf("service %q is not implemented", serviceName)) |
| + } |
| + |
| + methodName := p.ByName("method") |
| + 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. |