Explorar o código

Fix: upstream HTTP proxy bugs

* Broken error handling in Windows TCPConn related to
  HTTP proxy case.

* Testing revealed that response parsing in HttpProxyConnect
  was too strict. Now using Go's http.ReadResponse.
Rod Hynes %!s(int64=11) %!d(string=hai) anos
pai
achega
5c8e21e69d
Modificáronse 2 ficheiros con 16 adicións e 12 borrados
  1. 5 5
      psiphon/TCPConn_windows.go
  2. 11 7
      psiphon/conn.go

+ 5 - 5
psiphon/TCPConn_windows.go

@@ -73,11 +73,11 @@ func interruptibleTCPDial(addr string, config *DialConfig) (conn *TCPConn, err e
 
 		netConn, err := net.DialTimeout("tcp", dialAddr, config.ConnectTimeout)
 
-		if config.UpstreamHttpProxyAddress != "" {
-			err := HttpProxyConnect(netConn, addr)
-			if err != nil {
-				netConn = nil
-			}
+		if err == nil && config.UpstreamHttpProxyAddress != "" {
+			err = HttpProxyConnect(netConn, addr)
+		}
+		if err != nil {
+			netConn = nil
 		}
 
 		results <- &interruptibleDialResult{netConn, err}

+ 11 - 7
psiphon/conn.go

@@ -20,10 +20,13 @@
 package psiphon
 
 import (
-	"bytes"
+	"bufio"
+	"errors"
 	"fmt"
 	"io"
 	"net"
+	"net/http"
+	"strings"
 	"sync"
 	"time"
 )
@@ -168,15 +171,16 @@ func HttpProxyConnect(rawConn net.Conn, addr string) (err error) {
 		return ContextError(err)
 	}
 
-	expectedResponse := []byte("HTTP/1.1 200 OK\r\n\r\n")
-	readBuffer := make([]byte, len(expectedResponse))
-	_, err = io.ReadFull(rawConn, readBuffer)
+	// Adapted from dialConn in net/http/transport.go:
+	// Read response.
+	// Okay to use and discard buffered reader here, because
+	// TLS server will not speak until spoken to.
+	response, err := http.ReadResponse(bufio.NewReader(rawConn), nil)
 	if err != nil {
 		return ContextError(err)
 	}
-
-	if !bytes.Equal(readBuffer, expectedResponse) {
-		return fmt.Errorf("unexpected HTTP proxy response: %s", string(readBuffer))
+	if response.StatusCode != 200 {
+		return ContextError(errors.New(strings.SplitN(response.Status, " ", 2)[1]))
 	}
 
 	return nil