Skip to content

Commit d7b71e6

Browse files
authored
[#143]: feature: support custom interceptors
2 parents d904d39 + 0c73e3f commit d7b71e6

File tree

17 files changed

+417
-18
lines changed

17 files changed

+417
-18
lines changed
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
name: grpc-interceptors
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
- stable
8+
pull_request:
9+
branches:
10+
- master
11+
- stable
12+
13+
jobs:
14+
grpc_interceptors_test:
15+
name: gRPC interceptors (Go ${{ matrix.go }}, PHP ${{ matrix.php }}, OS ${{matrix.os}})
16+
runs-on: ${{ matrix.os }}
17+
timeout-minutes: 60
18+
strategy:
19+
matrix:
20+
php: ["8.5"]
21+
go: [stable]
22+
os: ["ubuntu-latest"]
23+
24+
steps:
25+
- name: Set up Go ${{ matrix.go }}
26+
uses: actions/setup-go@v5 # action page: <https://github.com/actions/setup-go>
27+
with:
28+
go-version: ${{ matrix.go }}
29+
30+
- name: Set up PHP ${{ matrix.php }}
31+
uses: shivammathur/setup-php@v2 # action page: <https://github.com/shivammathur/setup-php>
32+
with:
33+
php-version: ${{ matrix.php }}
34+
extensions: sockets
35+
36+
- name: Check out code
37+
uses: actions/checkout@v4
38+
39+
- name: Get Composer Cache Directory
40+
id: composer-cache
41+
run: |
42+
cd tests/php_test_files
43+
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
44+
45+
- name: Init Composer Cache # Docs: <https://git.io/JfAKn#php---composer>
46+
uses: actions/cache@v4
47+
with:
48+
path: ${{ steps.composer-cache.outputs.dir }}
49+
key: ${{ runner.os }}-composer-${{ matrix.php }}-${{ hashFiles('**/composer.json') }}
50+
restore-keys: ${{ runner.os }}-composer-
51+
52+
- name: Install Composer dependencies
53+
run: cd tests/php_test_files && composer update --prefer-dist --no-progress --ansi
54+
55+
- name: Init Go modules Cache # Docs: <https://git.io/JfAKn#go---modules>
56+
uses: actions/cache@v4
57+
with:
58+
path: ~/go/pkg/mod
59+
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
60+
restore-keys: ${{ runner.os }}-go-
61+
62+
- name: Install Go dependencies
63+
run: go mod download
64+
65+
- name: Run interceptors e2e test
66+
run: cd tests && go test -timeout 20m -v -race -tags=debug grpc_interceptors_test.go

config.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ type Config struct {
2929
TLS *TLS `mapstructure:"tls"`
3030

3131
// Env is environment variables passed to the http pool
32-
Env map[string]string `mapstructure:"env"`
32+
Env map[string]string `mapstructure:"env"`
33+
Interceptors []string `mapstructure:"interceptors"`
3334

3435
GrpcPool *pool.Config `mapstructure:"pool"`
3536
MaxSendMsgSize int64 `mapstructure:"max_send_msg_size"`

go.work.sum

Lines changed: 22 additions & 0 deletions
Large diffs are not rendered by default.

protoc_plugins/Dockerfile

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,39 @@
1-
FROM --platform=${TARGETPLATFORM:-linux/amd64} golang:1.22-alpine as builder
1+
FROM golang:1.26-alpine AS builder
2+
3+
ARG TARGETPLATFORM
24

35
ENV CGO_ENABLED=0
46

57
WORKDIR /src
6-
COPY protoc_plugins/ .
8+
# https://buf.build/docs/bsr/remote-plugins/custom-plugins/#build-a-docker-image
9+
RUN test "${TARGETPLATFORM}" = "linux/amd64" || (echo "buf plugin image must be built for linux/amd64" && exit 1)
10+
11+
COPY protoc_plugins/go.mod protoc_plugins/go.sum ./
712
RUN go mod download
8-
RUN go mod tidy
913

10-
RUN go build -trimpath -ldflags "-s" -o protoc-gen-php-grpc-plugin protoc-gen-php-grpc/main.go
14+
COPY protoc_plugins/ .
15+
16+
RUN go build -trimpath -ldflags "-s -w" -o /out/protoc-gen-php-grpc-plugin ./protoc-gen-php-grpc
1117

1218
FROM scratch
1319

14-
ARG APP_VERSION=""
20+
# Supply real metadata at build time, for example:
21+
# docker build --platform linux/amd64 --build-arg BUILD_TIME="$(date -u +%Y-%m-%dT%H:%M:%SZ)" --build-arg APP_VERSION="vX.Y.Z" -f protoc_plugins/Dockerfile .
22+
ARG APP_VERSION="unknown"
23+
ARG BUILD_TIME="unknown"
1524

1625
# Runtime dependencies
1726
LABEL org.opencontainers.image.title="protoc-gen-php-grpc"
1827
LABEL org.opencontainers.image.description="protoc plugin for generating PHP gRPC service stubs"
1928
LABEL org.opencontainers.image.url="https://roadrunner.dev"
2029
LABEL org.opencontainers.image.source="https://github.com/roadrunner-server/grpc"
2130
LABEL org.opencontainers.image.vendor="SpiralScout"
22-
LABEL org.opencontainers.image.version="$APP_VERSION"
23-
LABEL org.opencontainers.image.created="$BUILD_TIME"
31+
LABEL org.opencontainers.image.version="${APP_VERSION}"
32+
LABEL org.opencontainers.image.created="${BUILD_TIME}"
2433
LABEL org.opencontainers.image.licenses="MIT"
2534

26-
COPY --from=builder /src/protoc-gen-php-grpc-plugin /
35+
COPY --from=builder --chown=65532:65532 /out/protoc-gen-php-grpc-plugin /protoc-gen-php-grpc-plugin
36+
37+
USER 65532:65532
2738

2839
ENTRYPOINT ["/protoc-gen-php-grpc-plugin"]

protoc_plugins/go.mod

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
module github.com/roadrunner-server/grpc/protoc_plugins/v5
22

3-
go 1.23
4-
5-
toolchain go1.23.1
3+
go 1.26
64

75
require (
86
github.com/stretchr/testify v1.11.1

protoc_plugins/go.sum

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,11 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI
1515
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
1616
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
1717
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
18+
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
1819
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
20+
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
1921
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
22+
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
2023
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
2124
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
2225
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=

schema.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,24 @@
3434
]
3535
}
3636
},
37+
"interceptors": {
38+
"description": "List of registered unary gRPC interceptor plugin names.",
39+
"type": "array",
40+
"uniqueItems": true,
41+
"items": {
42+
"type": "string",
43+
"minLength": 1
44+
},
45+
"examples": [
46+
[
47+
"sample-grpc-interceptor"
48+
],
49+
[
50+
"auth-interceptor",
51+
"ratelimit-interceptor"
52+
]
53+
]
54+
},
3755
"tls": {
3856
"description": "GRPC TLS configuration",
3957
"type": "object",

server.go

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,21 @@ func (p *Plugin) createGRPCserver(interceptors map[string]api.Interceptor) (*grp
3333
grpc.UnaryServerInterceptor(p.interceptor),
3434
}
3535

36-
for _, interceptor := range interceptors {
37-
unaryInterceptors = append(
38-
unaryInterceptors,
39-
interceptor.UnaryServerInterceptor(),
40-
)
36+
// if we have interceptors in the config, we need to chain them with our interceptor, and add them to the server options
37+
if len(p.config.Interceptors) > 0 {
38+
// apply interceptors in the same order as they are configured
39+
for i := 0; i < len(p.config.Interceptors); i++ {
40+
name := p.config.Interceptors[i]
41+
if _, ok := interceptors[name]; !ok {
42+
// we should raise an error here, since we may silently ignore let's say auth interceptor, which is critical for security
43+
return nil, errors.E(op, errors.Str(fmt.Sprintf("interceptor %s is not registered", name)))
44+
}
45+
46+
unaryInterceptors = append(
47+
unaryInterceptors,
48+
interceptors[name].UnaryServerInterceptor(),
49+
)
50+
}
4151
}
4252

4353
opts = append(
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
version: '3'
2+
rpc:
3+
listen: "tcp://127.0.0.1:6011"
4+
server:
5+
command: "php php_test_files/worker-grpc.php"
6+
relay: "pipes"
7+
relay_timeout: "20s"
8+
logs:
9+
mode: development
10+
level: error
11+
grpc:
12+
listen: "tcp://127.0.0.1:9011"
13+
proto:
14+
- "proto/service/service.proto"
15+
interceptors:
16+
- "interceptor1"
17+
- "interceptor2"
18+
max_send_msg_size: 50
19+
max_recv_msg_size: 50
20+
max_connection_idle: 0s
21+
max_connection_age: 0s
22+
max_connection_age_grace: 0s
23+
max_concurrent_streams: 10
24+
ping_time: 1s
25+
timeout: 200s
26+
pool:
27+
num_workers: 2
28+
max_jobs: 0
29+
allocate_timeout: 60s
30+
destroy_timeout: 60s

tests/doc.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// Package grpc_test contains end-to-end tests for the gRPC plugin.
2+
package grpc_test

0 commit comments

Comments
 (0)