mirror of
https://git.phreedom.club/localhost_frssoft/compy.git
synced 2024-11-23 16:41:30 +00:00
add http2 support
Add http2 using the go-1.6 net/http built-in support. net/http's http2 doesn't support hijacking, so instead of hijacking the inital CONNECT tcp connection, tunnel proxied requests/responses over the reader and writer streams of the CONNECT request.
This commit is contained in:
parent
6dae9bda0c
commit
a4a691b7b8
74
proxy/mitmconn.go
Normal file
74
proxy/mitmconn.go
Normal file
|
@ -0,0 +1,74 @@
|
|||
package proxy
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
type mitmConn struct {
|
||||
w FlushWriter
|
||||
r io.Reader
|
||||
remoteAddr addr
|
||||
closed chan struct{}
|
||||
}
|
||||
|
||||
type FlushWriter interface {
|
||||
io.Writer
|
||||
http.Flusher
|
||||
}
|
||||
|
||||
func newMitmConn(w FlushWriter, r io.Reader, remoteAddr string) *mitmConn {
|
||||
return &mitmConn{
|
||||
w: w,
|
||||
r: r,
|
||||
remoteAddr: addr(remoteAddr),
|
||||
closed: make(chan struct{}),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *mitmConn) Read(b []byte) (int, error) {
|
||||
return c.r.Read(b)
|
||||
}
|
||||
|
||||
func (c *mitmConn) Write(b []byte) (int, error) {
|
||||
n, err := c.w.Write(b)
|
||||
c.w.Flush()
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (c *mitmConn) Close() error {
|
||||
close(c.closed)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *mitmConn) RemoteAddr() net.Addr {
|
||||
return c.remoteAddr
|
||||
}
|
||||
|
||||
func (c *mitmConn) LocalAddr() net.Addr {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
func (c *mitmConn) SetDeadline(t time.Time) error {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
func (c *mitmConn) SetReadDeadline(t time.Time) error {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
func (c *mitmConn) SetWriteDeadline(t time.Time) error {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
type addr string
|
||||
|
||||
func (a addr) String() string {
|
||||
return string(a)
|
||||
}
|
||||
|
||||
func (a addr) Network() string {
|
||||
return "tcp"
|
||||
}
|
|
@ -53,7 +53,7 @@ func (p *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
func (p *Proxy) handle(w http.ResponseWriter, r *http.Request) error {
|
||||
if r.Method == "CONNECT" {
|
||||
return p.handleConnect(w, r.Host)
|
||||
return p.handleConnect(w, r)
|
||||
}
|
||||
resp, err := forward(r)
|
||||
if err != nil {
|
||||
|
@ -88,24 +88,19 @@ func (p *Proxy) proxyResponse(w *ResponseWriter, r *ResponseReader) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (p *Proxy) handleConnect(w http.ResponseWriter, host string) error {
|
||||
func (p *Proxy) handleConnect(w http.ResponseWriter, r *http.Request) error {
|
||||
if p.ml == nil {
|
||||
return fmt.Errorf("CONNECT received but mitm is not enabled")
|
||||
}
|
||||
h, ok := w.(http.Hijacker)
|
||||
if !ok {
|
||||
return fmt.Errorf("connection cannot be hijacked")
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
conn, _, err := h.Hijack()
|
||||
fw := w.(FlushWriter)
|
||||
fw.Flush()
|
||||
conn := newMitmConn(fw, r.Body, r.RemoteAddr)
|
||||
sconn, err := p.ml.Serve(conn, r.Host)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sconn, err := p.ml.Serve(conn, host)
|
||||
if err != nil {
|
||||
conn.Close()
|
||||
return err
|
||||
}
|
||||
sconn.Close() // TODO: reuse this connection for https requests
|
||||
<-conn.closed
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue