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 }