...
Run Format

Source file src/net/http/npn_test.go

Documentation: net/http

  // Copyright 2013 The Go Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style
  // license that can be found in the LICENSE file.
  
  package http_test
  
  import (
  	"bufio"
  	"bytes"
  	"crypto/tls"
  	"crypto/x509"
  	"fmt"
  	"io"
  	"io/ioutil"
  	. "net/http"
  	"net/http/httptest"
  	"strings"
  	"testing"
  )
  
  func TestNextProtoUpgrade(t *testing.T) {
  	setParallel(t)
  	defer afterTest(t)
  	ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  		fmt.Fprintf(w, "path=%s,proto=", r.URL.Path)
  		if r.TLS != nil {
  			w.Write([]byte(r.TLS.NegotiatedProtocol))
  		}
  		if r.RemoteAddr == "" {
  			t.Error("request with no RemoteAddr")
  		}
  		if r.Body == nil {
  			t.Errorf("request with nil Body")
  		}
  	}))
  	ts.TLS = &tls.Config{
  		NextProtos: []string{"unhandled-proto", "tls-0.9"},
  	}
  	ts.Config.TLSNextProto = map[string]func(*Server, *tls.Conn, Handler){
  		"tls-0.9": handleTLSProtocol09,
  	}
  	ts.StartTLS()
  	defer ts.Close()
  
  	// Normal request, without NPN.
  	{
  		c := ts.Client()
  		res, err := c.Get(ts.URL)
  		if err != nil {
  			t.Fatal(err)
  		}
  		body, err := ioutil.ReadAll(res.Body)
  		if err != nil {
  			t.Fatal(err)
  		}
  		if want := "path=/,proto="; string(body) != want {
  			t.Errorf("plain request = %q; want %q", body, want)
  		}
  	}
  
  	// Request to an advertised but unhandled NPN protocol.
  	// Server will hang up.
  	{
  		certPool := x509.NewCertPool()
  		certPool.AddCert(ts.Certificate())
  		tr := &Transport{
  			TLSClientConfig: &tls.Config{
  				RootCAs:    certPool,
  				NextProtos: []string{"unhandled-proto"},
  			},
  		}
  		defer tr.CloseIdleConnections()
  		c := &Client{
  			Transport: tr,
  		}
  		res, err := c.Get(ts.URL)
  		if err == nil {
  			defer res.Body.Close()
  			var buf bytes.Buffer
  			res.Write(&buf)
  			t.Errorf("expected error on unhandled-proto request; got: %s", buf.Bytes())
  		}
  	}
  
  	// Request using the "tls-0.9" protocol, which we register here.
  	// It is HTTP/0.9 over TLS.
  	{
  		c := ts.Client()
  		tlsConfig := c.Transport.(*Transport).TLSClientConfig
  		tlsConfig.NextProtos = []string{"tls-0.9"}
  		conn, err := tls.Dial("tcp", ts.Listener.Addr().String(), tlsConfig)
  		if err != nil {
  			t.Fatal(err)
  		}
  		conn.Write([]byte("GET /foo\n"))
  		body, err := ioutil.ReadAll(conn)
  		if err != nil {
  			t.Fatal(err)
  		}
  		if want := "path=/foo,proto=tls-0.9"; string(body) != want {
  			t.Errorf("plain request = %q; want %q", body, want)
  		}
  	}
  }
  
  // handleTLSProtocol09 implements the HTTP/0.9 protocol over TLS, for the
  // TestNextProtoUpgrade test.
  func handleTLSProtocol09(srv *Server, conn *tls.Conn, h Handler) {
  	br := bufio.NewReader(conn)
  	line, err := br.ReadString('\n')
  	if err != nil {
  		return
  	}
  	line = strings.TrimSpace(line)
  	path := strings.TrimPrefix(line, "GET ")
  	if path == line {
  		return
  	}
  	req, _ := NewRequest("GET", path, nil)
  	req.Proto = "HTTP/0.9"
  	req.ProtoMajor = 0
  	req.ProtoMinor = 9
  	rw := &http09Writer{conn, make(Header)}
  	h.ServeHTTP(rw, req)
  }
  
  type http09Writer struct {
  	io.Writer
  	h Header
  }
  
  func (w http09Writer) Header() Header  { return w.h }
  func (w http09Writer) WriteHeader(int) {} // no headers
  

View as plain text