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