github.com/FenixAra/go@v0.0.0-20170127160404-96ea0918e670/src/net/http/npn_test.go (about) 1 // Copyright 2013 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package http_test 6 7 import ( 8 "bufio" 9 "bytes" 10 "crypto/tls" 11 "fmt" 12 "io" 13 "io/ioutil" 14 . "net/http" 15 "net/http/httptest" 16 "strings" 17 "testing" 18 ) 19 20 func TestNextProtoUpgrade(t *testing.T) { 21 setParallel(t) 22 defer afterTest(t) 23 ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) { 24 fmt.Fprintf(w, "path=%s,proto=", r.URL.Path) 25 if r.TLS != nil { 26 w.Write([]byte(r.TLS.NegotiatedProtocol)) 27 } 28 if r.RemoteAddr == "" { 29 t.Error("request with no RemoteAddr") 30 } 31 if r.Body == nil { 32 t.Errorf("request with nil Body") 33 } 34 })) 35 ts.TLS = &tls.Config{ 36 NextProtos: []string{"unhandled-proto", "tls-0.9"}, 37 } 38 ts.Config.TLSNextProto = map[string]func(*Server, *tls.Conn, Handler){ 39 "tls-0.9": handleTLSProtocol09, 40 } 41 ts.StartTLS() 42 defer ts.Close() 43 44 // Normal request, without NPN. 45 { 46 tr := newTLSTransport(t, ts) 47 defer tr.CloseIdleConnections() 48 c := &Client{Transport: tr} 49 50 res, err := c.Get(ts.URL) 51 if err != nil { 52 t.Fatal(err) 53 } 54 body, err := ioutil.ReadAll(res.Body) 55 if err != nil { 56 t.Fatal(err) 57 } 58 if want := "path=/,proto="; string(body) != want { 59 t.Errorf("plain request = %q; want %q", body, want) 60 } 61 } 62 63 // Request to an advertised but unhandled NPN protocol. 64 // Server will hang up. 65 { 66 tr := newTLSTransport(t, ts) 67 tr.TLSClientConfig.NextProtos = []string{"unhandled-proto"} 68 defer tr.CloseIdleConnections() 69 c := &Client{Transport: tr} 70 71 res, err := c.Get(ts.URL) 72 if err == nil { 73 defer res.Body.Close() 74 var buf bytes.Buffer 75 res.Write(&buf) 76 t.Errorf("expected error on unhandled-proto request; got: %s", buf.Bytes()) 77 } 78 } 79 80 // Request using the "tls-0.9" protocol, which we register here. 81 // It is HTTP/0.9 over TLS. 82 { 83 tlsConfig := newTLSTransport(t, ts).TLSClientConfig 84 tlsConfig.NextProtos = []string{"tls-0.9"} 85 conn, err := tls.Dial("tcp", ts.Listener.Addr().String(), tlsConfig) 86 if err != nil { 87 t.Fatal(err) 88 } 89 conn.Write([]byte("GET /foo\n")) 90 body, err := ioutil.ReadAll(conn) 91 if err != nil { 92 t.Fatal(err) 93 } 94 if want := "path=/foo,proto=tls-0.9"; string(body) != want { 95 t.Errorf("plain request = %q; want %q", body, want) 96 } 97 } 98 } 99 100 // handleTLSProtocol09 implements the HTTP/0.9 protocol over TLS, for the 101 // TestNextProtoUpgrade test. 102 func handleTLSProtocol09(srv *Server, conn *tls.Conn, h Handler) { 103 br := bufio.NewReader(conn) 104 line, err := br.ReadString('\n') 105 if err != nil { 106 return 107 } 108 line = strings.TrimSpace(line) 109 path := strings.TrimPrefix(line, "GET ") 110 if path == line { 111 return 112 } 113 req, _ := NewRequest("GET", path, nil) 114 req.Proto = "HTTP/0.9" 115 req.ProtoMajor = 0 116 req.ProtoMinor = 9 117 rw := &http09Writer{conn, make(Header)} 118 h.ServeHTTP(rw, req) 119 } 120 121 type http09Writer struct { 122 io.Writer 123 h Header 124 } 125 126 func (w http09Writer) Header() Header { return w.h } 127 func (w http09Writer) WriteHeader(int) {} // no headers