diff --git a/apps/run.go b/apps/run.go index 9b168544..ec1e34a0 100644 --- a/apps/run.go +++ b/apps/run.go @@ -2,6 +2,7 @@ package apps import ( "archive/tar" + "bufio" "bytes" "compress/gzip" "context" @@ -12,7 +13,6 @@ import ( "mime/multipart" "net" "net/http" - "net/http/httputil" "net/url" "os" "os/signal" @@ -322,42 +322,43 @@ func (runCtx *runContext) connectToRunServer(ctx context.Context) (*http.Respons return nil, nil, errgo.New("No attach URL to connect to") } - req, err := http.NewRequest("CONNECT", runCtx.attachURL, nil) + url, err := url.Parse(runCtx.attachURL) if err != nil { return nil, nil, errgo.Mask(err, errgo.Any) } - token, err := runCtx.scalingoClient.GetAccessToken(ctx) + // Establish an initial TCP connection + conn, err := net.Dial("tcp", url.Host) if err != nil { - return nil, nil, errgo.Notef(err, "fail to generate auth") + return nil, nil, errgo.Mask(err, errgo.Any) } - req.SetBasicAuth("", token) - url, err := url.Parse(runCtx.attachURL) + // Wrap with TLS if using HTTPS + if url.Scheme == "https" { + tlsConfig := config.TLSConfig.Clone() + tlsConfig.ServerName = strings.Split(url.Host, ":")[0] + conn = tls.Client(conn, tlsConfig) + } + + req, err := http.NewRequest("CONNECT", runCtx.attachURL, nil) if err != nil { return nil, nil, errgo.Mask(err, errgo.Any) } - dial, err := net.Dial("tcp", url.Host) + token, err := runCtx.scalingoClient.GetAccessToken(ctx) if err != nil { - return nil, nil, errgo.Mask(err, errgo.Any) + return nil, nil, errgo.Notef(err, "fail to generate auth") } + req.SetBasicAuth("", token) - var conn *httputil.ClientConn - if url.Scheme == "https" { - host := strings.Split(url.Host, ":")[0] - tlsConfig := config.TLSConfig.Clone() - tlsConfig.ServerName = host - tlsConn := tls.Client(dial, tlsConfig) - conn = httputil.NewClientConn(tlsConn, nil) - } else if url.Scheme == "http" { - conn = httputil.NewClientConn(dial, nil) - } else { - return nil, nil, errgo.Newf("invalid scheme format %s", url.Scheme) + // Write the HTTP request directly to the connection + err = req.Write(conn) + if err != nil { + return nil, nil, errgo.Mask(err, errgo.Any) } - res, err := conn.Do(req) - if err != httputil.ErrPersistEOF && err != nil { + resp, err := http.ReadResponse(bufio.NewReader(conn), req) + if err != nil { if err, ok := err.(*net.OpError); ok { if err.Err.Error() == "record overflow" { return nil, nil, errgo.Newf( @@ -371,8 +372,11 @@ func (runCtx *runContext) connectToRunServer(ctx context.Context) (*http.Respons return nil, nil, errgo.Mask(err, errgo.Any) } - connection, _ := conn.Hijack() - return res, connection, nil + if resp.StatusCode != http.StatusOK { + return resp, nil, nil + } + + return resp, conn, nil } func (runCtx *runContext) validateFiles(files []string) error { diff --git a/apps/run_test.go b/apps/run_test.go index 4a00f905..0319d42f 100644 --- a/apps/run_test.go +++ b/apps/run_test.go @@ -1,6 +1,8 @@ package apps -import "testing" +import ( + "testing" +) func TestParseEnvVar(t *testing.T) { ctx := &runContext{} diff --git a/go.mod b/go.mod index 8c1ccef4..c5f40e93 100644 --- a/go.mod +++ b/go.mod @@ -14,6 +14,7 @@ require ( github.com/dustin/go-humanize v1.0.1 github.com/fatih/color v1.18.0 github.com/go-git/go-git/v5 v5.12.0 + github.com/golang/mock v1.6.0 github.com/google/go-github/v47 v47.1.0 github.com/gorilla/websocket v1.5.3 github.com/gosuri/uilive v0.0.4 @@ -27,7 +28,7 @@ require ( github.com/urfave/cli/v2 v2.27.5 golang.org/x/crypto v0.29.0 golang.org/x/term v0.26.0 - golang.org/x/text v0.20.0 + golang.org/x/text v0.21.0 gopkg.in/errgo.v1 v1.0.1 ) @@ -45,7 +46,6 @@ require ( github.com/go-git/go-billy/v5 v5.6.0 // indirect github.com/golang-jwt/jwt/v4 v4.5.1 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/mock v1.6.0 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect diff --git a/go.sum b/go.sum index e086b262..3784d45d 100644 --- a/go.sum +++ b/go.sum @@ -201,8 +201,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= -golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= diff --git a/vendor/modules.txt b/vendor/modules.txt index 97f4b059..0cbdbffd 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -300,7 +300,7 @@ golang.org/x/sys/windows # golang.org/x/term v0.26.0 ## explicit; go 1.18 golang.org/x/term -# golang.org/x/text v0.20.0 +# golang.org/x/text v0.21.0 ## explicit; go 1.18 golang.org/x/text/cases golang.org/x/text/internal