使用go语言写的简单的http服务器程序,支持https代理以及直连。话不多说,直接上代码。
package main import ( "bytes" "log" "net" "io" "net/url" "runtime" "strings" ) func main() { runtime.GOMAXPROCS(1) log.SetFlags(log.LstdFlags | log.Lshortfile) log.Println("version: " + runtime.Version()) HttpAccept(8888) } func HttpAccept (port int) { tcpaddr := &net.TCPAddr{ IP: []byte{0, 0, 0, 0}, Port: port, Zone: "", } l, err := net.ListenTCP("tcp", tcpaddr) if err != nil { log.Println(err) return } for { client, err := l.AcceptTCP() if err != nil { log.Println(err) l.Close() return } go HttpProxyRequest(client) } } func HttpProxyRequest (client *net.TCPConn) { client.SetReadBuffer(32*1024) client.SetWriteBuffer(32*1024) b := make([]byte, 32*1024) n, err := client.Read(b) if err != nil { log.Println(err) client.Close() return } maddr := bytes.IndexByte(b, ' ') method := string(b[:maddr]) host := string(b[maddr+1:maddr+1+bytes.IndexByte(b[maddr+1:], ' ')]) if method == "CONNECT" { log.Println(host) tcpaddr, err := net.ResolveTCPAddr("tcp", host) if err != nil { log.Println(err) client.Close() return } server, err := net.DialTCP("tcp", nil, tcpaddr) if err != nil { log.Println(err) client.Close() return } server.SetReadBuffer(32*1024) server.SetWriteBuffer(32*1024) _, err = client.Write([]byte("HTTP/1.1 200 Connection established\r\n\r\n")) if err != nil { log.Println(err) client.Close() server.Close() return } go IoCopy(client, server) go IoCopy(server, client) } else { hostPortURL, err := url.Parse(host) if err != nil { log.Println(err) client.Close() return } address := hostPortURL.Host if strings.Index(address, ":") == -1 { address = address + ":80" } log.Println(address) tcpaddr, err := net.ResolveTCPAddr("tcp", address) if err != nil { log.Println(err) client.Close() return } server, err := net.DialTCP("tcp", nil, tcpaddr) if err != nil { log.Println(err) client.Close() return } server.SetReadBuffer(32*1024) server.SetWriteBuffer(32*1024) httpheadlen := bytes.Index(b, []byte("\r\n\r\n"))+4 httphead := b[:httpheadlen] start := bytes.Index(httphead, []byte(hostPortURL.Host)) + len(hostPortURL.Host) if start != -1 { httphead = append(httphead[:maddr+1], httphead[start:]...) } start = bytes.Index(httphead, []byte("Proxy-Connection:")) if start != -1 { httphead = append(httphead[:start], httphead[start+6:]...) } if httpheadlen < n { b = append(httphead, b[httpheadlen:n]...) } else { b = httphead } _, err = server.Write(b) if err != nil { log.Println(err) client.Close() server.Close() return } go IoCopy(client, server) go IoCopy(server, client) } } func IoCopy(dst *net.TCPConn, src *net.TCPConn) { io.Copy(dst, src) dst.Close() }
一共134行,编译后可直接使用。
文章作者:沃航科技