web-dev-qa-db-ja.com

Golang Gorilla muxとhttp.FileServerが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)
    //
    // 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>
`
33
dodgy_coder

これをgolang-nutsディスカッショングループに投稿して、 ToniCárdenasからこのソリューションを得ました ...

標準のnet/http ServeMux(これは、_http.Handle_を使用するときに使用する標準ハンドラーです)とmuxルーターでは、アドレスを照合する方法が異なります。

http://golang.org/pkg/net/http/#ServeMuxhttp://godoc.org/githubの違いを確認してください。 com/gorilla/mux

つまり、基本的に、http.Handle('/images/', ...)は '/ images/whatever'に一致し、myRouter.Handle('/images/', ...)onlyは '/ images /に一致します'、および'/images/whatever 'を処理する場合は、...

  1. ルーターで正規表現の一致を設定する、または
  2. 次のように、ルーターでPathPrefixメソッドを使用します。

コード例

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/")))
)
_
50
dodgy_coder

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) // getting 404
// works with strip: myRouter.Handle("/ui/", http.StripPrefix("/ui/", ui))
1
smile-on