Commit babdb383 authored by Caleb Spare's avatar Caleb Spare Committed by Brad Fitzpatrick

net/http: detect when an HTTPS client contacts an HTTP server

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: 's avatarBrad Fitzpatrick <bradfitz@golang.org>
parent 662ab8be
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
package http package http
import ( import (
"crypto/tls"
"encoding/base64" "encoding/base64"
"errors" "errors"
"fmt" "fmt"
...@@ -222,6 +223,14 @@ func send(req *Request, t RoundTripper) (resp *Response, err error) { ...@@ -222,6 +223,14 @@ func send(req *Request, t RoundTripper) (resp *Response, err error) {
if resp != nil { if resp != nil {
log.Printf("RoundTripper returned a response & error; ignoring response") 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 nil, err
} }
return resp, nil return resp, nil
......
...@@ -743,6 +743,20 @@ func TestResponseSetsTLSConnectionState(t *testing.T) { ...@@ -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 // Verify Response.ContentLength is populated. https://golang.org/issue/4126
func TestClientHeadContentLength(t *testing.T) { func TestClientHeadContentLength(t *testing.T) {
defer afterTest(t) defer afterTest(t)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment