_http.Handler
_インターフェイスを実装する型があり、そのServeHTTP
メソッドで、着信HTTP要求が検査され、何らかのアクションが実行され、その後、要求がリバースプロキシハンドラーに転送されます(_httputil.NewSingleHostReverseProxy
_)。
これは、URLやヘッダーなどの基本的なリクエストプロパティのみを検査している限り、正常に機能します。
たとえば、req.ParseForm()
を呼び出してから_req.Form
_プロパティを使用して、着信POST要求の本文を検査したい場合、エラーが発生します要求はリバースプロキシに渡されます。
_
http: proxy error: http: Request.ContentLength=687 with Body length 0
_
HTTPリクエストの本文を見ると_req.Body.Reader
_ストリームが排出され、プロキシハンドラーで再度読み取ることができないため、これが起こると思います。
私はio.Copy()
やbufio.Peek()
のようなもので遊んでいますが、実際にはどこにも行きません。
元の要求オブジェクトを元の状態のままにして、HTTPリクエストボディを覗いて(および_req.ParseForm
_などの組み込み解析を使用する)方法があります。これにより、リバースプロキシに渡すことができます。 ?
バッファに読み込んでから、バッファを使用して2つの新しいリーダーをバックアップしてみてください。1つは自分用、もう1つは後続のコンシューマ用です。たとえば、次のコードを変更するとします。
_doStuff(r.Body) // r is an http.Request
_
できること:
_buf, _ := ioutil.ReadAll(r.Body)
rdr1 := ioutil.NopCloser(bytes.NewBuffer(buf))
rdr2 := ioutil.NopCloser(bytes.NewBuffer(buf))
doStuff(rdr1)
r.Body = rdr2 // OK since rdr2 implements the io.ReadCloser interface
// Now the program can continue oblivious to the fact that
// r.Body was ever touched.
_
_*bytes.Buffer
_にはClose() error
メソッドがないため、_io.ReadCloser
_インターフェイスを実装しないことに注意してください。したがって、_*bytes.Buffer
_の呼び出しで_ioutil.NopCloser
_値をラップする必要があります。