...

パッケージ httputil

import "net/http/httputil"
概要
目次

概要 ▾

httputil パッケージは, net/http パッケージにある関数を補完し,HTTP でよく使われる関数を提供します。

目次 ▾

DumpRequest
DumpRequestOut
DumpResponse
ReverseProxy

パッケージファイル

dump.go httputil.go persist.go reverseproxy.go

変数

var (
    // 非推奨: もう使用されていません。
    ErrPersistEOF = &http.ProtocolError{ErrorString: "persistent connection closed"}

    // 非推奨: もう使用されていません。
    ErrClosed = &http.ProtocolError{ErrorString: "connection closed by user"}

    // 非推奨: もう使用されていません。
    ErrPipeline = &http.ProtocolError{ErrorString: "pipeline error"}
)

ErrLineTooLong は,長すぎる行を含む不正な形式のチャンクデータを読み込むと返されます。

var ErrLineTooLong = internal.ErrLineTooLong

func DumpRequest

func DumpRequest(req *http.Request, body bool) ([]byte, error)

DumpRequest は HTTP/1.x ワイヤ表現で与えられたリクエストを返します。 クライアントのリクエストをデバッグするためにサーバーによってのみ使用されるべきです。 返される表現は近似値です。 最初のリクエストの詳細は, http.Request に解析している間に失われます。 特に,ヘッダーフィールド名の順序と大文字と小文字は区別されません。 多値ヘッダーの値の順序は変わりません。 HTTP/2 リクエストは,元のバイナリ表現ではなく, HTTP/1.x 形式でダンプされます。

body が true の場合, DumpRequest は body も返します。 そうするために,それは req.Body を消費し,それから同じバイトを生成する新しい io.ReadCloser でそれを置き換えます。 DumpRequest がエラーを返した場合, req の状態は未定義です。

http.Request.Write のドキュメントでは, req のどのフィールドがダンプに含まれるかについて詳しく説明しています。

コード:

ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    dump, err := httputil.DumpRequest(r, true)
    if err != nil {
        http.Error(w, fmt.Sprint(err), http.StatusInternalServerError)
        return
    }

    fmt.Fprintf(w, "%q", dump)
}))
defer ts.Close()

const body = "Go is a general-purpose language designed with systems programming in mind."
req, err := http.NewRequest("POST", ts.URL, strings.NewReader(body))
if err != nil {
    log.Fatal(err)
}
req.Host = "www.example.org"
resp, err := http.DefaultClient.Do(req)
if err != nil {
    log.Fatal(err)
}
defer resp.Body.Close()

b, err := ioutil.ReadAll(resp.Body)
if err != nil {
    log.Fatal(err)
}

fmt.Printf("%s", b)

出力:

"POST / HTTP/1.1\r\nHost: www.example.org\r\nAccept-Encoding: gzip\r\nContent-Length: 75\r\nUser-Agent: Go-http-client/1.1\r\n\r\nGo is a general-purpose language designed with systems programming in mind."

func DumpRequestOut

func DumpRequestOut(req *http.Request, body bool) ([]byte, error)

DumpRequestOut は DumpRequest に似ていますが,発信クライアントリクエスト用です。 User-Agent など,標準の http.Transport によって追加されたヘッダーがすべて含まれます。

コード:

const body = "Go is a general-purpose language designed with systems programming in mind."
req, err := http.NewRequest("PUT", "http://www.example.org", strings.NewReader(body))
if err != nil {
    log.Fatal(err)
}

dump, err := httputil.DumpRequestOut(req, true)
if err != nil {
    log.Fatal(err)
}

fmt.Printf("%q", dump)

出力:

"PUT / HTTP/1.1\r\nHost: www.example.org\r\nUser-Agent: Go-http-client/1.1\r\nContent-Length: 75\r\nAccept-Encoding: gzip\r\n\r\nGo is a general-purpose language designed with systems programming in mind."

func DumpResponse

func DumpResponse(resp *http.Response, body bool) ([]byte, error)

DumpResponse は DumpRequest と似ていますが,レスポンスをダンプします。

コード:

const body = "Go is a general-purpose language designed with systems programming in mind."
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Date", "Wed, 19 Jul 1972 19:00:00 GMT")
    fmt.Fprintln(w, body)
}))
defer ts.Close()

resp, err := http.Get(ts.URL)
if err != nil {
    log.Fatal(err)
}
defer resp.Body.Close()

dump, err := httputil.DumpResponse(resp, true)
if err != nil {
    log.Fatal(err)
}

fmt.Printf("%q", dump)

出力:

"HTTP/1.1 200 OK\r\nContent-Length: 76\r\nContent-Type: text/plain; charset=utf-8\r\nDate: Wed, 19 Jul 1972 19:00:00 GMT\r\n\r\nGo is a general-purpose language designed with systems programming in mind.\n"

func NewChunkedReader

func NewChunkedReader(r io.Reader) io.Reader

NewChunkedReader は, r から読み取られたデータを返す前に, HTTP の "chunked" フォーマットから変換した新しい chunkedReader を返します。 最後の長さ 0 のチャンクが読み取られると, chunkedReader は io.EOF を返します。

NewChunkedReader は通常のアプリケーションでは必要ありません。 レスポンスパッケージを読むときに, http パッケージは自動的にチャンクをデコードします。

func NewChunkedWriter

func NewChunkedWriter(w io.Writer) io.WriteCloser

NewChunkedWriter は,書き込みを w に書き込む前に,書き込みを HTTP の "chunked" 形式に変換する新しい chunkedWriter を返します。 返された chunkedWriter を閉じると,ストリームの終わりを示す最後の長さ 0 のチャンクが送信されますが,トレーラの後に表示される最後の CRLF は送信されません。 トレーラーと最後の CRLF は別々に書く必要があります。

NewChunkedWriter は通常のアプリケーションでは必要ありません。 ハンドラが Content-Length ヘッダを設定しない場合, http パッケージは自動的にチャンクを追加します。 ハンドラ内で NewChunkedWriter を使用すると,ダブルチャンクまたは Content-Length の長さのチャンクになりますが,どちらも誤りです。

type BufferPool 1.6

BufferPool は, io.CopyBuffer で使用するための一時的なバイトスライスを取得および返すためのインターフェースです。

type BufferPool interface {
    Get() []byte
    Put([]byte)
}

type ClientConn

ClientConn は Go の初期の HTTP 実装の成果物です。 これは低レベルで古く, Go の現在の HTTP スタックでは使われていません。 Go 1 の前に削除したはずです。

非推奨: 代わりにパッケージ net/http でクライアントまたはトランスポートを使用してください。

type ClientConn struct {
    // エクスポートされていないフィールドがあります
}

func NewClientConn

func NewClientConn(c net.Conn, r *bufio.Reader) *ClientConn

NewClientConn は Go の初期の HTTP 実装の成果物です。 これは低レベルで古く, Go の現在の HTTP スタックでは使われていません。 Go 1 の前に削除したはずです。

非推奨: 代わりにパッケージ net/http のクライアントまたはトランスポートを使用してください。

func NewProxyClientConn

func NewProxyClientConn(c net.Conn, r *bufio.Reader) *ClientConn

NewProxyClientConn は, Go の初期の HTTP 実装の成果物です。 これは低レベルで古く, Go の現在の HTTP スタックでは使われていません。 Go 1 の前に削除したはずです。

非推奨: 代わりにパッケージ net/http のクライアントまたはトランスポートを使用してください。

func (*ClientConn) Close

func (cc *ClientConn) Close() error

Close は Hijack を呼び出してから,内部の接続も閉じます。

func (*ClientConn) Do

func (cc *ClientConn) Do(req *http.Request) (*http.Response, error)

Do はリクエストを書いてレスポンスを読む便利なメソッドです。

func (*ClientConn) Hijack

func (cc *ClientConn) Hijack() (c net.Conn, r *bufio.Reader)

Hijack は ClientConn をデタッチし,内部の接続と,データの一部が残っている可能性がある読み取り側の bufio を返します。 ユーザーまたは Read がキープアライブロジックの終了を通知する前に,ハイジャックが呼び出される可能性があります。 Read または Write が進行中の間,ユーザーは Hijack を呼び出してはいけません。

func (*ClientConn) Pending

func (cc *ClientConn) Pending() int

Pending は,接続で送信された未レスポンスのリクエストの数を返します。

func (*ClientConn) Read

func (cc *ClientConn) Read(req *http.Request) (resp *http.Response, err error)

Read はワイヤから次のレスポンスを読み込みます。 有効なレスポンスが ErrPersistEOF と一緒に返される可能性があります。 これは,リモートがこれが最後に処理されたリクエストであることをリクエストしたことを意味します。 Read は Write と平行に呼び出すことができますが,別の Read と平行に呼び出すことはできません。

func (*ClientConn) Write

func (cc *ClientConn) Write(req *http.Request) error

Write はリクエストを書き込みます。 HTTP キープアライブの意味で接続が閉じられた場合, ErrPersistEOF エラーが返されます。 req.Close が true の場合,キープアライブ接続はこのリクエストと論理サーバーに通知された後に論理的に閉じられます。 ErrUnexpectedEOF は,リモートが基本的な TCP 接続を閉じたことを示します。通常,これは正常な終了と見なされます。

type ReverseProxy

ReverseProxy は,着信リクエストを受け取り,それを別のサーバーに送信して,そのレスポンスをクライアントに戻す HTTP ハンドラーです。

type ReverseProxy struct {
    // Director は,トランスポートを使用して送信されるリクエストを新しいリクエストに変更する関数でなければなりません。
    // そのレスポンスは変更されずに元のクライアントにコピーされます。
    // Director は帰った後に渡された Request にアクセスしてはいけません。
    Director func(*http.Request)

    // プロキシリクエストを実行するために使用されるトランスポート。
    // nil の場合, http.DefaultTransport が使用されます。
    Transport http.RoundTripper

    // FlushInterval は,レスポンスボディをコピーしている間にクライアントにフラッシュするフラッシュ間隔を指定します。
    // ゼロの場合,定期的なフラッシュは行われません。
    // 負の値は,クライアントへの各書き込みの直後にフラッシュすることを意味します。
    // ReverseProxy がレスポンスをストリーミングレスポンスとして認識した場合, FlushInterval は無視されます。
    // そのようなレスポンスの場合,書き込みはすぐにクライアントにフラッシュされます。
    FlushInterval time.Duration

    // ErrorLog は,リクエストを代理しようとしたときに発生したエラーに対するオプションのロガーを指定します。
    // nil の場合,ログは log パッケージの標準ロガーを介して記録されます。
    ErrorLog *log.Logger // Go 1.4

    // BufferPool は, HTTP レスポンスボディをコピーするときに io.CopyBuffer によって使用されるバイトスライスを取得するためのバッファプールをオプションで指定します。
    BufferPool BufferPool // Go 1.6

    // ModifyResponse はバックエンドからの Response を変更するオプションの関数です。
    // バックエンドが何らかの HTTP ステータスコードとともにレスポンスを返した場合に呼び出されます。
    // バックエンドに到達できない場合は, ModifyResponse を呼び出さずにオプションの ErrorHandler が呼び出されます。
    //
    // ModifyResponse がエラーを返すと, ErrorHandler がそのエラー値とともに呼び出されます。
    // ErrorHandler が nil の場合,そのデフォルトの実装が使用されます。
    ModifyResponse func(*http.Response) error // Go 1.8

    // ErrorHandler は,バックエンドに到達したエラーや ModifyResponse からのエラーを処理するオプションの関数です。
    //
    // nil の場合,デフォルトでは渡されたエラーをログに記録し, 502 Status Bad Gateway レスポンスを返します。
    ErrorHandler func(http.ResponseWriter, *http.Request, error) // Go 1.11
}

コード:

backendServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "this call was relayed by the reverse proxy")
}))
defer backendServer.Close()

rpURL, err := url.Parse(backendServer.URL)
if err != nil {
    log.Fatal(err)
}
frontendProxy := httptest.NewServer(httputil.NewSingleHostReverseProxy(rpURL))
defer frontendProxy.Close()

resp, err := http.Get(frontendProxy.URL)
if err != nil {
    log.Fatal(err)
}

b, err := ioutil.ReadAll(resp.Body)
if err != nil {
    log.Fatal(err)
}

fmt.Printf("%s", b)

出力:

this call was relayed by the reverse proxy

func NewSingleHostReverseProxy

func NewSingleHostReverseProxy(target *url.URL) *ReverseProxy

NewSingleHostReverseProxy は, target に指定されたスキーム,ホスト,およびベースパスに URL をルーティングする新しい ReverseProxy を返します。 ターゲットのパスが "/base" で,着信リクエストが "/dir" に対するものである場合,ターゲットリクエストは /base/dir に対するものになります。 NewSingleHostReverseProxy は Host ヘッダーを書き換えません。 Host ヘッダーを書き換えるには, ReverseProxy をカスタムの Director ポリシーで直接使用します。

func (*ReverseProxy) ServeHTTP

func (p *ReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request)

type ServerConn

ServerConn は Go の初期の HTTP 実装の成果物です。 これは低レベルで古く, Go の現在の HTTP スタックでは使われていません。 Go 1 の前に削除したはずです。

非推奨: 代わりにパッケージ net/http のサーバーを使用してください。

type ServerConn struct {
    // エクスポートされていないフィールドがあります
}

func NewServerConn

func NewServerConn(c net.Conn, r *bufio.Reader) *ServerConn

NewServerConn は Go の初期の HTTP 実装の成果物です。 これは低レベルで古く, Go の現在の HTTP スタックでは使われていません。 Go 1 の前に削除したはずです。

非推奨: 代わりにパッケージ net/http のサーバーを使用してください。

func (*ServerConn) Close

func (sc *ServerConn) Close() error

Close は Hijack を呼び出してから,内部の接続も閉じます。

func (*ServerConn) Hijack

func (sc *ServerConn) Hijack() (net.Conn, *bufio.Reader)

Hijack は ServerConn をデタッチして,基盤となる接続と,データの一部が残っている可能性がある読み取り側の bufio を返します。 Read が keep-alive ロジックの終了を通知する前に,ハイジャックが呼び出される可能性があります。 Read または Write が進行中の間,ユーザーは Hijack を呼び出してはいけません。

func (*ServerConn) Pending

func (sc *ServerConn) Pending() int

Pending は,接続で受信された未レスポンスのリクエストの数を返します。

func (*ServerConn) Read

func (sc *ServerConn) Read() (*http.Request, error)

Read はワイヤ上の次のリクエストを返します。 ErrPersistEOF は,それ以上リクエストがないと適切に判断された場合 (たとえば, HTTP/1.0 接続での最初のリクエストの後,または Connection:HTTP/1.1 接続での終了後) に返されます。

func (*ServerConn) Write

func (sc *ServerConn) Write(req *http.Request, resp *http.Response) error

Write は req に応じて書き込みます。 接続を適切に閉じるには, Response.Close フィールドを true に設定します。 読み取り側で返されたエラーに関係なく,書き込みはエラーを返すまで操作可能と見なす必要があります。