1

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 ?

Somesh
  • 1,235
  • 2
  • 13
  • 29

1 Answers1

2

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.

Somesh
  • 1,235
  • 2
  • 13
  • 29