package wsutil
import (
"bufio"
"bytes"
"context"
"io"
"io/ioutil"
"net"
"net/http"
"github.com/gobwas/ws"
)
type DebugDialer struct {
Dialer ws .Dialer
OnRequest, OnResponse func ([]byte )
}
func (d *DebugDialer ) Dial (ctx context .Context , urlstr string ) (conn net .Conn , br *bufio .Reader , hs ws .Handshake , err error ) {
dialer := d .Dialer
var (
reqBuf bytes .Buffer
resBuf bytes .Buffer
resContentLength int64
)
userWrap := dialer .WrapConn
dialer .WrapConn = func (c net .Conn ) net .Conn {
if userWrap != nil {
c = userWrap (c )
}
conn = c
var (
r io .Reader = conn
w io .Writer = conn
)
if d .OnResponse != nil {
r = &prefetchResponseReader {
source : conn ,
buffer : &resBuf ,
contentLength : &resContentLength ,
}
}
if d .OnRequest != nil {
w = io .MultiWriter (conn , &reqBuf )
}
return rwConn {conn , r , w }
}
_, br , hs , err = dialer .Dial (ctx , urlstr )
if onRequest := d .OnRequest ; onRequest != nil {
onRequest (reqBuf .Bytes ())
}
if onResponse := d .OnResponse ; onResponse != nil {
p := resBuf .Bytes ()
n := bytes .Index (p , headEnd )
h := n + len (headEnd )
n = h + int (resContentLength )
onResponse (p [:n ])
if br != nil {
var r io .Reader = conn
if len (p ) > h {
r = io .MultiReader (
bytes .NewReader (p [h :]),
conn ,
)
}
br .Reset (r )
br .Peek (len (p [h :]))
}
}
return conn , br , hs , err
}
type rwConn struct {
net .Conn
r io .Reader
w io .Writer
}
func (rwc rwConn ) Read (p []byte ) (int , error ) {
return rwc .r .Read (p )
}
func (rwc rwConn ) Write (p []byte ) (int , error ) {
return rwc .w .Write (p )
}
var headEnd = []byte ("\r\n\r\n" )
type prefetchResponseReader struct {
source io .Reader
reader io .Reader
buffer *bytes .Buffer
contentLength *int64
}
func (r *prefetchResponseReader ) Read (p []byte ) (int , error ) {
if r .reader == nil {
resp , err := http .ReadResponse (bufio .NewReader (
io .TeeReader (r .source , r .buffer ),
), nil )
if err == nil {
*r .contentLength , _ = io .Copy (ioutil .Discard , resp .Body )
resp .Body .Close ()
}
bts := r .buffer .Bytes ()
r .reader = io .MultiReader (
bytes .NewReader (bts ),
r .source ,
)
}
return r .reader .Read (p )
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .