diff --git a/README.md b/README.md index fba08404..c9801498 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ func main() { } ``` -For a production quality example that shows off the low level API, see the [echo example](https://godoc.org/nhooyr.io/websocket#ex-Accept--Echo). +For a production quality example that shows off the low level API, see the echo example on the [godoc](https://godoc.org/nhooyr.io/websocket#Accept). ### Client diff --git a/go.mod b/go.mod index 60d1a3d0..3bce5bd6 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module nhooyr.io/websocket go 1.12 require ( + github.com/google/go-cmp v0.2.0 github.com/kr/pretty v0.1.0 // indirect go.coder.com/go-tools v0.0.0-20190317003359-0c6a35b74a16 golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3 diff --git a/go.sum b/go.sum index efb01309..9b7bf490 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= diff --git a/mask.go b/mask.go index 795d3660..6c67f1c0 100644 --- a/mask.go +++ b/mask.go @@ -1,15 +1,17 @@ package websocket -// Mask applies the WebSocket masking algorithm to p +// mask applies the WebSocket masking algorithm to p // with the given key where the first 3 bits of pos // are the starting position in the key. // See https://tools.ietf.org/html/rfc6455#section-5.3 // -// It is highly optimized to mask per word with the usage -// of unsafe. -// -// For targets that do not support unsafe, please report an issue. -// There is a mask by byte function below that will be used for such targets. +// The returned value is the position of the next byte +// to be used for masking in the key. This is so that +// unmasking can be performed without the entire frame. func mask(key [4]byte, pos int, p []byte) int { - panic("TODO") + for i := range p { + p[i] ^= key[pos&3] + pos++ + } + return pos & 3 } diff --git a/mask_test.go b/mask_test.go new file mode 100644 index 00000000..4a7b8c73 --- /dev/null +++ b/mask_test.go @@ -0,0 +1,24 @@ +package websocket + +import ( + "testing" + + "github.com/google/go-cmp/cmp" +) + +func Test_mask(t *testing.T) { + t.Parallel() + + key := [4]byte{0xa, 0xb, 0xc, 0xff} + p := []byte{0xa, 0xb, 0xc, 0xf2, 0xc} + pos := 0 + pos = mask(key, pos, p) + + if exp := []byte{0, 0, 0, 0x0d, 0x6}; !cmp.Equal(exp, p) { + t.Fatalf("unexpected mask: %v", cmp.Diff(exp, p)) + } + + if exp := 1; !cmp.Equal(exp, pos) { + t.Fatalf("unexpected mask pos: %v", cmp.Diff(exp, pos)) + } +}