nanomsg.org/go/mangos/v2@v2.0.9-0.20200203084354-8a092611e461/transport/ws/ws_test.go (about)

     1  // Copyright 2019 The Mangos Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use file except in compliance with the License.
     5  // You may obtain a copy of the license at
     6  //
     7  //    http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package ws
    16  
    17  import (
    18  	"github.com/gorilla/websocket"
    19  	"net/http"
    20  	"strings"
    21  	"testing"
    22  	"time"
    23  
    24  	"nanomsg.org/go/mangos/v2"
    25  	. "nanomsg.org/go/mangos/v2/internal/test"
    26  )
    27  
    28  var tran = Transport
    29  
    30  func TestWsOptions(t *testing.T) {
    31  	TranVerifyInvalidOption(t, tran)
    32  	TranVerifyIntOption(t, tran, mangos.OptionMaxRecvSize)
    33  	TranVerifyNoDelayOption(t, tran)
    34  	TranVerifyBoolOption(t, tran, OptionWebSocketCheckOrigin)
    35  }
    36  
    37  func TestWsScheme(t *testing.T) {
    38  	TranVerifyScheme(t, tran)
    39  }
    40  func TestWsRecvMax(t *testing.T) {
    41  	TranVerifyMaxRecvSize(t, tran, nil, nil)
    42  }
    43  func TestWsAcceptWithoutListen(t *testing.T) {
    44  	TranVerifyAcceptWithoutListen(t, tran)
    45  }
    46  func TestWsListenAndAccept(t *testing.T) {
    47  	TranVerifyListenAndAccept(t, tran, nil, nil)
    48  }
    49  func TestWsDuplicateListen(t *testing.T) {
    50  	TranVerifyDuplicateListen(t, tran, nil)
    51  }
    52  func TestWsConnectionRefused(t *testing.T) {
    53  	TranVerifyConnectionRefused(t, tran, nil)
    54  }
    55  func TestTcpHandshake(t *testing.T) {
    56  	TranVerifyHandshakeFail(t, tran, nil, nil)
    57  }
    58  func TestWsSendRecv(t *testing.T) {
    59  	TranVerifySendRecv(t, tran, nil, nil)
    60  }
    61  func TestWsAnonymousPort(t *testing.T) {
    62  	TranVerifyAnonymousPort(t, "ws://127.0.0.1:0/", nil, nil)
    63  }
    64  func TestWsInvalidDomain(t *testing.T) {
    65  	TranVerifyBadAddress(t, "ws://invalid.invalid/", nil, nil)
    66  }
    67  func TestWsInvalidURI(t *testing.T) {
    68  	TranVerifyBadAddress(t, "ws://127.0.0.1:80/\x01", nil, nil)
    69  }
    70  
    71  func TestWsInvalidLocalIP(t *testing.T) {
    72  	TranVerifyBadLocalAddress(t, "ws://1.1.1.1:80", nil)
    73  }
    74  func TestWsBroadcastIP(t *testing.T) {
    75  	TranVerifyBadAddress(t, "ws://255.255.255.255:80", nil, nil)
    76  }
    77  
    78  func TestWsListenerClosed(t *testing.T) {
    79  	TranVerifyListenerClosed(t, tran, nil)
    80  }
    81  
    82  func TestWsResolverChange(t *testing.T) {
    83  	sock := GetMockSocket()
    84  	defer MustClose(t, sock)
    85  
    86  	addr := AddrTestWS()
    87  	MustSucceed(t, sock.Listen(addr))
    88  
    89  	d, e := tran.NewDialer(addr, sock)
    90  	MustSucceed(t, e)
    91  	td := d.(*dialer)
    92  	addr = td.addr
    93  	td.addr = "ws://invalid.invalid:80"
    94  	p, e := d.Dial()
    95  	MustFail(t, e)
    96  	MustBeTrue(t, p == nil)
    97  
    98  	td.addr = addr
    99  	p, e = d.Dial()
   100  	MustSucceed(t, e)
   101  	MustSucceed(t, p.Close())
   102  }
   103  
   104  func TestWsPipeOptions(t *testing.T) {
   105  	TranVerifyPipeOptions(t, tran, nil, nil)
   106  }
   107  
   108  func TestWsMessageSize(t *testing.T) {
   109  	TranVerifyMessageSizes(t, tran, nil, nil)
   110  }
   111  
   112  func TestWsMessageHeader(t *testing.T) {
   113  	TranVerifyMessageHeader(t, tran, nil, nil)
   114  }
   115  func TestWsSendAbort(t *testing.T) {
   116  	wd := &websocket.Dialer{}
   117  	sock := GetMockSocket()
   118  	defer MustClose(t, sock)
   119  	addr := AddrTestWS()
   120  	l, e := sock.NewListener(addr, nil)
   121  	MustSucceed(t, e)
   122  	MustSucceed(t, l.Listen())
   123  
   124  	wd.Subprotocols = []string{sock.Info().PeerName + ".sp.nanomsg.org"}
   125  	ws, _, e := wd.Dial(addr, nil)
   126  	MustSucceed(t, e)
   127  	MustSend(t, sock, make([]byte, 2*1024*1024)) // TCP window size is 64k
   128  	time.Sleep(time.Millisecond * 100)
   129  	MustSucceed(t, ws.Close())
   130  	MustSend(t, sock, make([]byte, 2*1024*1024)) // TCP window size is 64k
   131  }
   132  
   133  func TestWsCheckOriginDefault(t *testing.T) {
   134  	sock := GetMockSocket()
   135  	defer MustClose(t, sock)
   136  	l, e := sock.NewListener(AddrTestWS(), nil)
   137  	MustSucceed(t, e)
   138  	v, e := l.GetOption(OptionWebSocketCheckOrigin)
   139  	MustSucceed(t, e)
   140  	b, ok := v.(bool)
   141  	MustBeTrue(t, ok)
   142  	MustBeTrue(t, b)
   143  
   144  	MustSucceed(t, l.SetOption(OptionWebSocketCheckOrigin, false))
   145  	MustSucceed(t, l.SetOption(OptionWebSocketCheckOrigin, true))
   146  }
   147  
   148  func TestWsCheckOriginDisabled(t *testing.T) {
   149  	sock := GetMockSocket()
   150  	defer MustClose(t, sock)
   151  	peer := GetMockSocket()
   152  	defer MustClose(t, peer)
   153  	addr := AddrTestWS()
   154  	l, e := sock.NewListener(addr, nil)
   155  	MustSucceed(t, l.SetOption(OptionWebSocketCheckOrigin, false))
   156  	MustSucceed(t, l.Listen())
   157  	MustSucceed(t, peer.Dial(addr))
   158  	MustSucceed(t, e)
   159  }
   160  
   161  func TestWsBadWsVersion(t *testing.T) {
   162  	sock := GetMockSocket()
   163  	defer MustClose(t, sock)
   164  	addr := AddrTestWS()
   165  	l, e := sock.NewListener(addr, nil)
   166  	MustSucceed(t, e)
   167  	MustSucceed(t, l.Listen())
   168  
   169  	url := "http://" + addr[len("ws://"):]
   170  	req, e := http.NewRequest("GET", url, strings.NewReader(""))
   171  	MustSucceed(t, e)
   172  	req.Header.Set("Sec-WebSocket-Version", "10")
   173  	req.Header.Set("Sec-WebSocket-Protocol", sock.Info().PeerName+".sp.nanomsg.org")
   174  
   175  	client := &http.Client{}
   176  	res, e := client.Do(req)
   177  	MustSucceed(t, e)
   178  	MustBeTrue(t, res.StatusCode == http.StatusBadRequest)
   179  }
   180  
   181  func TestWsCloseOneOfTwo(t *testing.T) {
   182  	sock1 := GetMockSocket()
   183  	defer MustClose(t, sock1)
   184  	sock2 := GetMockSocket()
   185  	defer MustClose(t, sock2)
   186  	peer := GetMockSocket()
   187  	defer MustClose(t, peer)
   188  
   189  	addr := AddrTestWS()
   190  	addr1 := addr + "redline"
   191  	l1, e := sock1.NewListener(addr1, nil)
   192  	MustSucceed(t, e)
   193  	MustSucceed(t, l1.Listen())
   194  
   195  	muxi, e := l1.GetOption(OptionWebSocketMux)
   196  	if e != nil {
   197  		t.Errorf("Failed get mux: %v", e)
   198  	}
   199  
   200  	addr2 := addr + "blueline"
   201  	l2, e := sock2.NewListener(addr2, nil)
   202  	MustSucceed(t, e)
   203  	i2, e := l2.GetOption(OptionWebSocketHandler)
   204  	MustSucceed(t, e)
   205  	h2, ok := i2.(http.Handler)
   206  	MustBeTrue(t, ok)
   207  
   208  	mux := muxi.(*http.ServeMux)
   209  	mux.Handle("/blueline", h2)
   210  
   211  	e = l2.Listen()
   212  	MustSucceed(t, e)
   213  
   214  	MustSucceed(t, l2.Close())
   215  
   216  	MustBeError(t, peer.Dial(addr2), mangos.ErrBadProto)
   217  	MustSucceed(t, peer.Dial(addr1))
   218  	// Nothing here, so that's a 404... which we treat as proto error.
   219  	MustBeError(t, peer.Dial(addr+"nobody"), mangos.ErrBadProto)
   220  }
   221  
   222  func TestWsClosePending(t *testing.T) {
   223  	addr := AddrTestWS()
   224  	sock1 := GetMockSocket()
   225  	defer MustClose(t, sock1)
   226  	sock2 := GetMockSocket()
   227  	defer MustClose(t, sock2)
   228  	sock3 := GetMockSocket()
   229  	defer MustClose(t, sock3)
   230  
   231  	l, e := Transport.NewListener(addr, sock1)
   232  	MustSucceed(t, e)
   233  	MustSucceed(t, l.Listen())
   234  
   235  	// We don't *accept* them.
   236  
   237  	MustSucceed(t, sock2.Dial(addr))
   238  	MustSucceed(t, sock3.Dial(addr))
   239  
   240  	time.Sleep(time.Millisecond * 100)
   241  	MustSucceed(t, l.Close())
   242  	time.Sleep(time.Millisecond * 100)
   243  }