前言
《grpc-gateway使用教程》中已有现成的 grpc+https 服务器搭建教程&源码,可直接学习搭建。基于爱搞事情的心态,就是不想用 TLS,应该怎么处理?详见本文
去除TLS & 解决遇到的问题
按照《grpc-gateway使用教程》描述,去掉项目中的TLS配置相关代码,设置 dialOpt 为 grpc.WithInsecure() 即可
dialOpt := []grpc.DialOption{grpc.WithInsecure()}
结果实际测试发起请求,却遇到了下面问题:
通过《Why am i getting connection connection closed before server preface received in go?》可以知道问题的解决方式,使用 h2c 改造 /pkg/util/grpc.go
代码如下:
package util
import (
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
"google.golang.org/grpc"
"net/http"
"strings"
)
// GrpcHandlerFunc 函数是用于判断请求来源于Rpc客户端还是Restful api的请求,根据不同的请求注册不同的ServerHTTP服务,
// r.ProtoMajor=2代表着请求必须基于HTTP/2
func GrpcHandlerFunc(grpcServer *grpc.Server, otherHandler http.Handler) http.Handler {
return h2c.NewHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if otherHandler == nil {
grpcServer.ServeHTTP(w, r)
return
}
if r.ProtoMajor == 2 && strings.Contains(r.Header.Get("Content-Type"), "application/grpc") {
grpcServer.ServeHTTP(w, r)
} else {
otherHandler.ServeHTTP(w, r)
}
}), &http2.Server{})
}
好了,现在可以正常使用http访问了
解决CORS问题
HTTP服务器常遇跨域CORS问题,可在上文/pkg/util/grpc.go
的otherHandler.ServeHTTP(w, r)
前加入下述代码解决
// CORS
if r.Method == "OPTIONS" && r.Header.Get("Access-Control-Request-Method") != "" {
w.Header().Set("Access-Control-Allow-Origin", "*")
headers := []string{"Content-Type", "Accept"}
w.Header().Set("Access-Control-Allow-Headers", strings.Join(headers, ","))
methods := []string{"GET", "HEAD", "POST", "PUT", "DELETE"}
w.Header().Set("Access-Control-Allow-Methods", strings.Join(methods, ","))
return
}
// 可根据需要,调整允许访问的orgin
w.Header().Set("Access-Control-Allow-Origin", "*")
可使用 cors.html 进行测试
具体请见:grpc-gateway-demo的wipe_tls分支代码
参考文章
- grpc-gateway使用教程-为之守望
- Why am i getting connection connection closed before server preface received in go?
- cors.html