Skip to content

Instantly share code, notes, and snippets.

@hightemp
Last active August 6, 2024 07:58
Show Gist options
  • Save hightemp/e15e1341558d11e4bc45bfc4fb273b39 to your computer and use it in GitHub Desktop.
Save hightemp/e15e1341558d11e4bc45bfc4fb273b39 to your computer and use it in GitHub Desktop.
simple https proxy on golang
package main
import (
"bufio"
"crypto/tls"
"fmt"
"io"
"log"
"net"
"strings"
)
// generate keys
// openssl req -x509 -newkey rsa:4096 -keyout server.key -out server.crt -days 365 -nodes
func main() {
// Загрузка сертификата и ключа
cert, err := tls.LoadX509KeyPair("server.crt", "server.key")
if err != nil {
log.Fatal("Failed to load certificate:", err)
}
// Конфигурация TLS
config := &tls.Config{
Certificates: []tls.Certificate{cert},
}
// Запуск HTTPS сервера
listener, err := tls.Listen("tcp", ":8443", config)
if err != nil {
log.Fatal("Failed to start HTTPS server:", err)
}
defer listener.Close()
fmt.Println("HTTPS Proxy server listening on :8443")
for {
conn, err := listener.Accept()
if err != nil {
log.Println("Failed to accept connection:", err)
continue
}
go handleConnection(conn)
}
}
func handleConnection(clientConn net.Conn) {
defer clientConn.Close()
reader := bufio.NewReader(clientConn)
requestLine, err := reader.ReadString('\n')
if err != nil {
log.Println("Error reading request:", err)
return
}
parts := strings.Split(strings.TrimSpace(requestLine), " ")
if len(parts) != 3 {
log.Println("Invalid request line:", requestLine)
return
}
method, host, version := parts[0], parts[1], parts[2]
if method == "CONNECT" {
handleHTTPS(clientConn, host)
} else {
handleHTTP(clientConn, method, host, version, reader)
}
}
func handleHTTP(clientConn net.Conn, method, host, version string, reader *bufio.Reader) {
if !strings.HasPrefix(host, "http://") {
host = "http://" + host
}
targetConn, err := net.Dial("tcp", host[7:])
if err != nil {
log.Println("Failed to connect to target:", err)
return
}
defer targetConn.Close()
fmt.Fprintf(targetConn, "%s %s %s\r\n", method, host, version)
go io.Copy(targetConn, reader)
io.Copy(clientConn, targetConn)
}
func handleHTTPS(clientConn net.Conn, host string) {
targetConn, err := net.Dial("tcp", host)
if err != nil {
log.Println("Failed to connect to target:", err)
clientConn.Write([]byte("HTTP/1.1 502 Bad Gateway\r\n\r\n"))
return
}
defer targetConn.Close()
clientConn.Write([]byte("HTTP/1.1 200 Connection Established\r\n\r\n"))
go io.Copy(targetConn, clientConn)
io.Copy(clientConn, targetConn)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment