1 Star 0 Fork 0

qhitc/gweb

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
webserver.go 3.73 KB
一键复制 编辑 原始数据 按行查看 历史
qhitc 提交于 2023-07-14 15:12 +08:00 . 添加跨域访问
package grpcwebserver
import (
"net/http"
"strings"
"github.com/gin-gonic/gin"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
log "github.com/sirupsen/logrus"
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
)
type WebServer struct {
GrpcWebServer *GrpcWebServer
Router *gin.Engine
h2Handler http.Handler
rESTfulHandeler *RESTfulMux
}
type RESTfulMux struct {
Mux *runtime.ServeMux //实现RESTful风格api处理复用
Prefix string
}
type HttpsConf struct {
BindAddr string
HostName string //cert hostname
CertFile string
KeyFile string
}
func NewServer(grpcWebServer *GrpcWebServer, allowCross bool) *WebServer {
//gin.SetMode(gin.ReleaseMode)
var weserver = &WebServer{
GrpcWebServer: grpcWebServer,
Router: gin.New(), // 初始化一个空Gin路由
}
if allowCross {
weserver.Router.Use(Cors())
}
return weserver
}
func (s *WebServer) Serve(httpBind string, https *HttpsConf) error {
// 监听端口并处理服务分流
s.h2Handler = h2c.NewHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
//if s.GrpcWebServer.WrappedGrpc.IsGrpcWebRequest(r) ||
// r.Method == http.MethodOptions {
if s.GrpcWebServer.WrappedGrpc.IsGrpcWebRequest(r) {
// 判断协议是否为grpc-web
s.GrpcWebServer.WrappedGrpc.ServeHTTP(w, r)
} else if r.ProtoMajor == 2 &&
strings.HasPrefix(r.Header.Get("Content-Type"), "application/grpc") {
// 判断协议是否为http/2 && 是grpc
s.GrpcWebServer.GrpcServer.ServeHTTP(w, r)
} else if strings.HasPrefix(r.RequestURI, s.rESTfulHandeler.Prefix) && s.rESTfulHandeler != nil {
//grpc-gateway 实现RESTful风格api
s.rESTfulHandeler.Mux.ServeHTTP(w, r)
} else {
// 当作普通http api
s.Router.ServeHTTP(w, r)
}
}), &http2.Server{})
if https != nil {
go func() {
err := http.ListenAndServeTLS(https.BindAddr, https.CertFile, https.KeyFile, s.h2Handler)
if err != nil {
log.Errorln(err)
}
}()
}
if httpBind != "" {
if err := http.ListenAndServe(httpBind, s.h2Handler); err != nil {
log.Println("http server done:", err.Error())
return err
}
}
return nil
}
func (s *WebServer) SetRESTfulMux(mux *RESTfulMux) {
s.rESTfulHandeler = mux
}
func Cors() gin.HandlerFunc {
return func(c *gin.Context) {
method := c.Request.Method
origin := c.Request.Header.Get("Origin") //请求头部
if origin != "" {
//接收客户端发送的origin (重要!)
c.Writer.Header().Set("Access-Control-Allow-Origin", origin)
//服务器支持的所有跨域请求的方法
c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE,UPDATE")
//允许跨域设置可以返回其他子段,可以自定义字段
c.Header("Access-Control-Allow-Headers", "Authorization, Content-Length, X-CSRF-Token, Token,session,X_Requested_With,Accept, Origin, Host, Connection, Accept-Encoding, Accept-Language,DNT, X-CustomHeader, Keep-Alive, User-Agent, X-Requested-With, If-Modified-Since, Cache-Control, Content-Type, Pragma, Authorization, Content-Type, Grpc-Timeout, X-Grpc-Web")
// 允许浏览器(客户端)可以解析的头部 (重要)
c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers")
//设置缓存时间
c.Header("Access-Control-Max-Age", "172800")
//允许客户端传递校验信息比如 cookie (重要)
c.Header("Access-Control-Allow-Credentials", "true")
}
//允许类型校验
if method == "OPTIONS" {
c.JSON(http.StatusOK, "ok!")
}
defer func() {
if err := recover(); err != nil {
log.Printf("Panic info is: %v", err)
}
}()
c.Next()
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/qhitc_admin/gweb.git
git@gitee.com:qhitc_admin/gweb.git
qhitc_admin
gweb
gweb
v1.0.0

搜索帮助