github.com/simonmittag/ws@v1.1.0-rc.5.0.20210419231947-82b846128245/tests/deflate_test.go (about)

     1  package tests
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"io"
     7  	"net"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/gobwas/httphead"
    12  	"github.com/simonmittag/ws"
    13  	"github.com/simonmittag/ws/wsflate"
    14  	"github.com/simonmittag/ws/wsutil"
    15  )
    16  
    17  func TestFlateClientServer(t *testing.T) {
    18  	e := wsflate.Extension{
    19  		Parameters: wsflate.DefaultParameters,
    20  	}
    21  	client, server := net.Pipe()
    22  
    23  	serverDone := make(chan error)
    24  	go func() {
    25  		defer func() {
    26  			client.Close()
    27  			close(serverDone)
    28  		}()
    29  		u := ws.Upgrader{
    30  			Negotiate: e.Negotiate,
    31  		}
    32  		_, err := u.Upgrade(client)
    33  		if err != nil {
    34  			serverDone <- err
    35  			return
    36  		}
    37  		var buf bytes.Buffer
    38  		for {
    39  			frame, err := ws.ReadFrame(client)
    40  			if err != nil {
    41  				serverDone <- err
    42  				return
    43  			}
    44  			frame = ws.UnmaskFrameInPlace(frame)
    45  			frame, err = wsflate.DecompressFrameBuffer(&buf, frame)
    46  			if err != nil {
    47  				serverDone <- err
    48  				return
    49  			}
    50  			echo := ws.NewTextFrame(reverse(frame.Payload))
    51  			if err := ws.WriteFrame(client, echo); err != nil {
    52  				serverDone <- err
    53  				return
    54  			}
    55  			buf.Reset()
    56  		}
    57  	}()
    58  
    59  	d := ws.Dialer{
    60  		Extensions: []httphead.Option{
    61  			e.Parameters.Option(),
    62  		},
    63  		NetDial: func(_ context.Context, network, addr string) (net.Conn, error) {
    64  			return server, nil
    65  		},
    66  	}
    67  	dd := wsutil.DebugDialer{
    68  		Dialer: d,
    69  		OnRequest: func(p []byte) {
    70  			t.Logf("Request:\n%s", p)
    71  		},
    72  		OnResponse: func(p []byte) {
    73  			t.Logf("Response:\n%s", p)
    74  		},
    75  	}
    76  	conn, _, _, err := dd.Dial(context.Background(), "ws://stubbed")
    77  	if err != nil {
    78  		t.Fatalf("unexpected Dial() error: %v", err)
    79  	}
    80  
    81  	payload := []byte("hello, deflate!")
    82  
    83  	frame := ws.NewTextFrame(payload)
    84  	frame, err = wsflate.CompressFrame(frame)
    85  	if err != nil {
    86  		t.Fatalf("can't compress frame: %v", err)
    87  	}
    88  	frame = ws.MaskFrameInPlace(frame)
    89  	if err := ws.WriteFrame(server, frame); err != nil {
    90  		t.Fatalf("unexpected WriteFrame() error: %v", err)
    91  	}
    92  
    93  	echo, err := ws.ReadFrame(server)
    94  	if err != nil {
    95  		t.Fatalf("unexpected ReadFrame() error: %v", err)
    96  	}
    97  	if !bytes.Equal(reverse(echo.Payload), payload) {
    98  		t.Fatalf("unexpected echoed bytes")
    99  	}
   100  
   101  	conn.Close()
   102  
   103  	const timeout = time.Second
   104  	select {
   105  	case <-time.After(timeout):
   106  		t.Fatalf("server goroutine timeout: %s", timeout)
   107  
   108  	case err := <-serverDone:
   109  		if err != io.EOF {
   110  			t.Fatalf("unexpected server goroutine error: %v", err)
   111  		}
   112  	}
   113  }
   114  
   115  func reverse(buf []byte) []byte {
   116  	for i, j := 0, len(buf)-1; i < j; i, j = i+1, j-1 {
   117  		buf[i], buf[j] = buf[j], buf[i]
   118  	}
   119  	return buf
   120  }