]> Cypherpunks repositories - gostls13.git/commitdiff
net/http: detect when an HTTPS client contacts an HTTP server
authorCaleb Spare <cespare@gmail.com>
Tue, 20 Oct 2015 07:35:42 +0000 (00:35 -0700)
committerBrad Fitzpatrick <bradfitz@golang.org>
Tue, 17 Nov 2015 04:06:32 +0000 (04:06 +0000)
Inspect the crypto/tls error to recognize this case and give a more
helpful error.

Fixes #11111.

Change-Id: I63f6af8c375aa892326ccccbd29655d54d68df0b
Reviewed-on: https://go-review.googlesource.com/16079
Run-TryBot: Caleb Spare <cespare@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/net/http/client.go
src/net/http/client_test.go

index 7f2fbb4678ef1c32164620d459b0599680952d91..47f145a0cae6f6fbedff286df30864252e2362b6 100644 (file)
@@ -10,6 +10,7 @@
 package http
 
 import (
+       "crypto/tls"
        "encoding/base64"
        "errors"
        "fmt"
@@ -222,6 +223,14 @@ func send(req *Request, t RoundTripper) (resp *Response, err error) {
                if resp != nil {
                        log.Printf("RoundTripper returned a response & error; ignoring response")
                }
+               if tlsErr, ok := err.(tls.RecordHeaderError); ok {
+                       // If we get a bad TLS record header, check to see if the
+                       // response looks like HTTP and give a more helpful error.
+                       // See golang.org/issue/11111.
+                       if string(tlsErr.RecordHeader[:]) == "HTTP/" {
+                               err = errors.New("http: server gave HTTP response to HTTPS client")
+                       }
+               }
                return nil, err
        }
        return resp, nil
index 01f8cbaa2dfdcb9241e2e88da3eec6c029ede12f..40d5109862fe14b66734db035d278d47aa26c2af 100644 (file)
@@ -743,6 +743,20 @@ func TestResponseSetsTLSConnectionState(t *testing.T) {
        }
 }
 
+// Check that an HTTPS client can interpret a particular TLS error
+// to determine that the server is speaking HTTP.
+// See golang.org/issue/11111.
+func TestHTTPSClientDetectsHTTPServer(t *testing.T) {
+       defer afterTest(t)
+       ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
+       defer ts.Close()
+
+       _, err := Get(strings.Replace(ts.URL, "http", "https", 1))
+       if got := err.Error(); !strings.Contains(got, "HTTP response to HTTPS client") {
+               t.Fatalf("error = %q; want error indicating HTTP response to HTTPS request", got)
+       }
+}
+
 // Verify Response.ContentLength is populated. https://golang.org/issue/4126
 func TestClientHeadContentLength(t *testing.T) {
        defer afterTest(t)