Golang negroni和http.NewServeMux()问题

huangapple go评论89阅读模式
英文:

Golang negroni and http.NewServeMux() issue

问题

我正在运行一个带有以下代码的服务器:

// 假设没有导入错误
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
    http.Error(w, "文件未找到", http.StatusNotFound)
})

n := negroni.Classic()
n.Use(negroni.HandlerFunc(bodmas.sum(4,5)))
n.UseHandler(mux)
n.Run(":4000")

它完全正常工作。

但是,当我将bodmas.sum包装在另一个http handler中时,我总是得到"文件未找到"的错误。流程不会进入这个路由。

mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
    http.Error(w, "文件未找到", http.StatusNotFound)
})

n := negroni.Classic()
n.Use(negroni.HandlerFunc(wrapper.RateLimit(bodmas.sum(4,5),10)))
n.UseHandler(mux)
n.Run(":" + cfg.Server.Port)

wrapper.RateLimit定义如下。在单独测试时,它按预期工作:

func RateLimit(h resized.HandlerFunc, rate int) (resized.HandlerFunc) {
    // 逻辑在这里

    rl, _ := ratelimit.NewRateLimiter(rate)

    return func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc){
        if rl.Limit(){
            http.Error(w, "网关超时", http.StatusGatewayTimeout)
        } else {
            next(w, r)
        }
    }
}

没有错误。
对于这种行为有什么建议吗?
如何使其工作?

英文:

I am running a server with below code:

// Assuming there is no import error
  mux := http.NewServeMux()
  mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
  http.Error(w, "File not found", http.StatusNotFound)
  })

  n := negroni.Classic()
  n.Use(negroni.HandlerFunc(bodmas.sum(4,5)))
  n.UseHandler(mux)
  n.Run(":4000" )

It works perfectly fine.

But when I wrap bodmas.sum with another http handler I always get "File not found." The flow does not go to this route.

  mux := http.NewServeMux()
  mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
    http.Error(w, "File not found", http.StatusNotFound)
  })

  n := negroni.Classic()
  n.Use(negroni.HandlerFunc(wrapper.RateLimit(bodmas.sum(4,5),10)))
  n.UseHandler(mux)
  n.Run(":" + cfg.Server.Port)
}

wrapper.RateLimit is define as below. This works as expected when tested separately:

func RateLimit(h resized.HandlerFunc, rate int) (resized.HandlerFunc) {
    :
 	:
  // logic here

    rl, _ := ratelimit.NewRateLimiter(rate)

    return func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc){
        if rl.Limit(){
            http.Error(w, "Gateway Timeout", http.StatusGatewayTimeout )
        } else {
             next(w, r)
         }
    }
}

There is no error.
Any suggestions about this behavior ?
How to make it work ?

答案1

得分: 2

我不确定这段代码有什么问题,但它似乎不是使用negroni的方式。如果我们用另一个http.Handlerfunc包装它的处理程序,negroni可能不会按预期工作。所以,我修改了我的代码,并通过middleware完成了工作。

我的当前代码如下所示:

mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
    http.Error(w, "File not found", http.StatusNotFound)
})

n := negroni.Classic()
n.Use(wrapper.Ratelimit(10))
n.Use(negroni.HandlerFunc(bodmas.sum(4,5)))
n.UseHandler(mux)
n.Run(":4000")

wrapper.go文件中有以下内容:

type RatelimitStruct struct {
    rate int
}

// 一个具有ServeHTTP方法的结构体
func Ratelimit(rate int) *RatelimitStruct {
    return &RatelimitStruct{rate}
}

func (r *RatelimitStruct) ServeHTTP(w http.ResponseWriter, req *http.Request, next http.HandlerFunc) {
    rl, _ := ratelimit.NewRateLimiter(r.rate)

    if rl.Limit() {
        http.Error(w, "Gateway Timeout", http.StatusGatewayTimeout)
    } else {
        next(w, req)
    }
}

希望对某人有所帮助。

英文:

I am not sure what sure what is the problem with this code, but it appears to be not the negorni way. negroni might not behave as expected if we wrap its handler with another http.Handlerfunc. So, I modified my code and got the work done by middleware.

My current code looks something like as below:

         mux := http.NewServeMux()
          mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
            http.Error(w, "File not found", http.StatusNotFound)
          })
    
          n := negroni.Classic()
          n.Use(wrapper.Ratelimit(10))
          n.Use(negroni.HandlerFunc(bodmas.sum(4,5)))
          n.UseHandler(mux)
          n.Run(":4000")
    }

wrapper.go has :

    type RatelimitStruct struct {
          rate int 
    }
      
    // A struct that has a ServeHTTP method
    func Ratelimit(rate  int) *RatelimitStruct{
        return &RatelimitStruct{rate}
    }

    func (r *RatelimitStruct) ServeHTTP(w http.ResponseWriter, req *http.Request, next       http.HandlerFunc){
        rl, _ := ratelimit.NewRateLimiter(r.rate)
       
        if rl.Limit(){
            http.Error(w, "Gateway Timeout", http.StatusGatewayTimeout )
        }

 else {
        next(w, req)
    } 
}

Hope it helps someone.

huangapple
  • 本文由 发表于 2014年11月19日 15:02:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/27010867.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定