Commit 346c2c27 authored by rui.zheng's avatar rui.zheng

add HTTP2 proxy support

parent 1c76ca4b
......@@ -2,9 +2,13 @@ package main
import (
"bufio"
"crypto/tls"
"log"
"net/http"
"net/http/httputil"
"net/url"
"time"
"github.com/ginuerzh/gost/gost"
)
......@@ -85,36 +89,55 @@ func main() {
},
*/
// http+kcp
// http2
gost.Node{
Addr: "127.0.0.1:8388",
Addr: "127.0.0.1:1443",
Client: gost.NewClient(
gost.HTTPConnector(nil),
gost.KCPTransporter(nil),
gost.HTTP2Connector(url.UserPassword("admin", "123456")),
gost.HTTP2Transporter(
nil,
&tls.Config{InsecureSkipVerify: true},
time.Second*60,
),
),
},
/*
// http+kcp
gost.Node{
Addr: "127.0.0.1:8388",
Client: gost.NewClient(
gost.HTTPConnector(nil),
gost.KCPTransporter(nil),
),
},
*/
)
conn, err := chain.Dial("localhost:10000")
if err != nil {
log.Fatal(err)
}
//conn = tls.Client(conn, &tls.Config{InsecureSkipVerify: true})
req, err := http.NewRequest(http.MethodGet, "http://localhost:10000/pkg", nil)
if err != nil {
log.Fatal(err)
}
if err := req.Write(conn); err != nil {
log.Fatal(err)
}
resp, err := http.ReadResponse(bufio.NewReader(conn), req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
for i := 0; i < 10; i++ {
conn, err := chain.Dial("localhost:10000")
if err != nil {
log.Fatal(err)
}
//conn = tls.Client(conn, &tls.Config{InsecureSkipVerify: true})
req, err := http.NewRequest(http.MethodGet, "http://localhost:10000/pkg", nil)
if err != nil {
log.Fatal(err)
}
if err := req.Write(conn); err != nil {
log.Fatal(err)
}
resp, err := http.ReadResponse(bufio.NewReader(conn), req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
rb, _ := httputil.DumpRequest(req, true)
log.Println(string(rb))
rb, _ = httputil.DumpResponse(resp, true)
log.Println(string(rb))
rb, _ := httputil.DumpRequest(req, true)
log.Println(string(rb))
rb, _ = httputil.DumpResponse(resp, true)
log.Println(string(rb))
time.Sleep(100 * time.Millisecond)
}
}
......@@ -63,6 +63,8 @@ type Connector interface {
type Transporter interface {
Dial(addr string) (net.Conn, error)
Handshake(conn net.Conn) (net.Conn, error)
// Indicate that the Transporter supports multiplex
Multiplex() bool
}
type tcpTransporter struct {
......@@ -80,3 +82,7 @@ func (tr *tcpTransporter) Dial(addr string) (net.Conn, error) {
func (tr *tcpTransporter) Handshake(conn net.Conn) (net.Conn, error) {
return conn, nil
}
func (tr *tcpTransporter) Multiplex() bool {
return false
}
......@@ -28,6 +28,10 @@ var (
ReadTimeout = 30 * time.Second
// WriteTimeout is the timeout for writing.
WriteTimeout = 60 * time.Second
// PingTimeout is the timeout for pinging.
PingTimeout = 30 * time.Second
// PingRetries is the reties of ping.
PingRetries = 3
// default udp node TTL in second for udp port forwarding.
defaultTTL = 60
)
......
......@@ -110,21 +110,8 @@ func (h *httpHandler) Handle(conn net.Conn) {
return
}
valid := false
u, p, _ := h.basicProxyAuth(req.Header.Get("Proxy-Authorization"))
users := h.options.Users
for _, user := range users {
username := user.Username()
password, _ := user.Password()
if (u == username && p == password) ||
(u == username && password == "") ||
(username == "" && p == password) {
valid = true
break
}
}
if len(users) > 0 && !valid {
u, p, _ := basicProxyAuth(req.Header.Get("Proxy-Authorization"))
if !authenticate(u, p, h.options.Users...) {
log.Logf("[http] %s <- %s : proxy authentication required", conn.RemoteAddr(), req.Host)
resp := "HTTP/1.1 407 Proxy Authentication Required\r\n" +
"Proxy-Authenticate: Basic realm=\"gost\"\r\n" +
......@@ -182,7 +169,7 @@ func (h *httpHandler) Handle(conn net.Conn) {
log.Logf("[http] %s >-< %s", conn.RemoteAddr(), req.Host)
}
func (h *httpHandler) basicProxyAuth(proxyAuth string) (username, password string, ok bool) {
func basicProxyAuth(proxyAuth string) (username, password string, ok bool) {
if proxyAuth == "" {
return
}
......@@ -202,3 +189,20 @@ func (h *httpHandler) basicProxyAuth(proxyAuth string) (username, password strin
return cs[:s], cs[s+1:], true
}
func authenticate(username, password string, users ...*url.Userinfo) bool {
if len(users) == 0 {
return true
}
for _, user := range users {
u := user.Username()
p, _ := user.Password()
if (u == username && p == password) ||
(u == username && p == "") ||
(u == "" && p == password) {
return true
}
}
return false
}
This diff is collapsed.
......@@ -196,7 +196,7 @@ func (tr *kcpTransporter) Dial(addr string) (conn net.Conn, err error) {
if err != nil {
tr.sessionMutex.Lock()
session.Close()
delete(tr.sessions, addr)
delete(tr.sessions, addr) // TODO: we could obtain a new session automatically.
tr.sessionMutex.Unlock()
}
return
......@@ -245,6 +245,10 @@ func (tr *kcpTransporter) Handshake(conn net.Conn) (net.Conn, error) {
return conn, nil
}
func (tr *kcpTransporter) Multiplex() bool {
return true
}
type kcpListener struct {
config *KCPConfig
ln *kcp.Listener
......
......@@ -15,17 +15,18 @@ func init() {
}
func main() {
go httpServer()
go socks5Server()
go tlsServer()
go shadowServer()
go wsServer()
go wssServer()
go kcpServer()
go tcpForwardServer()
go rtcpForwardServer()
// go httpServer()
// go socks5Server()
// go tlsServer()
// go shadowServer()
// go wsServer()
// go wssServer()
// go kcpServer()
// go tcpForwardServer()
// go rtcpForwardServer()
// go rudpForwardServer()
go tcpRedirectServer()
// go tcpRedirectServer()
go http2Server()
select {}
}
......@@ -43,15 +44,10 @@ func httpServer() {
}
func socks5Server() {
cert, err := tls.LoadX509KeyPair("cert.pem", "key.pem")
if err != nil {
log.Fatal(err)
}
s := &gost.Server{}
s.Handle(gost.SOCKS5Handler(
gost.UsersHandlerOption(url.UserPassword("admin", "123456")),
gost.TLSConfigHandlerOption(&tls.Config{Certificates: []tls.Certificate{cert}}),
gost.TLSConfigHandlerOption(tlsConfig()),
))
ln, err := gost.TCPListener(":1080")
if err != nil {
......@@ -77,11 +73,7 @@ func tlsServer() {
s.Handle(gost.HTTPHandler(
gost.UsersHandlerOption(url.UserPassword("admin", "123456")),
))
cert, err := tls.LoadX509KeyPair("cert.pem", "key.pem")
if err != nil {
log.Fatal(err)
}
ln, err := gost.TLSListener(":1443", &tls.Config{Certificates: []tls.Certificate{cert}})
ln, err := gost.TLSListener(":1443", tlsConfig())
if err != nil {
log.Fatal(err)
}
......@@ -105,12 +97,7 @@ func wssServer() {
s.Handle(gost.HTTPHandler(
gost.UsersHandlerOption(url.UserPassword("admin", "123456")),
))
cert, err := tls.LoadX509KeyPair("cert.pem", "key.pem")
if err != nil {
log.Fatal(err)
}
ln, err := gost.WSSListener(":8443", &gost.WSOptions{TLSConfig: &tls.Config{Certificates: []tls.Certificate{cert}}})
ln, err := gost.WSSListener(":8443", &gost.WSOptions{TLSConfig: tlsConfig()})
if err != nil {
log.Fatal(err)
}
......@@ -194,3 +181,26 @@ func tcpRedirectServer() {
}
log.Fatal(s.Serve(ln))
}
func http2Server() {
// http2.VerboseLogs = true
s := &gost.Server{}
s.Handle(gost.HTTP2Handler(
gost.UsersHandlerOption(url.UserPassword("admin", "123456")),
))
ln, err := gost.TLSListener(":1443", tlsConfig())
// ln, err := gost.TCPListener(":1443")
if err != nil {
log.Fatal(err)
}
log.Fatal(s.Serve(ln))
}
func tlsConfig() *tls.Config {
cert, err := tls.LoadX509KeyPair("cert.pem", "key.pem")
if err != nil {
panic(err)
}
return &tls.Config{Certificates: []tls.Certificate{cert}}
}
package gost
......@@ -6,13 +6,13 @@ import (
)
type tlsTransporter struct {
TLSClientConfig *tls.Config
tlsConfig *tls.Config
}
// TLSTransporter creates a Transporter that is used by TLS proxy client.
// It accepts a TLS config for TLS handshake.
func TLSTransporter(cfg *tls.Config) Transporter {
return &tlsTransporter{TLSClientConfig: cfg}
return &tlsTransporter{tlsConfig: cfg}
}
func (tr *tlsTransporter) Dial(addr string) (net.Conn, error) {
......@@ -20,7 +20,11 @@ func (tr *tlsTransporter) Dial(addr string) (net.Conn, error) {
}
func (tr *tlsTransporter) Handshake(conn net.Conn) (net.Conn, error) {
return tls.Client(conn, tr.TLSClientConfig), nil
return tls.Client(conn, tr.tlsConfig), nil
}
func (tr *tlsTransporter) Multiplex() bool {
return false
}
type tlsListener struct {
......@@ -33,5 +37,5 @@ func TLSListener(addr string, config *tls.Config) (Listener, error) {
if err != nil {
return nil, err
}
return &tlsListener{Listener: ln}, nil
return &tlsListener{ln}, nil
}
......@@ -120,6 +120,10 @@ func (tr *wsTransporter) Handshake(conn net.Conn) (net.Conn, error) {
return websocketClientConn(url.String(), conn, tr.options)
}
func (tr *wsTransporter) Multiplex() bool {
return false
}
type wssTransporter struct {
addr string
options *WSOptions
......@@ -142,6 +146,10 @@ func (tr *wssTransporter) Handshake(conn net.Conn) (net.Conn, error) {
return websocketClientConn(url.String(), conn, tr.options)
}
func (tr *wssTransporter) Multiplex() bool {
return false
}
type wsListener struct {
addr net.Addr
upgrader *websocket.Upgrader
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment