英文:
Golang Gorilla mux with http.FileServer returning 404
问题
我看到的问题是,我正在尝试使用http.FileServer
与Gorilla mux的Router.Handle函数。
这样不起作用(图像返回404):
myRouter := mux.NewRouter()
myRouter.Handle("/images/", http.StripPrefix("/images/", http.FileServer(http.Dir(HomeFolder + "images/"))))
这样可以正常工作(图像显示正常):
http.Handle("/images/", http.StripPrefix("/images/", http.FileServer(http.Dir(HomeFolder + "images/"))))
下面是一个简单的Go Web服务器程序,展示了这个问题:
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)
//
// 下一行,图像路由处理程序导致test.png图像返回404。
// myRouter.Handle("/images/", http.StripPrefix("/images/", http.FileServer(http.Dir(HomeFolder + "images/"))))
//
myRouter.Host("mydomain.com")
http.Handle("/", myRouter)
// 这种设置图像路由处理程序的方法可以正常工作。
// test.png图像显示正常。
http.Handle("/images/", http.StripPrefix("/images/", http.FileServer(http.Dir(HomeFolder + "images/"))))
// HTTP - 端口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>
`
英文:
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>
`
答案1
得分: 68
我在golang-nuts讨论组上发布了这个问题,并从Toni Cárdenas那里得到了这个解决方案...
标准的net/http ServeMux(在使用http.Handle
时使用的标准处理程序)和mux Router在匹配地址时有不同的方式。
请参阅http://golang.org/pkg/net/http/#ServeMux和http://godoc.org/github.com/gorilla/mux之间的区别。
所以基本上,http.Handle('/images/', ...)
可以匹配'/images/whatever',而myRouter.Handle('/images/', ...)
只能匹配'/images/',如果你想处理'/images/whatever',你需要...
选项1 - 在你的路由器中使用正则表达式匹配
myRouter.Handle("/images/{rest}",
http.StripPrefix("/images/", http.FileServer(http.Dir(HomeFolder + "images/"))))
选项2 - 在你的路由器上使用PathPrefix方法:
myRouter.PathPrefix("/images/").Handler(http.StripPrefix("/images/",
http.FileServer(http.Dir(HomeFolder + "images/"))))
英文:
I posted this on golang-nuts discussion group and got this solution from Toni Cárdenas ...
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, <code>http.Handle('/images/', ...)</code> matches '/images/whatever', while <code>myRouter.Handle('/images/', ...)</code> only matches '/images/', and if you want to handle '/images/whatever', you have to ...
Option 1 - Use a regular expression match in your router
myRouter.Handle("/images/{rest}",
http.StripPrefix("/images/", http.FileServer(http.Dir(HomeFolder + "images/"))))
Option 2 - Use the PathPrefix method on your router:
myRouter.PathPrefix("/images/").Handler(http.StripPrefix("/images/",
http.FileServer(http.Dir(HomeFolder + "images/"))))
答案2
得分: 0
截至2015年5月,gorilla/mux包仍然没有发布版本。但问题现在已经不同了。不是myRouter.Handle
不匹配URL并需要正则表达式,它是可以匹配的!但是http.FileServer
需要从URL中删除前缀。下面的示例可以正常工作。
ui := http.FileServer(http.Dir("ui"))
myRouter.Handle("/ui/", http.StripPrefix("/ui/", ui))
注意,上面的示例中没有/ui/**{rest}**
。你还可以将http.FileServer
包装到gorilla/handler的日志记录器中,查看请求进入FileServer和响应404离开的情况。
ui := handlers.CombinedLoggingHandler(os.Stderr, http.FileServer(http.Dir("ui")))
myRouter.Handle("/ui/", ui) // 得到404
// 使用strip可以正常工作:myRouter.Handle("/ui/", http.StripPrefix("/ui/", ui))
英文:
As of May 2015 gorilla/mux package still have no version releases. But problem is different now. It is not that myRouter.Handle
does not match url and needs regexp, it does! But http.FileServer
requires prefix to be removed from url. Below example works fine.
ui := http.FileServer(http.Dir("ui"))
myRouter.Handle("/ui/", http.StripPrefix("/ui/", ui))
Note, there is no /ui/{rest} in abowe example. You may also wrap http.FileServer
into logger gorilla/handler and see request to coming to FileServer and response 404 going out.
ui := handlers.CombinedLoggingHandler(os.Stderr,http.FileServer(http.Dir("ui"))
myRouter.Handle("/ui/", ui) // getting 404
// works with strip: myRouter.Handle("/ui/", http.StripPrefix("/ui/", ui))
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论