浏览代码

refind http proxy

v2ray 10 年之前
父节点
当前提交
b3ec97058e
共有 1 个文件被更改,包括 74 次插入88 次删除
  1. 74 88
      proxy/http/http.go

+ 74 - 88
proxy/http/http.go

@@ -8,7 +8,6 @@ import (
 	"strconv"
 	"strings"
 	"sync"
-	"time"
 
 	"github.com/v2ray/v2ray-core/app"
 	"github.com/v2ray/v2ray-core/common/alloc"
@@ -85,111 +84,98 @@ func (this *HttpProxyServer) handleConnection(conn *net.TCPConn) {
 		if err != nil {
 			break
 		}
-		this.handleRequest(request, reader, conn)
-	}
-}
-
-func (this *HttpProxyServer) handleRequest(request *http.Request, reader io.Reader, writer io.Writer) {
-	log.Info("Request to Method [%s] Host [%s] with URL [%s]", request.Method, request.Host, request.URL.String())
-	defaultPort := v2net.Port(80)
-	if strings.ToLower(request.URL.Scheme) == "https" {
-		defaultPort = v2net.Port(443)
-	}
-	if strings.ToUpper(request.Method) == "CONNECT" {
-		address, err := parseHost(request.Host, defaultPort)
-		if err != nil {
-			log.Warning("Malformed proxy host: %v", err)
-			return
+		log.Info("Request to Method [%s] Host [%s] with URL [%s]", request.Method, request.Host, request.URL.String())
+		defaultPort := v2net.Port(80)
+		if strings.ToLower(request.URL.Scheme) == "https" {
+			defaultPort = v2net.Port(443)
 		}
-		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,
+		host := request.Host
+		if len(host) == 0 {
+			host = request.URL.Host
 		}
-
-		buffer := alloc.NewSmallBuffer().Clear()
-		response.Write(buffer)
-		writer.Write(buffer.Value)
-
-		packet := v2net.NewPacket(v2net.NewTCPDestination(address), nil, true)
-		ray := this.space.PacketDispatcher().DispatchToOutbound(packet)
-		this.transport(reader, writer, ray)
-	} else if len(request.URL.Host) > 0 {
-		address, err := parseHost(request.URL.Host, defaultPort)
+		address, err := parseHost(host, defaultPort)
 		if err != nil {
-			log.Warning("Malformed proxy host: %v", err)
-			return
+			log.Warning("Malformed proxy host (%s): %v", host, err)
 		}
-		request.Host = request.URL.Host
-		request.Header.Set("Connection", "keep-alive")
-		request.Header.Del("Proxy-Connection")
-		buffer := alloc.NewBuffer().Clear()
-		request.Write(buffer)
-		log.Info("Request to remote: %s", string(buffer.Value))
-		packet := v2net.NewPacket(v2net.NewTCPDestination(address), buffer, true)
-		ray := this.space.PacketDispatcher().DispatchToOutbound(packet)
-		defer close(ray.InboundInput())
-
-		responseReader := bufio.NewReader(NewChanReader(ray.InboundOutput()))
-		response, err := http.ReadResponse(responseReader, request)
-		if err != nil {
-			return
+		if strings.ToUpper(request.Method) == "CONNECT" {
+			this.handleConnect(request, address, reader, conn)
+		} else if len(request.URL.Host) > 0 {
+			request.Host = request.URL.Host
+			request.Header.Set("Connection", "keep-alive")
+			request.Header.Del("Proxy-Connection")
+			buffer := alloc.NewBuffer().Clear()
+			request.Write(buffer)
+			log.Info("Request to remote: %s", string(buffer.Value))
+			packet := v2net.NewPacket(v2net.NewTCPDestination(address), buffer, true)
+			ray := this.space.PacketDispatcher().DispatchToOutbound(packet)
+			defer close(ray.InboundInput())
+
+			responseReader := bufio.NewReader(NewChanReader(ray.InboundOutput()))
+			response, err := http.ReadResponse(responseReader, request)
+			if err != nil {
+				return
+			}
+
+			responseBuffer := alloc.NewBuffer().Clear()
+			response.Write(responseBuffer)
+			conn.Write(responseBuffer.Value)
+			responseBuffer.Release()
+		} else {
+			response := &http.Response{
+				Status:        "400 Bad Request",
+				StatusCode:    400,
+				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)
+			buffer.Release()
 		}
+	}
+}
 
-		responseBuffer := alloc.NewBuffer().Clear()
-		defer responseBuffer.Release()
-		response.Write(responseBuffer)
-		writer.Write(responseBuffer.Value)
+func (this *HttpProxyServer) handleConnect(request *http.Request, address v2net.Address, reader io.Reader, writer io.Writer) {
+	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,
+	}
 
-	} else {
-		response := &http.Response{
-			Status:        "400 Bad Request",
-			StatusCode:    400,
-			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)
+	writer.Write(buffer.Value)
 
-		buffer := alloc.NewSmallBuffer().Clear()
-		response.Write(buffer)
-		writer.Write(buffer.Value)
-	}
+	packet := v2net.NewPacket(v2net.NewTCPDestination(address), nil, true)
+	ray := this.space.PacketDispatcher().DispatchToOutbound(packet)
+	this.transport(reader, writer, ray)
 }
 
 func (this *HttpProxyServer) transport(input io.Reader, output io.Writer, ray ray.InboundRay) {
-	var inputFinish, outputFinish sync.Mutex
+	var outputFinish sync.Mutex
 	outputFinish.Lock()
 
-	if input != nil {
-		inputFinish.Lock()
-		go func() {
-			v2net.ReaderToChan(ray.InboundInput(), input)
-			inputFinish.Unlock()
-		}()
-	} else {
-		// TODO: We can not close write so quickly, as some HTTP server will stop responding if so.
-
-	}
+	go func() {
+		v2net.ReaderToChan(ray.InboundInput(), input)
+		close(ray.InboundInput())
+	}()
 
 	go func() {
 		v2net.ChanToWriter(output, ray.InboundOutput())
 		outputFinish.Unlock()
 	}()
 
-	inputFinish.Lock()
-	go func() {
-		<-time.After(10 * time.Second)
-		close(ray.InboundInput())
-	}()
 	outputFinish.Lock()
 }