TUN-5837: Log panic recovery in http2 logic with debug level log
This commit is contained in:
parent
d17a61c15b
commit
7220c2c214
|
@ -100,7 +100,7 @@ func (c *HTTP2Connection) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
connType := determineHTTP2Type(r)
|
connType := determineHTTP2Type(r)
|
||||||
handleMissingRequestParts(connType, r)
|
handleMissingRequestParts(connType, r)
|
||||||
|
|
||||||
respWriter, err := NewHTTP2RespWriter(r, w, connType)
|
respWriter, err := NewHTTP2RespWriter(r, w, connType, c.log)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.observer.log.Error().Msg(err.Error())
|
c.observer.log.Error().Msg(err.Error())
|
||||||
return
|
return
|
||||||
|
@ -163,14 +163,16 @@ type http2RespWriter struct {
|
||||||
w http.ResponseWriter
|
w http.ResponseWriter
|
||||||
flusher http.Flusher
|
flusher http.Flusher
|
||||||
shouldFlush bool
|
shouldFlush bool
|
||||||
|
log *zerolog.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHTTP2RespWriter(r *http.Request, w http.ResponseWriter, connType Type) (*http2RespWriter, error) {
|
func NewHTTP2RespWriter(r *http.Request, w http.ResponseWriter, connType Type, log *zerolog.Logger) (*http2RespWriter, error) {
|
||||||
flusher, isFlusher := w.(http.Flusher)
|
flusher, isFlusher := w.(http.Flusher)
|
||||||
if !isFlusher {
|
if !isFlusher {
|
||||||
respWriter := &http2RespWriter{
|
respWriter := &http2RespWriter{
|
||||||
r: r.Body,
|
r: r.Body,
|
||||||
w: w,
|
w: w,
|
||||||
|
log: log,
|
||||||
}
|
}
|
||||||
respWriter.WriteErrorResponse()
|
respWriter.WriteErrorResponse()
|
||||||
return nil, fmt.Errorf("%T doesn't implement http.Flusher", w)
|
return nil, fmt.Errorf("%T doesn't implement http.Flusher", w)
|
||||||
|
@ -181,6 +183,7 @@ func NewHTTP2RespWriter(r *http.Request, w http.ResponseWriter, connType Type) (
|
||||||
w: w,
|
w: w,
|
||||||
flusher: flusher,
|
flusher: flusher,
|
||||||
shouldFlush: connType.shouldFlush(),
|
shouldFlush: connType.shouldFlush(),
|
||||||
|
log: log,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,7 +242,7 @@ func (rp *http2RespWriter) Write(p []byte) (n int, err error) {
|
||||||
// Implementer of OriginClient should make sure it doesn't write to the connection after Proxy returns
|
// Implementer of OriginClient should make sure it doesn't write to the connection after Proxy returns
|
||||||
// Register a recover routine just in case.
|
// Register a recover routine just in case.
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
println(fmt.Sprintf("Recover from http2 response writer panic, error %s", debug.Stack()))
|
rp.log.Debug().Msgf("Recover from http2 response writer panic, error %s", debug.Stack())
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
n, err = rp.w.Write(p)
|
n, err = rp.w.Write(p)
|
||||||
|
|
|
@ -332,7 +332,8 @@ func proxyHTTP(t *testing.T, originProxy connection.OriginProxy, hostname string
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
respWriter, err := connection.NewHTTP2RespWriter(req, w, connection.TypeHTTP)
|
log := zerolog.Nop()
|
||||||
|
respWriter, err := connection.NewHTTP2RespWriter(req, w, connection.TypeHTTP, &log)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = originProxy.ProxyHTTP(respWriter, req, false)
|
err = originProxy.ProxyHTTP(respWriter, req, false)
|
||||||
|
@ -358,7 +359,8 @@ func proxyTCP(t *testing.T, originProxy connection.OriginProxy, originAddr strin
|
||||||
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("http://%s", originAddr), reqBody)
|
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("http://%s", originAddr), reqBody)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
respWriter, err := connection.NewHTTP2RespWriter(req, w, connection.TypeTCP)
|
log := zerolog.Nop()
|
||||||
|
respWriter, err := connection.NewHTTP2RespWriter(req, w, connection.TypeTCP, &log)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
tcpReq := &connection.TCPRequest{
|
tcpReq := &connection.TCPRequest{
|
||||||
|
@ -578,7 +580,8 @@ func TestPersistentConnection(t *testing.T) {
|
||||||
// ProxyHTTP will add Connection, Upgrade and Sec-Websocket-Version headers
|
// ProxyHTTP will add Connection, Upgrade and Sec-Websocket-Version headers
|
||||||
req.Header.Add("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==")
|
req.Header.Add("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==")
|
||||||
|
|
||||||
respWriter, err := connection.NewHTTP2RespWriter(req, wsRespReadWriter, connection.TypeWebsocket)
|
log := zerolog.Nop()
|
||||||
|
respWriter, err := connection.NewHTTP2RespWriter(req, wsRespReadWriter, connection.TypeWebsocket, &log)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = originProxy.ProxyHTTP(respWriter, req, true)
|
err = originProxy.ProxyHTTP(respWriter, req, true)
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"runtime/debug"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -77,7 +78,7 @@ func unidirectionalStream(dst io.Writer, src io.Reader, dir string, status *bidi
|
||||||
// exited. In such case, we stop a possible panic from propagating upstream.
|
// exited. In such case, we stop a possible panic from propagating upstream.
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
// We handle such unexpected errors only when we detect that one side of the streaming is done.
|
// We handle such unexpected errors only when we detect that one side of the streaming is done.
|
||||||
log.Debug().Msgf("Handled gracefully error %v in Streaming for %s", r, dir)
|
log.Debug().Msgf("Gracefully handled error %v in Streaming for %s, error %s", r, dir, debug.Stack())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
Loading…
Reference in New Issue