Skip to content

Commit 41edff7

Browse files
tmcyugui
authored andcommitted
Add request_context flag to utilize (*http.Request).Context() in handlers (#265)
* Add usage of http.Request's Context * add request_context flag Contribution by @kokaz, @tmc and @yugui
1 parent a51e1d5 commit 41edff7

File tree

6 files changed

+41
-12
lines changed

6 files changed

+41
-12
lines changed

.travis.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,13 @@ before_script:
2323
- sh -c 'cd examples/browser && npm install'
2424
script:
2525
- make realclean && make examples SWAGGER_CODEGEN="java -jar $HOME/local/swagger-codegen-cli.jar"
26-
- if ! go version | grep devel; then test -z "$(git status --porcelain)" || (git status; git diff; exit 1); fi
26+
- if (go version | grep -qv devel) && [ -z "${GATEWAY_PLUGIN_FLAGS}" ]; then test -z "$(git status --porcelain)" || (git status; git diff; exit 1); fi
2727
- env GLOG_logtostderr=1 go test -race -v github.com/grpc-ecosystem/grpc-gateway/...
2828
- make lint
2929
- sh -c 'cd examples/browser && gulp'
3030
env:
3131
global:
3232
- "PATH=$PATH:$HOME/local/bin"
33+
matrix:
34+
- GATEWAY_PLUGIN_FLAGS=
35+
- GATEWAY_PLUGIN_FLAGS=request_context=true

Makefile

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ GATEWAY_PLUGIN_SRC= utilities/doc.go \
3535
protoc-gen-grpc-gateway/httprule/parse.go \
3636
protoc-gen-grpc-gateway/httprule/types.go \
3737
protoc-gen-grpc-gateway/main.go
38+
GATEWAY_PLUGIN_FLAGS?=
3839

3940
GOOGLEAPIS_DIR=third_party/googleapis
4041
OPTIONS_PROTO=$(GOOGLEAPIS_DIR)/google/api/annotations.proto $(GOOGLEAPIS_DIR)/google/api/http.proto
@@ -45,6 +46,10 @@ RUNTIME_PROTO=runtime/internal/stream_chunk.proto
4546
RUNTIME_GO=$(RUNTIME_PROTO:.proto=.pb.go)
4647

4748
PKGMAP=Mgoogle/protobuf/descriptor.proto=$(GO_PLUGIN_PKG)/descriptor,Mgoogle/api/annotations.proto=$(PKG)/$(GOOGLEAPIS_DIR)/google/api,Mexamples/sub/message.proto=$(PKG)/examples/sub
49+
ADDITIONAL_FLAGS=
50+
ifneq "$(GATEWAY_PLUGIN_FLAGS)" ""
51+
ADDITIONAL_FLAGS=,$(GATEWAY_PLUGIN_FLAGS)
52+
endif
4853
SWAGGER_EXAMPLES=examples/examplepb/echo_service.proto \
4954
examples/examplepb/a_bit_of_everything.proto
5055
EXAMPLES=examples/examplepb/echo_service.proto \
@@ -102,7 +107,7 @@ $(EXAMPLE_DEPSRCS): $(GO_PLUGIN) $(EXAMPLE_DEPS)
102107
protoc -I $(PROTOC_INC_PATH) -I. --plugin=$(GO_PLUGIN) --go_out=$(PKGMAP),plugins=grpc:$(OUTPUT_DIR) $(@:.pb.go=.proto)
103108
cp $(OUTPUT_DIR)/$(PKG)/$@ $@ || cp $(OUTPUT_DIR)/$@ $@
104109
$(EXAMPLE_GWSRCS): $(GATEWAY_PLUGIN) $(EXAMPLES)
105-
protoc -I $(PROTOC_INC_PATH) -I. -I$(GOOGLEAPIS_DIR) --plugin=$(GATEWAY_PLUGIN) --grpc-gateway_out=logtostderr=true,$(PKGMAP):. $(EXAMPLES)
110+
protoc -I $(PROTOC_INC_PATH) -I. -I$(GOOGLEAPIS_DIR) --plugin=$(GATEWAY_PLUGIN) --grpc-gateway_out=logtostderr=true,$(PKGMAP)$(ADDITIONAL_FLAGS):. $(EXAMPLES)
106111
$(EXAMPLE_SWAGGERSRCS): $(SWAGGER_PLUGIN) $(SWAGGER_EXAMPLES)
107112
protoc -I $(PROTOC_INC_PATH) -I. -I$(GOOGLEAPIS_DIR) --plugin=$(SWAGGER_PLUGIN) --swagger_out=logtostderr=true,$(PKGMAP):. $(SWAGGER_EXAMPLES)
108113

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,9 @@ Make sure that your `$GOPATH/bin` is in your `$PATH`.
186186
`protoc-gen-grpc-gateway` supports custom mapping from Protobuf `import` to Golang import path.
187187
They are compatible to [the parameters with same names in `protoc-gen-go`](https://github.com/golang/protobuf#parameters).
188188
189+
In addition we also support the `request_context` parameter in order to use the `http.Request`'s Context (only for Go 1.7 and above).
190+
This parameter can be useful to pass request scoped context between the gateway and the gRPC service.
191+
189192
`protoc-gen-grpc-gateway` also supports some more command line flags to control logging. You can give these flags together with parameters above. Run `protoc-gen-grpc-gateway --help` for more details about the flags.
190193
191194
## More Examples

protoc-gen-grpc-gateway/gengateway/generator.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,13 @@ var (
2020
)
2121

2222
type generator struct {
23-
reg *descriptor.Registry
24-
baseImports []descriptor.GoPackage
23+
reg *descriptor.Registry
24+
baseImports []descriptor.GoPackage
25+
useRequestContext bool
2526
}
2627

2728
// New returns a new generator which generates grpc gateway files.
28-
func New(reg *descriptor.Registry) gen.Generator {
29+
func New(reg *descriptor.Registry, useRequestContext bool) gen.Generator {
2930
var imports []descriptor.GoPackage
3031
for _, pkgpath := range []string{
3132
"io",
@@ -54,7 +55,7 @@ func New(reg *descriptor.Registry) gen.Generator {
5455
}
5556
imports = append(imports, pkg)
5657
}
57-
return &generator{reg: reg, baseImports: imports}
58+
return &generator{reg: reg, baseImports: imports, useRequestContext: useRequestContext}
5859
}
5960

6061
func (g *generator) Generate(targets []*descriptor.File) ([]*plugin.CodeGeneratorResponse_File, error) {
@@ -107,5 +108,5 @@ func (g *generator) generate(file *descriptor.File) (string, error) {
107108
imports = append(imports, pkg)
108109
}
109110
}
110-
return applyTemplate(param{File: file, Imports: imports})
111+
return applyTemplate(param{File: file, Imports: imports, UseRequestContext: g.useRequestContext})
111112
}

protoc-gen-grpc-gateway/gengateway/template.go

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ import (
1313

1414
type param struct {
1515
*descriptor.File
16-
Imports []descriptor.GoPackage
16+
Imports []descriptor.GoPackage
17+
UseRequestContext bool
1718
}
1819

1920
type binding struct {
@@ -66,6 +67,11 @@ func (f queryParamFilter) String() string {
6667
return fmt.Sprintf("&utilities.DoubleArray{Encoding: map[string]int{%s}, Base: %#v, Check: %#v}", e, f.Base, f.Check)
6768
}
6869

70+
type trailerParams struct {
71+
Services []*descriptor.Service
72+
UseRequestContext bool
73+
}
74+
6975
func applyTemplate(p param) (string, error) {
7076
w := bytes.NewBuffer(nil)
7177
if err := headerTemplate.Execute(w, p); err != nil {
@@ -90,7 +96,12 @@ func applyTemplate(p param) (string, error) {
9096
if len(targetServices) == 0 {
9197
return "", errNoTargetService
9298
}
93-
if err := trailerTemplate.Execute(w, targetServices); err != nil {
99+
100+
tp := trailerParams{
101+
Services: targetServices,
102+
UseRequestContext: p.UseRequestContext,
103+
}
104+
if err := trailerTemplate.Execute(w, tp); err != nil {
94105
return "", err
95106
}
96107
return w.String(), nil
@@ -295,7 +306,8 @@ var (
295306
`))
296307

297308
trailerTemplate = template.Must(template.New("trailer").Parse(`
298-
{{range $svc := .}}
309+
{{$UseRequestContext := .UseRequestContext}}
310+
{{range $svc := .Services}}
299311
// Register{{$svc.GetName}}HandlerFromEndpoint is same as Register{{$svc.GetName}}Handler but
300312
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
301313
func Register{{$svc.GetName}}HandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
@@ -328,7 +340,11 @@ func Register{{$svc.GetName}}Handler(ctx context.Context, mux *runtime.ServeMux,
328340
{{range $m := $svc.Methods}}
329341
{{range $b := $m.Bindings}}
330342
mux.Handle({{$b.HTTPMethod | printf "%q"}}, pattern_{{$svc.GetName}}_{{$m.GetName}}_{{$b.Index}}, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
343+
{{- if $UseRequestContext }}
344+
ctx, cancel := context.WithCancel(req.Context())
345+
{{- else -}}
331346
ctx, cancel := context.WithCancel(ctx)
347+
{{- end }}
332348
defer cancel()
333349
if cn, ok := w.(http.CloseNotifier); ok {
334350
go func(done <-chan struct{}, closed <-chan bool) {

protoc-gen-grpc-gateway/main.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ import (
2323
)
2424

2525
var (
26-
importPrefix = flag.String("import_prefix", "", "prefix to be added to go package paths for imported proto files")
26+
importPrefix = flag.String("import_prefix", "", "prefix to be added to go package paths for imported proto files")
27+
useRequestContext = flag.Bool("request_context", false, "determine whether to use http.Request's context or not")
2728
)
2829

2930
func parseReq(r io.Reader) (*plugin.CodeGeneratorRequest, error) {
@@ -73,7 +74,7 @@ func main() {
7374
}
7475
}
7576

76-
g := gengateway.New(reg)
77+
g := gengateway.New(reg, *useRequestContext)
7778

7879
reg.SetPrefix(*importPrefix)
7980
if err := reg.Load(req); err != nil {

0 commit comments

Comments
 (0)