websocket

package
v6.2.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 13, 2019 License: Apache-2.0 Imports: 14 Imported by: 0

README

websocket

Websocket is an extension package that makes the Teleport framework compatible with websocket protocol as specified in RFC 6455.

Usage

import ws "github.com/henrylee2cn/teleport/v6/mixer/websocket"

Test

import (
	"net/http"
	"testing"
	"time"

	tp "github.com/henrylee2cn/teleport/v6"
	ws "github.com/henrylee2cn/teleport/v6/mixer/websocket"
	"github.com/henrylee2cn/teleport/v6/mixer/websocket/jsonSubProto"
	"github.com/henrylee2cn/teleport/v6/plugin/auth"
)

type Arg struct {
	A int
	B int `param:"<range:1:>"`
}

type P struct{ tp.CallCtx }

func (p *P) Divide(arg *Arg) (int, *tp.Status) {
	return arg.A / arg.B, nil
}

func TestJSONWebsocket(t *testing.T) {
	srv := ws.NewServer("/", tp.PeerConfig{ListenPort: 9090})
	srv.RouteCall(new(P))
	go srv.ListenAndServe()

	time.Sleep(time.Second * 1)

	cli := ws.NewClient("/", tp.PeerConfig{})
	sess, stat := cli.Dial(":9090")
	if !stat.OK() {
		t.Fatal(stat)
	}
	var result int
	stat = sess.Call("/p/divide", &Arg{
		A: 10,
		B: 2,
	}, &result,
	).Status()
	if !stat.OK() {
		t.Fatal(stat)
	}
	t.Logf("10/2=%d", result)
	time.Sleep(time.Second)
}

func TestPbWebsocketTLS(t *testing.T) {
	srv := ws.NewServer("/abc", tp.PeerConfig{ListenPort: 9091})
	srv.RouteCall(new(P))
	srv.SetTLSConfig(tp.GenerateTLSConfigForServer())
	go srv.ListenAndServeProtobuf()

	time.Sleep(time.Second * 1)

	cli := ws.NewClient("/abc", tp.PeerConfig{})
	cli.SetTLSConfig(tp.GenerateTLSConfigForClient())
	sess, err := cli.DialProtobuf(":9091")
	if err != nil {
		t.Fatal(err)
	}
	var result int
	stat := sess.Call("/p/divide", &Arg{
		A: 10,
		B: 2,
	}, &result,
	).Status()
	if !stat.OK() {
		t.Fatal(stat)
	}
	t.Logf("10/2=%d", result)
	time.Sleep(time.Second)
}

func TestCustomizedWebsocket(t *testing.T) {
	srv := tp.NewPeer(tp.PeerConfig{})
	http.Handle("/ws", ws.NewJSONServeHandler(srv, nil))
	go http.ListenAndServe(":9092", nil)
	srv.RouteCall(new(P))
	time.Sleep(time.Second * 1)

	cli := tp.NewPeer(tp.PeerConfig{}, ws.NewDialPlugin("/ws"))
	sess, stat := cli.Dial(":9092", jsonSubProto.NewJSONSubProtoFunc())
	if !stat.OK() {
		t.Fatal(stat)
	}
	var result int
	stat = sess.Call("/p/divide", &Arg{
		A: 10,
		B: 2,
	}, &result,
	).Status()
	if !stat.OK() {
		t.Fatal(stat)
	}
	t.Logf("10/2=%d", result)
	time.Sleep(time.Second)
}

func TestJSONWebsocketAuth(t *testing.T) {
	srv := ws.NewServer(
		"/",
		tp.PeerConfig{ListenPort: 9090},
		authChecker,
	)
	srv.RouteCall(new(P))
	go srv.ListenAndServe()

	time.Sleep(time.Second * 1)

	cli := ws.NewClient(
		"/",
		tp.PeerConfig{},
		authBearer,
	)
	sess, stat := cli.Dial(":9090")
	if !stat.OK() {
		t.Fatal(stat)
	}
	var result int
	stat = sess.Call("/p/divide", &Arg{
		A: 10,
		B: 2,
	}, &result,
	).Status()
	if !stat.OK() {
		t.Fatal(stat)
	}
	t.Logf("10/2=%d", result)
	time.Sleep(time.Second)
}

const clientAuthInfo = "client-auth-info-12345"

var authBearer = auth.NewBearerPlugin(
	func(sess auth.Session, fn auth.SendOnce) (stat *tp.Status) {
		var ret string
		stat = fn(clientAuthInfo, &ret)
		if !stat.OK() {
			return
		}
		tp.Infof("auth info: %s, result: %s", clientAuthInfo, ret)
		return
	},
	tp.WithBodyCodec('s'),
)

var authChecker = auth.NewCheckerPlugin(
	func(sess auth.Session, fn auth.RecvOnce) (ret interface{}, stat *tp.Status) {
		var authInfo string
		stat = fn(&authInfo)
		if !stat.OK() {
			return
		}
		tp.Infof("auth info: %v", authInfo)
		if clientAuthInfo != authInfo {
			return nil, tp.NewStatus(403, "auth fail", "auth fail detail")
		}
		return "pass", nil
	},
	tp.WithBodyCodec('s'),
)

test command:

go test -v -run=TestJSONWebsocket
go test -v -run=TestPbWebsocketTLS
go test -v -run=TestCustomizedWebsocket
go test -v -run=TestJSONWebsocketAuth

Among them, TestJSONWebsocket's request body is:

{
  "seq": 0,
  "mtype": 1,
  "uri": "/p/divide",
  "meta": "",
  "body_codec": 106,
  "body": "{\"A\":10,\"B\":2}",
  "xfer_pipe": []
}

TestJSONWebsocket's response body is:

{
  "seq": 0,
  "mtype": 2,
  "uri": "/p/divide",
  "meta": "",
  "body_codec": 106,
  "body": "5",
  "xfer_pipe": []
}

Documentation

Overview

Package websocket is an extension package that makes the Teleport framework compatible with websocket protocol as specified in RFC 6455.

Copyright 2018 HenryLee. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewDialPlugin

func NewDialPlugin(rootPath string) tp.Plugin

NewDialPlugin creates a websocket plugin for client.

func NewJSONServeHandler

func NewJSONServeHandler(peer tp.Peer, handshake func(*ws.Config, *http.Request) error) http.Handler

NewJSONServeHandler creates a websocket json handler.

func NewPbServeHandler

func NewPbServeHandler(peer tp.Peer, handshake func(*ws.Config, *http.Request) error) http.Handler

NewPbServeHandler creates a websocket protobuf handler.

func NewServeHandler

func NewServeHandler(peer tp.Peer, handshake func(*ws.Config, *http.Request) error, protoFunc ...tp.ProtoFunc) http.Handler

NewServeHandler creates a websocket handler.

func NewWsProtoFunc

func NewWsProtoFunc(subProto ...tp.ProtoFunc) tp.ProtoFunc

NewWsProtoFunc wraps a protocol to a new websocket protocol.

Types

type Client

type Client struct {
	tp.Peer
}

Client a websocket client

func NewClient

func NewClient(rootPath string, cfg tp.PeerConfig, globalLeftPlugin ...tp.Plugin) *Client

NewClient creates a websocket client.

func (*Client) Dial

func (c *Client) Dial(addr string, protoFunc ...tp.ProtoFunc) (tp.Session, *tp.Status)

Dial connects with the peer of the destination address.

func (*Client) DialJSON

func (c *Client) DialJSON(addr string) (tp.Session, *tp.Status)

DialJSON connects with the JSON protocol.

func (*Client) DialProtobuf

func (c *Client) DialProtobuf(addr string) (tp.Session, *tp.Status)

DialProtobuf connects with the Protobuf protocol.

type Server

type Server struct {
	tp.Peer
	// contains filtered or unexported fields
}

Server a websocket server

func NewServer

func NewServer(rootPath string, cfg tp.PeerConfig, globalLeftPlugin ...tp.Plugin) *Server

NewServer creates a websocket server.

func (*Server) Close

func (srv *Server) Close() error

Close closes the server.

func (*Server) Handle

func (srv *Server) Handle(rootPath string, handler http.Handler)

Handle registers the handler for the given rootPath. If a handler already exists for rootPath, Handle panics.

func (*Server) HandleFunc

func (srv *Server) HandleFunc(rootPath string, handler func(http.ResponseWriter, *http.Request))

HandleFunc registers the handler function for the given rootPath.

func (*Server) ListenAndServe

func (srv *Server) ListenAndServe(protoFunc ...tp.ProtoFunc) (err error)

ListenAndServe listens on the TCP network address addr and then calls Serve with handler to handle requests on incoming connections. Accepted connections are configured to enable TCP keep-alives.

The handler is typically nil, in which case the DefaultServeMux is used.

ListenAndServe always returns a non-nil error.

If protoFunc is empty, JSON is used by default.

func (*Server) ListenAndServeJSON

func (srv *Server) ListenAndServeJSON() error

ListenAndServeJSON listen and serve with the JSON protocol.

func (*Server) ListenAndServeProtobuf

func (srv *Server) ListenAndServeProtobuf() error

ListenAndServeProtobuf listen and serve with the Protobuf protocol.

func (*Server) SetHandshake

func (srv *Server) SetHandshake(handshake func(*ws.Config, *http.Request) error)

SetHandshake sets customized handshake function.

Directories

Path Synopsis
Package jsonSubProto is implemented JSON socket communication protocol.
Package jsonSubProto is implemented JSON socket communication protocol.
Package pbSubProto is implemented PROTOBUF socket communication protocol.
Package pbSubProto is implemented PROTOBUF socket communication protocol.
pb
Package websocket implements a client and server for the WebSocket protocol as specified in RFC 6455.
Package websocket implements a client and server for the WebSocket protocol as specified in RFC 6455.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL