Gorilla toolkit - mux with http.FileServer returning 404

1,363 views
Skip to first unread message

harvey....@gmail.com

unread,
Jan 20, 2014, 11:17:14 PM1/20/14
to golan...@googlegroups.com
The problem I'm seeing is that I'm trying to use the http.FileServer with the Gorilla mux Router.Handle function.

This doesn't work (the image returns a 404)..

  myRouter := mux.NewRouter()
  myRouter.Handle("/images/", http.StripPrefix("/images/", http.FileServer(http.Dir(HomeFolder + "images/"))))

this works (the image is shown ok)..

  http.Handle("/images/", http.StripPrefix("/images/", http.FileServer(http.Dir(HomeFolder + "images/"))))


Simple go web server program below, showing the problem...


package main

import (
    "fmt"
    "net/http"
    "io"
    "log"
    "github.com/gorilla/mux"
)

const (
    HomeFolder = "/root/test/"
)

func HomeHandler(w http.ResponseWriter, req *http.Request) {
    io.WriteString(w, htmlContents)
}

func main() {

    myRouter := mux.NewRouter()
    myRouter.HandleFunc("/", HomeHandler)
    //
    // The next line, the image route handler results in
    // the test.png image returning a 404.
    // myRouter.Handle("/images/", http.StripPrefix("/images/", http.FileServer(http.Dir(HomeFolder + "images/"))))
    //
    myRouter.Host("mydomain.com")
    http.Handle("/", myRouter)

    // This method of setting the image route handler works fine.
    // test.png is shown ok.
    http.Handle("/images/", http.StripPrefix("/images/", http.FileServer(http.Dir(HomeFolder + "images/"))))

    // HTTP - port 80
    err := http.ListenAndServe(":80", nil)

    if err != nil {
        log.Fatal("ListenAndServe: ", err)
        fmt.Printf("ListenAndServe:%s\n", err.Error())
    }
}

const htmlContents = `<!DOCTYPE HTML>
<html lang="en">
  <head>
    <title>Test page</title>
    <meta charset = "UTF-8" />
  </head>
  <body>
    <p align="center">
        <img src="/images/test.png" height="640" width="480">
    </p>
  </body>
</html>
`

Toni Cárdenas

unread,
Jan 21, 2014, 1:51:37 AM1/21/14
to golan...@googlegroups.com
The standard net/http ServeMux (which is the standard handler you are using when you use `http.Handle`) and the mux Router have different ways of matching an address. See the differences between http://golang.org/pkg/net/http/#ServeMux and http://godoc.org/github.com/gorilla/mux.

So basically, http.Handle('/images/', ...) matches '/images/whatever', while myRouter.Handle('/images/', ...) _only_ matches '/images/', and if you want to handle '/images/whatever', you have to 1. set a regular expression match in your router or 2. use the PathPrefix method on your router, like:

1. myRouter.Handle('/images/{rest}', http.StripPrefix("/images/", http.FileServer(http.Dir(HomeFolder + "images/"))))
2. myRouter.PathPrefix("/images/").Handler(http.StripPrefix("/images/", http.FileServer(http.Dir(HomeFolder + "images/"))))

harvey....@gmail.com

unread,
Jan 21, 2014, 2:09:56 AM1/21/14
to golan...@googlegroups.com
Thanks Toni, this is the solution to my issue
I should have read through the docs on gorilla in more detail!

zhiwei dong

unread,
Mar 22, 2023, 12:47:57 AM3/22/23
to golang-nuts
The 127.0.0.1:8084/apidoc/  return a 404

Demo
package main

import (
"fmt"
"github.com/gorilla/mux"
"net/http"
)

func main() {
//http.Handle("/apidoc/", http.StripPrefix("/apidoc", http.FileServer(http.Dir("api-swagger"))))
//if err := http.ListenAndServe(":8082", nil); err != nil {
// fmt.Println(err)
//}
router := mux.NewRouter()
router.PathPrefix("/apidoc/").Handler(http.StripPrefix("/apidoc/", http.FileServer(http.Dir("api-swagger"))))
if err := http.ListenAndServe(":8084", nil); err != nil {
fmt.Println(err)
}
//
//router.Use(mux.CORSMethodMiddleware(router))
}

Marvin Renich

unread,
Mar 22, 2023, 8:00:05 AM3/22/23
to golan...@googlegroups.com
* zhiwei dong <dongzhi...@gmail.com> [230322 00:47]:
> The 127.0.0.1:8084/apidoc/ return a 404
>
> Demo
> package main
>
> import (
> "fmt"
> "github.com/gorilla/mux"
> "net/http"
> )
>
> func main() {
> router := mux.NewRouter()
> router.PathPrefix("/apidoc/").Handler(http.StripPrefix("/apidoc/", http.FileServer(http.Dir("api-swagger"))))

I think you are missing

http.Handle("/", router)

> if err := http.ListenAndServe(":8084", nil); err != nil {
> fmt.Println(err)
> }
> }

...Marvin

Reply all
Reply to author
Forward
0 new messages