github.com/searKing/golang/go@v1.2.117/net/mux/server_test.go (about)

     1  // Copyright 2020 The searKing Author. 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 mux_test
     6  
     7  import (
     8  	"context"
     9  	"io"
    10  	"log"
    11  	"net"
    12  	"strings"
    13  	"sync"
    14  	"sync/atomic"
    15  	"testing"
    16  	"time"
    17  
    18  	"github.com/searKing/golang/go/net/mux"
    19  	"github.com/searKing/golang/go/testing/leakcheck"
    20  
    21  	"golang.org/x/net/http2"
    22  )
    23  
    24  const (
    25  	handleHTTP1Close   = 1
    26  	handleHTTP1Request = 2
    27  	handleAnyClose     = 3
    28  	handleAnyRequest   = 4
    29  )
    30  
    31  func TestTimeout(t *testing.T) {
    32  	defer leakcheck.Check(t)
    33  	loopbackLis := testListener(t)
    34  	defer loopbackLis.Close()
    35  	result := make(chan int, 5)
    36  	testDuration := time.Millisecond * 500
    37  	muxer := mux.NewServeMux()
    38  	muxer.SetReadTimeout(testDuration)
    39  	http1Listener := muxer.HandleListener(mux.HTTP1Fast())
    40  	defer http1Listener.Close()
    41  	anyListener := muxer.HandleListener(mux.Any())
    42  	defer anyListener.Close()
    43  
    44  	srv := mux.NewServer()
    45  	defer srv.Close()
    46  	srv.Handler = muxer
    47  
    48  	ctx, cancelFn := context.WithCancel(context.TODO())
    49  	defer cancelFn()
    50  	go func() {
    51  		_ = srv.Serve(loopbackLis)
    52  	}()
    53  	go func() {
    54  		for {
    55  			select {
    56  			case <-ctx.Done():
    57  				return
    58  			default:
    59  			}
    60  			con, err := http1Listener.Accept()
    61  			if err != nil {
    62  				result <- handleHTTP1Close
    63  			} else {
    64  				_, _ = con.Write([]byte("http1Listener"))
    65  				result <- handleHTTP1Request
    66  				select {
    67  				case <-ctx.Done():
    68  					break
    69  				}
    70  				_ = con.Close()
    71  			}
    72  			select {
    73  			case <-ctx.Done():
    74  				return
    75  			}
    76  		}
    77  	}()
    78  	go func() {
    79  		for {
    80  			select {
    81  			case <-ctx.Done():
    82  				return
    83  			default:
    84  			}
    85  			con, err := anyListener.Accept()
    86  			if err != nil {
    87  				result <- handleAnyClose
    88  			} else {
    89  				_, err = con.Write([]byte("any"))
    90  				result <- handleAnyRequest
    91  				select {
    92  				case <-ctx.Done():
    93  					break
    94  				}
    95  				_ = con.Close()
    96  			}
    97  		}
    98  	}()
    99  	time.Sleep(testDuration) // wait to prevent timeouts on slow test-runners
   100  	client, err := net.Dial("tcp", loopbackLis.Addr().String())
   101  	if err != nil {
   102  		log.Fatal("testTimeout client failed: ", err)
   103  	}
   104  	defer client.Close()
   105  	time.Sleep(testDuration / 2)
   106  	if len(result) != 0 {
   107  		log.Print("tcp ")
   108  		t.Fatal("testTimeout failed: accepted to fast: ", len(result))
   109  	}
   110  	//_ = client.SetReadDeadline(time.Now().Add(testDuration * 3))
   111  	buffer := make([]byte, 10)
   112  	rl, err := client.Read(buffer)
   113  	if err != nil {
   114  		t.Fatal("testTimeout failed: client error: ", err, rl)
   115  	}
   116  	_ = srv.Close()
   117  	if rl != len("any") {
   118  		log.Print("testTimeout failed: response from wrong service ", rl)
   119  	}
   120  	if string(buffer[0:3]) != "any" {
   121  		log.Print("testTimeout failed: response from wrong service ")
   122  	}
   123  	time.Sleep(testDuration * 2)
   124  	if len(result) != 2 {
   125  		t.Fatal("testTimeout failed: accepted to less: ", len(result))
   126  	}
   127  	if a := <-result; a != handleAnyRequest {
   128  		t.Fatal("testTimeout failed: anyListener rule did not match")
   129  	}
   130  	if a := <-result; a != handleHTTP1Close {
   131  		t.Fatal("testTimeout failed: no close an http rule")
   132  	}
   133  }
   134  
   135  func TestRead(t *testing.T) {
   136  	defer leakcheck.Check(t)
   137  	errCh := make(chan error)
   138  	defer func() {
   139  		select {
   140  		case err := <-errCh:
   141  			t.Fatal(err)
   142  		default:
   143  		}
   144  	}()
   145  	const payload = "hello world\r\n"
   146  	const mult = 2
   147  
   148  	writer, reader := net.Pipe()
   149  	go func() {
   150  		if _, err := io.WriteString(writer, strings.Repeat(payload, mult)); err != nil {
   151  			t.Fatal(err)
   152  		}
   153  		if err := writer.Close(); err != nil {
   154  			t.Fatal(err)
   155  		}
   156  	}()
   157  
   158  	muxer := mux.NewServeMux()
   159  	// Register a bogus matcher to force buffering exactly the right amount.
   160  	// Before this fix, this would trigger a bug where `Read` would incorrectly
   161  	// report `io.EOF` when only the buffer had been consumed.
   162  	_ = muxer.HandleListener(mux.MatcherFunc(func(w io.Writer, r io.Reader) bool {
   163  		var b [len(payload)]byte
   164  		_, _ = r.Read(b[:])
   165  		return false
   166  	}))
   167  	anyl := muxer.HandleListener(mux.Any())
   168  
   169  	l := newChanListener()
   170  	l.Notify(reader)
   171  	defer l.Close()
   172  	srv := mux.NewServer()
   173  	defer srv.Close()
   174  	srv.Handler = muxer
   175  	go safeServe(errCh, srv, l)
   176  	muxedConn, err := anyl.Accept()
   177  	if err != nil {
   178  		t.Fatal(err)
   179  	}
   180  	for i := 0; i < mult; i++ {
   181  		var b [len(payload)]byte
   182  		n, err := muxedConn.Read(b[:])
   183  		if err != nil {
   184  			t.Error(err)
   185  			continue
   186  		}
   187  		if e := len(b); n != e {
   188  			t.Errorf("expected to read %d bytes, but read %d bytes", e, n)
   189  		}
   190  	}
   191  	var b [1]byte
   192  	if _, err := muxedConn.Read(b[:]); err != io.EOF {
   193  		t.Errorf("unexpected error %v, expected %v", err, io.EOF)
   194  	}
   195  
   196  }
   197  
   198  func TestAny(t *testing.T) {
   199  	defer leakcheck.Check(t)
   200  	errCh := make(chan error, 5)
   201  	defer func() {
   202  		for {
   203  			select {
   204  			case err, ok := <-errCh:
   205  				if !ok {
   206  					return
   207  				}
   208  				t.Fatal(err)
   209  			default:
   210  				close(errCh)
   211  				return
   212  			}
   213  		}
   214  	}()
   215  	l := testListener(t)
   216  	defer l.Close()
   217  
   218  	var wg sync.WaitGroup
   219  	func() {
   220  		muxer := mux.NewServeMux()
   221  		httpl := muxer.HandleListener(mux.Any())
   222  
   223  		srv := mux.NewServer()
   224  		defer srv.Close()
   225  		srv.Handler = muxer
   226  
   227  		wg.Add(1)
   228  		go func() {
   229  			defer wg.Done()
   230  			runTestHTTPServer(errCh, httpl)
   231  		}()
   232  		wg.Add(1)
   233  		go func() {
   234  			defer wg.Done()
   235  			safeServe(errCh, srv, l)
   236  		}()
   237  		runTestHTTP1Client(t, l.Addr())
   238  	}()
   239  	wg.Wait()
   240  }
   241  
   242  func TestTLS(t *testing.T) {
   243  	generateTLSCert(t)
   244  	defer cleanupTLSCert(t)
   245  	defer leakcheck.Check(t)
   246  	errCh := make(chan error)
   247  	defer func() {
   248  		for {
   249  			select {
   250  			case err, ok := <-errCh:
   251  				if !ok {
   252  					return
   253  				}
   254  				t.Fatal(err)
   255  			default:
   256  				close(errCh)
   257  				return
   258  			}
   259  		}
   260  	}()
   261  	l := testListener(t)
   262  	defer l.Close()
   263  	muxer := mux.NewServeMux()
   264  
   265  	tlsl := muxer.HandleListener(mux.TLS())
   266  	httpl := muxer.HandleListener(mux.Any())
   267  
   268  	srv := mux.NewServer()
   269  	defer srv.Close()
   270  	srv.Handler = muxer
   271  
   272  	go runTestTLSServer(errCh, tlsl)
   273  	go runTestHTTPServer(errCh, httpl)
   274  	go safeServe(errCh, srv, l)
   275  
   276  	runTestHTTP1Client(t, l.Addr())
   277  	runTestTLSClient(t, l.Addr())
   278  }
   279  
   280  func TestHTTP2(t *testing.T) {
   281  	defer leakcheck.Check(t)
   282  	errCh := make(chan error)
   283  	defer func() {
   284  		for {
   285  			select {
   286  			case err, ok := <-errCh:
   287  				if !ok {
   288  					return
   289  				}
   290  				t.Fatal(err)
   291  			default:
   292  				close(errCh)
   293  				return
   294  			}
   295  		}
   296  	}()
   297  	writer, reader := net.Pipe()
   298  	go func() {
   299  		if _, err := io.WriteString(writer, http2.ClientPreface); err != nil {
   300  			t.Fatal(err)
   301  		}
   302  		if err := writer.Close(); err != nil {
   303  			t.Fatal(err)
   304  		}
   305  	}()
   306  	muxer := mux.NewServeMux()
   307  
   308  	// Register a bogus matcher that only reads one byte.
   309  	muxer.HandleListener(mux.MatcherFunc(func(w io.Writer, r io.Reader) bool {
   310  		var b [1]byte
   311  		_, _ = r.Read(b[:])
   312  		return false
   313  	}))
   314  	h2l := muxer.HandleListener(mux.HTTP2())
   315  
   316  	l := newChanListener()
   317  	l.Notify(reader)
   318  	srv := mux.NewServer()
   319  	defer srv.Close()
   320  	srv.Handler = muxer
   321  	go safeServe(errCh, srv, l)
   322  	muxedConn, err := h2l.Accept()
   323  	_ = l.Close()
   324  	if err != nil {
   325  		t.Fatal(err)
   326  	}
   327  	var b [len(http2.ClientPreface)]byte
   328  	var n int
   329  	// We have the sniffed buffer first...
   330  	if n, err = muxedConn.Read(b[:]); err == io.EOF {
   331  		t.Fatal(err)
   332  	}
   333  	// and then we read from the source.
   334  	if _, err = muxedConn.Read(b[n:]); err != nil && err != io.EOF {
   335  		t.Fatal(err)
   336  	}
   337  	if string(b[:]) != http2.ClientPreface {
   338  		t.Errorf("got unexpected read %s, expected %s", b, http2.ClientPreface)
   339  	}
   340  }
   341  
   342  func TestHTTP2MatchHeaderField(t *testing.T) {
   343  	testHTTP2HeaderField(t, mux.HTTP2HeaderFieldEqual, "value", "value", "anothervalue")
   344  }
   345  
   346  func TestHTTP2MatchHeaderFieldPrefix(t *testing.T) {
   347  	testHTTP2HeaderField(t, mux.HTTP2HeaderFieldPrefix, "application/grpc+proto", "application/grpc", "application/json")
   348  }
   349  
   350  func TestHTTPGoRPC(t *testing.T) {
   351  	defer leakcheck.Check(t)
   352  	errCh := make(chan error)
   353  	defer func() {
   354  		for {
   355  			select {
   356  			case err, ok := <-errCh:
   357  				if !ok {
   358  					return
   359  				}
   360  				t.Fatal(err)
   361  			default:
   362  				close(errCh)
   363  				return
   364  			}
   365  		}
   366  	}()
   367  	l := testListener(t)
   368  	defer l.Close()
   369  
   370  	muxer := mux.NewServeMux()
   371  
   372  	httpl := muxer.HandleListener(mux.MatcherAny(mux.HTTP2(), mux.HTTP1Fast()))
   373  
   374  	rpcl := muxer.HandleListener(mux.Any())
   375  
   376  	srv := mux.NewServer()
   377  	defer srv.Close()
   378  	srv.Handler = muxer
   379  
   380  	go runTestHTTPServer(errCh, httpl)
   381  	go runTestRPCServer(errCh, rpcl)
   382  	go safeServe(errCh, srv, l)
   383  
   384  	runTestHTTP1Client(t, l.Addr())
   385  	runTestRPCClient(t, l.Addr())
   386  }
   387  
   388  func TestErrorHandler(t *testing.T) {
   389  	defer leakcheck.Check(t)
   390  	errCh := make(chan error)
   391  	defer func() {
   392  		for {
   393  			select {
   394  			case err, ok := <-errCh:
   395  				if !ok {
   396  					return
   397  				}
   398  				t.Fatal(err)
   399  			default:
   400  				close(errCh)
   401  				return
   402  			}
   403  		}
   404  	}()
   405  	l := testListener(t)
   406  	muxer := mux.NewServeMux()
   407  
   408  	srv := mux.NewServer()
   409  	defer srv.Close()
   410  	srv.Handler = muxer
   411  	srv.Handler = muxer
   412  
   413  	httpl := muxer.HandleListener(mux.MatcherAny(mux.HTTP2(), mux.HTTP1Fast()))
   414  
   415  	go runTestHTTPServer(errCh, httpl)
   416  	go safeServe(errCh, srv, l)
   417  
   418  	var errCount uint32
   419  	srv.HandleError(mux.ErrorHandlerFunc(func(err error) bool {
   420  		if atomic.AddUint32(&errCount, 1) == 1 {
   421  			t.Logf("got an expected error: %v", err)
   422  		}
   423  		return true
   424  	}))
   425  
   426  	//runTestRPCClient(t, l.Addr())
   427  	c, clean := safeDial(t, l.Addr())
   428  	defer clean()
   429  
   430  	l.Close()
   431  
   432  	var num int
   433  	for atomic.LoadUint32(&errCount) == 0 {
   434  		if err := c.Call("TestRPCRcvr.Test", rpcVal, &num); err == nil {
   435  			// The connection is simply closed.
   436  			t.Errorf("unexpected rpc success after %d errors", atomic.LoadUint32(&errCount))
   437  		}
   438  	}
   439  }
   440  
   441  func TestMultipleMatchers(t *testing.T) {
   442  	defer leakcheck.Check(t)
   443  	errCh := make(chan error)
   444  	defer func() {
   445  		for {
   446  			select {
   447  			case err, ok := <-errCh:
   448  				if !ok {
   449  					return
   450  				}
   451  				t.Fatal(err)
   452  			default:
   453  				close(errCh)
   454  				return
   455  			}
   456  		}
   457  	}()
   458  	l := testListener(t)
   459  	defer l.Close()
   460  
   461  	matcher := func(w io.Writer, r io.Reader) bool {
   462  		return true
   463  	}
   464  	unmatcher := func(w io.Writer, r io.Reader) bool {
   465  		return false
   466  	}
   467  
   468  	muxer := mux.NewServeMux()
   469  	srv := mux.NewServer()
   470  	defer srv.Close()
   471  	srv.Handler = muxer
   472  
   473  	lis := muxer.HandleListener(mux.MatcherAny(mux.MatcherFunc(unmatcher), mux.MatcherFunc(matcher), mux.MatcherFunc(unmatcher)))
   474  
   475  	go runTestHTTPServer(errCh, lis)
   476  	go safeServe(errCh, srv, l)
   477  
   478  	runTestHTTP1Client(t, l.Addr())
   479  }
   480  
   481  func TestClose(t *testing.T) {
   482  	defer leakcheck.Check(t)
   483  	errCh := make(chan error)
   484  	defer func() {
   485  		for {
   486  			select {
   487  			case err, ok := <-errCh:
   488  				if !ok {
   489  					return
   490  				}
   491  				t.Fatal(err)
   492  			default:
   493  				close(errCh)
   494  				return
   495  			}
   496  		}
   497  	}()
   498  	l := newChanListener()
   499  
   500  	c1, c2 := net.Pipe()
   501  	muxer := mux.NewServeMux()
   502  
   503  	srv := mux.NewServer()
   504  	defer srv.Close()
   505  	srv.Handler = muxer
   506  
   507  	anyl := muxer.HandleListener(mux.Any())
   508  
   509  	go safeServe(errCh, srv, l)
   510  
   511  	l.Notify(c1)
   512  
   513  	// First connection goes through.
   514  	if _, err := anyl.Accept(); err != nil {
   515  		t.Fatal(err)
   516  	}
   517  
   518  	// Second connection is sent
   519  	l.Notify(c2)
   520  
   521  	// Listener is closed.
   522  	l.Close()
   523  
   524  	// Second connection either goes through or it is closed.
   525  	if _, err := anyl.Accept(); err != nil {
   526  		if err != mux.ErrListenerClosed {
   527  			t.Fatal(err)
   528  		}
   529  		// The error is either io.ErrClosedPipe or net.OpError wrapping
   530  		// a net.pipeError depending on the go version.
   531  		if _, err := c2.Read([]byte{}); !strings.Contains(err.Error(), "closed") {
   532  			t.Fatalf("connection is not closed and is leaked: %v", err)
   533  		}
   534  	}
   535  }