2017-09-18 6 views
-1

をログインしたときに、次のように私は私のmain.goでシンプルなリバースプロキシを作成しました:Golang DumpResponse gzipの問題レスポンスボディ(リバースプロキシ)

reverseproxy := httputil.NewSingleHostReverseProxy("https://someurl/someuri") 

これが正常に動作している、しかし、私は応答を記録したいと思いますそれはサーバーから戻ってきます。私はまた、golangが推奨する標準の往復のメソッド内に次のコードを利用し、これを行うことができます:gzipで、文字列はに表示されます。Content-エンコーディング時に一つのこと、応答、別に期待通り

response, err := http.DefaultTransport.RoundTrip(request) 
dumpresp, err := httputil.DumpResponse(response, true) 

if err != nil { 
    return nil, err 
} 
log.Printf("%s", dumpresp) 

上記のすべての作品そのログは非utf8 gzip文字です。それはgolang見落としであるようですが、多分私はいくつかの時間の完了に読んだドキュメントで逃した何かがあります。とにかくこのサイトに表示されないように、文字はutf8ではないので、ここにログを投稿することはできません。だから、私はあなたの考えを知っている、ちょうどgzipのコンテンツをつかんで、gzip圧縮を削除する方法を使用する。 DumpResponseからの応答が部分的にgzipではなく、部分的にutf8で部分を区切る方法がない場合は、これは素晴らしいことです。

私はあなたの言うことを知っています。なぜなら、以下のような生のレスポンスとgzipデコードを取るだけでなく、DumpResponseを使用しないのです。さて、私は同様にそれを行うことができますが、以下の場合には問題があります:

var reader io.Reader 
startreader := httputility.NewChunkedReader(reader) 
switch response.Header.Get("Content-Encoding") { 
case "gzip": 
    startreader, err = gzip.NewReader(response.Body) 
    log.Println("Response body gzip: ") 
    buf := new(bytes.Buffer) 
    buf.ReadFrom(startreader) 
    b := buf.Bytes() 
    s := *(*string)(unsafe.Pointer(&b)) 
    for name, value := range response.Header { 
     var hvaluecomp string = "" 
     for i := 0; i < len(value); i++ { 
      hvaluecomp += value[i] 
     } 
     response.Header.Add(name,hvaluecomp) 
    } 
    log.Printf("%s", s) 



default: 
    startreader = response.Body 
    buf := new(bytes.Buffer) 
    buf.ReadFrom(startreader) 
    b := buf.Bytes() 
    s := *(*string)(unsafe.Pointer(&b)) 
    for name, value := range response.Header { 
     fmt.Printf("%v: %v\n", name, value) 
    } 
    log.Printf("%s", s) 
} 

上記の問題は、応答がで読み取ることができない後に応答が唯一、リーダーを経由して1時間を読み取ることができ、ありますリバースプロキシはもう使用できなくなり、プロキシレスポンスがブラウザのnil =に戻ってしまいますので、やはり失敗しました。私はgolangをコーディングしている人々がgzipのデコードを見逃していただろうと想像できません。ちょっと変わって、それはとても簡単です。

私の質問は、DumpResponseは私にgzipを解凍する能力を与えるので、utf8以外の文字ではなく実際の応答を記録できるのですか?これは、プロダクション製品の問題をデバッグする際にログリーダーがうまくいかないことを意味します。これは、私の目の中でgolangリバースプロキシを無駄にすることになり、自分で開発を始めるでしょう。

答えて

0

DumpResponseは私にはありません、それはないのgzip

を解凍する能力を与えません。

私にとっては、リバースプロキシもDumpResponseでもなく、バイナリデータを「ログ」しようとしているようです。gzipや画像のような他のバイナリデータにしてください。あなたのロギングロジックを修正してください:生のボディがバイナリの場合は、何らかの表現や変換を行う必要があります。 gziped stuff gunzipの場合は、最初に(しかしこれはまだログには不適切なバイナリの "non utf8"のデータかもしれません)。実際の問題に焦点を当てる:バイナリデータを "ログ"する方法。

+0

と* 'のようなものをやって停止してください(*文字列)(unsafe.Pointer(&b)) '。お願いします。 – Volker

+0

あなたはこの質問を読んだことがあります。私が応答から得た情報は動的です。私はそれを支配しません。私がこのサイトに投稿してもらえれば質問しました。あなたは少なくとも質問に答えることができますか? – code

+0

私はバイナリデータをログに記録しようとしていませんが、データを変換しようとしていますが、実際にインテリジェントな答えを出す前に明確に定義された質問を理解する必要があると思います。 – code

0

答えはストリームをコピーすることです。次に、2番目の変数を使用してストリームをrequest.bodyオブジェクトに再ポストして、データを失わないようにすることができます。

buf, _ := ioutil.ReadAll(response.Body) 
responseuse1 := ioutil.NopCloser(bytes.NewBuffer(buf)) 
responsehold := ioutil.NopCloser(bytes.NewBuffer(buf)) 

ログをプルする方法:extractLogging(responseuse1)その手つかずのよう後ろ身頃にホールドを押し :response.Body = responsehold

戻り応答

関連する問題