├── .gitignore ├── CHANGELOG.md ├── CODE-OF-CONDUCT.md ├── CODE-OF-CONDUCT.zh_CN.md ├── CONTRIBUTING.md ├── CONTRIBUTING.zh_CN.md ├── CONTRIBUTORS.md ├── CONTRIBUTORS.zh_CN.md ├── LICENSE ├── Makefile ├── README.md ├── common ├── README.md ├── convert │ ├── map.go │ ├── map_test.go │ ├── string.go │ └── string_test.go ├── errs │ ├── errs.go │ ├── http_code.go │ ├── http_code_test.go │ ├── wrap.go │ └── wrap_test.go ├── gwmsg │ ├── gwmsg.go │ ├── gwmsg_imp.go │ ├── gwmsg_imp_test.go │ └── mock │ │ └── mock_msg.go ├── http │ ├── context.go │ ├── context_test.go │ ├── header.go │ ├── header_test.go │ ├── param.go │ ├── param_test.go │ └── proxy.go ├── plugin │ └── plugin.go └── trpc │ ├── env.go │ ├── env_test.go │ ├── serialization.go │ └── serialization_test.go ├── core ├── README.md ├── config │ ├── config.go │ ├── config_test.go │ ├── configmock │ │ └── loader_mock.go │ ├── loader.go │ ├── loader_test.go │ ├── options.go │ ├── options_test.go │ └── proxy_test.go ├── entity │ ├── proxy.go │ └── proxy_test.go ├── loader │ ├── etcd │ │ ├── README.md │ │ ├── etcd_loader.go │ │ ├── etcd_loader_test.go │ │ ├── go.mod │ │ └── go.sum │ └── file │ │ ├── file_loader.go │ │ └── file_loader_test.go ├── router │ ├── README.md │ ├── README.zh_CN.md │ ├── fasthttp_router.go │ ├── fasthttp_router_test.go │ ├── mock │ │ └── mockrouter.go │ ├── router.go │ └── router_test.go ├── rule │ ├── README.md │ ├── rule.go │ └── rule_test.go └── service │ ├── fhttp │ ├── README.md │ ├── codec.go │ ├── codec_test.go │ ├── connpool.go │ ├── connpool_test.go │ ├── handler.go │ ├── handler_test.go │ ├── mock │ │ └── pool_mock.go │ ├── service_desc.go │ ├── service_desc_test.go │ ├── tls.go │ ├── tls_test.go │ ├── transport.go │ └── transport_test.go │ └── protocol │ ├── README.md │ ├── cliprotocol.go │ ├── cliprotocol_test.go │ ├── fasthttp │ ├── transformer.go │ └── transformer_test.go │ ├── grpc │ ├── Makefile │ ├── READEME.md │ ├── codec.go │ ├── codec_json.go │ ├── codec_json_test.go │ ├── codec_test.go │ ├── go.mod │ ├── go.sum │ ├── header.go │ ├── header_test.go │ ├── mock │ │ ├── connpool.go │ │ ├── grpcclient.go │ │ └── messge.go │ ├── pool.go │ ├── pool_test.go │ ├── transformer.go │ ├── transformer_test.go │ ├── transport.go │ └── transport_test.go │ ├── http │ ├── README.md │ ├── print.go │ ├── print_test.go │ ├── transformer.go │ └── transformer_test.go │ ├── mock │ └── protocol_mock.go │ └── trpc │ ├── transformer.go │ └── transformer_test.go ├── example ├── http2grpc │ ├── Makefile │ ├── README.md │ ├── conf │ │ └── router.yaml │ ├── go.mod │ ├── go.sum │ ├── main.go │ ├── test.http │ ├── trpc_go.yaml │ └── upstream │ │ ├── jsoncodec │ │ └── proto.go │ │ ├── main.go │ │ └── proto │ │ ├── helloworld.pb.go │ │ ├── helloworld.proto │ │ └── helloworld_grpc.pb.go ├── loader │ ├── etcd │ │ ├── Makefile │ │ ├── README.md │ │ ├── conf │ │ │ └── router.yaml │ │ ├── go.mod │ │ ├── go.sum │ │ ├── main.go │ │ ├── test.http │ │ └── trpc_go.yaml │ ├── file │ │ ├── Makefile │ │ ├── README.md │ │ ├── conf │ │ │ └── router.yaml │ │ ├── go.mod │ │ ├── go.sum │ │ ├── main.go │ │ ├── test.http │ │ └── trpc_go.yaml │ └── upstream │ │ ├── greeter.go │ │ ├── helloworld.proto │ │ ├── main.go │ │ └── trpc_go.yaml ├── sse │ ├── Makefile │ ├── README.md │ ├── conf │ │ └── router.yaml │ ├── go.mod │ ├── go.sum │ ├── main.go │ ├── test.http │ ├── trpc_go.yaml │ └── upstream │ │ └── main.go └── websocket │ ├── Makefile │ ├── README.md │ ├── client │ └── client.go │ ├── conf │ └── router.yaml │ ├── go.mod │ ├── go.sum │ ├── main.go │ ├── trpc_go.yaml │ └── upstream │ └── main.go ├── go.mod ├── go.sum ├── internal ├── hopbyhop.go ├── pool │ └── objectpool │ │ ├── buffer_pool.go │ │ ├── buffer_pool_test.go │ │ ├── bytes_pool.go │ │ └── bytes_pool_test.go ├── reuseport │ ├── reuseport.go │ ├── reuseport_bsd.go │ ├── reuseport_linux.go │ ├── reuseport_windows.go │ ├── tcp.go │ ├── tcp_linux_test.go │ ├── tcp_test.go │ ├── testdata │ │ ├── EmptyLine.txt │ │ ├── NoEof.txt │ │ ├── NumMax.txt │ │ └── NumZero.txt │ ├── udp.go │ └── udp_test.go └── util │ ├── env.go │ ├── plugin.go │ └── plugin_test.go ├── plugin ├── README.md ├── accesslog │ ├── Makefile │ ├── README.md │ ├── go.mod │ ├── go.sum │ ├── plugin.go │ └── plugin_test.go ├── batchrequest │ ├── Makefile │ ├── README.md │ ├── docs │ │ ├── batch_request.png │ │ └── console.png │ ├── go.mod │ ├── go.sum │ ├── plugin.go │ └── plugin_test.go ├── cors │ ├── CHANGELOG.md │ ├── Makefile │ ├── README.md │ ├── cors.go │ ├── cors_test.go │ ├── go.mod │ └── go.sum ├── demo │ ├── Makefile │ ├── README.md │ ├── demo.go │ └── demo_test.go ├── devenv │ ├── Makefile │ ├── README.md │ ├── docs │ │ ├── console.png │ │ └── devenv.png │ ├── go.mod │ ├── go.sum │ ├── plugin.go │ └── plugin_test.go ├── limiter │ └── polaris │ │ ├── CHANGELOG.md │ │ ├── Makefile │ │ ├── README.md │ │ ├── docs │ │ └── img.png │ │ ├── go.mod │ │ ├── go.sum │ │ ├── mock │ │ ├── polaris_mock.go │ │ └── quota_mock.go │ │ ├── plugin.go │ │ └── plugin_test.go ├── logreplay │ ├── Makefile │ ├── README.md │ ├── docs │ │ ├── img.png │ │ └── logreplay.png │ ├── go.mod │ ├── go.sum │ ├── plugin.go │ └── plugin_test.go ├── mock │ ├── decoder.go │ ├── gatewayplugin.go │ └── trpcplugin.go ├── mocking │ ├── Makefile │ ├── README.md │ ├── go.mod │ ├── go.sum │ ├── plugin.go │ └── plugin_test.go ├── plugin.go ├── plugin_test.go ├── polaris │ ├── canaryrouter │ │ ├── Makefile │ │ ├── README.md │ │ ├── go.mod │ │ ├── go.sum │ │ ├── plugin.go │ │ └── plugin_test.go │ ├── metarouter │ │ ├── Makefile │ │ ├── README.md │ │ ├── go.mod │ │ ├── go.sum │ │ ├── plugin.go │ │ └── plugin_test.go │ └── setrouter │ │ ├── Makefile │ │ ├── README.md │ │ ├── go.mod │ │ ├── go.sum │ │ ├── plugin.go │ │ └── plugin_test.go ├── redirect │ ├── Makefile │ ├── README.md │ ├── docs │ │ └── img.png │ ├── go.mod │ ├── go.sum │ ├── plugin.go │ └── plugin_test.go ├── routercheck │ ├── Makefile │ ├── README.md │ ├── go.mod │ ├── go.sum │ ├── plugin.go │ └── plugin_test.go ├── traceid │ ├── Makefile │ ├── README.md │ ├── docs │ │ └── img.png │ ├── go.mod │ ├── go.sum │ ├── plugin.go │ └── plugin_test.go └── transformer │ ├── request │ ├── CHANGLOG.md │ ├── Makefile │ ├── README.md │ ├── docs │ │ └── img.png │ ├── go.mod │ ├── go.sum │ ├── plugin.go │ └── plugin_test.go │ ├── response │ ├── Makefile │ ├── README.md │ ├── docs │ │ └── img.png │ ├── go.mod │ ├── go.sum │ ├── plugin.go │ ├── plugin_test.go │ └── testdata │ │ └── router.yaml │ └── trpcerr2body │ ├── Makefile │ ├── README.md │ ├── docs │ └── img.png │ ├── go.mod │ ├── go.sum │ ├── plugin.go │ └── plugin_test.go ├── testdata ├── README.md ├── router.d │ └── router.yaml ├── router.yaml ├── router_invalid.yaml ├── routerbenchmark.yaml ├── routerbenchmarkregexp.yaml ├── server.crt ├── server.csr ├── server.key ├── testcase │ └── router.md ├── trpc_go.yaml └── trpc_go_error.yaml └── version.go /.gitignore: -------------------------------------------------------------------------------- 1 | trpc-gateway 2 | # Binaries for programs and plugins 3 | *.exe 4 | *.exe~ 5 | *.dll 6 | *.so 7 | *.dylib 8 | 9 | # Test binary, built with `go test -c` 10 | *.test 11 | 12 | # Output of the go coverage tool, specifically when used with LiteIDE 13 | *.out 14 | 15 | # Editor files 16 | .vscode/ 17 | .idea/ 18 | 19 | # Temp files 20 | *.log 21 | **/.DS_Store 22 | log/trpc_time.log.* 23 | cover.html 24 | cover.out.tmp 25 | 26 | # Vendor 27 | vendor/ 28 | 29 | # Project's binary 30 | examples/helloworld/helloworld 31 | examples/helloworld/helloworld.test -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | ## [v1.0.2](https://github.com/trpc-ecosystem/go-gateway/tree/v1.0.2) (2024-07-20) 3 | 4 | ### Features 5 | 6 | - Supports custom server TLS configurations,[more detail](https://github.com/trpc-ecosystem/go-gateway/tree/main/core/service/fhttp#17-supporting-custom-tls-configurations) 7 | 8 | ## [v1.0.1](https://github.com/trpc-ecosystem/go-gateway/tree/v1.0.1) (2024-06-02) 9 | 10 | ### Features 11 | 12 | - update trpc-go version to support SSE timeout setting 13 | - add SSE,Websocket example 14 | - limiter/polaris support more labels options 15 | -------------------------------------------------------------------------------- /CODE-OF-CONDUCT.zh_CN.md: -------------------------------------------------------------------------------- 1 | [English](CODE-OF-CONDUCT.md) | 中文 2 | 3 | # 社区行为准则 4 | 5 | 欢迎来到我们的开源项目! 6 | 7 | 我们致力于创建一个友好、尊重和包容的社区,我们希望所有人都能为此做出贡献。 8 | 为了确保在我们的项目中有一个积极的体验,我们制定了以下行为准则,我们要求所有参与者遵守这些准则,并向所有社区成员提供一个安全和包容的环境。 9 | 10 | ## 我们的承诺 11 | 12 | 作为我们社区的参与者、贡献者和维护者,我们承诺: 13 | - 以开放、包容和合作的态度对待所有人; 14 | - 尊重不同背景和观点的人,不论是性别、性取向、残疾、种族、民族、宗教、年龄或任何其他因素; 15 | - 专注于对项目的贡献和改进,而不是对个人的攻击或抨击; 16 | - 与社区成员建立互信关系,通过积极的反馈来推动我们的项目发展; 17 | - 为社区成员提供一个安全、支持和鼓励的环境,以促进学习和个人成长。 18 | 19 | ## 我们的标准 20 | 21 | 我们的社区成员应该遵守以下标准: 22 | - 尊重他人的意见、观点和经验; 23 | - 避免使用侮辱性、歧视性或有损的语言; 24 | - 不要骚扰、恐吓或威胁他人; 25 | - 不要公开或私下发布他人的私人信息,例如联系方式或地址; 26 | - 尊重他人的隐私权; 27 | - 为社区成员建立安全、包容和尊重的环境。 28 | 29 | ## 我们的责任 30 | 31 | 项目维护者有责任为我们的社区成员创造一个友好、尊重和包容的环境。 32 | 他们应该: 33 | - 明确和公开地说明社区准则; 34 | - 处理准则违规行为的举报,通过适当的方式解决纠纷; 35 | - 保护所有社区成员的隐私和安全; 36 | - 保持公正、透明和负责任的态度。 37 | 38 | ## 管理范围 39 | 40 | 本行为准则适用于所有的项目空间,包括GitHub、邮件列表、论坛、社交媒体、聚会和会议等。 41 | 违反准则的行为将受到处理,包括但不限于警告、暂时或永久禁言、撤销贡献权、撤销项目访问权等。 42 | 43 | ## 实施指南 44 | 45 | 如果你遇到了违反本准则的行为,你可以: 46 | - 私下与相关人员沟通,以尝试解决问题; 47 | - 向项目维护者报告违规行为,维护者会根据情况采取必要的行动; 48 | - 如果你不满意维护者的处理方式,你可以向更高级别的机构或组织寻求帮助。 49 | 50 | 我们的社区是一个多样化、开放和包容的社区,我们欢迎所有人的参与和贡献。 51 | 我们相信,只有在一个安全、尊重和包容的环境中,我们才能共同创造出最优秀的项目。 -------------------------------------------------------------------------------- /CONTRIBUTORS.zh_CN.md: -------------------------------------------------------------------------------- 1 | [English](CONTRIBUTORS.md) | 中文 2 | 3 | # 贡献者管理说明文档 4 | 5 | 感谢您对本开源项目的关注和支持!本文档将阐述贡献者在项目中的角色、职责以及如何从Contributor升级为Maintainer,以及Maintainer降级为Contributor的规则。我们希望通过这份文档,让每位贡献者都能清楚地了解自己的成长路径,并为项目的发展做出更大的贡献。 6 | 7 | ## 贡献者角色及职责 8 | 9 | 在本开源项目中,我们主要设有两个贡献者角色:Contributor和Maintainer。 10 | 以下是对这两个角色的简要介绍: 11 | 1. Contributor:项目的贡献者,可以是代码贡献者、文档贡献者、测试贡献者等。Contributor为项目提供了宝贵的资源,帮助项目不断完善和发展。 12 | 2. Maintainer:项目的维护者,负责项目的日常维护工作,包括审查和合并PR、处理Issue、发布版本等。Maintainer是项目的核心成员,对项目的发展方向和决策具有重要的影响力。 13 | 14 | ## Contributor升级为Maintainer 15 | 16 | 我们非常欢迎每位Contributor为项目的发展做出贡献,并鼓励Contributor向Maintainer的角色发展。 17 | 以下是从Contributor升级为Maintainer的条件: 18 | 1. 持续贡献:Contributor需要在一段时间内(例如3个月)持续为项目贡献代码、文档或其他资源。这表明Contributor对项目的关注度和热情。 19 | 2. 质量保证:Contributor提交的代码或文档等资源需要保持较高的质量,符合项目的规范要求,并对项目产生积极的影响。 20 | 3. 积极参与:Contributor需要积极参与到项目的讨论和决策中来,为项目的发展提供建设性的意见和建议。 21 | 4. 团队协作:Contributor需要具备良好的团队协作精神,能够与其他贡献者和Maintainer友好沟通,共同解决问题。 22 | 5. 责任担当:Contributor需要具备一定的责任心,愿意承担项目维护的部分工作,包括审查PR、处理Issue等。 23 | 24 | 当Contributor满足以上条件时,现有的Maintainer将会对其进行评估,如果达到Maintainer的要求,将会邀请其成为新的Maintainer。 25 | 26 | ## Maintainer降级为Contributor 27 | 28 | Maintainer在项目中承担了重要的职责,我们希望每位Maintainer都能够保持对项目的关注和热情。 29 | 然而,我们也理解每个人的时间和精力是有限的,因此,当Maintainer无法继续履行职责时,将会降级为Contributor: 30 | 1. 长时间不活跃:如果Maintainer在一段时间内(例如3个月)没有参与项目的维护工作,包括审查PR、处理Issue等,将被视为不活跃。 31 | 2. 质量问题:如果Maintainer在项目中的工作出现严重的质量问题,导致项目的发展受到影响,将被视为不符合Maintainer的要求。 32 | 3. 团队协作问题:如果Maintainer在与其他贡献者和Maintainer的协作过程中出现严重的沟通问题或团队协作问题,如不尊重他人意见、频繁产生冲突、拒绝协作等,影响到项目的正常运作和氛围,将被视为不符合Maintainer的要求。 33 | 4. 违反规定:如果Maintainer违反了项目的规定或行为准则,包括但不限于泄露敏感信息、滥用权限等,将被视为不符合Maintainer的要求。 34 | 5. 主动申请:如果Maintainer由于个人原因无法继续履行职责,可以主动申请降级为Contributor。 -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | GO = go 2 | DTOOLS = dtools 3 | TARGET = trpc-gateway 4 | 5 | # set for mac M1Pro 6 | export GOARCH=amd64 7 | 8 | all: fmt goimports lint 9 | 10 | fmt: 11 | @gofmt -s -w ./$* 12 | 13 | vet: 14 | @go vet -all ./ 15 | 16 | ec: 17 | @errcheck ./... | grep -v Close 18 | 19 | lint: 20 | @golint ./... 21 | 22 | goimports: 23 | @goimports -d -w ./ 24 | 25 | test: 26 | CFLAGS=-g 27 | export CFLAGS 28 | $(GO) test $(M) -v -gcflags=all=-l -coverpkg=./... -coverprofile=test.out ./... 29 | clean: 30 | rm -f $(TARGET) 31 | rm -rf release 32 | 33 | cover: COVERAGE_FILE := coverage.out 34 | cover: 35 | @go test ./... -coverprofile=$(COVERAGE_FILE) -gcflags=all=-l && \ 36 | go tool cover -html=$(COVERAGE_FILE) && rm $(COVERAGE_FILE) 37 | 38 | mod: 39 | cd plugin/accesslog && go mod tidy 40 | cd plugin/batchrequest && go mod tidy 41 | cd plugin/cors && go mod tidy 42 | cd plugin/devenv && go mod tidy 43 | cd plugin/limiter/polaris && go mod tidy 44 | cd plugin/logreplay && go mod tidy 45 | cd plugin/mocking && go mod tidy 46 | cd plugin/polaris/canaryrouter && go mod tidy 47 | cd plugin/polaris/metarouter && go mod tidy 48 | cd plugin/polaris/setrouter && go mod tidy 49 | cd plugin/redirect && go mod tidy 50 | cd plugin/routercheck && go mod tidy 51 | cd plugin/traceid && go mod tidy 52 | cd plugin/transformer/request && go mod tidy 53 | cd plugin/transformer/response && go mod tidy 54 | cd plugin/transformer/trpcerr2body && go mod tidy 55 | cd core/loader/etcd && go mod tidy 56 | cd core/service/protocol/grpc && go mod tidy 57 | cd example/loader/etcd && go mod tidy 58 | cd example/loader/file && go mod tidy -------------------------------------------------------------------------------- /common/README.md: -------------------------------------------------------------------------------- 1 | # Gateway Common Package 2 | 3 | The common package is the basic package and cannot depend on other packages of this project. 4 | 5 | ### convert 6 | 7 | Tools and methods related to format conversion 8 | 9 | ### errs 10 | 11 | Error code constants and related methods that this project and third-party plug-ins rely on. 12 | 13 | ### file 14 | 15 | Related tools and methods for file operations 16 | 17 | ### gwmsg 18 | 19 | Gateway msg related methods, the same implementation as trpc-go msg. 20 | 21 | ### http 22 | 23 | Common methods related to http used by gateway core and plugins 24 | 25 | ### trpc 26 | 27 | A simple encapsulation of the trpc method, providing the ability to be rewritten by the business side. 28 | 29 | ### plugin 30 | 31 | Common methods related to plugins 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /common/convert/map.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package convert 15 | 16 | // StrSlice2Map converts a string slice into a map. Note: it will filter out empty strings. 17 | func StrSlice2Map(list []string) map[string]struct{} { 18 | m := make(map[string]struct{}, len(list)) 19 | for _, s := range list { 20 | if s == "" { 21 | continue 22 | } 23 | m[s] = struct{}{} 24 | } 25 | return m 26 | } 27 | -------------------------------------------------------------------------------- /common/convert/map_test.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package convert 15 | 16 | import ( 17 | "testing" 18 | 19 | "github.com/stretchr/testify/assert" 20 | ) 21 | 22 | func TestStr2Map(t *testing.T) { 23 | s := []string{"a", "b", ""} 24 | assert.EqualValues(t, map[string]struct{}{"a": {}, "b": {}}, StrSlice2Map(s)) 25 | } 26 | -------------------------------------------------------------------------------- /common/convert/string.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | // Package convert some parameter conversion utility functions. 15 | package convert 16 | 17 | import ( 18 | "encoding/json" 19 | "hash/fnv" 20 | "strconv" 21 | ) 22 | 23 | // ToJSONStr converts to JSON string for logging purposes. 24 | func ToJSONStr(o interface{}) string { 25 | // 用于日志打印,忽略错误 26 | b, _ := json.Marshal(o) 27 | return string(b) 28 | } 29 | 30 | // ToIntSlice converts to a list of integers. 31 | func ToIntSlice(list []string) ([]int, error) { 32 | var idxList []int 33 | for _, i := range list { 34 | idx, err := strconv.Atoi(i) 35 | if err != nil { 36 | return nil, err 37 | } 38 | idxList = append(idxList, idx) 39 | } 40 | return idxList, nil 41 | } 42 | 43 | // Fnv32 Fnv-hash algorithm 44 | // FNV can quickly hash large amounts of data while maintaining a low collision rate. 45 | // Its high dispersion makes it suitable for hashing very similar strings. 46 | func Fnv32(str string) uint32 { 47 | h := fnv.New32a() 48 | _, _ = h.Write([]byte(str)) 49 | return h.Sum32() 50 | } 51 | -------------------------------------------------------------------------------- /common/convert/string_test.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package convert_test 15 | 16 | import ( 17 | "testing" 18 | 19 | "github.com/stretchr/testify/assert" 20 | "trpc.group/trpc-go/trpc-gateway/common/convert" 21 | ) 22 | 23 | func TestToJSONStr(t *testing.T) { 24 | assert.Equal(t, convert.ToJSONStr(1), "1") 25 | } 26 | 27 | func TestToIntSlice(t *testing.T) { 28 | s := []string{"1", "2"} 29 | got, err := convert.ToIntSlice(s) 30 | assert.Nil(t, err) 31 | assert.ElementsMatch(t, got, []int{1, 2}) 32 | 33 | s = []string{"1", "2", "c"} 34 | _, err = convert.ToIntSlice(s) 35 | assert.NotNil(t, err) 36 | } 37 | 38 | func TestFnv32(t *testing.T) { 39 | ret := convert.Fnv32("str") 40 | t.Log(ret) 41 | assert.Equal(t, uint32(3259748752), ret) 42 | } 43 | -------------------------------------------------------------------------------- /common/errs/errs.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | // Package errs API gateway framework error related definitions, related methods 15 | package errs 16 | 17 | import trpcpb "trpc.group/trpc/trpc-protocol/pb/go/trpc" 18 | 19 | const ( 20 | // Success status code 21 | Success = 0 22 | // ErrGatewayUnknown Distinguishing between unknown errors in the gateway and unknown error codes in trpc 23 | ErrGatewayUnknown = trpcpb.TrpcRetCode(999) 24 | 25 | // ErrWrongConfig Configuration error 26 | ErrWrongConfig = trpcpb.TrpcRetCode(1001) 27 | 28 | // ErrPathNotFound No route matched 29 | ErrPathNotFound = trpcpb.TrpcRetCode(1002) 30 | 31 | // ErrWrongContext Context type error (non-fasthttp context) 32 | ErrWrongContext = trpcpb.TrpcRetCode(1003) 33 | 34 | // ErrTargetServiceNotFound Failed to obtain the target server 35 | ErrTargetServiceNotFound = trpcpb.TrpcRetCode(1004) 36 | 37 | // ErrContextNoServiceVal Failed to obtain service information from the context 38 | ErrContextNoServiceVal = trpcpb.TrpcRetCode(1005) 39 | 40 | // ErrPluginConfigNotFound Failed to obtain plugin configuration from the context 41 | ErrPluginConfigNotFound = trpcpb.TrpcRetCode(1006) 42 | 43 | // ErrInvalidPluginConfig Plugin configuration error 44 | ErrInvalidPluginConfig = trpcpb.TrpcRetCode(1007) 45 | 46 | // ErrUpstreamRspErr upstream HTTP status code is not 200 47 | ErrUpstreamRspErr = trpcpb.TrpcRetCode(1008) 48 | 49 | // ErrInvalidReq Illegal request, protocol error, etc. 50 | ErrInvalidReq = trpcpb.TrpcRetCode(1009) 51 | 52 | // ErrUnSupportProtocol Unsupported protocol type 53 | ErrUnSupportProtocol = trpcpb.TrpcRetCode(1010) 54 | 55 | // ErrProtocolTrans Protocol conversion failed 56 | ErrProtocolTrans = trpcpb.TrpcRetCode(1011) 57 | 58 | // ErrConnClosed Connection pool closed 59 | ErrConnClosed = trpcpb.TrpcRetCode(1012) 60 | ) 61 | 62 | const ( 63 | // GatewayERRKey Reporting key for abnormal configuration loading to be used for monitoring and alerting 64 | GatewayERRKey = "trpc_gateway_report" 65 | ) 66 | -------------------------------------------------------------------------------- /common/errs/http_code_test.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package errs_test 15 | 16 | import ( 17 | "testing" 18 | 19 | "github.com/stretchr/testify/assert" 20 | "github.com/valyala/fasthttp" 21 | gerrs "trpc.group/trpc-go/trpc-gateway/common/errs" 22 | "trpc.group/trpc-go/trpc-go/errs" 23 | ) 24 | 25 | func TestRegister(t *testing.T) { 26 | // Error code already exists 27 | err := gerrs.Register(errs.RetServerDecodeFail, 1) 28 | assert.NotNil(t, err) 29 | // Registration successful 30 | err = gerrs.Register(4001, 1) 31 | assert.Nil(t, err) 32 | } 33 | 34 | func TestGetCodeMap(t *testing.T) { 35 | // Successful retrieval 36 | httpCode := gerrs.GetHTTPStatus(errs.RetServerDecodeFail) 37 | assert.Equal(t, fasthttp.StatusBadRequest, httpCode) 38 | // fallback obtained 39 | httpCode = gerrs.GetHTTPStatus(4002) 40 | assert.Equal(t, fasthttp.StatusInternalServerError, httpCode) 41 | } 42 | 43 | func TestRegisterHTTPSuccessStatus(t *testing.T) { 44 | gerrs.RegisterSuccessHTTPStatus([]int32{302}) 45 | gerrs.IsSuccessHTTPStatus(302) 46 | } 47 | -------------------------------------------------------------------------------- /common/errs/wrap.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package errs 15 | 16 | import ( 17 | "errors" 18 | "fmt" 19 | 20 | "trpc.group/trpc-go/trpc-go/errs" 21 | ) 22 | 23 | // Wrap the error to use a unified log separator, 24 | // refer to this article for the usage of the errors standard library: 25 | // https://www.flysnow.org/2019/09/06/go1.13-error-wrapping.html 26 | func Wrap(e error, msg string) error { 27 | return fmt.Errorf("%s||%w", msg, wrapAsTRPCErr(e)) 28 | } 29 | 30 | // Wrapf Wrap the error to use a unified log separator, with the ability to pass parameters 31 | func Wrapf(err error, format string, arg ...interface{}) error { 32 | return fmt.Errorf("%s||%w", fmt.Sprintf(format, arg...), wrapAsTRPCErr(err)) 33 | } 34 | 35 | // UnWrap Obtain the most original trpc error 36 | func UnWrap(e error) (*errs.Error, bool) { 37 | if e == nil { 38 | return nil, false 39 | } 40 | var terr *errs.Error 41 | if !errors.As(e, &terr) { 42 | return nil, false 43 | } 44 | return terr, true 45 | } 46 | 47 | // If it is not a trpc error, wrap it as a trpc error 48 | func wrapAsTRPCErr(e error) error { 49 | if e == nil { 50 | return nil 51 | } 52 | var terr *errs.Error 53 | if !errors.As(e, &terr) { 54 | return errs.Wrap(e, ErrGatewayUnknown, e.Error()) 55 | } 56 | return e 57 | } 58 | -------------------------------------------------------------------------------- /common/errs/wrap_test.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package errs_test 15 | 16 | import ( 17 | "errors" 18 | "testing" 19 | 20 | "github.com/stretchr/testify/assert" 21 | gerrs "trpc.group/trpc-go/trpc-gateway/common/errs" 22 | "trpc.group/trpc-go/trpc-go/errs" 23 | ) 24 | 25 | func TestWrap(t *testing.T) { 26 | err := gerrs.Wrap(errors.New("err"), "my err") 27 | assert.NotNil(t, err) 28 | 29 | err = gerrs.Wrap(nil, "my err") 30 | assert.NotNil(t, err) 31 | 32 | var e *errs.Error 33 | err = gerrs.Wrap(e, "my err") 34 | assert.NotNil(t, err) 35 | } 36 | 37 | func TestWrapf(t *testing.T) { 38 | err := gerrs.Wrapf(errors.New("err"), "my err:%s", "args") 39 | assert.NotNil(t, err) 40 | } 41 | 42 | func TestUnWrap(t *testing.T) { 43 | _, ok := gerrs.UnWrap(nil) 44 | assert.False(t, ok) 45 | _, ok = gerrs.UnWrap(errors.New("err")) 46 | assert.False(t, ok) 47 | terr, ok := gerrs.UnWrap(errs.New(1, "trpc err")) 48 | assert.True(t, ok) 49 | assert.Equal(t, 1, int(terr.Code)) 50 | } 51 | -------------------------------------------------------------------------------- /common/gwmsg/gwmsg.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | // Package gwmsg defines gateway message 15 | package gwmsg 16 | 17 | import ( 18 | "trpc.group/trpc-go/trpc-go/client" 19 | ) 20 | 21 | //go:generate mockgen -destination=./mock/mock_msg.go . GwMsg 22 | 23 | // GwMsg Gateway Msg interface, used for parameter sharing 24 | type GwMsg interface { 25 | // WithTargetService sets target service 26 | WithTargetService(cli *client.BackendConfig) 27 | // TargetService returns target service 28 | TargetService() *client.BackendConfig 29 | 30 | // WithPluginConfig sets plugin configuration 31 | WithPluginConfig(name string, config interface{}) 32 | // PluginConfig returns plugin configuration, do not make concurrent calls 33 | PluginConfig(name string) interface{} 34 | 35 | // WithRouterID sets router ID 36 | WithRouterID(routerID string) 37 | // RouterID returns router ID 38 | RouterID() string 39 | 40 | // WithUpstreamLatency sets upstream latency 41 | WithUpstreamLatency(latency int64) 42 | // UpstreamLatency returns upstream latency 43 | UpstreamLatency() int64 44 | 45 | // WithUpstreamAddr sets upstream address 46 | WithUpstreamAddr(add string) 47 | // UpstreamAddr returns upstream address 48 | UpstreamAddr() string 49 | 50 | // WithUpstreamMethod sets upstream method 51 | WithUpstreamMethod(method string) 52 | // UpstreamMethod returns upstream method 53 | UpstreamMethod() string 54 | 55 | // WithUpstreamRspHead sets upstream ClientRspHead 56 | WithUpstreamRspHead(rspHead interface{}) 57 | // UpstreamRspHead returns upstream ClientRspHead 58 | UpstreamRspHead() interface{} 59 | 60 | // WithTRPCClientOpts sets trpc client options 61 | WithTRPCClientOpts(opts []client.Option) 62 | // TRPCClientOpts returns trpc client options 63 | TRPCClientOpts() []client.Option 64 | } 65 | -------------------------------------------------------------------------------- /common/http/context.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package http 15 | 16 | import ( 17 | "context" 18 | 19 | "github.com/valyala/fasthttp" 20 | ) 21 | 22 | // ContextKey defines context key of http. 23 | type ContextKey string 24 | 25 | // ContextKeyReq key of fasthttp header 26 | const ContextKeyReq = ContextKey("TRPC_SERVER_FASTHTTP_REQ") 27 | 28 | // RequestContext gets the corresponding fasthttp header from context. 29 | func RequestContext(ctx context.Context) *fasthttp.RequestCtx { 30 | if ret, ok := ctx.Value(ContextKeyReq).(*fasthttp.RequestCtx); ok { 31 | return ret 32 | } 33 | return nil 34 | } 35 | 36 | // WithRequestContext sets fasthttp header in context. 37 | func WithRequestContext(ctx context.Context, val *fasthttp.RequestCtx) context.Context { 38 | return context.WithValue(ctx, ContextKeyReq, val) 39 | } 40 | -------------------------------------------------------------------------------- /common/http/context_test.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package http_test 15 | 16 | import ( 17 | "context" 18 | "testing" 19 | 20 | "github.com/stretchr/testify/assert" 21 | "github.com/valyala/fasthttp" 22 | "trpc.group/trpc-go/trpc-gateway/common/http" 23 | trpc "trpc.group/trpc-go/trpc-go" 24 | ) 25 | 26 | func TestWithRequestContext(t *testing.T) { 27 | ctx := trpc.BackgroundContext() 28 | fctx := &fasthttp.RequestCtx{} 29 | 30 | ctx = http.WithRequestContext(ctx, fctx) 31 | assert.NotNil(t, ctx) 32 | 33 | tmpCtx := http.RequestContext(ctx) 34 | assert.Equal(t, tmpCtx, fctx) 35 | 36 | ctx = context.WithValue(ctx, http.ContextKeyReq, "a") 37 | fctx = http.RequestContext(ctx) 38 | assert.Nil(t, fctx) 39 | } 40 | -------------------------------------------------------------------------------- /common/http/header.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package http 15 | 16 | import ( 17 | "net/http" 18 | "net/url" 19 | ) 20 | 21 | const ( 22 | // TRPCGatewayHTTPHeader http header 23 | TRPCGatewayHTTPHeader = "TRPC_GATEWAY_HTTP_HEADER" 24 | // TRPCGatewayHTTPQuery http raw uri 25 | TRPCGatewayHTTPQuery = "TRPC_GATEWAY_HTTP_QUERY" 26 | ) 27 | 28 | // EncodeHTTPHeaders encode http headers to string 29 | func EncodeHTTPHeaders(h http.Header) string { 30 | if len(h) == 0 { 31 | return "" 32 | } 33 | u := make(url.Values) 34 | for k, v := range h { 35 | u[k] = v 36 | } 37 | return u.Encode() 38 | } 39 | -------------------------------------------------------------------------------- /common/http/header_test.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package http 15 | 16 | import ( 17 | "net/http" 18 | "testing" 19 | 20 | "github.com/stretchr/testify/assert" 21 | ) 22 | 23 | func TestEncodeHTTPHeaders(t *testing.T) { 24 | type args struct { 25 | h http.Header 26 | } 27 | tests := []struct { 28 | name string 29 | args args 30 | want string 31 | }{ 32 | // TODO: Add test cases. 33 | { 34 | name: "header exist", 35 | args: args{ 36 | h: http.Header{ 37 | "Content-Type": []string{ 38 | "application/json", 39 | }, 40 | }, 41 | }, 42 | want: "Content-Type=application%2Fjson", 43 | }, 44 | { 45 | name: "header not exist", 46 | args: args{}, 47 | want: "", 48 | }, 49 | } 50 | for _, tt := range tests { 51 | t.Run(tt.name, func(t *testing.T) { 52 | assert.Equalf(t, tt.want, EncodeHTTPHeaders(tt.args.h), "EncodeHTTPHeaders(%v)", tt.args.h) 53 | }) 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /common/http/param.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | // Package http contains utility methods related to HTTP. 15 | package http 16 | 17 | import ( 18 | "strings" 19 | 20 | "github.com/valyala/fasthttp" 21 | ) 22 | 23 | // GetString returns HTTP request parameters. 24 | func GetString(fctx *fasthttp.RequestCtx, key string) (ret string) { 25 | ret = string(fctx.QueryArgs().Peek(key)) 26 | 27 | if ret == "" { 28 | ret = string(fctx.PostArgs().Peek(key)) 29 | } 30 | 31 | if "" == ret { 32 | ret = string(fctx.Request.Header.Peek(key)) 33 | } 34 | 35 | if "" == ret { 36 | ret = string(fctx.Request.Header.Cookie(key)) 37 | } 38 | 39 | if "" == ret { 40 | ret = string(fctx.Request.Header.Cookie("%20" + key)) 41 | } 42 | return 43 | } 44 | 45 | // GetParam retrieves the parameter and checks if it exists or not. 46 | func GetParam(ctx *fasthttp.RequestCtx, key string) (string, bool) { 47 | if ctx.PostArgs().Has(key) { 48 | return string(ctx.PostArgs().Peek(key)), true 49 | } 50 | 51 | if ctx.QueryArgs().Has(key) { 52 | return string(ctx.QueryArgs().Peek(key)), true 53 | } 54 | 55 | return "", false 56 | } 57 | 58 | const localAddress = "127.0.0.1" 59 | 60 | // GetClientIP returns the client's IP address. 61 | func GetClientIP(fctx *fasthttp.RequestCtx) string { 62 | clientIPByte := fctx.Request.Header.Peek(fasthttp.HeaderXForwardedFor) 63 | clientIPs := strings.Split(string(clientIPByte), ",") 64 | clientIP := clientIPs[0] 65 | if len(clientIP) > 0 && clientIP != localAddress { 66 | return clientIP 67 | } 68 | clientIP = strings.TrimSpace(string(fctx.Request.Header.Peek("X-Real-Ip"))) 69 | if clientIP != "" && clientIP != localAddress { 70 | return clientIP 71 | } 72 | return "" 73 | } 74 | -------------------------------------------------------------------------------- /common/http/param_test.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package http_test 15 | 16 | import ( 17 | "testing" 18 | 19 | "github.com/stretchr/testify/assert" 20 | "github.com/valyala/fasthttp" 21 | "trpc.group/trpc-go/trpc-gateway/common/http" 22 | ) 23 | 24 | func TestGetString(t *testing.T) { 25 | ctx := &fasthttp.RequestCtx{} 26 | ret := http.GetString(ctx, "devid") 27 | assert.Equal(t, "", ret) 28 | } 29 | 30 | func TestGetParam(t *testing.T) { 31 | ctx := &fasthttp.RequestCtx{} 32 | ret, ok := http.GetParam(ctx, "devid") 33 | assert.Equal(t, "", ret) 34 | assert.Equal(t, false, ok) 35 | 36 | ctx.PostArgs().Set("devid", "devid") 37 | ret, ok = http.GetParam(ctx, "devid") 38 | assert.Equal(t, "devid", ret) 39 | assert.Equal(t, true, ok) 40 | 41 | ctx.QueryArgs().Set("suid", "suid") 42 | ret, ok = http.GetParam(ctx, "suid") 43 | assert.Equal(t, "suid", ret) 44 | assert.Equal(t, true, ok) 45 | } 46 | 47 | func Test_getClientIPFromContext(t *testing.T) { 48 | localAddress := "127.0.0.1" 49 | fCtx := &fasthttp.RequestCtx{} 50 | clientIP := http.GetClientIP(fCtx) 51 | assert.Equal(t, "", clientIP) 52 | fCtx.Request.Header.Set("X-Forwarded-For", "1.1.1.1") 53 | clientIP = http.GetClientIP(fCtx) 54 | assert.Equal(t, "1.1.1.1", clientIP) 55 | 56 | fCtx.Request.Header.Set("X-Forwarded-For", localAddress) 57 | clientIP = http.GetClientIP(fCtx) 58 | assert.Equal(t, "", clientIP) 59 | 60 | fCtx.Request.Header.Set("X-Real-Ip", "1.1.1.1") 61 | fCtx.Request.Header.Set("X-Forwarded-For", localAddress) 62 | clientIP = http.GetClientIP(fCtx) 63 | assert.Equal(t, "1.1.1.1", clientIP) 64 | 65 | fCtx.Request.Header.Set("X-Real-Ip", localAddress) 66 | fCtx.Request.Header.Set("X-Forwarded-For", localAddress) 67 | clientIP = http.GetClientIP(fCtx) 68 | assert.Equal(t, "", clientIP) 69 | } 70 | -------------------------------------------------------------------------------- /common/http/proxy.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package http 15 | 16 | const ( 17 | // XUpstreamLatencyHeader is the upstream latency response header. 18 | XUpstreamLatencyHeader = "X-Upstream-Latency" 19 | // XProxyLatencyHeader is the gateway latency response header. 20 | XProxyLatencyHeader = "X-Proxy-Latency" 21 | // XRouterIDHeader is the router ID. 22 | XRouterIDHeader = "X-Router-Id" 23 | // GatewayName is the name of the gateway service. 24 | GatewayName = "tRPC-Gateway" 25 | ) 26 | -------------------------------------------------------------------------------- /common/plugin/plugin.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | // Package plugin refers to constants and common methods related to gateway plugins. 15 | package plugin 16 | 17 | const ( 18 | // DefaultType refers to the default type of plugin. 19 | DefaultType = "gateway" 20 | ) 21 | -------------------------------------------------------------------------------- /common/trpc/env.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package trpc 15 | 16 | import ( 17 | trpc "trpc.group/trpc-go/trpc-go" 18 | ) 19 | 20 | // IsProduction determines whether it is a production environment 21 | type IsProduction func() bool 22 | 23 | // DefaultIsProduction determines whether it is a production environment and can be overridden 24 | var DefaultIsProduction IsProduction = func() bool { 25 | return trpc.GlobalConfig().Global.Namespace == "Production" 26 | } 27 | -------------------------------------------------------------------------------- /common/trpc/env_test.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package trpc_test 15 | 16 | import ( 17 | "testing" 18 | 19 | "github.com/stretchr/testify/assert" 20 | gtrpc "trpc.group/trpc-go/trpc-gateway/common/trpc" 21 | ) 22 | 23 | func TestIsProduction(t *testing.T) { 24 | assert.False(t, gtrpc.DefaultIsProduction()) 25 | } 26 | -------------------------------------------------------------------------------- /common/trpc/serialization_test.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package trpc 15 | 16 | import ( 17 | "testing" 18 | 19 | "github.com/stretchr/testify/assert" 20 | "trpc.group/trpc-go/trpc-go/codec" 21 | ) 22 | 23 | func TestGetSerializationType(t *testing.T) { 24 | got, err := GetSerializationType("application/json") 25 | assert.Nil(t, err) 26 | assert.Equal(t, codec.SerializationTypeJSON, got) 27 | got, err = GetSerializationType("application/json; charset=UTF-8") 28 | assert.Nil(t, err) 29 | assert.Equal(t, codec.SerializationTypeJSON, got) 30 | 31 | err = Register("application/json", 111) 32 | assert.Nil(t, err) 33 | got, err = GetSerializationType("application/json; charset=UTF-8") 34 | assert.Nil(t, err) 35 | assert.Equal(t, 111, got) 36 | 37 | got, err = GetSerializationType("text/plain; charset=UTF-8") 38 | assert.NotNil(t, err) 39 | } 40 | -------------------------------------------------------------------------------- /core/README.md: -------------------------------------------------------------------------------- 1 | # Gateway Core Package 2 | 3 | This package contains the core functionality of the gateway, including configuration reading, routing logic, and 4 | protocol forwarding. 5 | 6 | ### config 7 | 8 | Defines the gateway configuration structure and various methods for reading configuration from different sources. 9 | 10 | ### router 11 | 12 | Implements the routing strategy for the gateway. See [路由配置](router/README.md) for more details. 13 | 14 | ### rule 15 | 16 | Implements the rule engine for fine-grained matching rules. See [精细匹配规则引擎](rule/README.md) for more details. 17 | 18 | ### service 19 | 20 | Supports multiple forwarding protocols, currently including HTTP and tRPC. Support for other protocols such as gRPC will 21 | be added in the future. -------------------------------------------------------------------------------- /core/config/configmock/loader_mock.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | // Code generated by MockGen. DO NOT EDIT. 15 | // Source: trpc.group/trpc-go/trpc-gateway/core/config (interfaces: Loader) 16 | 17 | // Package configmock is a generated GoMock package. 18 | package configmock 19 | 20 | import ( 21 | context "context" 22 | reflect "reflect" 23 | 24 | gomock "github.com/golang/mock/gomock" 25 | ) 26 | 27 | // MockLoader is a mock of Loader interface. 28 | type MockLoader struct { 29 | ctrl *gomock.Controller 30 | recorder *MockLoaderMockRecorder 31 | } 32 | 33 | // MockLoaderMockRecorder is the mock recorder for MockLoader. 34 | type MockLoaderMockRecorder struct { 35 | mock *MockLoader 36 | } 37 | 38 | // NewMockLoader creates a new mock instance. 39 | func NewMockLoader(ctrl *gomock.Controller) *MockLoader { 40 | mock := &MockLoader{ctrl: ctrl} 41 | mock.recorder = &MockLoaderMockRecorder{mock} 42 | return mock 43 | } 44 | 45 | // EXPECT returns an object that allows the caller to indicate expected use. 46 | func (m *MockLoader) EXPECT() *MockLoaderMockRecorder { 47 | return m.recorder 48 | } 49 | 50 | // LoadConf mocks base method. 51 | func (m *MockLoader) LoadConf(arg0 context.Context, arg1 string) error { 52 | m.ctrl.T.Helper() 53 | ret := m.ctrl.Call(m, "LoadConf", arg0, arg1) 54 | ret0, _ := ret[0].(error) 55 | return ret0 56 | } 57 | 58 | // LoadConf indicates an expected call of LoadConf. 59 | func (mr *MockLoaderMockRecorder) LoadConf(arg0, arg1 interface{}) *gomock.Call { 60 | mr.mock.ctrl.T.Helper() 61 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LoadConf", reflect.TypeOf((*MockLoader)(nil).LoadConf), arg0, arg1) 62 | } 63 | -------------------------------------------------------------------------------- /core/config/loader.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package config 15 | 16 | import ( 17 | "context" 18 | "sync" 19 | ) 20 | 21 | var ( 22 | loaders = make(map[string]Loader) 23 | muxLoader sync.RWMutex 24 | ) 25 | 26 | // RegisterConfLoader register a router config loader 27 | func RegisterConfLoader(provider string, loader Loader) { 28 | muxLoader.Lock() 29 | loaders[provider] = loader 30 | muxLoader.Unlock() 31 | } 32 | 33 | // GetConfLoader returns a router config loader 34 | func GetConfLoader(provider string) Loader { 35 | muxLoader.RLock() 36 | l := loaders[provider] 37 | muxLoader.RUnlock() 38 | return l 39 | } 40 | 41 | // Loader is the interface for configuration loaders. 42 | // 43 | //go:generate mockgen -destination=./configmock/loader_mock.go -package=configmock . Loader 44 | type Loader interface { 45 | // LoadConf 加载配置 46 | LoadConf(ctx context.Context, protocol string) error 47 | } 48 | -------------------------------------------------------------------------------- /core/config/loader_test.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package config 15 | 16 | import ( 17 | "context" 18 | "testing" 19 | 20 | "github.com/stretchr/testify/assert" 21 | ) 22 | 23 | type mockLoader struct { 24 | } 25 | 26 | func (m mockLoader) LoadConf(context.Context, string) error { 27 | return nil 28 | } 29 | 30 | func TestRegisterConfLoader(t *testing.T) { 31 | ml := mockLoader{} 32 | RegisterConfLoader("test", ml) 33 | l := GetConfLoader("test") 34 | assert.Equal(t, l, ml) 35 | } 36 | -------------------------------------------------------------------------------- /core/config/options_test.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package config 15 | 16 | import ( 17 | "testing" 18 | "time" 19 | 20 | "github.com/stretchr/testify/assert" 21 | ) 22 | 23 | func TestOptions(t *testing.T) { 24 | opts := []ServerOption{ 25 | WithReusePort(true), 26 | WithMaxCons(10), 27 | WithMaxConsPerIP(5), 28 | WithMaxRequestBodySize(0), 29 | WithReadBufferSize(0), 30 | WithReadTimeout(time.Second), 31 | WithWriteTimeout(time.Second), 32 | } 33 | 34 | opt := &ServerOptions{} 35 | for _, o := range opts { 36 | o(opt) 37 | } 38 | 39 | assert.Equal(t, 10, opt.MaxCons) 40 | } 41 | 42 | func fakeTransOpt(...ServerOption) { 43 | } 44 | 45 | func TestRegisterCustomTransOpts(t *testing.T) { 46 | RegisterCustomTransOpts("test", fakeTransOpt) 47 | f := GetCustomTransOpts("test") 48 | assert.NotNil(t, f) 49 | } 50 | -------------------------------------------------------------------------------- /core/config/proxy_test.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package config 15 | 16 | import ( 17 | "encoding/json" 18 | "fmt" 19 | "os" 20 | "testing" 21 | 22 | "github.com/stretchr/testify/assert" 23 | "gopkg.in/yaml.v3" 24 | "trpc.group/trpc-go/trpc-gateway/core/entity" 25 | ) 26 | 27 | func TestProxyConfig(t *testing.T) { 28 | // load config 29 | confBytes, err := os.ReadFile("../../testdata/router.yaml") 30 | assert.Nil(t, err) 31 | var proxyConfig entity.ProxyConfig 32 | err = yaml.Unmarshal(confBytes, &proxyConfig) 33 | assert.Nil(t, err) 34 | config, _ := json.MarshalIndent(proxyConfig, "", " ") 35 | t.Log(string(config)) 36 | m, _ := yaml.Marshal(proxyConfig) 37 | fmt.Println(string(m)) 38 | } 39 | -------------------------------------------------------------------------------- /core/entity/proxy_test.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package entity_test 15 | 16 | import ( 17 | "testing" 18 | 19 | "github.com/stretchr/testify/assert" 20 | "gopkg.in/yaml.v3" 21 | "trpc.group/trpc-go/trpc-gateway/core/entity" 22 | "trpc.group/trpc-go/trpc-go/client" 23 | ) 24 | 25 | func TestUnmarshalYAML(t *testing.T) { 26 | bc := &entity.BackendConfig{ 27 | BackendConfig: client.BackendConfig{}, 28 | Plugins: nil, 29 | } 30 | bcByte, err := yaml.Marshal(bc) 31 | assert.Nil(t, err) 32 | err = yaml.Unmarshal(bcByte, &bc) 33 | assert.Nil(t, err) 34 | } 35 | -------------------------------------------------------------------------------- /core/loader/etcd/README.md: -------------------------------------------------------------------------------- 1 | # Router configuration etcd loader 2 | 3 | ## Usage: 4 | 5 | - Create a key named "router_conf" in etcd to manage the router configuration. 6 | - Import the etcd loader anonymously in the main.go file of the project. 7 | 8 | ```go 9 | import _ "trpc.group/trpc-go/trpc-gateway/core/loader/etcd" 10 | ``` 11 | 12 | - Specify the etcd loader in the trpc_go.yaml framework configuration and configure the etcd address. 13 | 14 | ```yaml 15 | global: # Global configuration 16 | conf_provider: etcd # Specify the etcd loader 17 | server: 18 | app: ${app} # Application name 19 | server: ${server} # Process server name 20 | service: # Services provided by the business 21 | - name: trpc.${app}.${server}.gateway # Service route name, replace ReplaceMe with your own service name, do not change app and server placeholders 22 | plugins: 23 | # Configure etcd information, refer to: https://git.woa.com/trpc-go/trpc-config-etcd 24 | config: 25 | etcd: 26 | endpoints: ["http://127.0.0.1:2380"] 27 | ``` 28 | 29 | - Configuration example:[etcd loader example](../../../example/loader/etcd) 30 | -------------------------------------------------------------------------------- /core/loader/etcd/etcd_loader_test.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package etcd 15 | 16 | import ( 17 | "testing" 18 | ) 19 | 20 | func TestETCDConfLoader_LoadConf(t *testing.T) { 21 | // TODO 补充单测 22 | } 23 | -------------------------------------------------------------------------------- /core/loader/etcd/go.mod: -------------------------------------------------------------------------------- 1 | module trpc.group/trpc-go/trpc-gateway/core/loader/etcd 2 | 3 | go 1.18 4 | 5 | require ( 6 | gopkg.in/yaml.v3 v3.0.1 7 | trpc.group/trpc-go/trpc-config-etcd v0.0.0-20230829073930-07f202f52c32 8 | trpc.group/trpc-go/trpc-gateway v1.0.0 9 | trpc.group/trpc-go/trpc-go v0.0.0-20231008070952-27a655b3e79c 10 | ) 11 | 12 | require ( 13 | code.cloudfoundry.org/bytefmt v0.0.0-20211005130812-5bb3c17173e5 // indirect 14 | github.com/BurntSushi/toml v0.3.1 // indirect 15 | github.com/andybalholm/brotli v1.0.5 // indirect 16 | github.com/armon/go-radix v1.0.0 // indirect 17 | github.com/coreos/go-semver v0.3.0 // indirect 18 | github.com/coreos/go-systemd/v22 v22.3.2 // indirect 19 | github.com/fsnotify/fsnotify v1.4.9 // indirect 20 | github.com/gogo/protobuf v1.3.2 // indirect 21 | github.com/golang/protobuf v1.5.2 // indirect 22 | github.com/golang/snappy v0.0.4 // indirect 23 | github.com/google/flatbuffers v2.0.0+incompatible // indirect 24 | github.com/hashicorp/errwrap v1.0.0 // indirect 25 | github.com/hashicorp/go-multierror v1.1.1 // indirect 26 | github.com/json-iterator/go v1.1.12 // indirect 27 | github.com/klauspost/compress v1.16.3 // indirect 28 | github.com/lestrrat-go/strftime v1.0.6 // indirect 29 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 30 | github.com/modern-go/reflect2 v1.0.2 // indirect 31 | github.com/panjf2000/ants/v2 v2.4.7 // indirect 32 | github.com/pkg/errors v0.9.1 // indirect 33 | github.com/spf13/cast v1.3.1 // indirect 34 | github.com/valyala/bytebufferpool v1.0.0 // indirect 35 | github.com/valyala/fasthttp v1.45.0 // indirect 36 | go.etcd.io/etcd/api/v3 v3.5.9 // indirect 37 | go.etcd.io/etcd/client/pkg/v3 v3.5.9 // indirect 38 | go.etcd.io/etcd/client/v3 v3.5.9 // indirect 39 | go.uber.org/atomic v1.9.0 // indirect 40 | go.uber.org/automaxprocs v1.3.0 // indirect 41 | go.uber.org/multierr v1.6.0 // indirect 42 | go.uber.org/zap v1.24.0 // indirect 43 | golang.org/x/net v0.8.0 // indirect 44 | golang.org/x/sync v0.1.0 // indirect 45 | golang.org/x/sys v0.13.0 // indirect 46 | golang.org/x/text v0.13.0 // indirect 47 | google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 // indirect 48 | google.golang.org/grpc v1.41.0 // indirect 49 | google.golang.org/protobuf v1.30.0 // indirect 50 | trpc.group/trpc-go/tnet v0.0.0-20230810071536-9d05338021cf // indirect 51 | trpc.group/trpc/trpc-protocol/pb/go/trpc v0.0.0-20230803031059-de4168eb5952 // indirect 52 | ) 53 | -------------------------------------------------------------------------------- /core/loader/file/file_loader_test.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package file 15 | 16 | import ( 17 | "context" 18 | "testing" 19 | 20 | "github.com/golang/mock/gomock" 21 | "github.com/stretchr/testify/assert" 22 | "trpc.group/trpc-go/trpc-gateway/core/router" 23 | mock_router "trpc.group/trpc-go/trpc-gateway/core/router/mock" 24 | ) 25 | 26 | const configPathInvalid = "../../../testdata/trpc_go_error.yaml" 27 | const configPathNoFile = "../../testdata/trpc_go_error.yaml" 28 | const configPath = "../../../testdata/router.yaml" 29 | 30 | func Test_LoadConf(t *testing.T) { 31 | ctrl := gomock.NewController(t) 32 | defer ctrl.Finish() 33 | loader := ConfLoader{} 34 | err := loader.LoadConf(context.Background(), "fasthttp") 35 | assert.NotNil(t, err) 36 | DefaultRouterConfDir = "../../../testdata/router.d/" 37 | DefaultRouterConfFile = "../../../testdata/router.yaml" 38 | err = loader.LoadConf(context.Background(), "fasthttp") 39 | assert.NotNil(t, err) 40 | 41 | DefaultRouterConfDir = "" 42 | DefaultRouterConfFile = configPath 43 | mockRouter := mock_router.NewMockRouter(ctrl) 44 | mockRouter.EXPECT().InitRouterConfig(gomock.Any(), gomock.Any()).Return(nil) 45 | router.RegisterRouter("fasthttp", mockRouter) 46 | err = loader.LoadConf(context.Background(), "fasthttp") 47 | assert.Nil(t, err) 48 | 49 | _, err = getConfigFromFile(configPathNoFile) 50 | assert.NotNil(t, err) 51 | _, err = getConfigFromFile(configPathInvalid) 52 | assert.NotNil(t, err) 53 | _, err = getConfigFromFile(configPath) 54 | assert.Nil(t, err) 55 | } 56 | 57 | func Test_getConfigFromFile(t *testing.T) { 58 | _, err := getConfigFromFile(configPathNoFile) 59 | assert.NotNil(t, err) 60 | _, err = getConfigFromFile(configPathInvalid) 61 | assert.NotNil(t, err) 62 | _, err = getConfigFromFile(configPath) 63 | assert.Nil(t, err) 64 | } 65 | -------------------------------------------------------------------------------- /core/router/router_test.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package router 15 | 16 | import ( 17 | "testing" 18 | 19 | "github.com/stretchr/testify/assert" 20 | "trpc.group/trpc-go/trpc-gateway/core/entity" 21 | ) 22 | 23 | func TestWithRadixTreeRouter(t *testing.T) { 24 | o := &Options{} 25 | // item is nil 26 | WithRadixTreeRouter(nil)(o) 27 | 28 | routerItem := &entity.RouterItem{ 29 | Method: "/user/info", 30 | } 31 | // radixTree is nil 32 | WithRadixTreeRouter(routerItem)(o) 33 | leaf, ok := o.RadixTree.Get("/user/info") 34 | assert.True(t, ok) 35 | routerList, ok := leaf.([]*entity.RouterItem) 36 | assert.True(t, ok) 37 | assert.Equal(t, len(routerList), 1) 38 | 39 | // Set successfully 40 | routerItem2 := &entity.RouterItem{ 41 | Method: "/user/info", 42 | Host: []string{"r.inews.qq.com"}, 43 | } 44 | // Update node 45 | WithRadixTreeRouter(routerItem2)(o) 46 | leaf, ok = o.RadixTree.Get("/user/info") 47 | assert.True(t, ok) 48 | routerList, ok = leaf.([]*entity.RouterItem) 49 | assert.True(t, ok) 50 | assert.Equal(t, len(routerList), 2) 51 | } 52 | 53 | func TestWithRegRouter(t *testing.T) { 54 | o := &Options{} 55 | // item is nil 56 | WithRegRouter(nil)(o) 57 | 58 | routerItem := &entity.RouterItem{ 59 | Method: "/user/info", 60 | IsRegexp: true, 61 | } 62 | // RegRouterList is nil 63 | WithRegRouter(routerItem)(o) 64 | assert.Equal(t, len(o.RegRouterList), 1) 65 | 66 | // Set successfully 67 | routerItem2 := &entity.RouterItem{ 68 | Method: "/user/info", 69 | Host: []string{"r.inews.qq.com"}, 70 | IsRegexp: true, 71 | } 72 | // Update node 73 | WithRegRouter(routerItem2)(o) 74 | assert.Equal(t, len(o.RegRouterList[0].ItemList), 2) 75 | } 76 | 77 | func TestWithRouterClient(t *testing.T) { 78 | o := &Options{} 79 | // item is nil 80 | WithRouterClient(nil)(o) 81 | // Set successfully 82 | c := &entity.BackendConfig{} 83 | WithRouterClient(c)(o) 84 | assert.Equal(t, len(o.Clients), 1) 85 | 86 | r := GetRouter("fasthttp") 87 | assert.NotNil(t, r) 88 | } 89 | -------------------------------------------------------------------------------- /core/rule/README.md: -------------------------------------------------------------------------------- 1 | ## Rule Matching 2 | 3 | ----- 4 | 5 | Abstract conditional expressions to perform logical operations between conditions and output matching results. 6 | 7 | Encapsulate a simple rule matching mechanism for parameter matching. 8 | 9 | Currently supported expressions: 10 | 11 | **Currently supported expressions are: ">, >=, <, <=, ==, !=, in, !in, regexp".** 12 | 13 | ### Configuration Usage 14 | 15 | Below is a configuration example in YAML format, written in the router configuration. 16 | 17 | ```yaml 18 | rule: # Dynamic Rule Matching 19 | conditions: # Rule conditions 20 | - key: devid # Condition key 21 | val: ff3cfb53b1288dc9,ebe564cc9994dddb # Condition value 22 | oper: in # Expression evaluation condition, supports >, >=, <, <=, ==, in, !in, !=, regexp 23 | - key: appver # Condition key 24 | val: 660 # Condition value 25 | oper: ">=" # Expression evaluation condition, supports >, >=, <, <=, ==, in, !in, !=, regexp 26 | expression: 0&&1 # Logical expression, connected by && or ||, using the index of the conditions array 27 | ``` -------------------------------------------------------------------------------- /core/service/fhttp/connpool_test.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package fhttp 15 | 16 | import ( 17 | "testing" 18 | 19 | "github.com/stretchr/testify/assert" 20 | "github.com/valyala/fasthttp" 21 | ) 22 | 23 | func TestNewConnPool(t *testing.T) { 24 | p := NewConnPool(0) 25 | assert.NotNil(t, p) 26 | 27 | p = NewConnPool(200) 28 | assert.NotNil(t, p) 29 | } 30 | 31 | func TestConnPool_Get(t *testing.T) { 32 | p := NewConnPool(200) 33 | proxy, err := p.Get("localhost:80") 34 | assert.Nil(t, err) 35 | assert.NotNil(t, proxy) 36 | 37 | p = &ConnPool{} 38 | proxy, err = p.Get("localhost") 39 | assert.Nil(t, proxy) 40 | assert.NotNil(t, err) 41 | } 42 | 43 | func TestConnPool_Put(t *testing.T) { 44 | p := NewConnPool(3).(*ConnPool) 45 | proxy := &fasthttp.HostClient{} 46 | err := p.Put(proxy) 47 | assert.Nil(t, err) 48 | // Put empty proxy 49 | err = p.Put(nil) 50 | assert.NotNil(t, err) 51 | // Current ip:port exists, but the connection pool is empty 52 | proxy.Addr = "ip:port" 53 | p.proxyChanMap = map[string]ProxyChan{ 54 | "ip:port": nil, 55 | } 56 | err = p.Put(proxy) 57 | assert.Nil(t, err) 58 | } 59 | 60 | func TestConnPool_Len(t *testing.T) { 61 | p := NewConnPool(200) 62 | num := p.Len() 63 | assert.Equal(t, 0, num) 64 | } 65 | 66 | func TestConnPool_Close(t *testing.T) { 67 | p := NewConnPool(200).(*ConnPool) 68 | p.proxyChanMap = make(map[string]ProxyChan) 69 | p.proxyChanMap["ip:port1"] = nil 70 | pool := make(chan *fasthttp.HostClient, 1) 71 | pool <- &fasthttp.HostClient{} 72 | p.proxyChanMap["ip:port2"] = pool 73 | p.Close() 74 | } 75 | -------------------------------------------------------------------------------- /core/service/fhttp/tls.go: -------------------------------------------------------------------------------- 1 | package fhttp 2 | 3 | import ( 4 | "crypto/tls" 5 | "crypto/x509" 6 | ) 7 | 8 | // TLSOption is a function type used to set one attribute of *tls.Config. 9 | type TLSOption func(o *tls.Config) 10 | 11 | var ( 12 | customTLSOptions = make([]TLSOption, 0) 13 | ) 14 | 15 | // RegisterTLSConfig registers one or more TLSOption into the gateway. 16 | func RegisterTLSConfig(opts ...TLSOption) { 17 | customTLSOptions = append(customTLSOptions, opts...) 18 | } 19 | 20 | // SetCustomTLSOptions applies all registered TLSOption to *tls.Config. 21 | func SetCustomTLSOptions(tlsConfig *tls.Config) { 22 | for _, o := range customTLSOptions { 23 | o(tlsConfig) 24 | } 25 | } 26 | 27 | // WithTLSPeerVerifier creates a TLSOption used to set the VerifyPeerCertificate attribute in *tls.Config. 28 | func WithTLSPeerVerifier(f func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error) TLSOption { 29 | return func(o *tls.Config) { 30 | o.VerifyPeerCertificate = f 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /core/service/fhttp/tls_test.go: -------------------------------------------------------------------------------- 1 | package fhttp 2 | 3 | import ( 4 | "crypto/tls" 5 | "crypto/x509" 6 | "errors" 7 | "testing" 8 | 9 | "github.com/stretchr/testify/assert" 10 | ) 11 | 12 | func TestRegisterTlsConfig(t *testing.T) { 13 | RegisterTLSConfig(WithTLSPeerVerifier(func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error { 14 | t.Log("this is a test for tls peer verifier who returns nil") 15 | return nil 16 | })) 17 | tlsConfig := &tls.Config{} 18 | SetCustomTLSOptions(tlsConfig) 19 | assert.Nil(t, tlsConfig.VerifyPeerCertificate(nil, nil)) 20 | t.Log("TlsPeerVerifier test pass for nil return") 21 | 22 | errStr := "this is a test for tls peer verifier" 23 | RegisterTLSConfig(WithTLSPeerVerifier(func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error { 24 | t.Log("this is a test for tls peer verifier who returns an error") 25 | return errors.New(errStr) 26 | })) 27 | SetCustomTLSOptions(tlsConfig) 28 | assert.NotNil(t, tlsConfig.VerifyPeerCertificate(nil, nil)) 29 | assert.Equal(t, tlsConfig.VerifyPeerCertificate(nil, nil).Error(), errStr) 30 | t.Log("TlsPeerVerifier test pass for error return") 31 | } 32 | -------------------------------------------------------------------------------- /core/service/protocol/README.md: -------------------------------------------------------------------------------- 1 | # Forward Protocol Support 2 | 3 | This package is used to support other backend protocols and perform conversion operations from HTTP to various protocols 4 | such as HTTP, tRPC, gRPC, and WebSocket. 5 | 6 | ### Directory Structure 7 | 8 | - [cliprotocol.go](./cliprotocol.go) Protocol conversion interface definition 9 | - [http](http) HTTP to HTTP conversion 10 | - [trpc](trpc) HTTP to tRPC conversion 11 | - [grpc](grpc) HTTP to tRPC conversion 12 | 13 | You can implement the [cliprotocol.go](./cliprotocol.go) interface to enable custom protocol conversion for your 14 | business. -------------------------------------------------------------------------------- /core/service/protocol/cliprotocol.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package protocol 15 | 16 | import ( 17 | "context" 18 | "sync" 19 | 20 | gerrs "trpc.group/trpc-go/trpc-gateway/common/errs" 21 | "trpc.group/trpc-go/trpc-go/client" 22 | "trpc.group/trpc-go/trpc-go/errs" 23 | ) 24 | 25 | var ( 26 | protocolHandler = make(map[string]CliProtocolHandler) 27 | lock sync.RWMutex 28 | ) 29 | 30 | // RegisterCliProtocolHandler registers downstream protocol handler 31 | func RegisterCliProtocolHandler(protocol string, handler CliProtocolHandler) { 32 | lock.Lock() 33 | protocolHandler[protocol] = handler 34 | lock.Unlock() 35 | } 36 | 37 | // GetCliProtocolHandler gets the downstream protocol handler based on the protocol 38 | func GetCliProtocolHandler(protocol string) (CliProtocolHandler, error) { 39 | lock.RLock() 40 | defer lock.RUnlock() 41 | c, ok := protocolHandler[protocol] 42 | if !ok { 43 | return nil, errs.Newf(gerrs.ErrUnSupportProtocol, "protocol %s not registered", protocol) 44 | } 45 | return c, nil 46 | } 47 | 48 | // CliProtocolHandler handles downstream requests based on the downstream client request protocol type 49 | // 50 | //go:generate mockgen -destination=./mock/protocol_mock.go -package=mock . CliProtocolHandler 51 | type CliProtocolHandler interface { 52 | // WithCtx sets the context header 53 | WithCtx(ctx context.Context) (context.Context, error) 54 | // GetCliOptions gets specific client options for the request 55 | GetCliOptions(ctx context.Context) ([]client.Option, error) 56 | // TransReqBody transforms the request body 57 | TransReqBody(ctx context.Context) (interface{}, error) 58 | // TransRspBody transforms the response body 59 | TransRspBody(ctx context.Context) (interface{}, error) 60 | // HandleErr handles error information 61 | HandleErr(ctx context.Context, err error) error 62 | // HandleRspBody handles the response 63 | HandleRspBody(ctx context.Context, rspBody interface{}) error 64 | } 65 | -------------------------------------------------------------------------------- /core/service/protocol/cliprotocol_test.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package protocol 15 | 16 | import ( 17 | "testing" 18 | 19 | "github.com/golang/mock/gomock" 20 | "github.com/stretchr/testify/assert" 21 | "trpc.group/trpc-go/trpc-gateway/core/service/protocol/mock" 22 | ) 23 | 24 | func TestGetCliProtocolHandler(t *testing.T) { 25 | RegisterCliProtocolHandler("trpc", &mock.MockCliProtocolHandler{}) 26 | RegisterCliProtocolHandler("fasthttp", &mock.MockCliProtocolHandler{}) 27 | 28 | h, err := GetCliProtocolHandler("trpc") 29 | assert.Nil(t, err) 30 | assert.NotNil(t, h) 31 | 32 | h, err = GetCliProtocolHandler("fasthttp") 33 | assert.Nil(t, err) 34 | assert.NotNil(t, h) 35 | } 36 | 37 | func TestDefaultProtocolHandler(t *testing.T) { 38 | ctrl := gomock.NewController(t) 39 | defer ctrl.Finish() 40 | mockCliProtocol := mock.NewMockCliProtocolHandler(ctrl) 41 | RegisterCliProtocolHandler("fasthttp", mockCliProtocol) 42 | h, err := GetCliProtocolHandler("fasthttp") 43 | assert.Nil(t, err) 44 | assert.NotNil(t, h) 45 | h, err = GetCliProtocolHandler("invalid") 46 | assert.NotNil(t, err) 47 | } 48 | -------------------------------------------------------------------------------- /core/service/protocol/fasthttp/transformer_test.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package fasthttp 15 | 16 | import ( 17 | "context" 18 | "errors" 19 | "testing" 20 | 21 | "github.com/stretchr/testify/assert" 22 | "github.com/valyala/fasthttp" 23 | "trpc.group/trpc-go/trpc-gateway/common/http" 24 | "trpc.group/trpc-go/trpc-go/errs" 25 | ) 26 | 27 | func Test_defaultProtocolHandler_HandleErr(t *testing.T) { 28 | h := &defaultProtocolHandler{} 29 | err := h.HandleErr(context.Background(), nil) 30 | assert.Nil(t, err) 31 | err = h.HandleErr(context.Background(), errs.New(1, "business err")) 32 | assert.NotNil(t, err) 33 | 34 | fctx := &fasthttp.RequestCtx{} 35 | ctx := http.WithRequestContext(context.Background(), fctx) 36 | err = h.HandleErr(ctx, errors.New("err")) 37 | assert.NotNil(t, err) 38 | err = errs.NewFrameError(1, "frame err") 39 | err = h.HandleErr(ctx, err) 40 | assert.NotNil(t, err) 41 | 42 | err = errs.New(2, "business err") 43 | err = h.HandleErr(ctx, err) 44 | assert.NotNil(t, err) 45 | } 46 | 47 | func Test_defaultProtocolHandler_TransReqBody(t *testing.T) { 48 | h := &defaultProtocolHandler{} 49 | got, err := h.TransReqBody(context.Background()) 50 | assert.Nil(t, err) 51 | assert.Nil(t, got) 52 | err = h.HandleRspBody(context.Background(), nil) 53 | assert.Nil(t, err) 54 | fctx := &fasthttp.RequestCtx{} 55 | ctx := http.WithRequestContext(context.Background(), fctx) 56 | got, err = h.TransReqBody(ctx) 57 | assert.Nil(t, err) 58 | assert.Nil(t, got) 59 | rb, err := h.TransRspBody(ctx) 60 | assert.Nil(t, rb) 61 | assert.Nil(t, err) 62 | 63 | opts, err := h.GetCliOptions(ctx) 64 | assert.Nil(t, err) 65 | assert.Nil(t, opts) 66 | 67 | ctx, _ = h.WithCtx(ctx) 68 | assert.NotNil(t, ctx) 69 | 70 | err = h.HandleRspBody(ctx, nil) 71 | assert.Nil(t, err) 72 | } 73 | -------------------------------------------------------------------------------- /core/service/protocol/grpc/Makefile: -------------------------------------------------------------------------------- 1 | GO = go 2 | DTOOLS = dtools 3 | TARGET = trpc-gateway 4 | 5 | # Add this parameter for M1Pro, otherwise make cover throws an error 6 | export GOARCH=amd64 7 | 8 | all: fmt goimports lint 9 | 10 | fmt: 11 | @gofmt -s -w ./$* 12 | 13 | vet: 14 | @go vet -all ./ 15 | 16 | # Check for unchecked errors in the code 17 | ec: 18 | @errcheck ./... | grep -v Close 19 | 20 | lint: 21 | @golint ./... 22 | 23 | goimports: 24 | @goimports -d -w ./ 25 | 26 | test: 27 | CFLAGS=-g 28 | export CFLAGS 29 | $(GO) test $(M) -v -gcflags=all=-l -coverpkg=./... -coverprofile=test.out ./... 30 | clean: 31 | rm -f $(TARGET) 32 | rm -rf release 33 | 34 | cover: COVERAGE_FILE := coverage.out 35 | cover: 36 | @go test ./... -coverprofile=$(COVERAGE_FILE) -gcflags=all=-l && \ 37 | go tool cover -html=$(COVERAGE_FILE) && rm $(COVERAGE_FILE) 38 | -------------------------------------------------------------------------------- /core/service/protocol/grpc/READEME.md: -------------------------------------------------------------------------------- 1 | # HTTP to gRPC Forwarding 2 | 3 | ## Key Implementation Points 4 | 5 | - Use the TRPC_GATEWAY_GRPC_HEADER in the context to pass the gRPC request body, response body, and metadata. The main 6 | purpose is to bypass specific steps in the tRPC-Go framework, such as serialization and deserialization, as the 7 | grpc-go framework already handles these steps. Skipping these steps reduces unnecessary data conversion. 8 | - Use JSON format to transmit gRPC data. This requires the client to send data in JSON format, and the gRPC server needs 9 | to support JSON codec by implementing the Encode and Decode methods. Refer to the implementation in the 10 | grpc-go/encoding package. 11 | - Before the invoke function in tRPC-Go, the JSON request body and headers need to be placed in the grpc header defined 12 | by TRPC_GATEWAY_GRPC_HEADER. This step essentially performs protocol conversion. 13 | - TRPC_GATEWAY_GRPC_HEADER needs to be placed in the ctx in the server function of the transport layer. This is the 14 | top-level ctx so that it can be accessed from all places. 15 | 16 | ## Requirements for Upstream gRPC Services 17 | 18 | The upstream gRPC services need to register the JSON codec to support JSON format request bodies. -------------------------------------------------------------------------------- /core/service/protocol/grpc/codec.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package grpc 15 | 16 | import ( 17 | "trpc.group/trpc-go/trpc-go/codec" 18 | ) 19 | 20 | var ( 21 | // DefaultServerCodec is the default encoding/decoding instance for the server 22 | DefaultServerCodec = &ServerCodec{} 23 | // DefaultClientCodec is the default encoding/decoding instance for the client 24 | DefaultClientCodec = &ClientCodec{} 25 | ) 26 | 27 | // init registers the grpc codec 28 | func init() { 29 | codec.Register(Protocol, DefaultServerCodec, DefaultClientCodec) 30 | } 31 | 32 | // ServerCodec is the server-side codec for encoding/decoding 33 | type ServerCodec struct{} 34 | 35 | // Decode is used to decode the message 36 | func (s *ServerCodec) Decode(_ codec.Msg, reqbuf []byte) ([]byte, error) { 37 | return reqbuf, nil 38 | } 39 | 40 | // Encode is used to encode the message 41 | func (s *ServerCodec) Encode(_ codec.Msg, reqbuf []byte) ([]byte, error) { 42 | return reqbuf, nil 43 | } 44 | 45 | // ClientCodec is the codec for the grpc client, it does nothing 46 | type ClientCodec struct{} 47 | 48 | // Encode is the encoder for the grpc client, it does nothing 49 | func (c *ClientCodec) Encode(_ codec.Msg, reqbody []byte) ([]byte, error) { 50 | return reqbody, nil 51 | } 52 | 53 | // Decode is the decoder for the grpc client, it does nothing 54 | func (c *ClientCodec) Decode(_ codec.Msg, rspbody []byte) ([]byte, error) { 55 | return rspbody, nil 56 | } 57 | -------------------------------------------------------------------------------- /core/service/protocol/grpc/codec_json.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package grpc 15 | 16 | import ( 17 | "context" 18 | 19 | "github.com/golang/protobuf/jsonpb" 20 | "github.com/golang/protobuf/proto" 21 | json "github.com/json-iterator/go" 22 | "github.com/oxtoacart/bpool" 23 | "google.golang.org/grpc/encoding" 24 | gerrs "trpc.group/trpc-go/trpc-gateway/common/errs" 25 | "trpc.group/trpc-go/trpc-go/errs" 26 | "trpc.group/trpc-go/trpc-go/log" 27 | ) 28 | 29 | func init() { 30 | encoding.RegisterCodec(jsonCodec{}) 31 | } 32 | 33 | // Create a buffer Pool with 16 instances, each preallocated with 256 bytes 34 | var bufferPool = bpool.NewSizedBufferPool(16, 256) 35 | 36 | var jsonpbMarshaler = &jsonpb.Marshaler{} 37 | 38 | type jsonCodec struct{} 39 | 40 | // Marshal serializes the data 41 | func (jsonCodec) Marshal(v interface{}) ([]byte, error) { 42 | if pb, ok := v.(proto.Message); ok { 43 | buf := bufferPool.Get() 44 | defer bufferPool.Put(buf) 45 | if err := jsonpbMarshaler.Marshal(buf, pb); err != nil { 46 | return nil, err 47 | } 48 | return buf.Bytes(), nil 49 | } 50 | bt, ok := v.([]byte) 51 | if ok { 52 | log.Debugf("byte req body:%s", string(bt)) 53 | return bt, nil 54 | } 55 | return json.Marshal(v) 56 | } 57 | 58 | // Unmarshal deserializes the data 59 | func (jsonCodec) Unmarshal(data []byte, v interface{}) error { 60 | if len(data) == 0 { 61 | return nil 62 | } 63 | ctx, ok := v.(context.Context) 64 | if !ok { 65 | return errs.New(gerrs.ErrGatewayUnknown, "invalid context") 66 | } 67 | header := Head(ctx) 68 | if header == nil { 69 | return errs.New(gerrs.ErrGatewayUnknown, "get no grpc header unmarshal") 70 | } 71 | header.Rsp = data 72 | return nil 73 | } 74 | 75 | // Name returns the codec name 76 | func (jsonCodec) Name() string { 77 | return "json" 78 | } 79 | -------------------------------------------------------------------------------- /core/service/protocol/grpc/codec_json_test.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package grpc 15 | 16 | import ( 17 | "context" 18 | "testing" 19 | 20 | "github.com/golang/mock/gomock" 21 | _ "github.com/golang/protobuf/proto" 22 | "github.com/stretchr/testify/assert" 23 | mockproto "trpc.group/trpc-go/trpc-gateway/core/service/protocol/grpc/mock" 24 | ) 25 | 26 | //go:generate mockgen -destination=./mock/messge.go -package=mock_grpc github.com/golang/protobuf/proto Message 27 | func Test_jsonCodec_Marshal(t *testing.T) { 28 | ctrl := gomock.NewController(t) 29 | defer ctrl.Finish() 30 | mockMessage := mockproto.NewMockMessage(ctrl) 31 | js := jsonCodec{} 32 | got, err := js.Marshal(mockMessage) 33 | assert.Nil(t, err) 34 | assert.NotNil(t, got) 35 | 36 | got, err = js.Marshal([]byte("xxx")) 37 | assert.Nil(t, err) 38 | assert.NotNil(t, got) 39 | 40 | got, err = js.Marshal(map[string]string{"a": "b"}) 41 | assert.Nil(t, err) 42 | assert.NotNil(t, got) 43 | } 44 | 45 | func Test_jsonCodec_Unmarshal(t *testing.T) { 46 | 47 | js := jsonCodec{} 48 | err := js.Unmarshal([]byte(""), nil) 49 | assert.Nil(t, err) 50 | 51 | err = js.Unmarshal([]byte("xx"), "aa") 52 | assert.NotNil(t, err) 53 | 54 | err = js.Unmarshal([]byte("xx"), context.Background()) 55 | assert.NotNil(t, err) 56 | 57 | ctx := WithHeader(context.Background(), &Header{ 58 | Req: nil, 59 | Rsp: nil, 60 | InMetadata: nil, 61 | OutMetadata: nil, 62 | }) 63 | err = js.Unmarshal([]byte("xxx"), ctx) 64 | assert.Nil(t, err) 65 | } 66 | -------------------------------------------------------------------------------- /core/service/protocol/grpc/codec_test.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package grpc 15 | 16 | import ( 17 | "testing" 18 | 19 | "github.com/stretchr/testify/assert" 20 | ) 21 | 22 | func TestServerCodec_Decode(t *testing.T) { 23 | s := &ServerCodec{} 24 | gotReqbody, err := s.Decode(nil, []byte("xx")) 25 | assert.Nil(t, err) 26 | assert.Equal(t, gotReqbody, []byte("xx")) 27 | 28 | gotReqbody, err = s.Encode(nil, []byte("xx")) 29 | assert.Nil(t, err) 30 | assert.Equal(t, gotReqbody, []byte("xx")) 31 | } 32 | 33 | func TestClientCodec_Encode(t *testing.T) { 34 | s := &ClientCodec{} 35 | gotReqbody, err := s.Decode(nil, []byte("xx")) 36 | assert.Nil(t, err) 37 | assert.Equal(t, gotReqbody, []byte("xx")) 38 | 39 | gotReqbody, err = s.Encode(nil, []byte("xx")) 40 | assert.Nil(t, err) 41 | assert.Equal(t, gotReqbody, []byte("xx")) 42 | } 43 | -------------------------------------------------------------------------------- /core/service/protocol/grpc/go.mod: -------------------------------------------------------------------------------- 1 | module trpc.group/trpc-go/trpc-gateway/core/service/protocol/grpc 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/golang/mock v1.6.0 7 | github.com/golang/protobuf v1.5.2 8 | github.com/json-iterator/go v1.1.12 9 | github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c 10 | github.com/prashantv/gostub v1.1.0 11 | github.com/stretchr/testify v1.8.2 12 | github.com/valyala/fasthttp v1.45.0 13 | google.golang.org/grpc v1.46.0 14 | trpc.group/trpc-go/trpc-gateway v1.0.0 15 | trpc.group/trpc-go/trpc-go v0.0.0-20231008070952-27a655b3e79c 16 | ) 17 | 18 | require ( 19 | github.com/BurntSushi/toml v0.3.1 // indirect 20 | github.com/andybalholm/brotli v1.0.5 // indirect 21 | github.com/davecgh/go-spew v1.1.1 // indirect 22 | github.com/fsnotify/fsnotify v1.4.9 // indirect 23 | github.com/golang/snappy v0.0.4 // indirect 24 | github.com/google/flatbuffers v2.0.0+incompatible // indirect 25 | github.com/hashicorp/errwrap v1.0.0 // indirect 26 | github.com/hashicorp/go-multierror v1.1.1 // indirect 27 | github.com/klauspost/compress v1.16.3 // indirect 28 | github.com/lestrrat-go/strftime v1.0.6 // indirect 29 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 30 | github.com/modern-go/reflect2 v1.0.2 // indirect 31 | github.com/panjf2000/ants/v2 v2.4.7 // indirect 32 | github.com/pkg/errors v0.9.1 // indirect 33 | github.com/pmezard/go-difflib v1.0.0 // indirect 34 | github.com/spf13/cast v1.3.1 // indirect 35 | github.com/valyala/bytebufferpool v1.0.0 // indirect 36 | go.uber.org/atomic v1.9.0 // indirect 37 | go.uber.org/multierr v1.6.0 // indirect 38 | go.uber.org/zap v1.24.0 // indirect 39 | golang.org/x/net v0.8.0 // indirect 40 | golang.org/x/sync v0.1.0 // indirect 41 | golang.org/x/sys v0.13.0 // indirect 42 | golang.org/x/text v0.13.0 // indirect 43 | google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 // indirect 44 | google.golang.org/protobuf v1.30.0 // indirect 45 | gopkg.in/yaml.v3 v3.0.1 // indirect 46 | trpc.group/trpc-go/tnet v0.0.0-20230810071536-9d05338021cf // indirect 47 | trpc.group/trpc/trpc-protocol/pb/go/trpc v0.0.0-20230803031059-de4168eb5952 // indirect 48 | ) 49 | -------------------------------------------------------------------------------- /core/service/protocol/grpc/header.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package grpc 15 | 16 | import ( 17 | "context" 18 | "strings" 19 | 20 | "google.golang.org/grpc/metadata" 21 | "trpc.group/trpc-go/trpc-go/log" 22 | ) 23 | 24 | // Header is stored in the context to communicate with trpc 25 | type Header struct { 26 | Req []byte // request 27 | Rsp []byte // response 28 | InMetadata metadata.MD // metadata from client 29 | OutMetadata metadata.MD // metadata sent to client 30 | } 31 | 32 | // ContextKey 定义 grpc 的 contextKey 33 | type ContextKey string 34 | 35 | // ContextKeyHeader is the key for the GRPC header information in the context 36 | const ContextKeyHeader = ContextKey("TRPC_GATEWAY_GRPC_HEADER") 37 | 38 | // Head retrieves the GRPC header information 39 | func Head(ctx context.Context) *Header { 40 | if header, ok := ctx.Value(ContextKeyHeader).(*Header); ok { 41 | return header 42 | } 43 | return nil 44 | } 45 | 46 | // WithHeader sets the GRPC header information in the context 47 | func WithHeader(ctx context.Context, header *Header) context.Context { 48 | return context.WithValue(ctx, ContextKeyHeader, header) 49 | } 50 | 51 | // WithServerGRPCMetadata is used for trpc-go server calls to send metadata 52 | func WithServerGRPCMetadata(ctx context.Context, key string, value []string) { 53 | // Cannot include connection metadata, otherwise grpc will upgrade to the http2 protocol 54 | if strings.ToLower(key) == "connection" { 55 | return 56 | } 57 | header := Head(ctx) 58 | if header == nil { 59 | log.DebugContextf(ctx, "with grpc metadata nil") 60 | return 61 | } 62 | if header.OutMetadata == nil { 63 | header.OutMetadata = metadata.MD{} 64 | } 65 | header.OutMetadata.Set(key, value...) 66 | } 67 | -------------------------------------------------------------------------------- /core/service/protocol/grpc/header_test.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package grpc 15 | 16 | import ( 17 | "context" 18 | "testing" 19 | ) 20 | 21 | func TestWithServerGRPCMetadata(t *testing.T) { 22 | WithServerGRPCMetadata(context.Background(), "connection", []string{"a"}) 23 | WithServerGRPCMetadata(context.Background(), "name", []string{"a"}) 24 | ctx := WithHeader(context.Background(), &Header{ 25 | Req: nil, 26 | Rsp: nil, 27 | InMetadata: nil, 28 | OutMetadata: nil, 29 | }) 30 | WithServerGRPCMetadata(ctx, "name", []string{"a"}) 31 | } 32 | -------------------------------------------------------------------------------- /core/service/protocol/grpc/mock/connpool.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | // Code generated by MockGen. DO NOT EDIT. 15 | // Source: trpc.group/trpc-go/trpc-gateway/core/service/protocol/grpc (interfaces: ConnPool) 16 | 17 | // Package mock_grpc is a generated GoMock package. 18 | package mock_grpc 19 | 20 | import ( 21 | reflect "reflect" 22 | time "time" 23 | 24 | gomock "github.com/golang/mock/gomock" 25 | grpc "google.golang.org/grpc" 26 | ) 27 | 28 | // MockConnPool is a mock of ConnPool interface. 29 | type MockConnPool struct { 30 | ctrl *gomock.Controller 31 | recorder *MockConnPoolMockRecorder 32 | } 33 | 34 | // MockConnPoolMockRecorder is the mock recorder for MockConnPool. 35 | type MockConnPoolMockRecorder struct { 36 | mock *MockConnPool 37 | } 38 | 39 | // NewMockConnPool creates a new mock instance. 40 | func NewMockConnPool(ctrl *gomock.Controller) *MockConnPool { 41 | mock := &MockConnPool{ctrl: ctrl} 42 | mock.recorder = &MockConnPoolMockRecorder{mock} 43 | return mock 44 | } 45 | 46 | // EXPECT returns an object that allows the caller to indicate expected use. 47 | func (m *MockConnPool) EXPECT() *MockConnPoolMockRecorder { 48 | return m.recorder 49 | } 50 | 51 | // Get mocks base method. 52 | func (m *MockConnPool) Get(arg0 string, arg1 time.Duration) (grpc.ClientConnInterface, error) { 53 | m.ctrl.T.Helper() 54 | ret := m.ctrl.Call(m, "Get", arg0, arg1) 55 | ret0, _ := ret[0].(grpc.ClientConnInterface) 56 | ret1, _ := ret[1].(error) 57 | return ret0, ret1 58 | } 59 | 60 | // Get indicates an expected call of Get. 61 | func (mr *MockConnPoolMockRecorder) Get(arg0, arg1 interface{}) *gomock.Call { 62 | mr.mock.ctrl.T.Helper() 63 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockConnPool)(nil).Get), arg0, arg1) 64 | } 65 | -------------------------------------------------------------------------------- /core/service/protocol/grpc/pool.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package grpc 15 | 16 | import ( 17 | "context" 18 | "sync" 19 | "time" 20 | 21 | "google.golang.org/grpc" 22 | "google.golang.org/grpc/credentials/insecure" 23 | "trpc.group/trpc-go/trpc-go/errs" 24 | ) 25 | 26 | // ConnPool connection pool 27 | // 28 | //go:generate mockgen -destination=./mock/connpool.go -package=mock_grpc . ConnPool 29 | type ConnPool interface { 30 | Get(address string, timeout time.Duration) (grpc.ClientConnInterface, error) 31 | } 32 | 33 | // Pool implements a simple grpc connection pool 34 | type Pool struct { 35 | connections sync.Map 36 | } 37 | 38 | // Get retrieves an available grpc client connection from the connection pool 39 | func (p *Pool) Get(address string, timeout time.Duration) (grpc.ClientConnInterface, error) { 40 | // TODO Consider timeout when indexing the connection pool 41 | if v, ok := p.connections.Load(address); ok { 42 | return v.(grpc.ClientConnInterface), nil 43 | } 44 | ctx, cancel := context.WithTimeout(context.Background(), timeout) 45 | defer cancel() 46 | conn, err := grpc.DialContext(ctx, address, 47 | grpc.WithTransportCredentials(insecure.NewCredentials()), // TODO 从ctx中获取证书相关配置,支持tls通讯 48 | grpc.WithDefaultCallOptions(grpc.CallContentSubtype("json")), 49 | ) 50 | if err != nil { 51 | return nil, errs.NewFrameError(errs.RetClientConnectFail, err.Error()) 52 | } 53 | v, loaded := p.connections.LoadOrStore(address, conn) 54 | if !loaded { 55 | return conn, nil 56 | } 57 | return v.(grpc.ClientConnInterface), nil 58 | } 59 | -------------------------------------------------------------------------------- /core/service/protocol/grpc/pool_test.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package grpc 15 | 16 | import ( 17 | "testing" 18 | "time" 19 | 20 | "github.com/stretchr/testify/assert" 21 | ) 22 | 23 | func Test_pool_Get(t *testing.T) { 24 | 25 | p := &Pool{} 26 | got, err := p.Get("localhost:0", 2*time.Second) 27 | assert.Nil(t, err) 28 | assert.NotNil(t, got) 29 | 30 | got, err = p.Get("localhost:0", 2*time.Second) 31 | assert.Nil(t, err) 32 | assert.NotNil(t, got) 33 | 34 | _, err = p.Get("127.0.0.1:8080", 10) 35 | assert.NotNil(t, err) 36 | } 37 | -------------------------------------------------------------------------------- /core/service/protocol/http/README.md: -------------------------------------------------------------------------------- 1 | # Fasthttp to net/http Forwarding 2 | 3 | This conversion is implemented to proxy WebSocket and HTTP chunked protocols. 4 | 5 | # Why Implement it Separately 6 | 7 | The support for HTTP chunked protocol in the Fasthttp client is currently not complete. Additionally, forwarding 8 | WebSocket and HTTP chunked protocols cannot fully utilize the advantages of Fasthttp. Therefore, the net/http package is 9 | used as the client to implement the forwarding of WebSocket and HTTP chunked protocols. 10 | 11 | # Implementation Reference 12 | 13 | The implementation is based on the reverseproxy.go file in the net/http/httputil package. 14 | 15 | # Usage Considerations 16 | 17 | - HTTP chunked requests need to include the appropriate headers. 18 | - For all body reading operations in the gateway, the following check should be performed to exclude stream requests: 19 | 20 | ```go 21 | if fctx.IsBodyStream() { 22 | return "stream body" 23 | } 24 | ``` -------------------------------------------------------------------------------- /core/service/protocol/http/print.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package http 6 | 7 | // equalFold is strings.EqualFold, ASCII only. It reports whether s and t 8 | // are equal, ASCII-case-insensitively. 9 | func equalFold(s, t string) bool { 10 | if len(s) != len(t) { 11 | return false 12 | } 13 | for i := 0; i < len(s); i++ { 14 | if lower(s[i]) != lower(t[i]) { 15 | return false 16 | } 17 | } 18 | return true 19 | } 20 | 21 | // lower returns the ASCII lowercase version of b. 22 | func lower(b byte) byte { 23 | if 'A' <= b && b <= 'Z' { 24 | return b + ('a' - 'A') 25 | } 26 | return b 27 | } 28 | 29 | // isPrint returns whether s is ASCII and printable according to 30 | // https://tools.ietf.org/html/rfc20#section-4.2. 31 | func isPrint(s string) bool { 32 | for i := 0; i < len(s); i++ { 33 | if s[i] < ' ' || s[i] > '~' { 34 | return false 35 | } 36 | } 37 | return true 38 | } 39 | -------------------------------------------------------------------------------- /core/service/protocol/http/print_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | // 5 | // This file may have been modified by THL A29 Limited ("Tencent Modifications"). All Tencent Modifications are Copyright (C) 2023 THL A29 Limited. 6 | 7 | package http 8 | 9 | import "testing" 10 | 11 | func TestEqualFold(t *testing.T) { 12 | var tests = []struct { 13 | name string 14 | a, b string 15 | want bool 16 | }{ 17 | { 18 | name: "empty", 19 | want: true, 20 | }, 21 | { 22 | name: "simple match", 23 | a: "CHUNKED", 24 | b: "chunked", 25 | want: true, 26 | }, 27 | { 28 | name: "same string", 29 | a: "chunked", 30 | b: "chunked", 31 | want: true, 32 | }, 33 | { 34 | name: "Unicode Kelvin symbol", 35 | a: "chunKed", // This "K" is 'KELVIN SIGN' (\u212A) 36 | b: "chunked", 37 | want: false, 38 | }, 39 | } 40 | for _, tt := range tests { 41 | t.Run(tt.name, func(t *testing.T) { 42 | if got := equalFold(tt.a, tt.b); got != tt.want { 43 | t.Errorf("AsciiEqualFold(%q,%q): got %v want %v", tt.a, tt.b, got, tt.want) 44 | } 45 | }) 46 | } 47 | } 48 | 49 | func TestIsPrint(t *testing.T) { 50 | var tests = []struct { 51 | name string 52 | in string 53 | want bool 54 | }{ 55 | { 56 | name: "empty", 57 | want: true, 58 | }, 59 | { 60 | name: "ASCII low", 61 | in: "This is a space: ' '", 62 | want: true, 63 | }, 64 | { 65 | name: "ASCII high", 66 | in: "This is a tilde: '~'", 67 | want: true, 68 | }, 69 | { 70 | name: "ASCII low non-print", 71 | in: "This is a unit separator: \x1F", 72 | want: false, 73 | }, 74 | { 75 | name: "Ascii high non-print", 76 | in: "This is a Delete: \x7F", 77 | want: false, 78 | }, 79 | { 80 | name: "Unicode letter", 81 | in: "Today it's 280K outside: it's freezing!", // This "K" is 'KELVIN SIGN' (\u212A) 82 | want: false, 83 | }, 84 | { 85 | name: "Unicode emoji", 86 | in: "Gophers like 🧀", 87 | want: false, 88 | }, 89 | } 90 | for _, tt := range tests { 91 | t.Run(tt.name, func(t *testing.T) { 92 | if got := isPrint(tt.in); got != tt.want { 93 | t.Errorf("IsASCIIPrint(%q): got %v want %v", tt.in, got, tt.want) 94 | } 95 | }) 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /example/http2grpc/Makefile: -------------------------------------------------------------------------------- 1 | TARGET = trpc-gateway 2 | SERVER = sever 3 | 4 | server: 5 | go run upstream/main.go 6 | 7 | run: 8 | go build -o ./bin/$(TARGET) 9 | ./bin/$(TARGET) -conf=./trpc_go.yaml -router=./conf/router.yaml 10 | -------------------------------------------------------------------------------- /example/http2grpc/README.md: -------------------------------------------------------------------------------- 1 | ## Example Explanation 2 | 3 | #### Local Execution Steps 4 | - Start the demo backend service: Execute the following command in the current directory 5 | ```sh 6 | $ make server 7 | ``` 8 | - Start the gateway service: Open another console and execute the following command in the current directory 9 | ```sh 10 | $ make run 11 | ``` 12 | - Call the API Execute the requests in [test.http](./test.http) file and observe the response results. -------------------------------------------------------------------------------- /example/http2grpc/conf/router.yaml: -------------------------------------------------------------------------------- 1 | router: 2 | - method: /greeting 3 | id: "path:/greeting" 4 | target_service: 5 | - service: grpc.hello.service 6 | weight: 10 7 | rewrite: /helloworld.Greeter/SayHello 8 | client: 9 | - name: grpc.hello.service 10 | namespace: Development 11 | target: ip://127.0.0.1:50051 12 | env_name: f81a848f 13 | network: tcp 14 | timeout: 8000 15 | protocol: grpc 16 | disable_servicerouter: true 17 | plugins: -------------------------------------------------------------------------------- /example/http2grpc/go.mod: -------------------------------------------------------------------------------- 1 | module trpc.group/trpc-go/trpc-gateway/example/http2grpc 2 | 3 | go 1.18 4 | 5 | require ( 6 | google.golang.org/grpc v1.62.1 7 | google.golang.org/protobuf v1.32.0 8 | trpc.group/trpc-go/trpc-gateway v1.0.0 9 | trpc.group/trpc-go/trpc-gateway/core/service/protocol/grpc v0.0.0-20240201145627-5c299871ec75 10 | trpc.group/trpc-go/trpc-go v0.0.0-20231008070952-27a655b3e79c 11 | ) 12 | 13 | require ( 14 | code.cloudfoundry.org/bytefmt v0.0.0-20211005130812-5bb3c17173e5 // indirect 15 | github.com/BurntSushi/toml v0.3.1 // indirect 16 | github.com/andybalholm/brotli v1.1.0 // indirect 17 | github.com/armon/go-radix v1.0.0 // indirect 18 | github.com/fsnotify/fsnotify v1.4.9 // indirect 19 | github.com/go-playground/form/v4 v4.2.0 // indirect 20 | github.com/golang/protobuf v1.5.3 // indirect 21 | github.com/golang/snappy v0.0.4 // indirect 22 | github.com/google/flatbuffers v2.0.0+incompatible // indirect 23 | github.com/hashicorp/errwrap v1.0.0 // indirect 24 | github.com/hashicorp/go-multierror v1.1.1 // indirect 25 | github.com/json-iterator/go v1.1.12 // indirect 26 | github.com/klauspost/compress v1.17.7 // indirect 27 | github.com/kr/pretty v0.2.1 // indirect 28 | github.com/lestrrat-go/strftime v1.0.6 // indirect 29 | github.com/mitchellh/mapstructure v1.5.0 // indirect 30 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 31 | github.com/modern-go/reflect2 v1.0.2 // indirect 32 | github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c // indirect 33 | github.com/panjf2000/ants/v2 v2.4.7 // indirect 34 | github.com/pkg/errors v0.9.1 // indirect 35 | github.com/spf13/cast v1.3.1 // indirect 36 | github.com/valyala/bytebufferpool v1.0.0 // indirect 37 | github.com/valyala/fasthttp v1.52.0 // indirect 38 | go.uber.org/atomic v1.9.0 // indirect 39 | go.uber.org/automaxprocs v1.3.0 // indirect 40 | go.uber.org/multierr v1.6.0 // indirect 41 | go.uber.org/zap v1.24.0 // indirect 42 | golang.org/x/net v0.21.0 // indirect 43 | golang.org/x/sync v0.6.0 // indirect 44 | golang.org/x/sys v0.17.0 // indirect 45 | golang.org/x/text v0.14.0 // indirect 46 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 // indirect 47 | gopkg.in/yaml.v3 v3.0.1 // indirect 48 | trpc.group/trpc-go/tnet v0.0.0-20230810071536-9d05338021cf // indirect 49 | trpc.group/trpc/trpc-protocol/pb/go/trpc v0.0.0-20230803031059-de4168eb5952 // indirect 50 | ) 51 | -------------------------------------------------------------------------------- /example/http2grpc/main.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | // Package file is gateway example 15 | package main 16 | 17 | import ( 18 | "flag" 19 | 20 | "trpc.group/trpc-go/trpc-gateway/core/config" 21 | "trpc.group/trpc-go/trpc-gateway/core/service/fhttp" 22 | "trpc.group/trpc-go/trpc-go/log" 23 | // Register file loader 24 | _ "trpc.group/trpc-go/trpc-gateway/core/loader/file" 25 | // Register upstream protocol 26 | _ "trpc.group/trpc-go/trpc-gateway/core/service/protocol/fasthttp" 27 | _ "trpc.group/trpc-go/trpc-gateway/core/service/protocol/grpc" 28 | _ "trpc.group/trpc-go/trpc-gateway/core/service/protocol/http" 29 | _ "trpc.group/trpc-go/trpc-gateway/core/service/protocol/trpc" 30 | ) 31 | 32 | func main() { 33 | flag.Parse() 34 | s := config.NewServer() 35 | // register gateway service 36 | fhttp.RegisterFastHTTPService(s) 37 | if err := s.Serve(); err != nil { 38 | log.Fatal(err) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /example/http2grpc/test.http: -------------------------------------------------------------------------------- 1 | #### 2 | POST http://localhost:8000/greeting 3 | 4 | { 5 | "name": "xxxx1" 6 | } -------------------------------------------------------------------------------- /example/http2grpc/upstream/jsoncodec/proto.go: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2018 gRPC authors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | 19 | // Package jsoncodec Package proto defines the protobuf codec. Importing this package will 20 | // register the codec. 21 | package jsoncodec 22 | 23 | import ( 24 | "encoding/json" 25 | 26 | "google.golang.org/grpc/encoding" 27 | ) 28 | 29 | // Name is the name registered for the proto compressor. 30 | const Name = "json" 31 | 32 | func init() { 33 | encoding.RegisterCodec(codec{}) 34 | } 35 | 36 | // codec is a Codec implementation with protobuf. It is the default codec for gRPC. 37 | type codec struct{} 38 | 39 | func (codec) Marshal(v interface{}) ([]byte, error) { 40 | return json.Marshal(v) 41 | } 42 | 43 | func (codec) Unmarshal(data []byte, v interface{}) error { 44 | err := json.Unmarshal(data, v) 45 | if err != nil { 46 | return err 47 | } 48 | return nil 49 | } 50 | 51 | func (codec) Name() string { 52 | return Name 53 | } 54 | -------------------------------------------------------------------------------- /example/http2grpc/upstream/main.go: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2015 gRPC authors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | 19 | // Package main implements a server for Greeter service. 20 | package main 21 | 22 | import ( 23 | "context" 24 | "encoding/json" 25 | "flag" 26 | "fmt" 27 | "log" 28 | "net" 29 | 30 | "google.golang.org/grpc" 31 | "google.golang.org/grpc/metadata" 32 | _ "trpc.group/trpc-go/trpc-gateway/example/http2grpc/upstream/jsoncodec" 33 | pb "trpc.group/trpc-go/trpc-gateway/example/http2grpc/upstream/proto" 34 | ) 35 | 36 | var ( 37 | port = flag.Int("port", 50051, "The server port") 38 | ) 39 | 40 | // server is used to implement helloworld.GreeterServer. 41 | type server struct { 42 | pb.UnimplementedGreeterServer 43 | } 44 | 45 | // SayHello implements helloworld.GreeterServer 46 | func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) { 47 | log.Printf("Received: %v", in.GetName()) 48 | md, ok := metadata.FromIncomingContext(ctx) 49 | if ok { 50 | data, _ := json.Marshal(md) 51 | fmt.Println(string(data)) 52 | } 53 | 54 | return &pb.HelloReply{Message: "Hello " + in.GetName()}, nil 55 | } 56 | 57 | func main() { 58 | flag.Parse() 59 | lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *port)) 60 | if err != nil { 61 | log.Fatalf("failed to listen: %v", err) 62 | } 63 | s := grpc.NewServer() 64 | pb.RegisterGreeterServer(s, &server{}) 65 | log.Printf("server listening at %v", lis.Addr()) 66 | if err := s.Serve(lis); err != nil { 67 | log.Fatalf("failed to serve: %v", err) 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /example/http2grpc/upstream/proto/helloworld.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2015 gRPC authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | option go_package = "google.golang.org/grpc/examples/helloworld/helloworld"; 18 | option java_multiple_files = true; 19 | option java_package = "io.grpc.examples.helloworld"; 20 | option java_outer_classname = "HelloWorldProto"; 21 | 22 | package helloworld; 23 | 24 | // The greeting service definition. 25 | service Greeter { 26 | // Sends a greeting 27 | rpc SayHello (HelloRequest) returns (HelloReply) {} 28 | } 29 | 30 | // The request message containing the user's name. 31 | message HelloRequest { 32 | string name = 1; 33 | } 34 | 35 | // The response message containing the greetings 36 | message HelloReply { 37 | string message = 1; 38 | } 39 | -------------------------------------------------------------------------------- /example/loader/etcd/Makefile: -------------------------------------------------------------------------------- 1 | GO = go 2 | DTOOLS = dtools 3 | TARGET = trpc-gateway 4 | SERVER = sever 5 | 6 | # Install etcd https://etcd.io/docs/v3.5/install/ and make sure to move it to the path 7 | # Start etcd 8 | etcd: 9 | etcd 10 | 11 | # 设置路由配置 12 | update_router: 13 | cat ./conf/router.yaml | etcdctl put router_conf 14 | 15 | server: 16 | cd ../upstream && go build -o ../bin/$(SERVER) && cd .. 17 | ../bin/$(SERVER) -conf=../upstream/trpc_go.yaml 18 | 19 | run: 20 | go build -o ./bin/$(TARGET) 21 | ./bin/$(TARGET) -conf=./trpc_go.yaml 22 | -------------------------------------------------------------------------------- /example/loader/etcd/README.md: -------------------------------------------------------------------------------- 1 | ## Example Instructions 2 | 3 | #### Local Execution 4 | - Start etcd and configure router.yaml, refer to [Makefile](./Makefile) 5 | - Install etcd and execute make run to start an etcd instance locally. 6 | - Execute make update_router to set route.yaml in etcd. 7 | - Start the demo backend service: Execute the following command in the current directory 8 | ```sh 9 | $ make server 10 | ``` 11 | - Start the gateway service: Open another console and execute the following command in the current directory 12 | ```sh 13 | $ make run 14 | ``` 15 | - Call the API Execute the requests in [test.http](./test.http) and observe the response results. -------------------------------------------------------------------------------- /example/loader/etcd/conf/router.yaml: -------------------------------------------------------------------------------- 1 | router: # Router configuration 2 | - method: /greeting # Exact match 3 | target_service: # Upstream service 4 | - service: trpc.user.service # Service name, corresponding to the name in the client configuration 5 | weight: 10 # Service weight, the sum of weights cannot be 0 6 | rewrite: /trpc.test.helloworld.Greeter/SayHello 7 | client: # Upstream service configuration, consistent with the trpc protocol 8 | - name: trpc.user.service 9 | namespace: Development 10 | target: ip://127.0.0.1:8081 11 | env_name: f81a848f 12 | network: tcp 13 | timeout: 8000 14 | protocol: fasthttp # Forward to an HTTP interface 15 | disable_servicerouter: true 16 | plugins: 17 | - name: demo # Global plugin 18 | props: 19 | suid_name: suidxxxglobal -------------------------------------------------------------------------------- /example/loader/etcd/main.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | // Package etcd is gateway usage example 15 | package main 16 | 17 | import ( 18 | "flag" 19 | 20 | "trpc.group/trpc-go/trpc-gateway/core/config" 21 | // Register loader 22 | _ "trpc.group/trpc-go/trpc-gateway/core/loader/etcd" 23 | "trpc.group/trpc-go/trpc-gateway/core/service/fhttp" 24 | "trpc.group/trpc-go/trpc-go/log" 25 | // Register upstream protocol 26 | _ "trpc.group/trpc-go/trpc-gateway/core/service/protocol/fasthttp" 27 | _ "trpc.group/trpc-go/trpc-gateway/core/service/protocol/trpc" 28 | _ "trpc.group/trpc-go/trpc-gateway/plugin/demo" 29 | ) 30 | 31 | func main() { 32 | flag.Parse() 33 | s := config.NewServer() 34 | // register gateway service 35 | fhttp.RegisterFastHTTPService(s) 36 | if err := s.Serve(); err != nil { 37 | log.Fatal(err) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /example/loader/etcd/test.http: -------------------------------------------------------------------------------- 1 | # Execute "make server" and "make run" in two separate terminals, then make the following request 2 | #### 3 | POST http://localhost:8080/greeting 4 | Content-Type: application/json 5 | 6 | { 7 | "msg": "xxxx" 8 | } -------------------------------------------------------------------------------- /example/loader/file/Makefile: -------------------------------------------------------------------------------- 1 | TARGET = trpc-gateway 2 | SERVER = sever 3 | 4 | server: 5 | cd ../upstream && go build -o ../bin/$(SERVER) && cd .. 6 | ../bin/$(SERVER) -conf=../upstream/trpc_go.yaml 7 | 8 | run: 9 | go build -o ./bin/$(TARGET) 10 | ./bin/$(TARGET) -conf=./trpc_go.yaml -router=./conf/router.yaml 11 | -------------------------------------------------------------------------------- /example/loader/file/README.md: -------------------------------------------------------------------------------- 1 | ## Example Explanation 2 | 3 | #### Local Execution Steps 4 | - Start the demo backend service: Execute the following command in the current directory 5 | ```sh 6 | $ make server 7 | ``` 8 | - Start the gateway service: Open another console and execute the following command in the current directory 9 | ```sh 10 | $ make run 11 | ``` 12 | - Call the API Execute the requests in [test.http](./test.http) file and observe the response results. -------------------------------------------------------------------------------- /example/loader/file/conf/router.yaml: -------------------------------------------------------------------------------- 1 | router: # Router configuration 2 | - method: /greeting # Exact match 3 | id: "path:/greeting" 4 | target_service: # Upstream service 5 | - service: trpc.user.service # Service name, corresponds to the 'name' field in the client configuration 6 | weight: 10 # Service weight, sum of weights should not be 0 7 | rewrite: /trpc.test.helloworld.Greeter/SayHello 8 | client: # Upstream service configuration, consistent with the trpc protocol 9 | - name: trpc.user.service 10 | namespace: Development 11 | target: ip://127.0.0.1:8081 12 | env_name: f81a848f 13 | network: tcp 14 | timeout: 8000 15 | protocol: fasthttp 16 | disable_servicerouter: true 17 | plugins: 18 | - name: demo # Service-level plugin 19 | props: 20 | suid_name: suidxxx 21 | plugins: 22 | - name: demo # Global plugin 23 | props: 24 | suid_name: suidxxxglobal -------------------------------------------------------------------------------- /example/loader/file/go.mod: -------------------------------------------------------------------------------- 1 | module trpc.group/trpc-go/trpc-gateway/example 2 | 3 | go 1.18 4 | 5 | require ( 6 | trpc.group/trpc-go/trpc-gateway v1.0.0 7 | trpc.group/trpc-go/trpc-go v0.0.0-20231008070952-27a655b3e79c 8 | ) 9 | 10 | require ( 11 | code.cloudfoundry.org/bytefmt v0.0.0-20211005130812-5bb3c17173e5 // indirect 12 | github.com/BurntSushi/toml v0.3.1 // indirect 13 | github.com/andybalholm/brotli v1.0.5 // indirect 14 | github.com/armon/go-radix v1.0.0 // indirect 15 | github.com/fsnotify/fsnotify v1.4.9 // indirect 16 | github.com/go-playground/form/v4 v4.2.0 // indirect 17 | github.com/golang/snappy v0.0.4 // indirect 18 | github.com/google/flatbuffers v2.0.0+incompatible // indirect 19 | github.com/hashicorp/errwrap v1.0.0 // indirect 20 | github.com/hashicorp/go-multierror v1.1.1 // indirect 21 | github.com/json-iterator/go v1.1.12 // indirect 22 | github.com/klauspost/compress v1.16.3 // indirect 23 | github.com/lestrrat-go/strftime v1.0.6 // indirect 24 | github.com/mitchellh/mapstructure v1.5.0 // indirect 25 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 26 | github.com/modern-go/reflect2 v1.0.2 // indirect 27 | github.com/panjf2000/ants/v2 v2.4.7 // indirect 28 | github.com/pkg/errors v0.9.1 // indirect 29 | github.com/spf13/cast v1.3.1 // indirect 30 | github.com/valyala/bytebufferpool v1.0.0 // indirect 31 | github.com/valyala/fasthttp v1.45.0 // indirect 32 | go.uber.org/atomic v1.9.0 // indirect 33 | go.uber.org/automaxprocs v1.3.0 // indirect 34 | go.uber.org/multierr v1.6.0 // indirect 35 | go.uber.org/zap v1.24.0 // indirect 36 | golang.org/x/net v0.8.0 // indirect 37 | golang.org/x/sync v0.1.0 // indirect 38 | golang.org/x/sys v0.13.0 // indirect 39 | golang.org/x/text v0.13.0 // indirect 40 | google.golang.org/protobuf v1.30.0 // indirect 41 | gopkg.in/yaml.v3 v3.0.1 // indirect 42 | trpc.group/trpc-go/tnet v0.0.0-20230810071536-9d05338021cf // indirect 43 | trpc.group/trpc/trpc-protocol/pb/go/trpc v0.0.0-20230803031059-de4168eb5952 // indirect 44 | ) 45 | -------------------------------------------------------------------------------- /example/loader/file/main.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | // Package file is gateway example 15 | package main 16 | 17 | import ( 18 | "flag" 19 | 20 | "trpc.group/trpc-go/trpc-gateway/core/config" 21 | "trpc.group/trpc-go/trpc-gateway/core/service/fhttp" 22 | "trpc.group/trpc-go/trpc-go/log" 23 | // Register file loader 24 | _ "trpc.group/trpc-go/trpc-gateway/core/loader/file" 25 | // Register upstream protocol 26 | _ "trpc.group/trpc-go/trpc-gateway/core/service/protocol/fasthttp" 27 | _ "trpc.group/trpc-go/trpc-gateway/core/service/protocol/http" 28 | _ "trpc.group/trpc-go/trpc-gateway/core/service/protocol/trpc" 29 | _ "trpc.group/trpc-go/trpc-gateway/plugin/demo" 30 | ) 31 | 32 | func main() { 33 | flag.Parse() 34 | s := config.NewServer() 35 | // register gateway service 36 | fhttp.RegisterFastHTTPService(s) 37 | if err := s.Serve(); err != nil { 38 | log.Fatal(err) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /example/loader/file/test.http: -------------------------------------------------------------------------------- 1 | # Execute "make server" and "make run" in two separate terminals, then make the following request 2 | #### 3 | POST http://localhost:8080/greeting 4 | Content-Type: application/json 5 | 6 | { 7 | "msg": "xxxx" 8 | } -------------------------------------------------------------------------------- /example/loader/upstream/greeter.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | // example of gateway 15 | package main 16 | 17 | import ( 18 | "context" 19 | 20 | "trpc.group/trpc-go/trpc-go/errs" 21 | pb "trpc.group/trpc-go/trpc-go/testdata/trpc/helloworld" 22 | ) 23 | 24 | var greeter = &greeterServiceImpl{ 25 | proxy: pb.NewGreeterClientProxy(), 26 | } 27 | 28 | // greeterServiceImpl greeter service implement 29 | type greeterServiceImpl struct { 30 | proxy pb.GreeterClientProxy 31 | } 32 | 33 | // SayHello 响应成功的示例 34 | func (s *greeterServiceImpl) SayHello(_ context.Context, _ *pb.HelloRequest) (*pb.HelloReply, error) { 35 | rsp := &pb.HelloReply{ 36 | Msg: "Hello", 37 | } 38 | return rsp, nil 39 | } 40 | 41 | // SayHi 返回 err 的示例 42 | func (s *greeterServiceImpl) SayHi(_ context.Context, _ *pb.HelloRequest) (*pb.HelloReply, error) { 43 | return nil, errs.New(8888, "say hi err") 44 | } 45 | -------------------------------------------------------------------------------- /example/loader/upstream/helloworld.proto: -------------------------------------------------------------------------------- 1 | copyright_string_place_holder 2 | syntax = "proto3"; 3 | package trpc.test.helloworld; 4 | option go_package="git.code.oa.com/trpcprotocol/test/trpc"; 5 | service Greeter { 6 | rpc SayHello (HelloRequest) returns (HelloReply) {} 7 | rpc SayHi (HelloRequest) returns (HelloReply) {} 8 | } 9 | message HelloRequest { 10 | string msg = 1; 11 | } 12 | message HelloReply { 13 | string msg = 1; 14 | } -------------------------------------------------------------------------------- /example/loader/upstream/main.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | // Package upstream is an upstream example 15 | package main 16 | 17 | import ( 18 | trpc "trpc.group/trpc-go/trpc-go" 19 | "trpc.group/trpc-go/trpc-go/log" 20 | pb "trpc.group/trpc-go/trpc-go/testdata/trpc/helloworld" 21 | ) 22 | 23 | func main() { 24 | s := trpc.NewServer() 25 | pb.RegisterGreeterService(s, greeter) 26 | if err := s.Serve(); err != nil { 27 | log.Fatalf("failed to serve: %v", err) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /example/loader/upstream/trpc_go.yaml: -------------------------------------------------------------------------------- 1 | global: # Global configuration 2 | namespace: Development # Environment type, divided into two types: "Production" and "Development" 3 | env_name: test # Environment name, name for non-production environments 4 | server: # Server configuration 5 | app: test # Application name for the business 6 | server: trpc # Process service name 7 | bin_path: /usr/local/trpc/bin/ # Path to binary executable files and framework configuration files 8 | conf_path: /usr/local/trpc/conf/ # Path to business configuration files 9 | data_path: /usr/local/trpc/data/ # Path to business data files 10 | service: # Services provided by the business, can have multiple services 11 | - name: trpc.test.http.Greeter # Routing name for the service 12 | ip: 127.0.0.1 # Service listening IP address 13 | port: 8081 # Service listening port 14 | network: tcp # Network listening type: tcp or udp 15 | protocol: http # Application layer protocol: trpc or http 16 | timeout: 1000 # Maximum processing time for requests, in milliseconds 17 | client: # Backend configuration for client calls 18 | plugins: # Plugin configuration 19 | log: # Log configuration 20 | default: # Default log configuration, supports multiple outputs 21 | - writer: console # Default console output 22 | level: debug # Log level for console output -------------------------------------------------------------------------------- /example/sse/Makefile: -------------------------------------------------------------------------------- 1 | GO = go 2 | DTOOLS = dtools 3 | TARGET = trpc-gateway 4 | SERVER = sever 5 | 6 | server: 7 | go run upstream/main.go 8 | 9 | run: 10 | go build -o ./bin/$(TARGET) 11 | ./bin/$(TARGET) -conf=./trpc_go.yaml -router=./conf/router.yaml 12 | -------------------------------------------------------------------------------- /example/sse/README.md: -------------------------------------------------------------------------------- 1 | ## Example Explanation 2 | 3 | #### Local Execution Steps 4 | 5 | - Start the demo backend service: Execute the following command in the current directory 6 | 7 | ```sh 8 | $ make server 9 | ``` 10 | 11 | - Start the gateway service: Open another console and execute the following command in the current directory 12 | 13 | ```sh 14 | $ make run 15 | ``` 16 | 17 | - Call the API Execute the requests in [test.http](./test.http) file and observe the response results. -------------------------------------------------------------------------------- /example/sse/conf/router.yaml: -------------------------------------------------------------------------------- 1 | router: 2 | - method: /stream 3 | id: "path:/stream" 4 | target_service: 5 | - service: trpc.stream.service 6 | weight: 10 7 | client: 8 | - name: trpc.stream.service 9 | namespace: Development 10 | # target: polaris://trpc.user.service 11 | target: ip://127.0.0.1:8081 12 | env_name: f81a848f 13 | network: tcp 14 | timeout: 5000 15 | protocol: http 16 | disable_servicerouter: true 17 | plugins: -------------------------------------------------------------------------------- /example/sse/go.mod: -------------------------------------------------------------------------------- 1 | module trpc.group/trpc-go/trpc-gateway/example 2 | 3 | go 1.18 4 | 5 | require ( 6 | trpc.group/trpc-go/trpc-gateway v1.0.0 7 | trpc.group/trpc-go/trpc-gateway/plugin/cors v1.0.0 8 | trpc.group/trpc-go/trpc-go v1.0.3 9 | ) 10 | 11 | replace trpc.group/trpc-go/trpc-gateway v1.0.0 => ../../ 12 | 13 | require ( 14 | code.cloudfoundry.org/bytefmt v0.0.0-20211005130812-5bb3c17173e5 // indirect 15 | github.com/BurntSushi/toml v0.3.1 // indirect 16 | github.com/andybalholm/brotli v1.1.0 // indirect 17 | github.com/armon/go-radix v1.0.0 // indirect 18 | github.com/fsnotify/fsnotify v1.4.9 // indirect 19 | github.com/go-playground/form/v4 v4.2.0 // indirect 20 | github.com/golang/snappy v0.0.4 // indirect 21 | github.com/google/flatbuffers v2.0.0+incompatible // indirect 22 | github.com/hashicorp/errwrap v1.0.0 // indirect 23 | github.com/hashicorp/go-multierror v1.1.1 // indirect 24 | github.com/json-iterator/go v1.1.12 // indirect 25 | github.com/klauspost/compress v1.17.7 // indirect 26 | github.com/lestrrat-go/strftime v1.0.6 // indirect 27 | github.com/mitchellh/mapstructure v1.5.0 // indirect 28 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 29 | github.com/modern-go/reflect2 v1.0.2 // indirect 30 | github.com/panjf2000/ants/v2 v2.4.7 // indirect 31 | github.com/pkg/errors v0.9.1 // indirect 32 | github.com/spf13/cast v1.3.1 // indirect 33 | github.com/valyala/bytebufferpool v1.0.0 // indirect 34 | github.com/valyala/fasthttp v1.52.0 // indirect 35 | go.uber.org/atomic v1.9.0 // indirect 36 | go.uber.org/automaxprocs v1.3.0 // indirect 37 | go.uber.org/multierr v1.6.0 // indirect 38 | go.uber.org/zap v1.24.0 // indirect 39 | golang.org/x/net v0.21.0 // indirect 40 | golang.org/x/sync v0.1.0 // indirect 41 | golang.org/x/sys v0.17.0 // indirect 42 | golang.org/x/text v0.14.0 // indirect 43 | google.golang.org/protobuf v1.33.0 // indirect 44 | gopkg.in/yaml.v3 v3.0.1 // indirect 45 | trpc.group/trpc-go/tnet v1.0.1 // indirect 46 | trpc.group/trpc/trpc-protocol/pb/go/trpc v1.0.0 // indirect 47 | ) 48 | -------------------------------------------------------------------------------- /example/sse/main.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | // Package file is gateway example 15 | package main 16 | 17 | import ( 18 | "flag" 19 | 20 | "trpc.group/trpc-go/trpc-gateway/core/config" 21 | "trpc.group/trpc-go/trpc-gateway/core/service/fhttp" 22 | "trpc.group/trpc-go/trpc-go/log" 23 | // Register file loader 24 | _ "trpc.group/trpc-go/trpc-gateway/core/loader/file" 25 | // Register upstream protocol 26 | _ "trpc.group/trpc-go/trpc-gateway/core/service/protocol/fasthttp" 27 | _ "trpc.group/trpc-go/trpc-gateway/core/service/protocol/http" 28 | _ "trpc.group/trpc-go/trpc-gateway/core/service/protocol/trpc" 29 | _ "trpc.group/trpc-go/trpc-gateway/plugin/cors" 30 | _ "trpc.group/trpc-go/trpc-gateway/plugin/demo" 31 | ) 32 | 33 | func main() { 34 | flag.Parse() 35 | s := config.NewServer() 36 | // register gateway service 37 | fhttp.RegisterFastHTTPService(s) 38 | if err := s.Serve(); err != nil { 39 | log.Fatal(err) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /example/sse/test.http: -------------------------------------------------------------------------------- 1 | GET http://localhost:8080/stream -------------------------------------------------------------------------------- /example/sse/upstream/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "time" 7 | ) 8 | 9 | func main() { 10 | http.HandleFunc("/stream", streamHandler) 11 | http.ListenAndServe(":8081", nil) 12 | } 13 | 14 | func streamHandler(w http.ResponseWriter, r *http.Request) { 15 | // 设置响应头,指定内容类型为text/event-stream 16 | w.Header().Set("Content-Type", "text/event-stream") 17 | // 设置响应头,禁用HTTP缓存 18 | w.Header().Set("Cache-Control", "no-cache") 19 | // 设置响应头,允许跨域访问 20 | w.Header().Set("Access-Control-Allow-Origin", "*") 21 | 22 | // 创建一个新的事件流 23 | eventStream := make(chan string) 24 | 25 | // 启动一个goroutine,用于向客户端发送事件 26 | go func() { 27 | for { 28 | // 模拟生成事件数据 29 | eventData := time.Now().Format("2006-01-02 15:04:05") 30 | // 将事件数据发送到事件流 31 | eventStream <- eventData 32 | 33 | // 等待1秒钟 34 | time.Sleep(1 * time.Second) 35 | } 36 | }() 37 | 38 | // 循环监听事件流,将事件数据写入响应流 39 | for { 40 | select { 41 | case eventData := <-eventStream: 42 | // 将事件数据写入响应流 43 | fmt.Fprintf(w, "data: %s\n\n", eventData) 44 | // 强制刷新响应流,确保数据被发送到客户端 45 | w.(http.Flusher).Flush() 46 | case <-r.Context().Done(): 47 | // 客户端连接关闭,停止监听事件流 48 | return 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /example/websocket/Makefile: -------------------------------------------------------------------------------- 1 | TARGET = trpc-gateway 2 | SERVER = sever 3 | 4 | server: 5 | go run upstream/main.go 6 | 7 | run: 8 | go build -o ./bin/$(TARGET) 9 | ./bin/$(TARGET) -conf=./trpc_go.yaml -router=./conf/router.yaml 10 | -------------------------------------------------------------------------------- /example/websocket/README.md: -------------------------------------------------------------------------------- 1 | ## Example Explanation 2 | 3 | #### Local Running Method 4 | 5 | - Start the demo backend service: Execute in the current directory 6 | 7 | ```sh 8 | $ make server 9 | ``` 10 | 11 | - Start the gateway service: Open another console, execute in the current directory 12 | 13 | ```sh 14 | $ make run 15 | ``` 16 | 17 | - Call the interface Execute the request in [client](client)and observe the response results. -------------------------------------------------------------------------------- /example/websocket/client/client.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "net/url" 6 | "os" 7 | "os/signal" 8 | "time" 9 | 10 | "github.com/gorilla/websocket" 11 | ) 12 | 13 | func conn() { 14 | // 解析 WebSocket 服务器地址 15 | u := url.URL{Scheme: "ws", Host: "localhost:8080", Path: "/greeting"} 16 | log.Printf("connecting to %s", u.String()) 17 | 18 | // 连接 WebSocket 服务器 19 | c, _, err := websocket.DefaultDialer.Dial(u.String(), nil) 20 | if err != nil { 21 | log.Fatal("dial:", err) 22 | } 23 | defer c.Close() 24 | 25 | // 处理中断信号 26 | done := make(chan struct{}) 27 | interrupt := make(chan os.Signal, 1) 28 | signal.Notify(interrupt, os.Interrupt) 29 | 30 | // 启动读取协程 31 | go func() { 32 | defer close(done) 33 | for { 34 | _, message, err := c.ReadMessage() 35 | if err != nil { 36 | log.Println("read:", err) 37 | return 38 | } 39 | log.Printf("recv: %s", message) 40 | } 41 | }() 42 | 43 | // 发送消息 44 | ticker := time.NewTicker(time.Millisecond) 45 | defer ticker.Stop() 46 | 47 | for { 48 | select { 49 | case <-done: 50 | return 51 | case t := <-ticker.C: 52 | err := c.WriteMessage(websocket.TextMessage, []byte(t.String())) 53 | if err != nil { 54 | log.Println("write:", err) 55 | return 56 | } 57 | case <-interrupt: 58 | log.Println("interrupt") 59 | err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, "xxxxx")) 60 | if err != nil { 61 | log.Println("write close:", err) 62 | return 63 | } 64 | select { 65 | case <-done: 66 | case <-time.After(time.Second): 67 | } 68 | return 69 | } 70 | } 71 | } 72 | 73 | func main() { 74 | conn() 75 | select {} 76 | } 77 | -------------------------------------------------------------------------------- /example/websocket/conf/router.yaml: -------------------------------------------------------------------------------- 1 | router: 2 | - method: /greeting 3 | id: "path:/greeting" 4 | target_service: 5 | - service: trpc.websocket.service 6 | weight: 10 7 | client: 8 | - name: trpc.websocket.service 9 | namespace: Development 10 | target: ip://127.0.0.1:8081 11 | env_name: f81a848f 12 | network: tcp 13 | timeout: 5000 14 | protocol: http 15 | disable_servicerouter: true 16 | plugins: -------------------------------------------------------------------------------- /example/websocket/go.mod: -------------------------------------------------------------------------------- 1 | module trpc.group/trpc-go/trpc-gateway/example 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/gorilla/websocket v1.5.1 7 | trpc.group/trpc-go/trpc-gateway v1.0.0 8 | trpc.group/trpc-go/trpc-gateway/plugin/cors v1.0.0 9 | trpc.group/trpc-go/trpc-go v1.0.3 10 | ) 11 | 12 | replace trpc.group/trpc-go/trpc-gateway v1.0.0 => ../../ 13 | 14 | require ( 15 | code.cloudfoundry.org/bytefmt v0.0.0-20211005130812-5bb3c17173e5 // indirect 16 | github.com/BurntSushi/toml v0.3.1 // indirect 17 | github.com/andybalholm/brotli v1.1.0 // indirect 18 | github.com/armon/go-radix v1.0.0 // indirect 19 | github.com/fasthttp/websocket v1.5.9 // indirect 20 | github.com/fsnotify/fsnotify v1.4.9 // indirect 21 | github.com/go-playground/form/v4 v4.2.0 // indirect 22 | github.com/golang/snappy v0.0.4 // indirect 23 | github.com/google/flatbuffers v2.0.0+incompatible // indirect 24 | github.com/hashicorp/errwrap v1.0.0 // indirect 25 | github.com/hashicorp/go-multierror v1.1.1 // indirect 26 | github.com/json-iterator/go v1.1.12 // indirect 27 | github.com/klauspost/compress v1.17.8 // indirect 28 | github.com/lestrrat-go/strftime v1.0.6 // indirect 29 | github.com/mitchellh/mapstructure v1.5.0 // indirect 30 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 31 | github.com/modern-go/reflect2 v1.0.2 // indirect 32 | github.com/panjf2000/ants/v2 v2.4.7 // indirect 33 | github.com/pkg/errors v0.9.1 // indirect 34 | github.com/savsgio/gotils v0.0.0-20240303185622-093b76447511 // indirect 35 | github.com/spf13/cast v1.3.1 // indirect 36 | github.com/valyala/bytebufferpool v1.0.0 // indirect 37 | github.com/valyala/fasthttp v1.54.0 // indirect 38 | go.uber.org/atomic v1.9.0 // indirect 39 | go.uber.org/automaxprocs v1.3.0 // indirect 40 | go.uber.org/multierr v1.6.0 // indirect 41 | go.uber.org/zap v1.24.0 // indirect 42 | golang.org/x/net v0.25.0 // indirect 43 | golang.org/x/sync v0.1.0 // indirect 44 | golang.org/x/sys v0.20.0 // indirect 45 | golang.org/x/text v0.15.0 // indirect 46 | google.golang.org/protobuf v1.33.0 // indirect 47 | gopkg.in/yaml.v3 v3.0.1 // indirect 48 | trpc.group/trpc-go/tnet v1.0.1 // indirect 49 | trpc.group/trpc/trpc-protocol/pb/go/trpc v1.0.0 // indirect 50 | ) 51 | -------------------------------------------------------------------------------- /example/websocket/main.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | // Package file is gateway example 15 | package main 16 | 17 | import ( 18 | "flag" 19 | 20 | "trpc.group/trpc-go/trpc-gateway/core/config" 21 | "trpc.group/trpc-go/trpc-gateway/core/service/fhttp" 22 | "trpc.group/trpc-go/trpc-go/log" 23 | // Register file loader 24 | _ "trpc.group/trpc-go/trpc-gateway/core/loader/file" 25 | // Register upstream protocol 26 | _ "trpc.group/trpc-go/trpc-gateway/core/service/protocol/fasthttp" 27 | _ "trpc.group/trpc-go/trpc-gateway/core/service/protocol/http" 28 | _ "trpc.group/trpc-go/trpc-gateway/core/service/protocol/trpc" 29 | _ "trpc.group/trpc-go/trpc-gateway/plugin/cors" 30 | _ "trpc.group/trpc-go/trpc-gateway/plugin/demo" 31 | ) 32 | 33 | func main() { 34 | flag.Parse() 35 | s := config.NewServer() 36 | // register gateway service 37 | fhttp.RegisterFastHTTPService(s) 38 | if err := s.Serve(); err != nil { 39 | log.Fatal(err) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module trpc.group/trpc-go/trpc-gateway 2 | 3 | go 1.18 4 | 5 | require ( 6 | code.cloudfoundry.org/bytefmt v0.0.0-20211005130812-5bb3c17173e5 7 | github.com/armon/go-radix v1.0.0 8 | github.com/golang/mock v1.6.0 9 | github.com/prashantv/gostub v1.1.0 10 | github.com/stretchr/testify v1.8.2 11 | github.com/valyala/fasthttp v1.45.0 12 | go.uber.org/automaxprocs v1.3.0 13 | golang.org/x/net v0.17.0 14 | gopkg.in/yaml.v3 v3.0.1 15 | trpc.group/trpc-go/trpc-go v1.0.3 16 | trpc.group/trpc/trpc-protocol/pb/go/trpc v1.0.0 17 | ) 18 | 19 | require ( 20 | github.com/BurntSushi/toml v0.3.1 // indirect 21 | github.com/andybalholm/brotli v1.0.5 // indirect 22 | github.com/davecgh/go-spew v1.1.1 // indirect 23 | github.com/fsnotify/fsnotify v1.4.9 // indirect 24 | github.com/go-playground/form/v4 v4.2.0 // indirect 25 | github.com/google/flatbuffers v2.0.0+incompatible // indirect 26 | github.com/hashicorp/errwrap v1.0.0 // indirect 27 | github.com/hashicorp/go-multierror v1.1.1 // indirect 28 | github.com/json-iterator/go v1.1.12 // indirect 29 | github.com/klauspost/compress v1.16.3 // indirect 30 | github.com/kr/text v0.2.0 // indirect 31 | github.com/lestrrat-go/strftime v1.0.6 // indirect 32 | github.com/mitchellh/mapstructure v1.5.0 // indirect 33 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 34 | github.com/modern-go/reflect2 v1.0.2 // indirect 35 | github.com/pkg/errors v0.9.1 // indirect 36 | github.com/pmezard/go-difflib v1.0.0 // indirect 37 | github.com/spf13/cast v1.3.1 // indirect 38 | github.com/valyala/bytebufferpool v1.0.0 // indirect 39 | go.uber.org/multierr v1.6.0 // indirect 40 | golang.org/x/sys v0.13.0 // indirect 41 | golang.org/x/text v0.13.0 // indirect 42 | ) 43 | 44 | require ( 45 | github.com/benbjohnson/clock v1.3.0 // indirect 46 | github.com/golang/snappy v0.0.4 // indirect 47 | github.com/panjf2000/ants/v2 v2.4.7 // indirect 48 | go.uber.org/atomic v1.9.0 // indirect 49 | go.uber.org/goleak v1.1.12 // indirect 50 | go.uber.org/zap v1.24.0 // indirect 51 | golang.org/x/sync v0.1.0 // indirect 52 | google.golang.org/protobuf v1.33.0 // indirect 53 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect 54 | trpc.group/trpc-go/tnet v1.0.1 // indirect 55 | ) 56 | -------------------------------------------------------------------------------- /internal/hopbyhop.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package internal 15 | 16 | // HopHeaders Hop-by-hop headers. These are removed when sent to the backend. 17 | // As of RFC 7230, hop-by-hop headers are required to appear in the 18 | // Connection header field. These are the headers defined by the 19 | // obsoleted RFC 2616 (section 13.5.1) and are used for backward 20 | // compatibility. 21 | var HopHeaders = []string{ 22 | "Connection", 23 | "Proxy-Connection", // non-standard but still sent by libcurl and rejected by e.g. google 24 | "Keep-Alive", 25 | "Proxy-Authenticate", 26 | "Proxy-Authorization", 27 | "Te", // canonicalized version of "TE" 28 | "Trailer", // not Trailers per URL above; https://www.rfc-editor.org/errata_search.php?eid=4522 29 | "Transfer-Encoding", 30 | "Upgrade", 31 | } 32 | -------------------------------------------------------------------------------- /internal/pool/objectpool/buffer_pool.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package objectpool 15 | 16 | import ( 17 | "bytes" 18 | "sync" 19 | ) 20 | 21 | // BufferPool represents the buffer object pool. 22 | type BufferPool struct { 23 | pool sync.Pool 24 | } 25 | 26 | // NewBufferPool creates a new bytes.Buffer object pool. 27 | func NewBufferPool() *BufferPool { 28 | return &BufferPool{ 29 | pool: sync.Pool{ 30 | New: func() interface{} { 31 | return new(bytes.Buffer) 32 | }, 33 | }, 34 | } 35 | } 36 | 37 | // Get takes the buffer from the pool. 38 | func (p *BufferPool) Get() *bytes.Buffer { 39 | return p.pool.Get().(*bytes.Buffer) 40 | } 41 | 42 | // Put puts buffer back into the pool. 43 | func (p *BufferPool) Put(buf *bytes.Buffer) { 44 | p.pool.Put(buf) 45 | } 46 | -------------------------------------------------------------------------------- /internal/pool/objectpool/buffer_pool_test.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package objectpool_test 15 | 16 | import ( 17 | "testing" 18 | 19 | "github.com/stretchr/testify/assert" 20 | "trpc.group/trpc-go/trpc-gateway/internal/pool/objectpool" 21 | ) 22 | 23 | func TestBufferPool_Get(t *testing.T) { 24 | p := objectpool.NewBufferPool() 25 | 26 | buf := p.Get() 27 | assert.NotNil(t, buf) 28 | buf.Reset() 29 | p.Put(buf) 30 | } 31 | -------------------------------------------------------------------------------- /internal/pool/objectpool/bytes_pool.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | // Package objectpool provides object pool. 15 | package objectpool 16 | 17 | import "sync" 18 | 19 | // BytesPool represents the bytes array object pool. 20 | type BytesPool struct { 21 | pool sync.Pool 22 | } 23 | 24 | // NewBytesPool creates a new bytes array object pool. 25 | func NewBytesPool(size int) *BytesPool { 26 | return &BytesPool{ 27 | pool: sync.Pool{ 28 | New: func() interface{} { 29 | return make([]byte, size) 30 | }, 31 | }, 32 | } 33 | } 34 | 35 | // Get takes the bytes array from the object pool. 36 | func (p *BytesPool) Get() []byte { 37 | return p.pool.Get().([]byte) 38 | } 39 | 40 | // Put puts bytes array back into object pool. 41 | func (p *BytesPool) Put(b []byte) { 42 | p.pool.Put(b) 43 | } 44 | -------------------------------------------------------------------------------- /internal/pool/objectpool/bytes_pool_test.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package objectpool_test 15 | 16 | import ( 17 | "testing" 18 | 19 | "github.com/stretchr/testify/assert" 20 | "trpc.group/trpc-go/trpc-gateway/internal/pool/objectpool" 21 | ) 22 | 23 | func TestBytesPool_Get(t *testing.T) { 24 | p := objectpool.NewBytesPool(100) 25 | assert.NotNil(t, p) 26 | 27 | buf := p.Get() 28 | assert.NotNil(t, buf) 29 | p.Put(buf) 30 | } 31 | -------------------------------------------------------------------------------- /internal/reuseport/reuseport.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | //go:build linux || darwin || dragonfly || freebsd || netbsd || openbsd 15 | // +build linux darwin dragonfly freebsd netbsd openbsd 16 | 17 | // Package reuseport provides a function that returns a net.Listener powered 18 | // by a net.FileListener with a SO_REUSEPORT option set to the socket. 19 | package reuseport 20 | 21 | import ( 22 | "errors" 23 | "fmt" 24 | "net" 25 | "os" 26 | "syscall" 27 | ) 28 | 29 | const fileNameTemplate = "reuseport.%d.%s.%s" 30 | 31 | var errUnsupportedProtocol = errors.New("only tcp, tcp4, tcp6, udp, udp4, udp6 are supported") 32 | 33 | // getSockaddr parses protocol and address and returns implementor 34 | // of syscall.Sockaddr: syscall.SockaddrInet4 or syscall.SockaddrInet6. 35 | func getSockaddr(proto, addr string) (sa syscall.Sockaddr, soType int, err error) { 36 | switch proto { 37 | case "tcp", "tcp4", "tcp6": 38 | return getTCPSockaddr(proto, addr) 39 | case "udp", "udp4", "udp6": 40 | return getUDPSockaddr(proto, addr) 41 | default: 42 | return nil, -1, errUnsupportedProtocol 43 | } 44 | } 45 | 46 | func getSocketFileName(proto, addr string) string { 47 | return fmt.Sprintf(fileNameTemplate, os.Getpid(), proto, addr) 48 | } 49 | 50 | // Listen function is an alias for NewReusablePortListener. 51 | func Listen(proto, addr string) (l net.Listener, err error) { 52 | return NewReusablePortListener(proto, addr) 53 | } 54 | 55 | // ListenPacket is an alias for NewReusablePortPacketConn. 56 | func ListenPacket(proto, addr string) (l net.PacketConn, err error) { 57 | return NewReusablePortPacketConn(proto, addr) 58 | } 59 | -------------------------------------------------------------------------------- /internal/reuseport/reuseport_bsd.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | //go:build darwin || dragonfly || freebsd || netbsd || openbsd 15 | // +build darwin dragonfly freebsd netbsd openbsd 16 | 17 | package reuseport 18 | 19 | import ( 20 | "runtime" 21 | "syscall" 22 | ) 23 | 24 | var reusePort = syscall.SO_REUSEPORT 25 | 26 | func maxListenerBacklog() int { 27 | var ( 28 | n uint32 29 | err error 30 | ) 31 | 32 | switch runtime.GOOS { 33 | case "darwin", "freebsd": 34 | n, err = syscall.SysctlUint32("kern.ipc.somaxconn") 35 | case "netbsd": 36 | // NOTE: NetBSD has no somaxconn-like kernel state so far 37 | case "openbsd": 38 | n, err = syscall.SysctlUint32("kern.somaxconn") 39 | default: 40 | } 41 | 42 | return defaultBacklog(n, err) 43 | } 44 | 45 | func defaultBacklog(n uint32, err error) int { 46 | if n == 0 || err != nil { 47 | return syscall.SOMAXCONN 48 | } 49 | 50 | // FreeBSD stores the backlog in a uint16, as does Linux. 51 | // Assume the other BSDs do too. Truncate number to avoid wrapping. 52 | // See issue 5030. 53 | if n > 1<<16-1 { 54 | n = 1<<16 - 1 55 | } 56 | return int(n) 57 | } 58 | -------------------------------------------------------------------------------- /internal/reuseport/reuseport_linux.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | //go:build linux 15 | // +build linux 16 | 17 | package reuseport 18 | 19 | import ( 20 | "bufio" 21 | "os" 22 | "strconv" 23 | "strings" 24 | "syscall" 25 | ) 26 | 27 | var reusePort = 0x0F 28 | var maxConnFileName = "/proc/sys/net/core/somaxconn" 29 | 30 | func maxListenerBacklog() int { 31 | fd, err := os.Open(maxConnFileName) 32 | if err != nil { 33 | return syscall.SOMAXCONN 34 | } 35 | defer fd.Close() 36 | 37 | rd := bufio.NewReader(fd) 38 | line, err := rd.ReadString('\n') 39 | if err != nil { 40 | return syscall.SOMAXCONN 41 | } 42 | 43 | f := strings.Fields(line) 44 | if len(f) < 1 { 45 | return syscall.SOMAXCONN 46 | } 47 | 48 | n, err := strconv.Atoi(f[0]) 49 | return defaultBacklog(uint32(n), err) 50 | } 51 | 52 | func defaultBacklog(n uint32, err error) int { 53 | if n == 0 || err != nil { 54 | return syscall.SOMAXCONN 55 | } 56 | 57 | // Linux stores the backlog in a uint16. 58 | // Truncate number to avoid wrapping. 59 | // See issue 5030. 60 | if n > 1<<16-1 { 61 | n = 1<<16 - 1 62 | } 63 | return int(n) 64 | } 65 | -------------------------------------------------------------------------------- /internal/reuseport/reuseport_windows.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | // Tencent is pleased to support the open source community by making tRPC available. 15 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. All rights reserved. 16 | // If you have downloaded a copy of the tRPC source code from Tencent, 17 | // please note that tRPC source code is licensed under the Apache 2.0 License that can be found in the LICENSE file. 18 | 19 | //go:build windows 20 | // +build windows 21 | 22 | package reuseport 23 | 24 | import ( 25 | "net" 26 | "syscall" 27 | ) 28 | 29 | var ListenerBacklogMaxSize = maxListenerBacklog() 30 | 31 | func maxListenerBacklog() int { 32 | return syscall.SOMAXCONN 33 | } 34 | 35 | func NewReusablePortListener(proto, addr string) (net.Listener, error) { 36 | return net.Listen(proto, addr) 37 | } 38 | 39 | func NewReusablePortPacketConn(proto, addr string) (net.PacketConn, error) { 40 | return net.ListenPacket(proto, addr) 41 | } 42 | 43 | // Listen function is an alias for NewReusablePortListener. 44 | func Listen(proto, addr string) (l net.Listener, err error) { 45 | return NewReusablePortListener(proto, addr) 46 | } 47 | 48 | // ListenPacket is an alias for NewReusablePortPacketConn. 49 | func ListenPacket(proto, addr string) (l net.PacketConn, err error) { 50 | return NewReusablePortPacketConn(proto, addr) 51 | } 52 | -------------------------------------------------------------------------------- /internal/reuseport/tcp_linux_test.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | //go:build linux 15 | // +build linux 16 | 17 | package reuseport 18 | 19 | import ( 20 | "syscall" 21 | "testing" 22 | 23 | "github.com/stretchr/testify/assert" 24 | ) 25 | 26 | func TestMaxListenerBackLog(t *testing.T) { 27 | oldMaxConnFileName := maxConnFileName 28 | defer func() { 29 | maxConnFileName = oldMaxConnFileName 30 | }() 31 | 32 | tests := []struct { 33 | name string 34 | fileName string 35 | want int 36 | }{ 37 | { 38 | name: "file not exist", 39 | fileName: "./testdata/NotExistFile.txt", 40 | want: syscall.SOMAXCONN, 41 | }, 42 | { 43 | name: "file content invalid, no eof", 44 | fileName: "./testdata/NoEof.txt", 45 | want: syscall.SOMAXCONN, 46 | }, 47 | { 48 | name: "empty line", 49 | fileName: "./testdata/EmptyLine.txt", 50 | want: syscall.SOMAXCONN, 51 | }, 52 | { 53 | name: "num zero", 54 | fileName: "./testdata/NumZero.txt", 55 | want: syscall.SOMAXCONN, 56 | }, 57 | { 58 | name: "num 65536", 59 | fileName: "./testdata/NumMax.txt", 60 | want: 65535, 61 | }, 62 | } 63 | 64 | for _, tt := range tests { 65 | t.Run(tt.name, func(t *testing.T) { 66 | maxConnFileName = tt.fileName 67 | assert.Equalf(t, tt.want, maxListenerBacklog(), "maxListenerBacklog()") 68 | }) 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /internal/reuseport/testdata/EmptyLine.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /internal/reuseport/testdata/NoEof.txt: -------------------------------------------------------------------------------- 1 | 2048 -------------------------------------------------------------------------------- /internal/reuseport/testdata/NumMax.txt: -------------------------------------------------------------------------------- 1 | 65536 2 | -------------------------------------------------------------------------------- /internal/reuseport/testdata/NumZero.txt: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /internal/util/env.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package util 15 | 16 | import "os" 17 | 18 | // ExpandEnv looks for ${var} in s and replaces them with value of the 19 | // corresponding environment variable. 20 | // $var is considered invalid. 21 | // It's not like os.ExpandEnv which will handle both ${var} and $var. 22 | // Since configurations like password for redis/mysql may contain $, this 23 | // method is needed. 24 | // TODO test case 25 | func ExpandEnv(s string) string { 26 | var buf []byte 27 | i := 0 28 | for j := 0; j < len(s); j++ { 29 | if s[j] == '$' && j+2 < len(s) && s[j+1] == '{' { // only ${var} instead of $var is valid 30 | if buf == nil { 31 | buf = make([]byte, 0, 2*len(s)) 32 | } 33 | buf = append(buf, s[i:j]...) 34 | name, w := getEnvName(s[j+1:]) 35 | if name == "" && w > 0 { 36 | // invalid matching, remove the $ 37 | } else if name == "" { 38 | buf = append(buf, s[j]) // keep the $ 39 | } else { 40 | buf = append(buf, os.Getenv(name)...) 41 | } 42 | j += w 43 | i = j + 1 44 | } 45 | } 46 | if buf == nil { 47 | return s 48 | } 49 | return string(buf) + s[i:] 50 | } 51 | 52 | // getEnvName gets env name, that is, var from ${var}. 53 | // And content of var and its len will be returned. 54 | func getEnvName(s string) (string, int) { 55 | // look for right curly bracket '}' 56 | // it's guaranteed that the first char is '{' and the string has at least two char 57 | for i := 1; i < len(s); i++ { 58 | if s[i] == ' ' || s[i] == '\n' || s[i] == '"' { // "xx${xxx" 59 | return "", 0 // encounter invalid char, keep the $ 60 | } 61 | if s[i] == '}' { 62 | if i == 1 { // ${} 63 | return "", 2 // remove ${} 64 | } 65 | return s[1:i], i + 1 66 | } 67 | } 68 | return "", 0 // no },keep the $ 69 | } 70 | -------------------------------------------------------------------------------- /internal/util/plugin.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package util 15 | 16 | // Deduplicate merges two slices. 17 | // Order will be kept and duplication will be removed. 18 | func Deduplicate(a, b []string) []string { 19 | r := make([]string, 0, len(a)+len(b)) 20 | m := make(map[string]bool) 21 | for _, s := range append(a, b...) { 22 | if _, ok := m[s]; !ok { 23 | m[s] = true 24 | r = append(r, s) 25 | } 26 | } 27 | return r 28 | } 29 | -------------------------------------------------------------------------------- /internal/util/plugin_test.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package util 15 | 16 | import ( 17 | "testing" 18 | 19 | "github.com/stretchr/testify/assert" 20 | ) 21 | 22 | // TestDeduplicate 23 | func TestDeduplicate(t *testing.T) { 24 | a := []string{"a1", "a2"} 25 | b := []string{"b1", "b2", "a2"} 26 | r := Deduplicate(a, b) 27 | assert.Equal(t, r, []string{"a1", "a2", "b1", "b2"}) 28 | } 29 | -------------------------------------------------------------------------------- /plugin/accesslog/Makefile: -------------------------------------------------------------------------------- 1 | # Targets: 2 | # 3 | # all: Builds the code locally after testing 4 | # 5 | # fmt: Formats the source files 6 | # build_dev: Builds the code locally 7 | # build Build production binary file. 8 | # vet: Vets the code 9 | # lint: Runs lint over the code (you do not need to fix everything) 10 | # test: Runs the tests 11 | # cover: Gives you the URL to a nice test coverage report 12 | 13 | 14 | export GO111MODULE=on 15 | export GOPRIVATE=git.code.oa.com 16 | export GOPROXY=goproxy.cn 17 | export GOSUMDB="sum.woa.com+643d7a06+Ac5f5VOC4N8NUXdmhbm8pZSXIWfhek5JSmWdWrq7pLX4" 18 | 19 | export GOARCH=amd64 20 | 21 | # The first target is always the default action if `make` is called without 22 | # args we build and install into $GOPATH so that it can just be run 23 | 24 | all: fmt goimports vet lint 25 | 26 | fmt: 27 | @gofmt -s -w ./$* 28 | gen: 29 | @go generate 30 | 31 | vet: 32 | @go vet -all ./ 33 | 34 | ec: 35 | @errcheck ./... | grep -v Close 36 | 37 | lint: 38 | @golint ./... 39 | 40 | goimports: 41 | @goimports -d -w ./ 42 | 43 | 44 | cover: COVERAGE_FILE := coverage.out 45 | cover: 46 | @go test ./... -coverprofile=$(COVERAGE_FILE) -gcflags=all=-l && \ 47 | go tool cover -html=$(COVERAGE_FILE) && rm $(COVERAGE_FILE) 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /plugin/accesslog/go.mod: -------------------------------------------------------------------------------- 1 | module trpc.group/trpc-go/trpc-gateway/plugin/accesslog 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/stretchr/testify v1.8.2 7 | github.com/valyala/fasthttp v1.45.0 8 | go.opentelemetry.io/otel/trace v1.10.0 9 | gopkg.in/yaml.v3 v3.0.1 10 | trpc.group/trpc-go/trpc-gateway v1.0.0 11 | trpc.group/trpc-go/trpc-go v0.0.0-20231008070952-27a655b3e79c 12 | ) 13 | 14 | require ( 15 | github.com/BurntSushi/toml v0.3.1 // indirect 16 | github.com/andybalholm/brotli v1.0.5 // indirect 17 | github.com/davecgh/go-spew v1.1.1 // indirect 18 | github.com/fsnotify/fsnotify v1.4.9 // indirect 19 | github.com/golang/snappy v0.0.4 // indirect 20 | github.com/google/flatbuffers v2.0.0+incompatible // indirect 21 | github.com/hashicorp/errwrap v1.0.0 // indirect 22 | github.com/hashicorp/go-multierror v1.1.1 // indirect 23 | github.com/json-iterator/go v1.1.12 // indirect 24 | github.com/klauspost/compress v1.16.3 // indirect 25 | github.com/lestrrat-go/strftime v1.0.6 // indirect 26 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 27 | github.com/modern-go/reflect2 v1.0.2 // indirect 28 | github.com/panjf2000/ants/v2 v2.4.7 // indirect 29 | github.com/pkg/errors v0.9.1 // indirect 30 | github.com/pmezard/go-difflib v1.0.0 // indirect 31 | github.com/spf13/cast v1.3.1 // indirect 32 | github.com/valyala/bytebufferpool v1.0.0 // indirect 33 | go.opentelemetry.io/otel v1.10.0 // indirect 34 | go.uber.org/atomic v1.9.0 // indirect 35 | go.uber.org/automaxprocs v1.3.0 // indirect 36 | go.uber.org/multierr v1.6.0 // indirect 37 | go.uber.org/zap v1.24.0 // indirect 38 | golang.org/x/sync v0.1.0 // indirect 39 | golang.org/x/sys v0.13.0 // indirect 40 | google.golang.org/protobuf v1.30.0 // indirect 41 | trpc.group/trpc-go/tnet v0.0.0-20230810071536-9d05338021cf // indirect 42 | trpc.group/trpc/trpc-protocol/pb/go/trpc v0.0.0-20230803031059-de4168eb5952 // indirect 43 | ) 44 | -------------------------------------------------------------------------------- /plugin/batchrequest/Makefile: -------------------------------------------------------------------------------- 1 | # Targets: 2 | # 3 | # all: Builds the code locally after testing 4 | # 5 | # fmt: Formats the source files 6 | # build_dev: Builds the code locally 7 | # build Build production binary file. 8 | # vet: Vets the code 9 | # lint: Runs lint over the code (you do not need to fix everything) 10 | # test: Runs the tests 11 | # cover: Gives you the URL to a nice test coverage report 12 | 13 | 14 | export GO111MODULE=on 15 | export GOPRIVATE=git.code.oa.com 16 | export GOPROXY=goproxy.cn 17 | export GOSUMDB="sum.woa.com+643d7a06+Ac5f5VOC4N8NUXdmhbm8pZSXIWfhek5JSmWdWrq7pLX4" 18 | 19 | # set for M1Pro 20 | export GOARCH=amd64 21 | 22 | # The first target is always the default action if `make` is called without 23 | # args we build and install into $GOPATH so that it can just be run 24 | 25 | all: fmt goimports vet lint 26 | 27 | fmt: 28 | @gofmt -s -w ./$* 29 | gen: 30 | @go generate 31 | 32 | vet: 33 | @go vet -all ./ 34 | 35 | ec: 36 | @errcheck ./... | grep -v Close 37 | 38 | lint: 39 | @golint ./... 40 | 41 | goimports: 42 | @goimports -d -w ./ 43 | 44 | 45 | cover: COVERAGE_FILE := coverage.out 46 | cover: 47 | @go test ./... -coverprofile=$(COVERAGE_FILE) -gcflags=all=-l && \ 48 | go tool cover -html=$(COVERAGE_FILE) && rm $(COVERAGE_FILE) 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /plugin/batchrequest/docs/batch_request.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trpc-ecosystem/go-gateway/fb963d00e11d5d66bd03b2e9e20ab48f68d0feec/plugin/batchrequest/docs/batch_request.png -------------------------------------------------------------------------------- /plugin/batchrequest/docs/console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trpc-ecosystem/go-gateway/fb963d00e11d5d66bd03b2e9e20ab48f68d0feec/plugin/batchrequest/docs/console.png -------------------------------------------------------------------------------- /plugin/batchrequest/go.mod: -------------------------------------------------------------------------------- 1 | module trpc.group/trpc-go/trpc-gateway/plugin/batchrequest 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/golang/mock v1.6.0 7 | github.com/prashantv/gostub v1.1.0 8 | github.com/stretchr/testify v1.8.2 9 | github.com/tidwall/gjson v1.16.0 10 | github.com/tidwall/sjson v1.2.5 11 | github.com/valyala/fasthttp v1.45.0 12 | trpc.group/trpc-go/trpc-gateway v1.0.0 13 | trpc.group/trpc-go/trpc-go v0.0.0-20231008070952-27a655b3e79c 14 | ) 15 | 16 | require ( 17 | github.com/BurntSushi/toml v0.3.1 // indirect 18 | github.com/andybalholm/brotli v1.0.5 // indirect 19 | github.com/davecgh/go-spew v1.1.1 // indirect 20 | github.com/fsnotify/fsnotify v1.4.9 // indirect 21 | github.com/golang/snappy v0.0.4 // indirect 22 | github.com/google/flatbuffers v2.0.0+incompatible // indirect 23 | github.com/hashicorp/errwrap v1.0.0 // indirect 24 | github.com/hashicorp/go-multierror v1.1.1 // indirect 25 | github.com/json-iterator/go v1.1.12 // indirect 26 | github.com/klauspost/compress v1.16.3 // indirect 27 | github.com/kr/pretty v0.2.1 // indirect 28 | github.com/lestrrat-go/strftime v1.0.6 // indirect 29 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 30 | github.com/modern-go/reflect2 v1.0.2 // indirect 31 | github.com/panjf2000/ants/v2 v2.4.7 // indirect 32 | github.com/pkg/errors v0.9.1 // indirect 33 | github.com/pmezard/go-difflib v1.0.0 // indirect 34 | github.com/spf13/cast v1.3.1 // indirect 35 | github.com/tidwall/match v1.1.1 // indirect 36 | github.com/tidwall/pretty v1.2.0 // indirect 37 | github.com/valyala/bytebufferpool v1.0.0 // indirect 38 | go.uber.org/atomic v1.9.0 // indirect 39 | go.uber.org/automaxprocs v1.3.0 // indirect 40 | go.uber.org/multierr v1.6.0 // indirect 41 | go.uber.org/zap v1.24.0 // indirect 42 | golang.org/x/sync v0.1.0 // indirect 43 | golang.org/x/sys v0.13.0 // indirect 44 | google.golang.org/protobuf v1.30.0 // indirect 45 | gopkg.in/yaml.v3 v3.0.1 // indirect 46 | trpc.group/trpc-go/tnet v0.0.0-20230810071536-9d05338021cf // indirect 47 | trpc.group/trpc/trpc-protocol/pb/go/trpc v0.0.0-20230803031059-de4168eb5952 // indirect 48 | ) 49 | -------------------------------------------------------------------------------- /plugin/cors/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log -------------------------------------------------------------------------------- /plugin/cors/Makefile: -------------------------------------------------------------------------------- 1 | GO = go 2 | DTOOLS = dtools 3 | TARGET = trpc-gateway 4 | 5 | # set for M1Pro 6 | export GOARCH=amd64 7 | 8 | all: fmt goimports vet lint 9 | 10 | fmt: 11 | @gofmt -s -w ./$* 12 | 13 | vet: 14 | @go vet -all ./ 15 | 16 | ec: 17 | @errcheck ./... | grep -v Close 18 | 19 | lint: 20 | @golint ./... 21 | 22 | goimports: 23 | @goimports -d -w ./ 24 | 25 | test: 26 | CFLAGS=-g 27 | export CFLAGS 28 | $(GO) test $(M) -v -gcflags=all=-l -coverpkg=./... -coverprofile=test.out ./... 29 | clean: 30 | rm -f $(TARGET) 31 | rm -rf release 32 | 33 | cover: COVERAGE_FILE := coverage.out 34 | cover: 35 | @go test ./... -coverprofile=$(COVERAGE_FILE) -gcflags=all=-l && \ 36 | go tool cover -html=$(COVERAGE_FILE) && rm $(COVERAGE_FILE) 37 | -------------------------------------------------------------------------------- /plugin/cors/go.mod: -------------------------------------------------------------------------------- 1 | module trpc.group/trpc-go/trpc-gateway/plugin/cors 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/stretchr/testify v1.8.2 7 | github.com/valyala/fasthttp v1.45.0 8 | trpc.group/trpc-go/trpc-gateway v1.0.0 9 | trpc.group/trpc-go/trpc-go v0.0.0-20231008070952-27a655b3e79c 10 | ) 11 | 12 | require ( 13 | github.com/BurntSushi/toml v0.3.1 // indirect 14 | github.com/andybalholm/brotli v1.0.5 // indirect 15 | github.com/davecgh/go-spew v1.1.1 // indirect 16 | github.com/fsnotify/fsnotify v1.4.9 // indirect 17 | github.com/golang/snappy v0.0.4 // indirect 18 | github.com/google/flatbuffers v2.0.0+incompatible // indirect 19 | github.com/hashicorp/errwrap v1.0.0 // indirect 20 | github.com/hashicorp/go-multierror v1.1.1 // indirect 21 | github.com/json-iterator/go v1.1.12 // indirect 22 | github.com/klauspost/compress v1.16.3 // indirect 23 | github.com/kr/pretty v0.2.1 // indirect 24 | github.com/lestrrat-go/strftime v1.0.6 // indirect 25 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 26 | github.com/modern-go/reflect2 v1.0.2 // indirect 27 | github.com/panjf2000/ants/v2 v2.4.7 // indirect 28 | github.com/pkg/errors v0.9.1 // indirect 29 | github.com/pmezard/go-difflib v1.0.0 // indirect 30 | github.com/spf13/cast v1.3.1 // indirect 31 | github.com/valyala/bytebufferpool v1.0.0 // indirect 32 | go.uber.org/atomic v1.9.0 // indirect 33 | go.uber.org/multierr v1.6.0 // indirect 34 | go.uber.org/zap v1.24.0 // indirect 35 | golang.org/x/sync v0.1.0 // indirect 36 | golang.org/x/sys v0.13.0 // indirect 37 | google.golang.org/protobuf v1.30.0 // indirect 38 | gopkg.in/yaml.v3 v3.0.1 // indirect 39 | trpc.group/trpc-go/tnet v0.0.0-20230810071536-9d05338021cf // indirect 40 | trpc.group/trpc/trpc-protocol/pb/go/trpc v0.0.0-20230803031059-de4168eb5952 // indirect 41 | ) 42 | -------------------------------------------------------------------------------- /plugin/demo/Makefile: -------------------------------------------------------------------------------- 1 | # Targets: 2 | # 3 | # all: Builds the code locally after testing 4 | # 5 | # fmt: Formats the source files 6 | # build_dev: Builds the code locally 7 | # build Build production binary file. 8 | # vet: Vets the code 9 | # lint: Runs lint over the code (you do not need to fix everything) 10 | # test: Runs the tests 11 | # cover: Gives you the URL to a nice test coverage report 12 | 13 | 14 | export GO111MODULE=on 15 | export GOPRIVATE=git.code.oa.com 16 | export GOPROXY=goproxy.cn 17 | export GOSUMDB="sum.woa.com+643d7a06+Ac5f5VOC4N8NUXdmhbm8pZSXIWfhek5JSmWdWrq7pLX4" 18 | 19 | export GOARCH=amd64 20 | 21 | # The first target is always the default action if `make` is called without 22 | # args we build and install into $GOPATH so that it can just be run 23 | 24 | all: fmt goimports vet lint 25 | 26 | fmt: 27 | @gofmt -s -w ./$* 28 | gen: 29 | @go generate 30 | 31 | vet: 32 | @go vet -all ./ 33 | 34 | ec: 35 | @errcheck ./... | grep -v Close 36 | 37 | lint: 38 | @golint ./... 39 | 40 | goimports: 41 | @goimports -d -w ./ 42 | 43 | 44 | cover: COVERAGE_FILE := coverage.out 45 | cover: 46 | @go test ./... -coverprofile=$(COVERAGE_FILE) -gcflags=all=-l && \ 47 | go tool cover -html=$(COVERAGE_FILE) && rm $(COVERAGE_FILE) 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /plugin/demo/README.md: -------------------------------------------------------------------------------- 1 | # tRPC-Gateway Gateway Demo Plugin 2 | 3 | This is a gateway plugin example that can be used as a template to quickly develop your own gateway plugins for your business. 4 | 5 | Note that this documentation currently only applies to the development of plugins for the HTTP protocol, which is the main supported protocol of tRPC-Gateway. 6 | 7 | Prerequisite Knowledge: 8 | - [fasthttp API](https://github.com/valyala/fasthttp) 9 | 10 | ## Usage Instructions 11 | 12 | ### Import the Plugin in the main.go file of the Gateway Project 13 | 14 | - Add the import statement 15 | 16 | ```go 17 | import ( 18 | _ "trpc.group/trpc-go/trpc-gateway/plugin/demo" 19 | ) 20 | ``` 21 | 22 | - trpc_go.yaml framework configuration file, enable the demo interceptor. 23 | 24 | Note: Make sure to register it under server.service.filter, not server.filter. 25 | 26 | ```yaml 27 | global: # Global configuration 28 | server: # Server configuration 29 | filter: # Interceptor list for all service handler functions 30 | service: # Business services provided, can have multiple 31 | - name: trpc.inews.trpc.gateway # Route name of the service 32 | filter: 33 | - demo # Gateway plugin registered as a filter in the service, so that it can be dynamically loaded in router.yaml 34 | plugins: # Plugin configuration 35 | log: # Log configuration 36 | gateway: # Plugin type is gateway 37 | demo: # Name of the CORS plugin 38 | ``` 39 | 40 | Configure the plugin in the gateway routing configuration router.yaml, supporting global, service, and router-level plugin configurations. 41 | 42 | ```yaml 43 | router: # Routing configuration 44 | - method: /v1/user/info 45 | target_service: 46 | - service: trpc.user.service 47 | plugins: 48 | - name: demo 49 | props: 50 | suid_name: xxx 51 | client: # Upstream service configuration, follows the tRPC protocol 52 | - name: trpc.user.service 53 | plugins: 54 | - name: request_transformer # Service-level configuration, will be effective for all interfaces forwarded to this service 55 | props: 56 | plugins: 57 | - name: demo # Global configuration, will be effective for all interfaces 58 | props: 59 | ``` -------------------------------------------------------------------------------- /plugin/devenv/Makefile: -------------------------------------------------------------------------------- 1 | # Targets: 2 | # 3 | # all: Builds the code locally after testing 4 | # 5 | # fmt: Formats the source files 6 | # build_dev: Builds the code locally 7 | # build Build production binary file. 8 | # vet: Vets the code 9 | # lint: Runs lint over the code (you do not need to fix everything) 10 | # test: Runs the tests 11 | # cover: Gives you the URL to a nice test coverage report 12 | 13 | 14 | export GO111MODULE=on 15 | export GOPRIVATE=git.code.oa.com 16 | export GOPROXY=goproxy.cn 17 | export GOSUMDB="sum.woa.com+643d7a06+Ac5f5VOC4N8NUXdmhbm8pZSXIWfhek5JSmWdWrq7pLX4" 18 | 19 | # set for M1Pro 20 | export GOARCH=amd64 21 | 22 | # The first target is always the default action if `make` is called without 23 | # args we build and install into $GOPATH so that it can just be run 24 | 25 | all: fmt goimports vet lint 26 | 27 | fmt: 28 | @gofmt -s -w ./$* 29 | gen: 30 | @go generate 31 | 32 | vet: 33 | @go vet -all ./ 34 | 35 | ec: 36 | @errcheck ./... | grep -v Close 37 | 38 | lint: 39 | @golint ./... 40 | 41 | goimports: 42 | @goimports -d -w ./ 43 | 44 | 45 | cover: COVERAGE_FILE := coverage.out 46 | cover: 47 | @go test ./... -coverprofile=$(COVERAGE_FILE) -gcflags=all=-l && \ 48 | go tool cover -html=$(COVERAGE_FILE) && rm $(COVERAGE_FILE) 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /plugin/devenv/docs/console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trpc-ecosystem/go-gateway/fb963d00e11d5d66bd03b2e9e20ab48f68d0feec/plugin/devenv/docs/console.png -------------------------------------------------------------------------------- /plugin/devenv/docs/devenv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trpc-ecosystem/go-gateway/fb963d00e11d5d66bd03b2e9e20ab48f68d0feec/plugin/devenv/docs/devenv.png -------------------------------------------------------------------------------- /plugin/devenv/go.mod: -------------------------------------------------------------------------------- 1 | module trpc.group/trpc-go/trpc-gateway/plugin/devenv 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/stretchr/testify v1.8.2 7 | github.com/valyala/fasthttp v1.45.0 8 | gopkg.in/yaml.v3 v3.0.1 9 | trpc.group/trpc-go/trpc-gateway v1.0.0 10 | trpc.group/trpc-go/trpc-go v0.0.0-20231008070952-27a655b3e79c 11 | ) 12 | 13 | require ( 14 | github.com/BurntSushi/toml v0.3.1 // indirect 15 | github.com/andybalholm/brotli v1.0.5 // indirect 16 | github.com/davecgh/go-spew v1.1.1 // indirect 17 | github.com/fsnotify/fsnotify v1.4.9 // indirect 18 | github.com/golang/snappy v0.0.4 // indirect 19 | github.com/google/flatbuffers v2.0.0+incompatible // indirect 20 | github.com/hashicorp/errwrap v1.0.0 // indirect 21 | github.com/hashicorp/go-multierror v1.1.1 // indirect 22 | github.com/json-iterator/go v1.1.12 // indirect 23 | github.com/klauspost/compress v1.16.3 // indirect 24 | github.com/kr/pretty v0.2.1 // indirect 25 | github.com/lestrrat-go/strftime v1.0.6 // indirect 26 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 27 | github.com/modern-go/reflect2 v1.0.2 // indirect 28 | github.com/panjf2000/ants/v2 v2.4.7 // indirect 29 | github.com/pkg/errors v0.9.1 // indirect 30 | github.com/pmezard/go-difflib v1.0.0 // indirect 31 | github.com/spf13/cast v1.3.1 // indirect 32 | github.com/valyala/bytebufferpool v1.0.0 // indirect 33 | go.uber.org/atomic v1.9.0 // indirect 34 | go.uber.org/multierr v1.6.0 // indirect 35 | go.uber.org/zap v1.24.0 // indirect 36 | golang.org/x/sync v0.1.0 // indirect 37 | golang.org/x/sys v0.13.0 // indirect 38 | google.golang.org/protobuf v1.30.0 // indirect 39 | trpc.group/trpc-go/tnet v0.0.0-20230810071536-9d05338021cf // indirect 40 | trpc.group/trpc/trpc-protocol/pb/go/trpc v0.0.0-20230803031059-de4168eb5952 // indirect 41 | ) 42 | -------------------------------------------------------------------------------- /plugin/limiter/polaris/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log -------------------------------------------------------------------------------- /plugin/limiter/polaris/Makefile: -------------------------------------------------------------------------------- 1 | cover: COVERAGE_FILE := coverage.out 2 | cover: 3 | @go test ./... -coverprofile=$(COVERAGE_FILE) -gcflags=all=-l && \ 4 | go tool cover -html=$(COVERAGE_FILE) && rm $(COVERAGE_FILE) 5 | -------------------------------------------------------------------------------- /plugin/limiter/polaris/docs/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trpc-ecosystem/go-gateway/fb963d00e11d5d66bd03b2e9e20ab48f68d0feec/plugin/limiter/polaris/docs/img.png -------------------------------------------------------------------------------- /plugin/logreplay/Makefile: -------------------------------------------------------------------------------- 1 | # Targets: 2 | # 3 | # all: Builds the code locally after testing 4 | # 5 | # fmt: Formats the source files 6 | # build_dev: Builds the code locally 7 | # build Build production binary file. 8 | # vet: Vets the code 9 | # lint: Runs lint over the code (you do not need to fix everything) 10 | # test: Runs the tests 11 | # cover: Gives you the URL to a nice test coverage report 12 | 13 | 14 | export GO111MODULE=on 15 | export GOPRIVATE=git.code.oa.com 16 | export GOPROXY=goproxy.cn 17 | export GOSUMDB="sum.woa.com+643d7a06+Ac5f5VOC4N8NUXdmhbm8pZSXIWfhek5JSmWdWrq7pLX4" 18 | 19 | # set for M1Pro 20 | export GOARCH=amd64 21 | 22 | # The first target is always the default action if `make` is called without 23 | # args we build and install into $GOPATH so that it can just be run 24 | 25 | all: fmt goimports vet lint 26 | 27 | fmt: 28 | @gofmt -s -w ./$* 29 | gen: 30 | @go generate 31 | 32 | vet: 33 | @go vet -all ./ 34 | 35 | ec: 36 | @errcheck ./... | grep -v Close 37 | 38 | lint: 39 | @golint ./... 40 | 41 | goimports: 42 | @goimports -d -w ./ 43 | 44 | 45 | cover: COVERAGE_FILE := coverage.out 46 | cover: 47 | @go test ./... -coverprofile=$(COVERAGE_FILE) -gcflags=all=-l && \ 48 | go tool cover -html=$(COVERAGE_FILE) && rm $(COVERAGE_FILE) 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /plugin/logreplay/docs/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trpc-ecosystem/go-gateway/fb963d00e11d5d66bd03b2e9e20ab48f68d0feec/plugin/logreplay/docs/img.png -------------------------------------------------------------------------------- /plugin/logreplay/docs/logreplay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trpc-ecosystem/go-gateway/fb963d00e11d5d66bd03b2e9e20ab48f68d0feec/plugin/logreplay/docs/logreplay.png -------------------------------------------------------------------------------- /plugin/logreplay/go.mod: -------------------------------------------------------------------------------- 1 | module trpc.group/trpc-go/trpc-gateway/plugin/logreplay 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/golang/mock v1.6.0 7 | github.com/prashantv/gostub v1.1.0 8 | github.com/stretchr/testify v1.8.2 9 | github.com/tidwall/sjson v1.2.5 10 | github.com/valyala/fasthttp v1.45.0 11 | trpc.group/trpc-go/trpc-gateway v1.0.0 12 | trpc.group/trpc-go/trpc-go v0.0.0-20231008070952-27a655b3e79c 13 | ) 14 | 15 | require ( 16 | code.cloudfoundry.org/bytefmt v0.0.0-20211005130812-5bb3c17173e5 // indirect 17 | github.com/BurntSushi/toml v0.3.1 // indirect 18 | github.com/andybalholm/brotli v1.0.5 // indirect 19 | github.com/armon/go-radix v1.0.0 // indirect 20 | github.com/davecgh/go-spew v1.1.1 // indirect 21 | github.com/fsnotify/fsnotify v1.4.9 // indirect 22 | github.com/go-playground/form/v4 v4.2.0 // indirect 23 | github.com/golang/snappy v0.0.4 // indirect 24 | github.com/google/flatbuffers v2.0.0+incompatible // indirect 25 | github.com/hashicorp/errwrap v1.0.0 // indirect 26 | github.com/hashicorp/go-multierror v1.1.1 // indirect 27 | github.com/json-iterator/go v1.1.12 // indirect 28 | github.com/klauspost/compress v1.16.3 // indirect 29 | github.com/kr/pretty v0.2.1 // indirect 30 | github.com/lestrrat-go/strftime v1.0.6 // indirect 31 | github.com/mitchellh/mapstructure v1.5.0 // indirect 32 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 33 | github.com/modern-go/reflect2 v1.0.2 // indirect 34 | github.com/panjf2000/ants/v2 v2.4.7 // indirect 35 | github.com/pkg/errors v0.9.1 // indirect 36 | github.com/pmezard/go-difflib v1.0.0 // indirect 37 | github.com/spf13/cast v1.3.1 // indirect 38 | github.com/tidwall/gjson v1.16.0 // indirect 39 | github.com/tidwall/match v1.1.1 // indirect 40 | github.com/tidwall/pretty v1.2.0 // indirect 41 | github.com/valyala/bytebufferpool v1.0.0 // indirect 42 | go.uber.org/atomic v1.9.0 // indirect 43 | go.uber.org/automaxprocs v1.3.0 // indirect 44 | go.uber.org/multierr v1.6.0 // indirect 45 | go.uber.org/zap v1.24.0 // indirect 46 | golang.org/x/net v0.8.0 // indirect 47 | golang.org/x/sync v0.1.0 // indirect 48 | golang.org/x/sys v0.13.0 // indirect 49 | golang.org/x/text v0.13.0 // indirect 50 | google.golang.org/protobuf v1.30.0 // indirect 51 | gopkg.in/yaml.v3 v3.0.1 // indirect 52 | trpc.group/trpc-go/tnet v0.0.0-20230810071536-9d05338021cf // indirect 53 | trpc.group/trpc/trpc-protocol/pb/go/trpc v0.0.0-20230803031059-de4168eb5952 // indirect 54 | ) 55 | -------------------------------------------------------------------------------- /plugin/mock/decoder.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | // Code generated by MockGen. DO NOT EDIT. 15 | // Source: trpc.group/trpc-go/trpc-go/plugin (interfaces: Decoder) 16 | 17 | // Package mock_plugin is a generated GoMock package. 18 | package mock_plugin 19 | 20 | import ( 21 | reflect "reflect" 22 | 23 | gomock "github.com/golang/mock/gomock" 24 | ) 25 | 26 | // MockDecoder is a mock of Decoder interface. 27 | type MockDecoder struct { 28 | ctrl *gomock.Controller 29 | recorder *MockDecoderMockRecorder 30 | } 31 | 32 | // MockDecoderMockRecorder is the mock recorder for MockDecoder. 33 | type MockDecoderMockRecorder struct { 34 | mock *MockDecoder 35 | } 36 | 37 | // NewMockDecoder creates a new mock instance. 38 | func NewMockDecoder(ctrl *gomock.Controller) *MockDecoder { 39 | mock := &MockDecoder{ctrl: ctrl} 40 | mock.recorder = &MockDecoderMockRecorder{mock} 41 | return mock 42 | } 43 | 44 | // EXPECT returns an object that allows the caller to indicate expected use. 45 | func (m *MockDecoder) EXPECT() *MockDecoderMockRecorder { 46 | return m.recorder 47 | } 48 | 49 | // Decode mocks base method. 50 | func (m *MockDecoder) Decode(arg0 interface{}) error { 51 | m.ctrl.T.Helper() 52 | ret := m.ctrl.Call(m, "Decode", arg0) 53 | ret0, _ := ret[0].(error) 54 | return ret0 55 | } 56 | 57 | // Decode indicates an expected call of Decode. 58 | func (mr *MockDecoderMockRecorder) Decode(arg0 interface{}) *gomock.Call { 59 | mr.mock.ctrl.T.Helper() 60 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Decode", reflect.TypeOf((*MockDecoder)(nil).Decode), arg0) 61 | } 62 | -------------------------------------------------------------------------------- /plugin/mocking/Makefile: -------------------------------------------------------------------------------- 1 | # Targets: 2 | # 3 | # all: Builds the code locally after testing 4 | # 5 | # fmt: Formats the source files 6 | # build_dev: Builds the code locally 7 | # build Build production binary file. 8 | # vet: Vets the code 9 | # lint: Runs lint over the code (you do not need to fix everything) 10 | # test: Runs the tests 11 | # cover: Gives you the URL to a nice test coverage report 12 | 13 | 14 | export GO111MODULE=on 15 | export GOPRIVATE=git.code.oa.com 16 | export GOPROXY=goproxy.cn 17 | export GOSUMDB="sum.woa.com+643d7a06+Ac5f5VOC4N8NUXdmhbm8pZSXIWfhek5JSmWdWrq7pLX4" 18 | 19 | # set for M1Pro 20 | export GOARCH=amd64 21 | 22 | # The first target is always the default action if `make` is called without 23 | # args we build and install into $GOPATH so that it can just be run 24 | 25 | all: fmt goimports vet lint 26 | 27 | fmt: 28 | @gofmt -s -w ./$* 29 | gen: 30 | @go generate 31 | 32 | vet: 33 | @go vet -all ./ 34 | 35 | ec: 36 | @errcheck ./... | grep -v Close 37 | 38 | lint: 39 | @golint ./... 40 | 41 | goimports: 42 | @goimports -d -w ./ 43 | 44 | 45 | cover: COVERAGE_FILE := coverage.out 46 | cover: 47 | @go test ./... -coverprofile=$(COVERAGE_FILE) -gcflags=all=-l && \ 48 | go tool cover -html=$(COVERAGE_FILE) && rm $(COVERAGE_FILE) -------------------------------------------------------------------------------- /plugin/mocking/go.mod: -------------------------------------------------------------------------------- 1 | module trpc.group/trpc-go/trpc-gateway/plugin/mocking 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/stretchr/testify v1.8.2 7 | github.com/valyala/fasthttp v1.45.0 8 | trpc.group/trpc-go/trpc-gateway v1.0.0 9 | trpc.group/trpc-go/trpc-go v0.0.0-20231008070952-27a655b3e79c 10 | ) 11 | 12 | require ( 13 | github.com/BurntSushi/toml v0.3.1 // indirect 14 | github.com/andybalholm/brotli v1.0.5 // indirect 15 | github.com/davecgh/go-spew v1.1.1 // indirect 16 | github.com/fsnotify/fsnotify v1.4.9 // indirect 17 | github.com/golang/snappy v0.0.4 // indirect 18 | github.com/google/flatbuffers v2.0.0+incompatible // indirect 19 | github.com/hashicorp/errwrap v1.0.0 // indirect 20 | github.com/hashicorp/go-multierror v1.1.1 // indirect 21 | github.com/json-iterator/go v1.1.12 // indirect 22 | github.com/klauspost/compress v1.16.3 // indirect 23 | github.com/kr/pretty v0.2.1 // indirect 24 | github.com/lestrrat-go/strftime v1.0.6 // indirect 25 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 26 | github.com/modern-go/reflect2 v1.0.2 // indirect 27 | github.com/panjf2000/ants/v2 v2.4.7 // indirect 28 | github.com/pkg/errors v0.9.1 // indirect 29 | github.com/pmezard/go-difflib v1.0.0 // indirect 30 | github.com/spf13/cast v1.3.1 // indirect 31 | github.com/valyala/bytebufferpool v1.0.0 // indirect 32 | go.uber.org/atomic v1.9.0 // indirect 33 | go.uber.org/multierr v1.6.0 // indirect 34 | go.uber.org/zap v1.24.0 // indirect 35 | golang.org/x/sync v0.1.0 // indirect 36 | golang.org/x/sys v0.13.0 // indirect 37 | google.golang.org/protobuf v1.30.0 // indirect 38 | gopkg.in/yaml.v3 v3.0.1 // indirect 39 | trpc.group/trpc-go/tnet v0.0.0-20230810071536-9d05338021cf // indirect 40 | trpc.group/trpc/trpc-protocol/pb/go/trpc v0.0.0-20230803031059-de4168eb5952 // indirect 41 | ) 42 | -------------------------------------------------------------------------------- /plugin/plugin.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | // Package plugin defines gateway plugins. 15 | package plugin 16 | 17 | import ( 18 | "errors" 19 | "reflect" 20 | 21 | "gopkg.in/yaml.v3" 22 | gerrs "trpc.group/trpc-go/trpc-gateway/common/errs" 23 | "trpc.group/trpc-go/trpc-go/plugin" 24 | ) 25 | 26 | //go:generate mockgen -destination ./mock/gatewayplugin.go . GatewayPlugin 27 | //go:generate mockgen -destination ./mock/trpcplugin.go trpc.group/trpc-go/trpc-go/plugin Factory 28 | //go:generate mockgen -destination ./mock/decoder.go trpc.group/trpc-go/trpc-go/plugin Decoder 29 | 30 | // GatewayPlugin 网关插件 31 | type GatewayPlugin interface { 32 | // Factory embed tRPC plugin 33 | plugin.Factory 34 | 35 | // CheckConfig 网关插件配置校验,并进行默认值的初始化 36 | CheckConfig(name string, dec plugin.Decoder) error 37 | } 38 | 39 | // PropsDecoder 解析插件配置 40 | type PropsDecoder struct { 41 | // 原始 props,类型为 map[string]interface{} 42 | Props interface{} 43 | // decode 之后的 props,类型为插件里定义的 44 | DecodedProps interface{} 45 | } 46 | 47 | // Decode 解析插件配置 48 | func (d *PropsDecoder) Decode(cfg interface{}) error { 49 | if d.Props == nil { 50 | d.Props = make(map[string]interface{}) 51 | } 52 | // 判断,需要是指针类型 53 | if reflect.ValueOf(cfg).Kind() != reflect.Ptr { 54 | return errors.New("need pointer cfg") 55 | } 56 | props, err := yaml.Marshal(d.Props) 57 | if err != nil { 58 | return gerrs.Wrap(err, "marshal plugin props err") 59 | } 60 | if err = yaml.Unmarshal(props, cfg); err != nil { 61 | return gerrs.Wrap(err, "unmarshal plugin props err") 62 | } 63 | d.DecodedProps = cfg 64 | return nil 65 | } 66 | -------------------------------------------------------------------------------- /plugin/plugin_test.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package plugin 15 | 16 | import ( 17 | "reflect" 18 | "testing" 19 | 20 | "github.com/stretchr/testify/assert" 21 | "gopkg.in/yaml.v3" 22 | "trpc.group/trpc-go/trpc-gateway/common/convert" 23 | ) 24 | 25 | func TestPropsDecoder_Decode(t *testing.T) { 26 | type user struct { 27 | Name string `yaml:"name"` 28 | Age int `yaml:"age"` 29 | } 30 | u := &user{Name: "quon"} 31 | decoder := &PropsDecoder{ 32 | Props: u, 33 | } 34 | nu := &user{} 35 | err := decoder.Decode(nu) 36 | assert.Nil(t, err) 37 | nu.Age = 19 38 | assert.EqualValues(t, decoder.DecodedProps, &user{Name: "quon", Age: 19}) 39 | 40 | decoder = &PropsDecoder{} 41 | err = decoder.Decode(&user{}) 42 | assert.Nil(t, err) 43 | decoder = &PropsDecoder{ 44 | Props: &user{}, 45 | } 46 | err = decoder.Decode(user{}) 47 | assert.NotNil(t, err) 48 | } 49 | 50 | func TestMashal(t *testing.T) { 51 | 52 | props, err := yaml.Marshal(make(map[string]interface{})) 53 | assert.Nil(t, err) 54 | t.Log(string(props)) 55 | type User struct { 56 | Name string 57 | } 58 | user := &User{} 59 | if reflect.ValueOf(&user).Kind() != reflect.Ptr { 60 | t.Error("invalid") 61 | return 62 | } 63 | err = yaml.Unmarshal(props, &user) 64 | 65 | assert.Nil(t, err) 66 | t.Log(convert.ToJSONStr(user)) 67 | user.Name = "xx" 68 | t.Log(convert.ToJSONStr(user)) 69 | } 70 | -------------------------------------------------------------------------------- /plugin/polaris/canaryrouter/Makefile: -------------------------------------------------------------------------------- 1 | # Targets: 2 | # 3 | # all: Builds the code locally after testing 4 | # 5 | # fmt: Formats the source files 6 | # build_dev: Builds the code locally 7 | # build Build production binary file. 8 | # vet: Vets the code 9 | # lint: Runs lint over the code (you do not need to fix everything) 10 | # test: Runs the tests 11 | # cover: Gives you the URL to a nice test coverage report 12 | 13 | 14 | export GO111MODULE=on 15 | export GOPRIVATE=git.code.oa.com 16 | export GOPROXY=goproxy.cn 17 | export GOSUMDB="sum.woa.com+643d7a06+Ac5f5VOC4N8NUXdmhbm8pZSXIWfhek5JSmWdWrq7pLX4" 18 | 19 | # set for M1Pro 20 | export GOARCH=amd64 21 | 22 | # The first target is always the default action if `make` is called without 23 | # args we build and install into $GOPATH so that it can just be run 24 | 25 | all: fmt goimports vet lint 26 | 27 | fmt: 28 | @gofmt -s -w ./$* 29 | gen: 30 | @go generate 31 | 32 | vet: 33 | @go vet -all ./ 34 | 35 | ec: 36 | @errcheck ./... | grep -v Close 37 | 38 | lint: 39 | @golint ./... 40 | 41 | goimports: 42 | @goimports -d -w ./ 43 | 44 | 45 | cover: COVERAGE_FILE := coverage.out 46 | cover: 47 | @go test ./... -coverprofile=$(COVERAGE_FILE) -gcflags=all=-l && \ 48 | go tool cover -html=$(COVERAGE_FILE) && rm $(COVERAGE_FILE) 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /plugin/polaris/metarouter/Makefile: -------------------------------------------------------------------------------- 1 | # Targets: 2 | # 3 | # all: Builds the code locally after testing 4 | # 5 | # fmt: Formats the source files 6 | # build_dev: Builds the code locally 7 | # build Build production binary file. 8 | # vet: Vets the code 9 | # lint: Runs lint over the code (you do not need to fix everything) 10 | # test: Runs the tests 11 | # cover: Gives you the URL to a nice test coverage report 12 | 13 | 14 | export GO111MODULE=on 15 | export GOPRIVATE=git.code.oa.com 16 | export GOPROXY=goproxy.cn 17 | export GOSUMDB="sum.woa.com+643d7a06+Ac5f5VOC4N8NUXdmhbm8pZSXIWfhek5JSmWdWrq7pLX4" 18 | 19 | # set for M1Pro 20 | export GOARCH=amd64 21 | 22 | # The first target is always the default action if `make` is called without 23 | # args we build and install into $GOPATH so that it can just be run 24 | 25 | all: fmt goimports vet lint 26 | 27 | fmt: 28 | @gofmt -s -w ./$* 29 | gen: 30 | @go generate 31 | 32 | vet: 33 | @go vet -all ./ 34 | 35 | ec: 36 | @errcheck ./... | grep -v Close 37 | 38 | lint: 39 | @golint ./... 40 | 41 | goimports: 42 | @goimports -d -w ./ 43 | 44 | 45 | cover: COVERAGE_FILE := coverage.out 46 | cover: 47 | @go test ./... -coverprofile=$(COVERAGE_FILE) -gcflags=all=-l && \ 48 | go tool cover -html=$(COVERAGE_FILE) && rm $(COVERAGE_FILE) 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /plugin/polaris/metarouter/go.mod: -------------------------------------------------------------------------------- 1 | module trpc.group/trpc-go/trpc-gateway/plugin/polaris/metarouter 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/stretchr/testify v1.8.2 7 | github.com/valyala/fasthttp v1.45.0 8 | trpc.group/trpc-go/trpc-gateway v1.0.0 9 | trpc.group/trpc-go/trpc-go v0.0.0-20231008070952-27a655b3e79c 10 | ) 11 | 12 | require gopkg.in/yaml.v3 v3.0.1 13 | 14 | require ( 15 | github.com/BurntSushi/toml v0.3.1 // indirect 16 | github.com/andybalholm/brotli v1.0.5 // indirect 17 | github.com/davecgh/go-spew v1.1.1 // indirect 18 | github.com/fsnotify/fsnotify v1.4.9 // indirect 19 | github.com/golang/snappy v0.0.4 // indirect 20 | github.com/google/flatbuffers v2.0.0+incompatible // indirect 21 | github.com/hashicorp/errwrap v1.0.0 // indirect 22 | github.com/hashicorp/go-multierror v1.1.1 // indirect 23 | github.com/json-iterator/go v1.1.12 // indirect 24 | github.com/klauspost/compress v1.16.3 // indirect 25 | github.com/kr/pretty v0.2.1 // indirect 26 | github.com/lestrrat-go/strftime v1.0.6 // indirect 27 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 28 | github.com/modern-go/reflect2 v1.0.2 // indirect 29 | github.com/panjf2000/ants/v2 v2.4.7 // indirect 30 | github.com/pkg/errors v0.9.1 // indirect 31 | github.com/pmezard/go-difflib v1.0.0 // indirect 32 | github.com/spf13/cast v1.3.1 // indirect 33 | github.com/valyala/bytebufferpool v1.0.0 // indirect 34 | go.uber.org/atomic v1.9.0 // indirect 35 | go.uber.org/multierr v1.6.0 // indirect 36 | go.uber.org/zap v1.24.0 // indirect 37 | golang.org/x/sync v0.1.0 // indirect 38 | golang.org/x/sys v0.13.0 // indirect 39 | google.golang.org/protobuf v1.30.0 // indirect 40 | trpc.group/trpc-go/tnet v0.0.0-20230810071536-9d05338021cf // indirect 41 | trpc.group/trpc/trpc-protocol/pb/go/trpc v0.0.0-20230803031059-de4168eb5952 // indirect 42 | ) 43 | -------------------------------------------------------------------------------- /plugin/polaris/setrouter/Makefile: -------------------------------------------------------------------------------- 1 | # Targets: 2 | # 3 | # all: Builds the code locally after testing 4 | # 5 | # fmt: Formats the source files 6 | # build_dev: Builds the code locally 7 | # build Build production binary file. 8 | # vet: Vets the code 9 | # lint: Runs lint over the code (you do not need to fix everything) 10 | # test: Runs the tests 11 | # cover: Gives you the URL to a nice test coverage report 12 | 13 | 14 | export GO111MODULE=on 15 | export GOPRIVATE=git.code.oa.com 16 | export GOPROXY=goproxy.cn 17 | export GOSUMDB="sum.woa.com+643d7a06+Ac5f5VOC4N8NUXdmhbm8pZSXIWfhek5JSmWdWrq7pLX4" 18 | 19 | # set for M1Pro 20 | export GOARCH=amd64 21 | 22 | # The first target is always the default action if `make` is called without 23 | # args we build and install into $GOPATH so that it can just be run 24 | 25 | all: fmt goimports vet lint 26 | 27 | fmt: 28 | @gofmt -s -w ./$* 29 | gen: 30 | @go generate 31 | 32 | vet: 33 | @go vet -all ./ 34 | 35 | ec: 36 | @errcheck ./... | grep -v Close 37 | 38 | lint: 39 | @golint ./... 40 | 41 | goimports: 42 | @goimports -d -w ./ 43 | 44 | 45 | cover: COVERAGE_FILE := coverage.out 46 | cover: 47 | @go test ./... -coverprofile=$(COVERAGE_FILE) -gcflags=all=-l && \ 48 | go tool cover -html=$(COVERAGE_FILE) && rm $(COVERAGE_FILE) 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /plugin/polaris/setrouter/go.mod: -------------------------------------------------------------------------------- 1 | module trpc.group/trpc-go/trpc-gateway/plugin/polaris/setrouter 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/stretchr/testify v1.8.2 7 | github.com/valyala/fasthttp v1.45.0 8 | gopkg.in/yaml.v3 v3.0.1 9 | trpc.group/trpc-go/trpc-gateway v1.0.0 10 | trpc.group/trpc-go/trpc-go v0.0.0-20231008070952-27a655b3e79c 11 | ) 12 | 13 | require ( 14 | github.com/BurntSushi/toml v0.3.1 // indirect 15 | github.com/andybalholm/brotli v1.0.5 // indirect 16 | github.com/davecgh/go-spew v1.1.1 // indirect 17 | github.com/fsnotify/fsnotify v1.4.9 // indirect 18 | github.com/golang/snappy v0.0.4 // indirect 19 | github.com/google/flatbuffers v2.0.0+incompatible // indirect 20 | github.com/hashicorp/errwrap v1.0.0 // indirect 21 | github.com/hashicorp/go-multierror v1.1.1 // indirect 22 | github.com/json-iterator/go v1.1.12 // indirect 23 | github.com/klauspost/compress v1.16.3 // indirect 24 | github.com/kr/pretty v0.2.1 // indirect 25 | github.com/lestrrat-go/strftime v1.0.6 // indirect 26 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 27 | github.com/modern-go/reflect2 v1.0.2 // indirect 28 | github.com/panjf2000/ants/v2 v2.4.7 // indirect 29 | github.com/pkg/errors v0.9.1 // indirect 30 | github.com/pmezard/go-difflib v1.0.0 // indirect 31 | github.com/spf13/cast v1.3.1 // indirect 32 | github.com/valyala/bytebufferpool v1.0.0 // indirect 33 | go.uber.org/atomic v1.9.0 // indirect 34 | go.uber.org/multierr v1.6.0 // indirect 35 | go.uber.org/zap v1.24.0 // indirect 36 | golang.org/x/sync v0.1.0 // indirect 37 | golang.org/x/sys v0.13.0 // indirect 38 | google.golang.org/protobuf v1.30.0 // indirect 39 | trpc.group/trpc-go/tnet v0.0.0-20230810071536-9d05338021cf // indirect 40 | trpc.group/trpc/trpc-protocol/pb/go/trpc v0.0.0-20230803031059-de4168eb5952 // indirect 41 | ) 42 | -------------------------------------------------------------------------------- /plugin/redirect/Makefile: -------------------------------------------------------------------------------- 1 | # Targets: 2 | # 3 | # all: Builds the code locally after testing 4 | # 5 | # fmt: Formats the source files 6 | # build_dev: Builds the code locally 7 | # build Build production binary file. 8 | # vet: Vets the code 9 | # lint: Runs lint over the code (you do not need to fix everything) 10 | # test: Runs the tests 11 | # cover: Gives you the URL to a nice test coverage report 12 | 13 | 14 | export GO111MODULE=on 15 | export GOPRIVATE=git.code.oa.com 16 | export GOPROXY=goproxy.cn 17 | export GOSUMDB="sum.woa.com+643d7a06+Ac5f5VOC4N8NUXdmhbm8pZSXIWfhek5JSmWdWrq7pLX4" 18 | 19 | # set fro M1Pro 20 | export GOARCH=amd64 21 | 22 | # The first target is always the default action if `make` is called without 23 | # args we build and install into $GOPATH so that it can just be run 24 | 25 | all: fmt goimports vet lint 26 | 27 | fmt: 28 | @gofmt -s -w ./$* 29 | gen: 30 | @go generate 31 | 32 | vet: 33 | @go vet -all ./ 34 | 35 | ec: 36 | @errcheck ./... | grep -v Close 37 | 38 | lint: 39 | @golint ./... 40 | 41 | goimports: 42 | @goimports -d -w ./ 43 | 44 | 45 | cover: COVERAGE_FILE := coverage.out 46 | cover: 47 | @go test ./... -coverprofile=$(COVERAGE_FILE) -gcflags=all=-l && \ 48 | go tool cover -html=$(COVERAGE_FILE) && rm $(COVERAGE_FILE) -------------------------------------------------------------------------------- /plugin/redirect/docs/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trpc-ecosystem/go-gateway/fb963d00e11d5d66bd03b2e9e20ab48f68d0feec/plugin/redirect/docs/img.png -------------------------------------------------------------------------------- /plugin/redirect/go.mod: -------------------------------------------------------------------------------- 1 | module trpc.group/trpc-go/trpc-gateway/plugin/redirect 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/stretchr/testify v1.8.2 7 | github.com/valyala/fasthttp v1.45.0 8 | trpc.group/trpc-go/trpc-gateway v1.0.0 9 | trpc.group/trpc-go/trpc-go v0.0.0-20231008070952-27a655b3e79c 10 | ) 11 | 12 | require ( 13 | github.com/BurntSushi/toml v0.3.1 // indirect 14 | github.com/andybalholm/brotli v1.0.5 // indirect 15 | github.com/davecgh/go-spew v1.1.1 // indirect 16 | github.com/fsnotify/fsnotify v1.4.9 // indirect 17 | github.com/golang/snappy v0.0.4 // indirect 18 | github.com/google/flatbuffers v2.0.0+incompatible // indirect 19 | github.com/hashicorp/errwrap v1.0.0 // indirect 20 | github.com/hashicorp/go-multierror v1.1.1 // indirect 21 | github.com/json-iterator/go v1.1.12 // indirect 22 | github.com/klauspost/compress v1.16.3 // indirect 23 | github.com/kr/pretty v0.2.1 // indirect 24 | github.com/lestrrat-go/strftime v1.0.6 // indirect 25 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 26 | github.com/modern-go/reflect2 v1.0.2 // indirect 27 | github.com/panjf2000/ants/v2 v2.4.7 // indirect 28 | github.com/pkg/errors v0.9.1 // indirect 29 | github.com/pmezard/go-difflib v1.0.0 // indirect 30 | github.com/spf13/cast v1.3.1 // indirect 31 | github.com/valyala/bytebufferpool v1.0.0 // indirect 32 | go.uber.org/atomic v1.9.0 // indirect 33 | go.uber.org/multierr v1.6.0 // indirect 34 | go.uber.org/zap v1.24.0 // indirect 35 | golang.org/x/sync v0.1.0 // indirect 36 | golang.org/x/sys v0.13.0 // indirect 37 | google.golang.org/protobuf v1.30.0 // indirect 38 | gopkg.in/yaml.v3 v3.0.1 // indirect 39 | trpc.group/trpc-go/tnet v0.0.0-20230810071536-9d05338021cf // indirect 40 | trpc.group/trpc/trpc-protocol/pb/go/trpc v0.0.0-20230803031059-de4168eb5952 // indirect 41 | ) 42 | -------------------------------------------------------------------------------- /plugin/routercheck/Makefile: -------------------------------------------------------------------------------- 1 | # Targets: 2 | # 3 | # all: Builds the code locally after testing 4 | # 5 | # fmt: Formats the source files 6 | # build_dev: Builds the code locally 7 | # build Build production binary file. 8 | # vet: Vets the code 9 | # lint: Runs lint over the code (you do not need to fix everything) 10 | # test: Runs the tests 11 | # cover: Gives you the URL to a nice test coverage report 12 | 13 | 14 | export GO111MODULE=on 15 | export GOPRIVATE=git.code.oa.com 16 | export GOPROXY=goproxy.cn 17 | export GOSUMDB="sum.woa.com+643d7a06+Ac5f5VOC4N8NUXdmhbm8pZSXIWfhek5JSmWdWrq7pLX4" 18 | 19 | export GOARCH=amd64 20 | 21 | # The first target is always the default action if `make` is called without 22 | # args we build and install into $GOPATH so that it can just be run 23 | 24 | all: fmt goimports vet lint 25 | 26 | fmt: 27 | @gofmt -s -w ./$* 28 | gen: 29 | @go generate 30 | 31 | vet: 32 | @go vet -all ./ 33 | 34 | ec: 35 | @errcheck ./... | grep -v Close 36 | 37 | lint: 38 | @golint ./... 39 | 40 | goimports: 41 | @goimports -d -w ./ 42 | 43 | 44 | cover: COVERAGE_FILE := coverage.out 45 | cover: 46 | @go test ./... -coverprofile=$(COVERAGE_FILE) -gcflags=all=-l && \ 47 | go tool cover -html=$(COVERAGE_FILE) && rm $(COVERAGE_FILE) -------------------------------------------------------------------------------- /plugin/routercheck/go.mod: -------------------------------------------------------------------------------- 1 | module trpc.group/trpc-go/trpc-gateway/plugin/routercheck 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/stretchr/testify v1.8.2 7 | github.com/tidwall/gjson v1.16.0 8 | github.com/valyala/fasthttp v1.45.0 9 | gopkg.in/yaml.v3 v3.0.1 10 | trpc.group/trpc-go/trpc-gateway v1.0.0 11 | trpc.group/trpc-go/trpc-go v0.0.0-20231008070952-27a655b3e79c 12 | ) 13 | 14 | require ( 15 | code.cloudfoundry.org/bytefmt v0.0.0-20211005130812-5bb3c17173e5 // indirect 16 | github.com/BurntSushi/toml v0.3.1 // indirect 17 | github.com/andybalholm/brotli v1.0.5 // indirect 18 | github.com/armon/go-radix v1.0.0 // indirect 19 | github.com/davecgh/go-spew v1.1.1 // indirect 20 | github.com/fsnotify/fsnotify v1.4.9 // indirect 21 | github.com/golang/snappy v0.0.4 // indirect 22 | github.com/google/flatbuffers v2.0.0+incompatible // indirect 23 | github.com/hashicorp/errwrap v1.0.0 // indirect 24 | github.com/hashicorp/go-multierror v1.1.1 // indirect 25 | github.com/json-iterator/go v1.1.12 // indirect 26 | github.com/klauspost/compress v1.16.3 // indirect 27 | github.com/kr/pretty v0.2.1 // indirect 28 | github.com/lestrrat-go/strftime v1.0.6 // indirect 29 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 30 | github.com/modern-go/reflect2 v1.0.2 // indirect 31 | github.com/panjf2000/ants/v2 v2.4.7 // indirect 32 | github.com/pkg/errors v0.9.1 // indirect 33 | github.com/pmezard/go-difflib v1.0.0 // indirect 34 | github.com/spf13/cast v1.3.1 // indirect 35 | github.com/tidwall/match v1.1.1 // indirect 36 | github.com/tidwall/pretty v1.2.0 // indirect 37 | github.com/valyala/bytebufferpool v1.0.0 // indirect 38 | go.uber.org/atomic v1.9.0 // indirect 39 | go.uber.org/automaxprocs v1.3.0 // indirect 40 | go.uber.org/multierr v1.6.0 // indirect 41 | go.uber.org/zap v1.24.0 // indirect 42 | golang.org/x/sync v0.1.0 // indirect 43 | golang.org/x/sys v0.13.0 // indirect 44 | google.golang.org/protobuf v1.30.0 // indirect 45 | trpc.group/trpc-go/tnet v0.0.0-20230810071536-9d05338021cf // indirect 46 | trpc.group/trpc/trpc-protocol/pb/go/trpc v0.0.0-20230803031059-de4168eb5952 // indirect 47 | ) 48 | -------------------------------------------------------------------------------- /plugin/traceid/Makefile: -------------------------------------------------------------------------------- 1 | # Targets: 2 | # 3 | # all: Builds the code locally after testing 4 | # 5 | # fmt: Formats the source files 6 | # build_dev: Builds the code locally 7 | # build Build production binary file. 8 | # vet: Vets the code 9 | # lint: Runs lint over the code (you do not need to fix everything) 10 | # test: Runs the tests 11 | # cover: Gives you the URL to a nice test coverage report 12 | 13 | 14 | export GO111MODULE=on 15 | export GOPRIVATE=git.code.oa.com 16 | export GOPROXY=goproxy.cn 17 | export GOSUMDB="sum.woa.com+643d7a06+Ac5f5VOC4N8NUXdmhbm8pZSXIWfhek5JSmWdWrq7pLX4" 18 | 19 | export GOARCH=amd64 20 | 21 | # The first target is always the default action if `make` is called without 22 | # args we build and install into $GOPATH so that it can just be run 23 | 24 | all: fmt goimports vet lint 25 | 26 | fmt: 27 | @gofmt -s -w ./$* 28 | gen: 29 | @go generate 30 | 31 | vet: 32 | @go vet -all ./ 33 | 34 | ec: 35 | @errcheck ./... | grep -v Close 36 | 37 | lint: 38 | @golint ./... 39 | 40 | goimports: 41 | @goimports -d -w ./ 42 | 43 | 44 | cover: COVERAGE_FILE := coverage.out 45 | cover: 46 | @go test ./... -coverprofile=$(COVERAGE_FILE) -gcflags=all=-l && \ 47 | go tool cover -html=$(COVERAGE_FILE) && rm $(COVERAGE_FILE) -------------------------------------------------------------------------------- /plugin/traceid/README.md: -------------------------------------------------------------------------------- 1 | # TraceID Setting Plugin 2 | 3 | Returning the trace ID of the call chain during interface debugging can improve problem troubleshooting efficiency. 4 | 5 | - It can be used as a tRPC-Go filter by configuring it in trpc_go.yaml. 6 | - It can also be used as a gateway plugin, configured to be effective at the interface level. 7 | 8 | ![img.png](docs/img.png) 9 | 10 | Note: Only sampled requests will return the trace ID. 11 | 12 | ## Usage 13 | 14 | ### Import the Plugin in the main.go of the Gateway Project 15 | 16 | - Add the import statement: 17 | 18 | ```go 19 | import ( 20 | _ "trpc.group/trpc-go/trpc-gateway/plugin/traceid" 21 | ) 22 | ``` 23 | 24 | - Configure the tRPC framework in the configuration file to enable the trace ID interceptor. 25 | 26 | Note: Make sure to register it in server.service.filter, not server.filter. 27 | 28 | ```yaml 29 | global: # Global configuration 30 | server: # Server configuration 31 | filter: # Interceptor list for all service handler functions 32 | service: # Business services provided, can have multiple 33 | - name: trpc.inews.trpc.gateway # Route name of the service 34 | filter: 35 | - traceid # Gateway plugin registered in the service filter, so that it can be dynamically loaded in router.yaml 36 | plugins: # Plugin configuration 37 | log: # Log configuration 38 | gateway: # Plugin type is gateway 39 | traceid: # TraceID plugin 40 | ``` 41 | 42 | #### Configure the Plugin in the Gateway Router Configuration router.yaml File 43 | 44 | ```yaml 45 | router: # Router configuration 46 | - method: /v1/user/info 47 | id: "xxxxxx" 48 | target_service: 49 | - service: trpc.user.service 50 | plugins: 51 | - name: traceid # Route-level plugin 52 | client: # Upstream service configuration, consistent with the tRPC protocol 53 | - name: trpc.user.service 54 | plugins: 55 | - name: traceid # Service-level configuration 56 | props: 57 | plugins: 58 | - name: traceid # Global configuration 59 | ``` -------------------------------------------------------------------------------- /plugin/traceid/docs/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trpc-ecosystem/go-gateway/fb963d00e11d5d66bd03b2e9e20ab48f68d0feec/plugin/traceid/docs/img.png -------------------------------------------------------------------------------- /plugin/traceid/go.mod: -------------------------------------------------------------------------------- 1 | module trpc.group/trpc-go/trpc-gateway/plugin/traceid 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/stretchr/testify v1.8.2 7 | github.com/valyala/fasthttp v1.45.0 8 | go.opentelemetry.io/otel/trace v1.10.0 9 | trpc.group/trpc-go/trpc-gateway v1.0.0 10 | trpc.group/trpc-go/trpc-go v0.0.0-20231008070952-27a655b3e79c 11 | ) 12 | 13 | require ( 14 | github.com/BurntSushi/toml v0.3.1 // indirect 15 | github.com/andybalholm/brotli v1.0.5 // indirect 16 | github.com/davecgh/go-spew v1.1.1 // indirect 17 | github.com/fsnotify/fsnotify v1.4.9 // indirect 18 | github.com/golang/snappy v0.0.4 // indirect 19 | github.com/google/flatbuffers v2.0.0+incompatible // indirect 20 | github.com/hashicorp/errwrap v1.0.0 // indirect 21 | github.com/hashicorp/go-multierror v1.1.1 // indirect 22 | github.com/json-iterator/go v1.1.12 // indirect 23 | github.com/klauspost/compress v1.16.3 // indirect 24 | github.com/kr/pretty v0.2.1 // indirect 25 | github.com/lestrrat-go/strftime v1.0.6 // indirect 26 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 27 | github.com/modern-go/reflect2 v1.0.2 // indirect 28 | github.com/panjf2000/ants/v2 v2.4.7 // indirect 29 | github.com/pkg/errors v0.9.1 // indirect 30 | github.com/pmezard/go-difflib v1.0.0 // indirect 31 | github.com/spf13/cast v1.3.1 // indirect 32 | github.com/valyala/bytebufferpool v1.0.0 // indirect 33 | go.opentelemetry.io/otel v1.10.0 // indirect 34 | go.uber.org/atomic v1.9.0 // indirect 35 | go.uber.org/multierr v1.6.0 // indirect 36 | go.uber.org/zap v1.24.0 // indirect 37 | golang.org/x/sync v0.1.0 // indirect 38 | golang.org/x/sys v0.13.0 // indirect 39 | google.golang.org/protobuf v1.30.0 // indirect 40 | gopkg.in/yaml.v3 v3.0.1 // indirect 41 | trpc.group/trpc-go/tnet v0.0.0-20230810071536-9d05338021cf // indirect 42 | trpc.group/trpc/trpc-protocol/pb/go/trpc v0.0.0-20230803031059-de4168eb5952 // indirect 43 | ) 44 | -------------------------------------------------------------------------------- /plugin/transformer/request/CHANGLOG.md: -------------------------------------------------------------------------------- 1 | # Change Log -------------------------------------------------------------------------------- /plugin/transformer/request/Makefile: -------------------------------------------------------------------------------- 1 | cover: COVERAGE_FILE := coverage.out 2 | cover: 3 | @go test ./... -coverprofile=$(COVERAGE_FILE) -gcflags=all=-l && \ 4 | go tool cover -html=$(COVERAGE_FILE) && rm $(COVERAGE_FILE) 5 | -------------------------------------------------------------------------------- /plugin/transformer/request/docs/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trpc-ecosystem/go-gateway/fb963d00e11d5d66bd03b2e9e20ab48f68d0feec/plugin/transformer/request/docs/img.png -------------------------------------------------------------------------------- /plugin/transformer/request/go.mod: -------------------------------------------------------------------------------- 1 | module trpc.group/trpc-go/trpc-gateway/plugin/transformer/request 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/stretchr/testify v1.8.2 7 | github.com/tidwall/gjson v1.16.0 8 | github.com/tidwall/sjson v1.2.5 9 | github.com/valyala/bytebufferpool v1.0.0 10 | github.com/valyala/fasthttp v1.45.0 11 | trpc.group/trpc-go/trpc-gateway v1.0.0 12 | trpc.group/trpc-go/trpc-go v0.0.0-20231008070952-27a655b3e79c 13 | ) 14 | 15 | require ( 16 | github.com/BurntSushi/toml v0.3.1 // indirect 17 | github.com/andybalholm/brotli v1.0.5 // indirect 18 | github.com/davecgh/go-spew v1.1.1 // indirect 19 | github.com/fsnotify/fsnotify v1.4.9 // indirect 20 | github.com/golang/snappy v0.0.4 // indirect 21 | github.com/google/flatbuffers v2.0.0+incompatible // indirect 22 | github.com/hashicorp/errwrap v1.0.0 // indirect 23 | github.com/hashicorp/go-multierror v1.1.1 // indirect 24 | github.com/json-iterator/go v1.1.12 // indirect 25 | github.com/klauspost/compress v1.16.3 // indirect 26 | github.com/kr/pretty v0.2.1 // indirect 27 | github.com/lestrrat-go/strftime v1.0.6 // indirect 28 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 29 | github.com/modern-go/reflect2 v1.0.2 // indirect 30 | github.com/panjf2000/ants/v2 v2.4.7 // indirect 31 | github.com/pkg/errors v0.9.1 // indirect 32 | github.com/pmezard/go-difflib v1.0.0 // indirect 33 | github.com/spf13/cast v1.3.1 // indirect 34 | github.com/tidwall/match v1.1.1 // indirect 35 | github.com/tidwall/pretty v1.2.0 // indirect 36 | go.uber.org/atomic v1.9.0 // indirect 37 | go.uber.org/multierr v1.6.0 // indirect 38 | go.uber.org/zap v1.24.0 // indirect 39 | golang.org/x/sync v0.1.0 // indirect 40 | golang.org/x/sys v0.13.0 // indirect 41 | google.golang.org/protobuf v1.30.0 // indirect 42 | gopkg.in/yaml.v3 v3.0.1 // indirect 43 | trpc.group/trpc-go/tnet v0.0.0-20230810071536-9d05338021cf // indirect 44 | trpc.group/trpc/trpc-protocol/pb/go/trpc v0.0.0-20230803031059-de4168eb5952 // indirect 45 | ) 46 | -------------------------------------------------------------------------------- /plugin/transformer/response/Makefile: -------------------------------------------------------------------------------- 1 | GO = go 2 | DTOOLS = dtools 3 | TARGET = trpc-gateway 4 | 5 | # set for M1Pro 6 | export GOARCH=amd64 7 | 8 | all: fmt goimports lint 9 | 10 | fmt: 11 | @gofmt -s -w ./$* 12 | 13 | vet: 14 | @go vet -all ./ 15 | 16 | ec: 17 | @errcheck ./... | grep -v Close 18 | 19 | lint: 20 | @golint ./... 21 | 22 | goimports: 23 | @goimports -d -w ./ 24 | 25 | test: 26 | CFLAGS=-g 27 | export CFLAGS 28 | $(GO) test $(M) -v -gcflags=all=-l -coverpkg=./... -coverprofile=test.out ./... 29 | clean: 30 | rm -f $(TARGET) 31 | rm -rf release 32 | 33 | cover: COVERAGE_FILE := coverage.out 34 | cover: 35 | @go test ./... -coverprofile=$(COVERAGE_FILE) -gcflags=all=-l && \ 36 | go tool cover -html=$(COVERAGE_FILE) && rm $(COVERAGE_FILE) 37 | -------------------------------------------------------------------------------- /plugin/transformer/response/docs/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trpc-ecosystem/go-gateway/fb963d00e11d5d66bd03b2e9e20ab48f68d0feec/plugin/transformer/response/docs/img.png -------------------------------------------------------------------------------- /plugin/transformer/response/go.mod: -------------------------------------------------------------------------------- 1 | module trpc.group/trpc-go/trpc-gateway/plugin/transformer/response 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/stretchr/testify v1.8.2 7 | github.com/tidwall/gjson v1.16.0 8 | github.com/tidwall/sjson v1.2.5 9 | github.com/valyala/fasthttp v1.45.0 10 | trpc.group/trpc-go/trpc-gateway v1.0.0 11 | trpc.group/trpc-go/trpc-go v0.0.0-20231008070952-27a655b3e79c 12 | ) 13 | 14 | require ( 15 | gopkg.in/yaml.v3 v3.0.1 16 | trpc.group/trpc/trpc-protocol/pb/go/trpc v0.0.0-20230803031059-de4168eb5952 17 | ) 18 | 19 | require ( 20 | github.com/BurntSushi/toml v0.3.1 // indirect 21 | github.com/andybalholm/brotli v1.0.5 // indirect 22 | github.com/davecgh/go-spew v1.1.1 // indirect 23 | github.com/fsnotify/fsnotify v1.4.9 // indirect 24 | github.com/golang/snappy v0.0.4 // indirect 25 | github.com/google/flatbuffers v2.0.0+incompatible // indirect 26 | github.com/hashicorp/errwrap v1.0.0 // indirect 27 | github.com/hashicorp/go-multierror v1.1.1 // indirect 28 | github.com/json-iterator/go v1.1.12 // indirect 29 | github.com/klauspost/compress v1.16.3 // indirect 30 | github.com/kr/pretty v0.2.1 // indirect 31 | github.com/lestrrat-go/strftime v1.0.6 // indirect 32 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 33 | github.com/modern-go/reflect2 v1.0.2 // indirect 34 | github.com/panjf2000/ants/v2 v2.4.7 // indirect 35 | github.com/pkg/errors v0.9.1 // indirect 36 | github.com/pmezard/go-difflib v1.0.0 // indirect 37 | github.com/spf13/cast v1.3.1 // indirect 38 | github.com/tidwall/match v1.1.1 // indirect 39 | github.com/tidwall/pretty v1.2.0 // indirect 40 | github.com/valyala/bytebufferpool v1.0.0 // indirect 41 | go.uber.org/atomic v1.9.0 // indirect 42 | go.uber.org/multierr v1.6.0 // indirect 43 | go.uber.org/zap v1.24.0 // indirect 44 | golang.org/x/sync v0.1.0 // indirect 45 | golang.org/x/sys v0.13.0 // indirect 46 | google.golang.org/protobuf v1.30.0 // indirect 47 | trpc.group/trpc-go/tnet v0.0.0-20230810071536-9d05338021cf // indirect 48 | ) 49 | -------------------------------------------------------------------------------- /plugin/transformer/trpcerr2body/Makefile: -------------------------------------------------------------------------------- 1 | # Targets: 2 | # 3 | # all: Builds the code locally after testing 4 | # 5 | # fmt: Formats the source files 6 | # build_dev: Builds the code locally 7 | # build Build production binary file. 8 | # vet: Vets the code 9 | # lint: Runs lint over the code (you do not need to fix everything) 10 | # test: Runs the tests 11 | # cover: Gives you the URL to a nice test coverage report 12 | 13 | 14 | export GO111MODULE=on 15 | export GOPRIVATE=git.code.oa.com 16 | export GOPROXY=goproxy.cn 17 | export GOSUMDB="sum.woa.com+643d7a06+Ac5f5VOC4N8NUXdmhbm8pZSXIWfhek5JSmWdWrq7pLX4" 18 | 19 | # set for M1Pro 20 | export GOARCH=amd64 21 | 22 | # The first target is always the default action if `make` is called without 23 | # args we build and install into $GOPATH so that it can just be run 24 | 25 | all: fmt goimports vet lint 26 | 27 | fmt: 28 | @gofmt -s -w ./$* 29 | gen: 30 | @go generate 31 | 32 | vet: 33 | @go vet -all ./ 34 | 35 | ec: 36 | @errcheck ./... | grep -v Close 37 | 38 | lint: 39 | @golint ./... 40 | 41 | goimports: 42 | @goimports -d -w ./ 43 | 44 | 45 | cover: COVERAGE_FILE := coverage.out 46 | cover: 47 | @go test ./... -coverprofile=$(COVERAGE_FILE) -gcflags=all=-l && \ 48 | go tool cover -html=$(COVERAGE_FILE) && rm $(COVERAGE_FILE) -------------------------------------------------------------------------------- /plugin/transformer/trpcerr2body/docs/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trpc-ecosystem/go-gateway/fb963d00e11d5d66bd03b2e9e20ab48f68d0feec/plugin/transformer/trpcerr2body/docs/img.png -------------------------------------------------------------------------------- /plugin/transformer/trpcerr2body/go.mod: -------------------------------------------------------------------------------- 1 | module trpc.group/trpc-go/trpc-gateway/plugin/transformer/trpcerr2body 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/stretchr/testify v1.8.2 7 | github.com/tidwall/sjson v1.2.5 8 | github.com/valyala/fasthttp v1.45.0 9 | trpc.group/trpc-go/trpc-gateway v1.0.0 10 | trpc.group/trpc-go/trpc-go v0.0.0-20231008070952-27a655b3e79c 11 | ) 12 | 13 | require ( 14 | github.com/BurntSushi/toml v0.3.1 // indirect 15 | github.com/andybalholm/brotli v1.0.5 // indirect 16 | github.com/davecgh/go-spew v1.1.1 // indirect 17 | github.com/fsnotify/fsnotify v1.4.9 // indirect 18 | github.com/go-playground/form/v4 v4.2.0 // indirect 19 | github.com/golang/snappy v0.0.4 // indirect 20 | github.com/google/flatbuffers v2.0.0+incompatible // indirect 21 | github.com/hashicorp/errwrap v1.0.0 // indirect 22 | github.com/hashicorp/go-multierror v1.1.1 // indirect 23 | github.com/json-iterator/go v1.1.12 // indirect 24 | github.com/klauspost/compress v1.16.3 // indirect 25 | github.com/kr/pretty v0.2.1 // indirect 26 | github.com/lestrrat-go/strftime v1.0.6 // indirect 27 | github.com/mitchellh/mapstructure v1.5.0 // indirect 28 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 29 | github.com/modern-go/reflect2 v1.0.2 // indirect 30 | github.com/panjf2000/ants/v2 v2.4.7 // indirect 31 | github.com/pkg/errors v0.9.1 // indirect 32 | github.com/pmezard/go-difflib v1.0.0 // indirect 33 | github.com/spf13/cast v1.3.1 // indirect 34 | github.com/tidwall/gjson v1.16.0 // indirect 35 | github.com/tidwall/match v1.1.1 // indirect 36 | github.com/tidwall/pretty v1.2.0 // indirect 37 | github.com/valyala/bytebufferpool v1.0.0 // indirect 38 | go.uber.org/atomic v1.9.0 // indirect 39 | go.uber.org/multierr v1.6.0 // indirect 40 | go.uber.org/zap v1.24.0 // indirect 41 | golang.org/x/net v0.8.0 // indirect 42 | golang.org/x/sync v0.1.0 // indirect 43 | golang.org/x/sys v0.13.0 // indirect 44 | golang.org/x/text v0.13.0 // indirect 45 | google.golang.org/protobuf v1.30.0 // indirect 46 | gopkg.in/yaml.v3 v3.0.1 // indirect 47 | trpc.group/trpc-go/tnet v0.0.0-20230810071536-9d05338021cf // indirect 48 | trpc.group/trpc/trpc-protocol/pb/go/trpc v0.0.0-20230803031059-de4168eb5952 // indirect 49 | ) 50 | -------------------------------------------------------------------------------- /testdata/README.md: -------------------------------------------------------------------------------- 1 | # Test Data Package 2 | 3 | Stores some test data used for testing purposes. -------------------------------------------------------------------------------- /testdata/router.d/router.yaml: -------------------------------------------------------------------------------- 1 | router: 2 | - method: /user/info 3 | target_service: 4 | - service: trpc.inews.user.User 5 | client: 6 | - name: trpc.inews.user.User 7 | disable_servicerouter: false 8 | namespace: Production 9 | target: polaris://trpc.inews.user.User 10 | network: tcp 11 | timeout: 500 12 | protocol: fasthttp 13 | serialization: null 14 | plugins: 15 | - name: auth # Service-level plugin: Signature plugin 16 | props: 17 | plugins: 18 | - name: proxyinfo # Global configuration plugin: Proxy information reporting 19 | props: -------------------------------------------------------------------------------- /testdata/router_invalid.yaml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /testdata/server.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICszCCAZugAwIBAgIJAMqC8Vpr2t+vMA0GCSqGSIb3DQEBCwUAMAwxCjAIBgNV 3 | BAMMASowHhcNMjEwMTI5MDgzODExWhcNMzQxMDA4MDgzODExWjAMMQowCAYDVQQD 4 | DAEqMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApYTWarzTRMASzbj3 5 | f11aMriroLo0VXPRZdGguGr663pShq+o/aP5xu0i5vwLUB+G5JrE+5hWJ6qNMhKa 6 | 9+tT3qapBBjoCbuMAmwyXrvl0o/QGnJoap1XhbGJrNoGfOKrQ9OAVtKnsd03YCgd 7 | gaUhXGuY39dLeZbmwYEsy87gtMKyTGx0LQfEIlhi6xmPRgowkzoyiNLyhxl8ydwv 8 | yiYaAokIqvHrxqB3fHJAEM/3OxJhYzt6gvDLiDQpqUPeB06kETIM+ukUygyg/SBO 9 | aZwo0CB8aJ4n5SqyGgqTDM0bbGpkz2O3Sz/sUoA7eKJG64tnVCMpaNiAO1wf9mbf 10 | NwiXuQIDAQABoxgwFjAUBgNVHREEDTALgglsb2NhbGhvc3QwDQYJKoZIhvcNAQEL 11 | BQADggEBAE5OB02bnr/eAnQASS97R2AeHgSSeailY61Js1lQ5Lz2cEMNRTVjFnNw 12 | mImT9SunMbR1HL9z3kk8DZ8bItqNbm1uzzFdyyrpY5dJct+zKojPtRRy+++REFZ8 13 | IGYex4/ShfwV3AJl+xOhZ/OJIlDPtiHBpvDU+BXYOlvjoy/40zrOX1JEDZ+YRa3X 14 | v4+B6d3cTGSpshYxhxrIC9you9NjirtEbGMbs7jHEnGP+Y694IpkZJZLctvau/JO 15 | HdWPlKh2JI/b8yurGBHntUVHEwTcH8i4849ZUVwet/Vpt27Cp9xhRzrXhoJuYLdn 16 | NmP0mdoINiNQ7ga03g1kcW3aF2fmlhw= 17 | -----END CERTIFICATE----- 18 | -------------------------------------------------------------------------------- /testdata/server.csr: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE REQUEST----- 2 | MIICUTCCATkCAQAwDDEKMAgGA1UEAwwBKjCCASIwDQYJKoZIhvcNAQEBBQADggEP 3 | ADCCAQoCggEBAKWE1mq800TAEs24939dWjK4q6C6NFVz0WXRoLhq+ut6UoavqP2j 4 | +cbtIub8C1AfhuSaxPuYVieqjTISmvfrU96mqQQY6Am7jAJsMl675dKP0BpyaGqd 5 | V4WxiazaBnziq0PTgFbSp7HdN2AoHYGlIVxrmN/XS3mW5sGBLMvO4LTCskxsdC0H 6 | xCJYYusZj0YKMJM6MojS8ocZfMncL8omGgKJCKrx68agd3xyQBDP9zsSYWM7eoLw 7 | y4g0KalD3gdOpBEyDPrpFMoMoP0gTmmcKNAgfGieJ+UqshoKkwzNG2xqZM9jt0s/ 8 | 7FKAO3iiRuuLZ1QjKWjYgDtcH/Zm3zcIl7kCAwEAAaAAMA0GCSqGSIb3DQEBCwUA 9 | A4IBAQCaBF0ivsxjvHtbAqJYUuyKVV97gSPcNfMTHguSIhoQ/zWtDlsG52FeqceM 10 | 4KCqihzduGauvaJZadexzebXsiJ1RY47RT6vKhEcGV2DFFKGo/ZijmCjaGR2d8qK 11 | PbB4KWqdPG1VPHa8zxcQ7DOYsTpfeigThpUQg3ZH+Dyya6rSzeC03aG5763ETDfN 12 | lrwKAeEujVvgWaPiSxZNvGSkXcMMSqgIokY1yFKtsvvhoPWg/DwdRtv0wzbgMLPs 13 | HQxUwFrMjkzNP/8Im+nnDKyoTzFNkB/DIZWgolxSUIyS2RFJv6nV5B9+IAUz/Xq3 14 | HcIBJsMu2W3ay3AoMHjtu0FujOqz 15 | -----END CERTIFICATE REQUEST----- 16 | -------------------------------------------------------------------------------- /testdata/server.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEpQIBAAKCAQEApYTWarzTRMASzbj3f11aMriroLo0VXPRZdGguGr663pShq+o 3 | /aP5xu0i5vwLUB+G5JrE+5hWJ6qNMhKa9+tT3qapBBjoCbuMAmwyXrvl0o/QGnJo 4 | ap1XhbGJrNoGfOKrQ9OAVtKnsd03YCgdgaUhXGuY39dLeZbmwYEsy87gtMKyTGx0 5 | LQfEIlhi6xmPRgowkzoyiNLyhxl8ydwvyiYaAokIqvHrxqB3fHJAEM/3OxJhYzt6 6 | gvDLiDQpqUPeB06kETIM+ukUygyg/SBOaZwo0CB8aJ4n5SqyGgqTDM0bbGpkz2O3 7 | Sz/sUoA7eKJG64tnVCMpaNiAO1wf9mbfNwiXuQIDAQABAoIBAQCH6/AQMwPjPz+x 8 | xKUp6EU7xb7a/E4hpjxcuqqbBu8LFKZUiEfkEhX5r56rxGqd32XssNP2MAEADeRp 9 | LDIqSQvUmVPOU42pAGRXUPaEKRTvtr2UGkN42cCXv1VpppkRUSqHRlXr9o1TWHAy 10 | /H5OioY82PbvSmNmc+8HFMbujvKkPLNFkZ4mskryd9xp7zUoRRKlrS73NYbkoYcN 11 | UxQ4mxP6E6zVz954bt0thzGciDLyVEt8Hqa2IlIR2yCWhp/WB3VMbIcQXoqc9ycq 12 | RlO33j3Oo4FJz/eNOjKxgDFwDcAzCUyNgveQWtmYhVv1lzUeoMH40Cdg4Si+FXzV 13 | DfKeoNQBAoGBANxSo5IdeREEQ770T05Tb5iA4s++ukYsC1m6eBjKnPxCdsMP8B7w 14 | /dT1j3Fq3+Qq3aXZI+lMsTfIF4J2NIpLWGZsWz1/rL8FiNLeKeXQGDLq6D7JU23X 15 | QMqZQ4HLHhgzul7Dv0Wb0ews7kvVC0MFJs638APWFS0IUmlU1DISxxP5AoGBAMBS 16 | VSIRAFmmBA3eql5dtM8anAN4qufOGbxH/vaHqxOpEbwb0SzQs3AJYao43asRdyNU 17 | iidodLgGVdFiWI+GFJx5uXuO4g5rG5CK4Il30ZVFicDMWgIwnFwaPIRl2Tal3g/G 18 | I4B7aFv5eGFjUgKWf7AXdOm6abMeWEp6hCG1VxHBAoGAGtV90pgAXNA2KBW9av7C 19 | gsJ/3WmPamiG4WDSq8JRqG+34z4Xss0LPVrDI78uka2e3Uo7E3khxHd8VYlsEMPo 20 | emEMI8tfEMztwzEHzVOw/tKZgrwmiyRCYeqUzEQe4De8pToWG7ZEtQ0r4NSL0Jfa 21 | CCdi9jSm05tF3kpUpdyfnpECgYEAjbQcRh2AxI0uL4oAvccNkgtpKKWgR2v0SmZB 22 | 1iPgSXwpNRDJ7ttXWxWOgH2l1oXn4oBHywGL/ousb7qmxhlk1mZZ5FBC/5yrkrTA 23 | /IjsQ7AY75WiPDrU+ofaTzM7+Kf+FmFHh0NmgV4u9JLZuk5phrXBzvUrLG8PXtEm 24 | yi9zGAECgYEAzgALtLd0ogG2LN8MSSroOhcAwyHgp46jY+In/xESUyeLKeHkL9ed 25 | 4Q/QZgKFoNy9bsMFYz5Obt+EQQDlQwi1PNYLSHeJVhyD7dY5Tl6vUq0wTwdvQjYS 26 | X8Q/5A00AozeiYXM0Ts0t2akTi/NasEBMkC5qBj79sgBp8oCRFifqrU= 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /testdata/testcase/router.md: -------------------------------------------------------------------------------- 1 | ### Routing Forwarding 2 | 3 | #### Normal Forwarding 4 | 5 | ##### Exact Match 6 | 7 | - Direct forwarding 8 | - Rewrite forwarding 9 | 10 | ##### Prefix Match 11 | 12 | - Remove prefix forwarding 13 | - Replace prefix forwarding 14 | 15 | ##### Regular Expression Match 16 | 17 | - Regular expression matching 18 | 19 | #### Forwarding Exceptions 20 | 21 | ##### No Route Matched 22 | 23 | - Return 404 24 | 25 | ##### Backend Service Request Failure 26 | 27 | - Monitoring report: 28 | - Report as an exception 29 | - Response headers: 30 | - trpc-fun 31 | - trpc-err-msg 32 | 33 | ##### Backend Service Returns trpc err 34 | 35 | - Monitoring report: Normal 36 | - Response headers: Trpc-Error-Msg: business err, Trpc-Func-Ret: 11111 37 | 38 | ##### Backend Service Request Successful, Non-200 Response -------------------------------------------------------------------------------- /version.go: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Tencent is pleased to support the open source community by making tRPC available. 4 | // 5 | // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 | // All rights reserved. 7 | // 8 | // If you have downloaded a copy of the tRPC source code from Tencent, 9 | // please note that tRPC source code is licensed under the Apache 2.0 License, 10 | // A copy of the Apache 2.0 License is included in this file. 11 | // 12 | // 13 | 14 | package trpc 15 | 16 | import "fmt" 17 | 18 | // rule of trpc version 19 | // 1. MAJOR version when you make incompatible API changes; 20 | // 2. MINOR version when you add functionality in a backwards-compatible manner; 21 | // 3. PATCH version when you make backwards-compatible bug fixes; 22 | // 4. Additional labels for pre-release and build metadata are available as extensions to the MAJOR.MINOR.PATCH format; 23 | // alpha 0.1.0-alpha 24 | // beta 0.1.0-beta 25 | // release candidate 0.1.0-rc 26 | // release 0.1.0 27 | const ( 28 | MajorVersion = 0 29 | MinorVersion = 1 30 | PatchVersion = 0 31 | VersionSuffix = "-dev" // -alpha -alpha.1 -beta -rc -rc.1 32 | ) 33 | 34 | // Version returns the version of trpc. 35 | func Version() string { 36 | return fmt.Sprintf("v%d.%d.%d%s", MajorVersion, MinorVersion, PatchVersion, VersionSuffix) 37 | } 38 | --------------------------------------------------------------------------------