Skip to content

API Stubs #28

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Mar 29, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 25 additions & 18 deletions .github/fmt/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,26 +1,33 @@
#!/usr/bin/env bash

source .github/lib.sh
source .github/lib.sh || exit 1

if [[ $(gofmt -l -s .) != "" ]]; then
echo "files are not formatted correctly"
echo "please run:"
echo "gofmt -w -s ."
exit 1
fi
gen() {
# Unfortunately, this is the only way to ensure go.mod and go.sum are correct.
# See https://github.com/golang/go/issues/27005
go list ./... > /dev/null
go mod tidy

out=$(go run golang.org/x/tools/cmd/goimports -l -local=nhooyr.io/ws .)
if [[ $out != "" ]]; then
echo "imports are not formatted correctly"
echo "please run:"
echo "goimports -w -local=nhooyr.io/ws ."
exit 1
fi
go install golang.org/x/tools/cmd/stringer
go generate ./...
}

fmt() {
gofmt -w -s .
go run go.coder.com/go-tools/cmd/goimports -w "-local=$(go list -m)" .
go run mvdan.cc/sh/cmd/shfmt -w -s -sr .
}

gen
fmt

out=$(go run mvdan.cc/sh/cmd/shfmt -l -s -sr .)
if [[ $out != "" ]]; then
echo "shell scripts are not formatted correctly"
if [[ $CI && $(unstaged_files) != "" ]]; then
set +x
echo
echo "files either need generation or are formatted incorrectly"
echo "please run:"
echo "shfmt -w -s -sr ."
echo "./test.sh"
echo
git status
exit 1
fi
14 changes: 13 additions & 1 deletion .github/lib.sh
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,16 @@
set -euxo pipefail

export GO111MODULE=on
export GOFLAGS=-mod=readonly
export PAGER=cat

# shellcheck disable=SC2034
# CI is used by the scripts that source this file.
export CI=${GITHUB_ACTION-}

if [[ $CI ]]; then
export GOFLAGS=-mod=readonly
fi

unstaged_files() {
git ls-files --other --modified --exclude-standard
}
10 changes: 10 additions & 0 deletions .github/lint/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
FROM codercom/playcicache

LABEL "com.github.actions.name"="lint"
LABEL "com.github.actions.description"="lint"
LABEL "com.github.actions.icon"="code"
LABEL "com.github.actions.color"="purple"

COPY entrypoint.sh /entrypoint.sh

CMD ["/entrypoint.sh"]
11 changes: 11 additions & 0 deletions .github/lint/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/usr/bin/env bash

source .github/lib.sh || exit 1

(
shopt -s globstar nullglob dotglob
shellcheck ./**/*.sh
)

go vet -composites=false ./...
go run golang.org/x/lint/golint -set_exit_status ./...
6 changes: 5 additions & 1 deletion .github/main.workflow
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
workflow "main" {
on = "push"
resolves = ["fmt", "test"]
resolves = ["fmt", "lint", "test"]
}

action "lint" {
uses = "./.github/lint"
}

action "fmt" {
Expand Down
42 changes: 11 additions & 31 deletions .github/test/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,37 +1,17 @@
#!/usr/bin/env bash

source .github/lib.sh
source .github/lib.sh || exit 1

function gomod_help() {
echo
echo "you may need to update go.mod/go.sum via:"
echo "go list all > /dev/null"
echo "go mod tidy"
echo
echo "or git add files to staging"
exit 1
}

go list ./... > /dev/null || gomod_help
go mod tidy

# Until https://github.com/golang/go/issues/27005 the previous command can actually modify go.sum so we need to ensure its not changed.
if [[ $(git diff --name-only) != "" ]]; then
git diff
gomod_help
fi

mapfile -t scripts <<< "$(find . -type f -name "*.sh")"
shellcheck "${scripts[@]}"
COVERAGE_PROFILE=$(mktemp)
go test -race -v "-coverprofile=${COVERAGE_PROFILE}" -vet=off ./...
go tool cover "-func=${COVERAGE_PROFILE}"

go vet -composites=false ./...

go test -race -v -coverprofile=coverage.out -vet=off ./...

if [[ -z ${GITHUB_ACTION-} ]]; then
go tool cover -html=coverage.out
if [[ $CI ]]; then
bash <(curl -s https://codecov.io/bash) -f "$COVERAGE_PROFILE"
else
bash <(curl -s https://codecov.io/bash)
fi
go tool cover "-html=${COVERAGE_PROFILE}" -o=coverage.html

rm coverage.out
set +x
echo
echo "please open coverage.html to see detailed test coverage stats"
fi
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
coverage.html
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,32 @@ This library is in heavy development.
```bash
go get nhooyr.io/ws
```

## Why

There is no other Go WebSocket library with a clean API.

Comparisons with existing WebSocket libraries below.

### [x/net/websocket](https://godoc.org/golang.org/x/net/websocket)


Unmaintained and the API does not reflect WebSocket semantics.

See https://github.com/golang/go/issues/18152

### [gorilla/websocket](https://github.com/gorilla/websocket)

This package is the community standard but it is very old and over time
has accumulated cruft. There are many ways to do the same thing and the API
overall is just not very clear.

The callback hooks are also confusing. The API for this library has been designed
such that there is only one way to do things and callbacks have been avoided.

Performance sensitive applications should use ws/wscore directly.

## [gobwas/ws](https://github.com/gobwas/ws)

This library has an extremely flexible API but that comes at a cost of usability
and clarity. Its just not clear and simple how to do things in a safe manner.
37 changes: 37 additions & 0 deletions accept.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package ws

import (
"fmt"
"net/http"
)

// AcceptOption is an option that can be passed to Accept.
type AcceptOption interface {
acceptOption()
fmt.Stringer
}

// AcceptSubprotocols list the subprotocols that Accept will negotiate with a client.
// The first protocol that a client supports will be negotiated.
// Pass "" as a subprotocol if you would like to allow the default protocol.
func AcceptSubprotocols(subprotocols ...string) AcceptOption {
panic("TODO")
}

// AcceptOrigins lists the origins that Accept will accept.
// Accept will always accept r.Host as the origin so you do not need to
// specify that with this option.
// Use this option with caution to avoid exposing your WebSocket
// server to a CSRF attack.
// See https://stackoverflow.com/a/37837709/4283659
func AcceptOrigins(origins ...string) AcceptOption {
panic("TODO")
}

// Accept accepts a WebSocket handshake from a client and upgrades the
// the connection to WebSocket.
// Accept will reject the handshake if the Origin is not the same as the Host unless
// InsecureAcceptOrigin is passed.
func Accept(w http.ResponseWriter, r *http.Request, opts ...AcceptOption) (*Conn, error) {
panic("TODO")
}
15 changes: 15 additions & 0 deletions datatype.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package ws

import (
"nhooyr.io/ws/wscore"
)

// DataType represents the Opcode of a WebSocket data frame.
//go:generate stringer -type=DataType
type DataType int

// DataType constants.
const (
Text DataType = DataType(wscore.OpText)
Binary DataType = DataType(wscore.OpBinary)
)
25 changes: 25 additions & 0 deletions datatype_string.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 41 additions & 0 deletions dial.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package ws

import (
"context"
"encoding/base64"
"fmt"
"net/http"
)

// DialOption represents a dial option that can be passed to Dial.
type DialOption interface {
dialOption()
fmt.Stringer
}

// DialHTTPClient is the http client used for the handshake.
// Its Transport must use HTTP/1.1 and must return writable bodies
// for WebSocket handshakes.
// http.Transport does this correctly.
func DialHTTPClient(h *http.Client) DialOption {
panic("TODO")
}

// DialHeader are the HTTP headers included in the handshake request.
func DialHeader(h http.Header) DialOption {
panic("TODO")
}

// DialSubprotocols accepts a slice of protcols to include in the Sec-WebSocket-Protocol header.
func DialSubprotocols(subprotocols ...string) DialOption {
panic("TODO")
}

// We use this key for all client requests as the Sec-WebSocket-Key header is useless.
// See https://stackoverflow.com/a/37074398/4283659.
var secWebSocketKey = base64.StdEncoding.EncodeToString(make([]byte, 16))

// Dial performs a websocket handshake on the given url with the given options.
func Dial(ctx context.Context, u string, opts ...DialOption) (*Conn, *http.Response, error) {
panic("TODO")
}
2 changes: 2 additions & 0 deletions doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Package ws implements the WebSocket protocol defined in RFC 6455.
package ws
Loading