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

Side by Side Diff: server/prpc/server.go

Issue 1638493004: server/prpc: updated server according to protocol (Closed) Base URL: https://chromium.googlesource.com/external/github.com/luci/luci-go@master
Patch Set: Created 4 years, 11 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
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package prpc 5 package prpc
6 6
7 import ( 7 import (
8 "fmt"
8 "net/http" 9 "net/http"
9 "sort" 10 "sort"
10 "sync" 11 "sync"
11 12
12 "github.com/julienschmidt/httprouter" 13 "github.com/julienschmidt/httprouter"
13 "golang.org/x/net/context" 14 "golang.org/x/net/context"
14 "google.golang.org/grpc" 15 "google.golang.org/grpc"
16 "google.golang.org/grpc/codes"
15 17
18 "github.com/luci/luci-go/common/logging"
16 "github.com/luci/luci-go/server/auth" 19 "github.com/luci/luci-go/server/auth"
17 "github.com/luci/luci-go/server/middleware" 20 "github.com/luci/luci-go/server/middleware"
18 ) 21 )
19 22
20 // Server is a pRPC server to serve RPC requests. 23 // Server is a pRPC server to serve RPC requests.
21 // Zero value is valid. 24 // Zero value is valid.
22 type Server struct { 25 type Server struct {
23 // CustomAuthenticator, if true, disables the forced authentication set by 26 // CustomAuthenticator, if true, disables the forced authentication set by
24 // RegisterDefaultAuth. 27 // RegisterDefaultAuth.
25 CustomAuthenticator bool 28 CustomAuthenticator bool
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 if a == nil { 70 if a == nil {
68 panicf("prpc: CustomAuthenticator is false, but default authenti cator was not registered. " + 71 panicf("prpc: CustomAuthenticator is false, but default authenti cator was not registered. " +
69 "Forgot to import appengine/gaeauth/server package?") 72 "Forgot to import appengine/gaeauth/server package?")
70 } 73 }
71 74
72 return func(h middleware.Handler) httprouter.Handle { 75 return func(h middleware.Handler) httprouter.Handle {
73 return base(func(c context.Context, w http.ResponseWriter, r *ht tp.Request, p httprouter.Params) { 76 return base(func(c context.Context, w http.ResponseWriter, r *ht tp.Request, p httprouter.Params) {
74 c = auth.SetAuthenticator(c, a) 77 c = auth.SetAuthenticator(c, a)
75 c, err := a.Authenticate(c, r) 78 c, err := a.Authenticate(c, r)
76 if err != nil { 79 if err != nil {
77 » » » » writeError(c, w, withStatus(err, http.StatusUnau thorized)) 80 » » » » res := errResponse(codes.Unauthenticated, http.S tatusUnauthorized, err.Error())
81 » » » » res.write(c, w)
78 return 82 return
79 } 83 }
80 h(c, w, r, p) 84 h(c, w, r, p)
81 }) 85 })
82 } 86 }
83 } 87 }
84 88
85 // InstallHandlers installs HTTP POST handlers at 89 // InstallHandlers installs HTTP handlers at /prpc/:service/:method.
86 // /prpc/{service_name}/{method_name} for all registered services. 90 // See https://godoc.org/github.com/luci/luci-go/common/prpc#hdr-Protocol
91 // for pRPC protocol.
87 func (s *Server) InstallHandlers(r *httprouter.Router, base middleware.Base) { 92 func (s *Server) InstallHandlers(r *httprouter.Router, base middleware.Base) {
88 s.mu.Lock() 93 s.mu.Lock()
89 defer s.mu.Unlock() 94 defer s.mu.Unlock()
90 95
91 if !s.CustomAuthenticator { 96 if !s.CustomAuthenticator {
92 base = s.authenticate(base) 97 base = s.authenticate(base)
93 } 98 }
94 99
95 » for _, service := range s.services { 100 » const path = "/prpc/:service/:method"
96 » » for _, m := range service.methods { 101 » handle := base(s.handle)
97 » » » m.InstallHandlers(r, base) 102 » 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
98 » » } 103 » r.GET(path, handle)
104 » r.PUT(path, handle)
105 » r.DELETE(path, handle)
106 » r.PATCH(path, handle)
107 }
108
109 // handle handles RPCs.
110 // See https://godoc.org/github.com/luci/luci-go/common/prpc#hdr-Protocol
111 // for pRPC protocol.
112 func (s *Server) handle(c context.Context, w http.ResponseWriter, r *http.Reques t, p httprouter.Params) {
113 » 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.
114
115 » c = logging.SetFields(c, logging.Fields{
116 » » "Service": p.ByName("service"),
117 » » "Method": p.ByName("method"),
118 » })
119 » res.write(c, w)
120 }
121
122 func (s *Server) respond(c context.Context, w http.ResponseWriter, r *http.Reque st, p httprouter.Params) *response {
123 » if r.Method != "POST" {
124 » » return errResponse(codes.Unimplemented, http.StatusMethodNotAllo wed, "HTTP method must be POST")
99 } 125 }
126
127 serviceName := p.ByName("service")
128 service := s.services[serviceName]
129 if service == nil {
130 return errResponse(
131 codes.Unimplemented,
132 http.StatusNotImplemented,
133 fmt.Sprintf("service %q is not implemented", serviceName ))
134 }
135
136 methodName := p.ByName("method")
137 method := service.methods[methodName]
138 if method == nil {
139 return errResponse(
140 codes.Unimplemented,
141 http.StatusNotImplemented,
142 fmt.Sprintf("method %q in service %q is not implemented" , methodName, serviceName))
143 }
144
145 return method.handle(c, w, r)
100 } 146 }
101 147
102 // ServiceNames returns a sorted list of full names of all registered services. 148 // ServiceNames returns a sorted list of full names of all registered services.
103 func (s *Server) ServiceNames() []string { 149 func (s *Server) ServiceNames() []string {
104 s.mu.Lock() 150 s.mu.Lock()
105 defer s.mu.Unlock() 151 defer s.mu.Unlock()
106 152
107 names := make([]string, 0, len(s.services)) 153 names := make([]string, 0, len(s.services))
108 for name := range s.services { 154 for name := range s.services {
109 names = append(names, name) 155 names = append(names, name)
110 } 156 }
111 sort.Strings(names) 157 sort.Strings(names)
112 return names 158 return names
113 } 159 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698