|  | @@ -87,11 +87,10 @@ func parseBasicAuth(auth string) (username, password string, ok bool) {
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  func (s *Server) Process(ctx context.Context, network net.Network, conn internet.Connection, dispatcher dispatcher.Interface) error {
 | 
	
		
			
				|  |  | +	reader := bufio.NewReaderSize(conn, 2048)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  Start:
 | 
	
		
			
				|  |  | -	reader := bufio.NewReaderSize(conn, buf.Size)
 | 
	
		
			
				|  |  | -	if err := conn.SetReadDeadline(time.Now().Add(time.Second * 16)); err != nil {
 | 
	
		
			
				|  |  | -		return newError("unable to set read deadtime").Base(err)
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | +	conn.SetReadDeadline(time.Now().Add(time.Second * 16))
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	request, err := http.ReadRequest(reader)
 | 
	
		
			
				|  |  |  	if err != nil {
 | 
	
	
		
			
				|  | @@ -111,9 +110,7 @@ Start:
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	log.Trace(newError("request to Method [", request.Method, "] Host [", request.Host, "] with URL [", request.URL, "]"))
 | 
	
		
			
				|  |  | -	if err := conn.SetReadDeadline(time.Time{}); err != nil {
 | 
	
		
			
				|  |  | -		log.Trace(newError("unable to set back read deadline").Base(err))
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | +	conn.SetReadDeadline(time.Time{})
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	defaultPort := net.Port(80)
 | 
	
		
			
				|  |  |  	if strings.ToLower(request.URL.Scheme) == "https" {
 | 
	
	
		
			
				|  | @@ -129,23 +126,13 @@ Start:
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  	log.Access(conn.RemoteAddr(), request.URL, log.AccessAccepted, "")
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	// Get rid of bufio.Reader.
 | 
	
		
			
				|  |  | -	var firstPayload *buf.Buffer
 | 
	
		
			
				|  |  | -	if reader.Buffered() > 0 {
 | 
	
		
			
				|  |  | -		firstPayload = buf.New()
 | 
	
		
			
				|  |  | -		common.Must(firstPayload.Reset(func(b []byte) (int, error) {
 | 
	
		
			
				|  |  | -			return reader.Read(b[:reader.Buffered()])
 | 
	
		
			
				|  |  | -		}))
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	reader = nil
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  	if strings.ToUpper(request.Method) == "CONNECT" {
 | 
	
		
			
				|  |  | -		return s.handleConnect(ctx, request, firstPayload, conn, conn, dest, dispatcher)
 | 
	
		
			
				|  |  | +		return s.handleConnect(ctx, request, reader, conn, dest, dispatcher)
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	keepAlive := (strings.TrimSpace(strings.ToLower(request.Header.Get("Proxy-Connection"))) == "keep-alive")
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	err = s.handlePlainHTTP(ctx, request, firstPayload, conn, conn, dest, dispatcher)
 | 
	
		
			
				|  |  | +	err = s.handlePlainHTTP(ctx, request, reader, conn, dest, dispatcher)
 | 
	
		
			
				|  |  |  	if err == errWaitAnother {
 | 
	
		
			
				|  |  |  		if keepAlive {
 | 
	
		
			
				|  |  |  			goto Start
 | 
	
	
		
			
				|  | @@ -156,7 +143,7 @@ Start:
 | 
	
		
			
				|  |  |  	return err
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -func (s *Server) handleConnect(ctx context.Context, request *http.Request, payload *buf.Buffer, reader io.Reader, writer io.Writer, dest net.Destination, dispatcher dispatcher.Interface) error {
 | 
	
		
			
				|  |  | +func (s *Server) handleConnect(ctx context.Context, request *http.Request, reader io.Reader, writer io.Writer, dest net.Destination, dispatcher dispatcher.Interface) error {
 | 
	
		
			
				|  |  |  	_, err := writer.Write([]byte("HTTP/1.1 200 Connection established\r\n\r\n"))
 | 
	
		
			
				|  |  |  	if err != nil {
 | 
	
		
			
				|  |  |  		return newError("failed to write back OK response").Base(err)
 | 
	
	
		
			
				|  | @@ -173,17 +160,14 @@ func (s *Server) handleConnect(ctx context.Context, request *http.Request, paylo
 | 
	
		
			
				|  |  |  		return err
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	if !payload.IsEmpty() {
 | 
	
		
			
				|  |  | -		if err := ray.InboundInput().WriteMultiBuffer(buf.NewMultiBufferValue(payload)); err != nil {
 | 
	
		
			
				|  |  | -			return err
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  	requestDone := signal.ExecuteAsync(func() error {
 | 
	
		
			
				|  |  |  		defer ray.InboundInput().Close()
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  		v2reader := buf.NewReader(reader)
 | 
	
		
			
				|  |  | -		return buf.Copy(v2reader, ray.InboundInput(), buf.UpdateActivity(timer))
 | 
	
		
			
				|  |  | +		if err := buf.Copy(v2reader, ray.InboundInput(), buf.UpdateActivity(timer)); err != nil {
 | 
	
		
			
				|  |  | +			return err
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		return nil
 | 
	
		
			
				|  |  |  	})
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	responseDone := signal.ExecuteAsync(func() error {
 | 
	
	
		
			
				|  | @@ -235,7 +219,7 @@ func StripHopByHopHeaders(header http.Header) {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  var errWaitAnother = newError("keep alive")
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -func (s *Server) handlePlainHTTP(ctx context.Context, request *http.Request, payload *buf.Buffer, reader io.Reader, writer io.Writer, dest net.Destination, dispatcher dispatcher.Interface) error {
 | 
	
		
			
				|  |  | +func (s *Server) handlePlainHTTP(ctx context.Context, request *http.Request, reader io.Reader, writer io.Writer, dest net.Destination, dispatcher dispatcher.Interface) error {
 | 
	
		
			
				|  |  |  	if !s.config.AllowTransparent && len(request.URL.Host) <= 0 {
 | 
	
		
			
				|  |  |  		// RFC 2068 (HTTP/1.1) requires URL to be absolute URL in HTTP proxy.
 | 
	
		
			
				|  |  |  		response := &http.Response{
 | 
	
	
		
			
				|  | @@ -267,12 +251,6 @@ func (s *Server) handlePlainHTTP(ctx context.Context, request *http.Request, pay
 | 
	
		
			
				|  |  |  	output := ray.InboundOutput()
 | 
	
		
			
				|  |  |  	defer input.Close()
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	if !payload.IsEmpty() {
 | 
	
		
			
				|  |  | -		if err := input.WriteMultiBuffer(buf.NewMultiBufferValue(payload)); err != nil {
 | 
	
		
			
				|  |  | -			return err
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  	var result error = errWaitAnother
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	requestDone := signal.ExecuteAsync(func() error {
 |