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

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

Issue 1605363002: common/prpc, tools/cmd/cproto: prpc client (Closed) Base URL: https://chromium.googlesource.com/external/github.com/luci/luci-go@master
Patch Set: rebased and addressed comments 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
« no previous file with comments | « server/prpc/error_test.go ('k') | server/prpc/response.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 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"
9 "net/http" 8 "net/http"
10 9
11 "github.com/golang/protobuf/proto" 10 "github.com/golang/protobuf/proto"
12 "github.com/julienschmidt/httprouter"
13 "golang.org/x/net/context" 11 "golang.org/x/net/context"
14 "google.golang.org/grpc" 12 "google.golang.org/grpc"
13 "google.golang.org/grpc/codes"
15 14
16 » "github.com/luci/luci-go/server/middleware" 15 » "github.com/luci/luci-go/common/grpcutil"
17 ) 16 )
18 17
19 type method struct { 18 type method struct {
20 service *service 19 service *service
21 desc grpc.MethodDesc 20 desc grpc.MethodDesc
22 } 21 }
23 22
24 func (m *method) Name() string {
25 return m.desc.MethodName
26 }
27
28 // Handle decodes an input protobuf message from the HTTP request,
29 // delegates RPC handling to the inner implementation and
30 // encodes the output message back to the HTTP response.
31 //
32 // If the inner handler returns an error, HTTP status is determined using
33 // ErrorStatus.
34 // If the status is http.StatusInternalServerError, only "Internal server error"
35 // is printed.
36 // All errors with status >= 500 are logged.
37 func (m *method) Handle(c context.Context, w http.ResponseWriter, r *http.Reques t, _ httprouter.Params) {
38 if err := m.handle(c, w, r); err != nil {
39 writeError(c, w, err)
40 }
41 }
42
43 // handle decodes an input protobuf message from the HTTP request, 23 // handle decodes an input protobuf message from the HTTP request,
44 // delegates RPC handling to the inner implementation and 24 // delegates RPC handling to the inner implementation and
45 // encodes the output message back to the HTTP response. 25 // encodes the output message back to the HTTP response.
46 func (m *method) handle(c context.Context, w http.ResponseWriter, r *http.Reques t) *httpError { 26 //
27 // If the inner handler returns an error, HTTP status is determined using
28 // errorStatus.
29 // Prints only "Internal server error" if the code is Internal.
30 // Logs the error if code is Internal or Unknown.
31 func (m *method) handle(c context.Context, w http.ResponseWriter, r *http.Reques t) *response {
47 defer r.Body.Close() 32 defer r.Body.Close()
48 » format, err := responseFormat(r.Header.Get(headerAccept)) 33
49 » if err != nil { 34 » format, perr := responseFormat(r.Header.Get(headerAccept))
50 » » return err 35 » if perr != nil {
36 » » return respondProtocolError(perr)
51 } 37 }
52 38
53 » c, rawErr := parseHeader(c, r.Header) 39 » c, err := parseHeader(c, r.Header)
54 » if rawErr != nil { 40 » if err != nil {
55 » » return withStatus(rawErr, http.StatusBadRequest) 41 » » return respondProtocolError(withStatus(err, http.StatusBadReques t))
56 } 42 }
57 43
58 » res, rawErr := m.desc.Handler(m.service.impl, c, func(msg interface{}) e rror { 44 » out, err := m.desc.Handler(m.service.impl, c, func(in interface{}) error {
59 » » if msg == nil { 45 » » if in == nil {
60 » » » panicf("cannot decode to nil") 46 » » » return grpcutil.Errf(codes.Internal, "input message is n il")
61 } 47 }
62 // Do not collapse it to one line. There is implicit err type co nversion. 48 // Do not collapse it to one line. There is implicit err type co nversion.
63 » » if err := readMessage(r, msg.(proto.Message)); err != nil { 49 » » if perr := readMessage(r, in.(proto.Message)); perr != nil {
64 » » » return err 50 » » » return perr
65 } 51 }
66 return nil 52 return nil
67 }) 53 })
68 » if rawErr != nil { 54 » if err != nil {
69 » » if err, ok := rawErr.(*httpError); ok { 55 » » if perr, ok := err.(*protocolError); ok {
70 » » » return err 56 » » » return respondProtocolError(perr)
71 } 57 }
72 » » return withStatus(rawErr, ErrorStatus(rawErr)) 58 » » return errResponse(errorCode(err), 0, grpc.ErrorDesc(err))
73 } 59 }
74 » if res == nil { 60
75 » » return m.internalServerError("service returned nil message") 61 » if out == nil {
62 » » return errResponse(codes.Internal, 0, "service returned nil mess age")
76 } 63 }
77 » if err := writeMessage(w, res.(proto.Message), format); err != nil { 64 » return respondMessage(out.(proto.Message), format)
78 » » return m.internalServerError("could not respond: %s", err)
79 » }
80 » return nil
81 } 65 }
82
83 // InstallHandlers installs a POST HTTP handlers at /prpc/{service_name}/{method _name}.
84 func (m *method) InstallHandlers(r *httprouter.Router, base middleware.Base) {
85 path := fmt.Sprintf("/prpc/%s/%s", m.service.Name(), m.Name())
86 r.POST(path, base(m.Handle))
87 }
88
89 func (m *method) internalServerError(format string, a ...interface{}) *httpError {
90 format = fmt.Sprintf("%s.%s: ", m.service.Name(), m.Name()) + format
91 return errorf(http.StatusInternalServerError, format, a...)
92 }
OLDNEW
« no previous file with comments | « server/prpc/error_test.go ('k') | server/prpc/response.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698