LoginSignup
5
5

More than 5 years have passed since last update.

golang net/http でURL正規化リダイレクトするのを無効化

Last updated at Posted at 2015-05-03

はじめに

URL正規化リダイレクト自体は正常な動作で、無効化する事による悪影響もあるので、気をつけて下さい。なんとなく黒魔術っぽい。

困った現象

  • http://〜/path?param の path に // があると / にマージした URL にリダイレクトされる。

通常は問題ないけど、path 部をパラメータとして使おうという場合、

  • http://〜/w=100,h=100/http://〜
    にアクセスすると、

  • http://〜/w=100,h=100/http:/〜

にリダイレクトされる。尚、URLエンコードしても無駄。

ちなみに、go-thumber の元画像URLにプロトコル部を試しに追加したらこの現象に遭遇しました。

原因

  • URL は正規化された方に Permanent Redirect される。
  • http://? の path の 正規化で // はマージされる

対応するコードは net/http/server.go:cleanPat => path.go:Clean

回避方法

HandleFunc を使わずに http.ListenAndServe の第二引数でハンドルを指定して、そこから自前で URL ルーティングを行う。

  • go-thumber でパラメータに // を使えるようにする改造
listenAndServe.go
type Handler struct{}

func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    uri := r.URL.Path
    switch uri {
    case "/server-status":
        statusServer(w, r)
    case "/favicon.ico":
        errorServer(w, r)
    default:
        thumbServer(w, r)
    }
}

func main() {
    flag.Parse()
    if *show_version {
        fmt.Printf("thumberd %s\n", version)
        return
    }

    client.Timeout = time.Duration(*timeout) * time.Second

    var err error

    if *local != "" { // Run as a local web server
        handler := new(Handler)
//      err = http.ListenAndServe(*local, nil)
        err = http.ListenAndServe(*local, handler)
    } else { // Run as FCGI via standard I/O
        err = fcgi.Serve(nil, nil)
    }
    if err != nil {
        log.Fatal(err)
    }
}

http.ListenAndServe(*local, nil)

http.ListenAndServe(*local, handle)
にして、handle で URI を見て処理をスイッチしてます。

ハマりどころ

  • Permanent Redirect はブラウザが覚えてしまうので、一度アクセスしたURLだとサーバ側で対処してもブラウザ側で勝手にアドレスを書き換えるかもしれない。(なので、当初対処に失敗したと勘違いしてた)
    • Chrome のシークレット・ウィンドウを使えば一時的に忘れてくれるので、動作確認に便利です。

使用上の注意

  • プロキシー等の経路で勝手に正規化されて無駄かもしれない
  • 正規化されない事でキャッシュ率が落ちるかもしれない
5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5