无法中止()上下文 - 杜松子酒

时间:2015-09-08 20:49:44

标签: go go-gin

我有以下Gin中间件:

new.palette=colorRampPalette(c("black","yellow","#007FFF","white"),space="rgb") 
    levelplot(IDX_as[1:ncol(IDX_as),ncol(IDX_as):1],col.regions=new.palette(20))

    quartz(width=7,height=6) #make a new quartz window of a given size 
    par(mar=c(2,3,2,1)) #set the margins of the figures to be smaller than default 
    layout(matrix(c(1,2),1,2,byrow=TRUE),widths=c(7,1)) #set the layout of the quartz window. This will create two plotting regions, with width ratio of 7 to 1 
    image(IDX_as[1:ncol(IDX_as),ncol(IDX_as):1],col=new.palette(20),xaxt="n",yaxt="n") #plot a heat map matrix with no tick marks or axis labels 
    axis(1,at=seq(0,1,length=20),labels=rep("",20)) #draw in tick marks 
    axis(2,at=seq(0,1,length=20),labels=rep("",20)) 

    #adding a color legend 
    s=seq(min(IDX_as),max(IDX_as),length=20) #20 values between minimum and maximum values of m 
    l=matrix(s,ncol=length(s),byrow=TRUE) #coerce it into a horizontal matrix 
    image(y=s,z=l,col=new.palette(20),ylim=c(min(IDX),max(IDX)),xaxt="n",las=1) #plot a one-column heat map

    heatmap(IDX_as,symm=TRUE,col=new.palette(20))

但是如果返回func CheckAppId(appC *core.Context) gin.HandlerFunc { return func(c *gin.Context) { //get Basic Auth credentials appId, token, _ := c.Request.BasicAuth() if appId == "" { c.JSON(http.StatusOK, gin.H{"code": "MISSING_APP_ID", "message": "Your request is missing an application id"}) return //this is being ignored??? } c.Next() //this still gets hit } } JSON并且appId == ""也被执行了。这是预期的行为吗?

修改 我认为这个问题已被出售,但同样的事情似乎正在发生。我现在有:

c.Next()

在对API的调用中,我收到“MISSING_APP_ID”Json和“INVALID_APP_ID”Json

2 个答案:

答案 0 :(得分:4)

查看Gin API文档,您需要调用context.Abort()而不是从您的方法返回。

  

Abort停止系统继续调用链中的挂起处理程序。假设您有一个授权中间件,如果授权失败(密码不匹配),则验证请求是否被授权。应该调用此方法(Abort())以停止执行实际的处理程序。

所以在你的特定情况下

if appId == "" {
    c.JSON(http.StatusOK, gin.H{"code": "MISSING_APP_ID", "message": "Your request is missing an application id"})
    c.Abort()
    return
}

答案 1 :(得分:1)

<强> TL; DR

你需要这样做:

if condition {
  c.Abort()
} else {
  c.Next()
}

<强>解释

(注意:这建立在@Landers答案的基础上)

c.Abort()只是设置一些内部标志,以某种方式标记上下文,指示异常终止。这是有道理的,它是一个无参数的方法,什么都不返回,所以你只是因为它的副作用而调用它。

c.Next()

相同

由于go的控制流程(没有异常或跳转),很明显这两种方法不会立即采取行动,而是为下一阶段“设置阶段”,想象一下Gins代码会调用你的CheckAppId FUNC:

// gin code
doStuff()
ctx := getContext()

// this is your CheckAppId
nextAction := FindAction()
nextAction(&ctx)

// here the context is evaluated to see if you either abort or continue.
checkContextStatus(&ctx)

因此,如果您正在调用c.Abort()然后调用c.Next(),那么您将覆盖中止指示。