| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 | package httpimport (	"bufio"	"net"	"net/http"	"strconv"	"strings"	"github.com/v2ray/v2ray-core/app"	"github.com/v2ray/v2ray-core/common/alloc"	"github.com/v2ray/v2ray-core/common/log"	v2net "github.com/v2ray/v2ray-core/common/net")type HttpProxyServer struct {	accepting bool	space     app.Space	config    Config}func NewHttpProxyServer(space app.Space, config Config) *HttpProxyServer {	return &HttpProxyServer{		space:  space,		config: config,	}}func (this *HttpProxyServer) Listen(port v2net.Port) error {	tcpListener, err := net.ListenTCP("tcp", &net.TCPAddr{		Port: int(port.Value()),		IP:   []byte{0, 0, 0, 0},	})	if err != nil {		return err	}	go this.accept(tcpListener)	return nil}func (this *HttpProxyServer) accept(listener *net.TCPListener) {	this.accepting = true	for this.accepting {		tcpConn, err := listener.AcceptTCP()		if err != nil {			log.Error("Failed to accept HTTP connection: %v", err)			continue		}		go this.handleConnection(tcpConn)	}}func parseHost(rawHost string) (v2net.Address, error) {	port := v2net.Port(80)	host, rawPort, err := net.SplitHostPort(rawHost)	if err != nil {		if addrError, ok := err.(*net.AddrError); ok && strings.Contains(addrError.Err, "missing port") {			host = rawHost			port = v2net.Port(80)		} else {			return nil, err		}	}	intPort, err := strconv.Atoi(rawPort)	if err != nil {		return nil, err	}	port = v2net.Port(intPort)	if ip := net.ParseIP(host); ip != nil {		return v2net.IPAddress(ip, port), nil	}	return v2net.DomainAddress(host, port), nil}func (this *HttpProxyServer) handleConnection(conn *net.TCPConn) {	httpReader := bufio.NewReader(conn)	request, err := http.ReadRequest(httpReader)	if err != nil {		log.Warning("Malformed HTTP request: %v", err)		return	}	if strings.ToUpper(request.Method) == "CONNECT" {		address, err := parseHost(request.Host)		if err != nil {			log.Warning("Malformed proxy host: %v", err)			return		}		response := &http.Response{			Status:        "200 OK",			StatusCode:    200,			Proto:         "HTTP/1.1",			ProtoMajor:    1,			ProtoMinor:    1,			Header:        http.Header(make(map[string][]string)),			Body:          nil,			ContentLength: 0,			Close:         false,		}		buffer := alloc.NewSmallBuffer().Clear()		response.Write(buffer)		conn.Write(buffer.Value)		packet := v2net.NewPacket(v2net.NewTCPDestination(address), nil, true)		this.space.PacketDispatcher().DispatchToOutbound(packet)	}}
 |