LoginSignup
34
24

More than 5 years have passed since last update.

Golangで、ResponseWriterを使ってHTTPレスポンスを組み立てる際にハマったこと

Last updated at Posted at 2015-07-26

GolangでHTTPサーバーを立てて、ブラウザからアクセスしたところ、毎回セッションが新しく作り直される現象にハマりました。

いろいろデバッグしていたところ、どうやら、レスポンスヘッダーをセットする前に、レスポンスボディーをセットしてしまうのがいけなかったようです。

あとでドキュメント読んだら、普通に書いてありましたが、io.WriteStringjson.NewEncoder(w).Encodeなどでコンテンツを書き込んでしまうと、レスポンスヘッダーを書き込めなくなってしまうようです。

順番は下記のようにしないと正常に動作しません。

  1. w.Header().Set("" "")
  2. w.WriteHeader(404) // 通常処理(status 200 OK)以外の場合は設定
  3. w.Write (html/json/xmlなどレスポンスタイプ毎に対応したメソッドを呼ぶ)

コンテンツを書き込んだあとに、セッション保存していたため、レスポンスヘッダーのSet-Cookieが無視され毎回セッション再生成される現象に陥りました。

server.go
// A ResponseWriter interface is used by an HTTP handler to
// construct an HTTP response.
type ResponseWriter interface {
    // Header returns the header map that will be sent by WriteHeader.
    // Changing the header after a call to WriteHeader (or Write) has
    // no effect.
    Header() Header

    // Write writes the data to the connection as part of an HTTP reply.
    // If WriteHeader has not yet been called, Write calls WriteHeader(http.StatusOK)
    // before writing the data.  If the Header does not contain a
    // Content-Type line, Write adds a Content-Type set to the result of passing
    // the initial 512 bytes of written data to DetectContentType.
    Write([]byte) (int, error)

    // WriteHeader sends an HTTP response header with status code.
    // If WriteHeader is not called explicitly, the first call to Write
    // will trigger an implicit WriteHeader(http.StatusOK).
    // Thus explicit calls to WriteHeader are mainly used to
    // send error codes.
    WriteHeader(int)
}

まとめ

ドキュメントはちゃんと読もう

34
24
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
34
24