golang做php的中间件,Golang 之 中间件
golang 中间件的实现本质:
写一个func,接受handler并且返回handler
把私货写在func里面,从而实现把你要写的操作执行了之后,再把原有的流程进行下去
一个好的中间件有一个责任就是可插拔并且自足。
例子:
package main
import (
"fmt"
"github.com/devfeel/dotweb"
)
func main() {
app := dotweb.New()
// App注册中间件
app.Use(NewSessionAuth())
// 开启SESSION
app.HttpServer.SetEnabledSession(true)
// 设置路由 输出字符串 Hello Dotweb
app.HttpServer.GET("/", func(ctx dotweb.Context) error {
method := ctx.Request().Method
return ctx.WriteString("Hello Dotweb\n" + "Method:" + method)
})
//开启服务 端口号
fmt.Println("dotweb.StartServer => 8080")
err := app.StartServer(8080)
fmt.Println("dotweb.StartServer error => ", err)
}
// SessionAuth 结构体
type SessionAuth struct {
dotweb.BaseMiddlware
}
// Handle 处理程序
func (m *SessionAuth) Handle(ctx dotweb.Context) error {
fmt.Println("SessionID = ", ctx.SessionID(), " RequestURI = ", ctx.Request().RequestURI)
return m.Next(ctx)
}
// NewSessionAuth New
func NewSessionAuth() *SessionAuth {
sAuth := new(SessionAuth)
return sAu
}
Handle是什么时候被调用的?
我们看看BaseMiddlWare的源码:
// BaseMiddleware is the base struct, user defined middleware should extend this
type BaseMiddleware struct {
next Middleware
excludeRouters map[string]struct{}
}
func (bm *BaseMiddleware) SetNext(m Middleware) {
bm.next = m
}
func (bm *BaseMiddleware) Next(ctx Context) error {
httpCtx := ctx.(*HttpContext)
if httpCtx.middlewareStep == "" {
httpCtx.middlewareStep = middleware_App
}
if bm.next == nil {
if httpCtx.middlewareStep == middleware_App {
httpCtx.middlewareStep = middleware_Group
if len(httpCtx.RouterNode().GroupMiddlewares()) > 0 {
return httpCtx.RouterNode().GroupMiddlewares()[0].Handle(ctx)
}
}
if httpCtx.middlewareStep == middleware_Group {
httpCtx.middlewareStep = middleware_Router
if len(httpCtx.RouterNode().Middlewares()) > 0 {
return httpCtx.RouterNode().Middlewares()[0].Handle(ctx)
}
}
if httpCtx.middlewareStep == middleware_Router {
return httpCtx.Handler()(ctx)
}
} else {
// check exclude config
if ctx.RouterNode().Node().hasExcludeMiddleware && bm.next.HasExclude() {
if bm.next.ExistsExcludeRouter(ctx.RouterNode().Node().fullPath) {
return bm.next.Next(ctx)
}
}
return bm.next.Handle(ctx)
}
return n
}
通过这个代码我们大概能看出:
BaseMiddleware其实是一个链表的node
中间件组成了一个链表,并且有不同的类型
有group中间件和普通中间件
根据当前ctx所处的处理步骤决定调用哪一个中间件
最后调用ctx的handler
自定义的middleware要继承 BaseMiddleware
并且实现handle
func (asm *ApiSignMiddleware) Handle(ctx dotweb.Context) error {
if sign := ctx.Request().QueryHeader("Sign"); len(sign) <= 0 {
return ctx.WriteJsonC(http.StatusBadRequest, models.Response{Err: common.ErrSignParams, Data: nil})
} else {
uri := ctx.Request().RequestURI
if index := strings.Index(uri, "?"); index != -1 {
uri = uri[:index]
}
if ok := checkSign(sign, uri); !ok {
return ctx.WriteJsonC(http.StatusBadRequest, models.Response{Err: common.ErrSignParams, Data: nil})
}
return asm.Next(ctx)
}
}
这样就可以对传进来的Contex进行解析
分析一下blogserver里面用到的middleware:
CrosMiddleware
func (cm *CrosMiddleware) Handle(ctx dotweb.Context) error {
if strings.Contains(ctx.Request().RequestURI, "v1") && ctx.Request().Method != "OPTIONS" {
if sign := ctx.Request().QueryHeader("Sign"); len(sign) <= 0 {
return ctx.WriteJsonC(http.StatusBadRequest, models.Response{Err: common.ErrSignParams, Data: nil})
} else {
uri := ctx.Request().RequestURI
if index := strings.Index(uri, "?"); index != -1 {
uri = uri[:index]
}
if ok := checkSign(sign, uri); !ok {
return ctx.WriteJsonC(http.StatusBadRequest, models.Response{Err: common.ErrSignParams, Data: nil})
}
return cm.Next(ctx)
}
}
return cm.Next(ctx)
}
CrosMiddleware 对uri的非参数部分调用checkSign
//验证签名 (requestUri(不含query)+secret)
func checkSign(sign, uri string) bool {
result := utils.Md5(uri + config.Config().SecretKey)
return result == sign
}
传过来得header里面得sign值应该跟 uri + 配置文件里面的 SecretKey 取md5 一致
文章来源: blog.csdn.net,作者:只要你在,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/icebergliu1234/article/details/110437090
golang做php的中间件,Golang 之 中间件相关推荐
- opentracing php,详解GoLang实现基于gin+jaeger的opentracing中间件
下面由golang教程栏目给大家介绍GoLang实现基于gin+jaeger的opentracing中间件的方法,希望对需要的朋友有所帮助! 完整源码:https://github.com/why44 ...
- golang游戏服务器项目,基于Golang的游戏服务器框架cellnet开发日记(一)
启程的故事 使用Golang写服务器是一件非常幸福的事情. 不用长时间的等待编译, 零依赖部署. 开发效率高, 多出的时间陪陪家人, 看书充充电多好. 所以Golang就像是手机界的苹果, 从发布后, ...
- Spring中间件 - 什么是中间件
一.前言 在互联网应用开发初期,所有用于支撑系统建设的,框架结构.基础工具.业务逻辑.功能服务包括页面展示等,都是在一个系统中开发完成,最终也只是把系统和数据库部署在同一台服务器上. 但随着互联网应用 ...
- PHP中间件 middleware,middleware 中间件详解
如果感觉这篇文章有用请点个赞,让我知道自己的努力不白费!!! 中间件是请求必经之处,所以此处能对请求的数据做一系列处理,相当于过滤器.例如跨域请求,验证会员是否登录跳转至登录页,前后端分离数据类型不一 ...
- 后盾网lavarel视频项目---lavarel中间件(使用中间件拦截没登录的用户)
后盾网lavarel视频项目---lavarel中间件(使用中间件拦截没登录的用户) 一.总结 一句话总结: 1.中间件中验证用户是否登录:if(!Auth::guard('admin')->c ...
- 【golang】从源代码编译golang编译器
文章目录 系统信息 下载并编译go1.4用作bootstrap编译器 下载golang源代码 编译最新的golang 检查golang编译版本信息 编译一个简单的go程序 系统信息 tsu5@hhvm ...
- golang go语言_Go(Golang)编程语言
golang go语言 Go (or golang) is a programming language created at Google in 2007 by Robert Griesemer, ...
- 什么是中间件?常见中间件有哪些?
文章目录 中间件是什么 为什么使用中间件 常见的中间件有哪些 中间件是什么 中间件是一种独立的系统软件或服务程序,分布式应用软件借助这种软件在不同的技术之间共享资源.中间件位于客户机/ 服务器的操作系 ...
- Java中间件(1)--分布式系统中间件从入门到精通(五)
上篇文章说了,当业务数据量大的时候,可以考虑业务和数据分离,当还解决不了的时候,可以考虑把数据库读写分离,缓存,还可以考虑把表垂直拆分,水平拆分. 大型网站架构(2)--分布式系统&中间件从入 ...
- go 基准测试 找不到函数_基于Golang做测试
本文在实习期间完成并完善,无任何公司机密,仅做语言交流学习之用. 持续更新. 1.Golang的单元测试 Go语言提供了丰富的单测功能.在Go中,我们通常认为函数是最小的可执行单元.本例中使用两个简单 ...
最新文章
- BZOJ3139/BZOJ1306 HNOI2013比赛/CQOI2009循环赛(搜索)
- BIEE 目录迁移(文件夹)方式
- ArrayList和LinkedList使用不当,性能差距会如此之大!
- 基于微服务架构、运行于容器中的.NET Core示例应用eShopOnContainers
- 《程序员面试宝典》精华 编程语言部分
- 中教云教师备课云平台获北京市新技术新产品(服务)认定
- Python+OpenCV:理解K-Means聚类(K-Means Clustering)
- 计算机必懂的54个英文单词和缩写
- NYOJ759 你知道这个规律吗
- 解锁lintcode数字图像识别
- 前端学习分为几个阶段,你属于哪个阶段?
- Android混淆规则
- w ndows 10画图,如何在Windows 10中打开和使用画图
- 阿里云ddns过程记录
- 校友厅——只有一层的“校友楼”
- 模型转换:pth转onnx
- 如何下载 Chrome 应用商店的 .crx 文件
- python内建方法
- 移动通信第三章,组网技术基础
- 【配电网重构】基于粒子群算法实现最小化功率损耗的配电网重构附matlab代码