mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2026-01-11 01:25:11 +08:00
81 lines
1.8 KiB
Go
81 lines
1.8 KiB
Go
package ssh
|
|
|
|
import (
|
|
"bufio"
|
|
"crypto/tls"
|
|
"encoding/base64"
|
|
"fmt"
|
|
"net"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/1Panel-dev/1Panel/core/global"
|
|
)
|
|
|
|
type HTTPProxyDialer struct {
|
|
Type string
|
|
URL string
|
|
User string
|
|
Password string
|
|
}
|
|
|
|
func HTTPDial(dialer HTTPProxyDialer, network, addr string) (net.Conn, error) {
|
|
var conn net.Conn
|
|
var err error
|
|
|
|
global.LOG.Debugf("Dialing HTTP proxy %s for %s", dialer.URL, addr)
|
|
dialer.URL = strings.TrimPrefix(dialer.URL, dialer.Type+"://")
|
|
if dialer.Type == "https" {
|
|
conn, err = tls.DialWithDialer(
|
|
&net.Dialer{Timeout: 30 * time.Second},
|
|
network,
|
|
dialer.URL,
|
|
&tls.Config{InsecureSkipVerify: true},
|
|
)
|
|
} else {
|
|
conn, err = net.DialTimeout(network, dialer.URL, 30*time.Second)
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
conn.SetDeadline(time.Now().Add(30 * time.Second))
|
|
connectReq := fmt.Sprintf("CONNECT %s HTTP/1.1\r\n", addr)
|
|
connectReq += fmt.Sprintf("Host: %s\r\n", addr)
|
|
connectReq += "User-Agent: Go-ssh-client/1.0\r\n"
|
|
|
|
if dialer.User != "" {
|
|
auth := base64.StdEncoding.EncodeToString(
|
|
[]byte(dialer.User + ":" + dialer.Password),
|
|
)
|
|
connectReq += fmt.Sprintf("Proxy-Authorization: Basic %s\r\n", auth)
|
|
}
|
|
connectReq += "Connection: keep-alive\r\n\r\n"
|
|
if _, err := conn.Write([]byte(connectReq)); err != nil {
|
|
conn.Close()
|
|
return nil, err
|
|
}
|
|
reader := bufio.NewReader(conn)
|
|
response, err := reader.ReadString('\n')
|
|
if err != nil {
|
|
conn.Close()
|
|
return nil, err
|
|
}
|
|
if !strings.HasPrefix(response, "HTTP/1.1 200") &&
|
|
!strings.HasPrefix(response, "HTTP/1.0 200") {
|
|
conn.Close()
|
|
return nil, fmt.Errorf("proxy connection failed: %s", strings.TrimSpace(response))
|
|
}
|
|
for {
|
|
line, err := reader.ReadString('\n')
|
|
if err != nil {
|
|
conn.Close()
|
|
return nil, err
|
|
}
|
|
if line == "\r\n" || line == "\n" {
|
|
break
|
|
}
|
|
}
|
|
conn.SetDeadline(time.Time{})
|
|
|
|
return conn, nil
|
|
}
|