とここで聞きました
応答に何かを書き込むと、要求本文が閉じられ、そこから何も読み取ることができなくなります
それが本当なら、 node.js で人々が行うのと同じように、ストリーミング形式で、リクエスト本文から読み取り、何らかの変換を行い、レスポンス本文に書き込むことができる適切な二重ハンドラーを作成するにはどうすればよいですか?
私はなんとかこれを行うことができましたhttp.Hijacker
。
リクエストが作成され、リクエスト ヘッダーが解析された後、次のように から読み取り*http.Request.Body
、接続をハイジャックして書き込むことができます。
hj, ok := w.(http.Hijacker)
if !ok {
http.Error(w, "hijacking not supported", 500)
return
}
conn, bufrw, err := hj.Hijack()
if err != nil {
http.Error(w, err.Error(), 500)
return
}
defer conn.Close()
そして、クライアントへの基礎となる TCP 接続である はでconn
あり、ボディを閉じずに応答を書き込むには、私がしなければならないことはnet.Conn
bufrw
*bufio.ReadWriter
_, err = bufrw.WriteString("HTTP/1.1 200 OK\n\n")
_, err = bufrw.WriteString("this")
_, err = bufrw.WriteString("is")
_, err = bufrw.WriteString("the")
_, err = bufrw.WriteString("response")
_, err = bufrw.WriteString("body")
そして、私はこれについて確信が持てませんが、誰かが答えを完成させることができるかもしれません。
err := bufrw.Flush()
参照しているnet/http ドキュメントから
var ErrBodyReadAfterClose = errors.New("http: 閉じた Body の無効な読み取り")
ErrBodyReadAfterClose は、ボディが閉じられた後に Request または Response Body を読み取るときに返されます。これは通常、HTTP ハンドラーがその ResponseWriter で WriteHeader または Write を呼び出した後に本文が読み取られるときに発生します。
ただし、あなたが言及したブログ記事からリンクされたコードを試してみましたが、最初に約 4k 以上のデータを書き込まない限り、go 1.1.2 で正常に動作しr.ParseForm()
ますErrBodyReadAfterClose
。
したがって、答えはノーだと思います。応答が短い場合 (4k 未満) でない限り、一般的に全二重 HTTP を実行することはできません。
ほとんどのクライアントはリクエストの送信が完了するまでレスポンスからの読み取りを試みないため、全二重 HTTP リクエストを実行することは大きなメリットにはなりそうにないと思います。クライアントとサーバーのバッファ。これらのバッファーを超えると、デッドロックが発生する可能性があります。