jsoffnet

package
v0.6.0 Latest Latest
Warning

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

Go to latest
Published: Feb 2, 2024 License: MIT Imports: 27 Imported by: 8

Documentation

Overview

interacting jsonrpc in http family specs, currently jsoffnet provides 3 mechanisms: the classical http/1.1, websocket and http/2 wire protocol.

Index

Constants

View Source
const (
	TransportHTTP      = "http"
	TransportWebsocket = "websocket"
	TransportHTTP2     = "http2"
	TransportTCP       = "tcp"
	TransportVsock     = "vsock"
)

Variables

View Source
var TransportClosed = errors.New("streaming closed")
View Source
var TransportConnectFailed = errors.New("connect refused")

errors

Functions

func ListenAndServe

func ListenAndServe(rootCtx context.Context, bind string, handler http.Handler, tlsConfigs ...*TLSConfig) error

func Logger

func Logger(r *http.Request) *log.Entry

log attaching remoteAddr

Types

type Actor

type Actor struct {
	ValidateSchema   bool
	RecoverFromPanic bool
	// contains filtered or unexported fields
}

func NewActor

func NewActor() *Actor

func (*Actor) AddChild

func (self *Actor) AddChild(child *Actor)

func (*Actor) Feed

func (self *Actor) Feed(req *RPCRequest) (jsoff.Message, error)

give the actor a request message

func (Actor) GetSchema

func (self Actor) GetSchema(method string) (jsoffschema.Schema, bool)

get the schema of a method

func (*Actor) HandleClose

func (self *Actor) HandleClose(session RPCSession)

call the close handler if possible

func (Actor) Has

func (self Actor) Has(method string) bool

returns there is a handler for a method

func (Actor) MethodList

func (self Actor) MethodList() []string

func (*Actor) Off

func (self *Actor) Off(method string)

Off unregister the method from handlers

func (*Actor) On

func (self *Actor) On(method string, callback MsgCallback, setters ...HandlerSetter)

register a method handler

func (*Actor) OnClose

func (self *Actor) OnClose(handler CloseCallback) error

OnClose handler is called when the stream beneath the actor is closed

func (*Actor) OnContext

func (self *Actor) OnContext(method string, callback ContextedMsgCallback, setters ...HandlerSetter)

func (*Actor) OnMissing

func (self *Actor) OnMissing(handler MissingCallback) error

register a callback called when no hander to handle a request message or non-request message met

func (*Actor) OnRequest

func (self *Actor) OnRequest(method string, callback RequestCallback, setters ...HandlerSetter) error

func (*Actor) OnTyped

func (self *Actor) OnTyped(method string, typedHandler interface{}, setters ...HandlerSetter)

register a typed method handler

func (*Actor) OnTypedContext

func (self *Actor) OnTypedContext(method string, typedHandler interface{}, setters ...HandlerSetter) error

func (*Actor) OnTypedRequest

func (self *Actor) OnTypedRequest(method string, typedHandler interface{}, setters ...HandlerSetter) error

type AuthConfig

type AuthConfig struct {
	Basic  []BasicAuthConfig  `yaml:"basic,omitempty" json:"basic,omitempty"`
	Bearer []BearerAuthConfig `yaml:"bearer,omitempty" json:"bearer,omitempty"`
	Jwt    *JwtAuthConfig     `yaml:"jwt,omitempty" json:"jwt,omitempty"`
}

func (*AuthConfig) ValidateValues

func (self *AuthConfig) ValidateValues() error

Auth config

type AuthHandler

type AuthHandler struct {
	// contains filtered or unexported fields
}

Auth handler

func NewAuthHandler

func NewAuthHandler(authConfig *AuthConfig, next http.Handler) *AuthHandler

func (*AuthHandler) ServeHTTP

func (self *AuthHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)

func (AuthHandler) TryAuth

func (self AuthHandler) TryAuth(r *http.Request) (*AuthInfo, bool)

type AuthInfo

type AuthInfo struct {
	Username string
	Settings map[string]interface{}
}

func AuthInfoFromContext

func AuthInfoFromContext(ctx context.Context) (*AuthInfo, bool)

type BasicAuthConfig

type BasicAuthConfig struct {
	Username string                 `yaml:"username" json:"username"`
	Password string                 `yaml:"password" json:"password"`
	Settings map[string]interface{} `yaml:"settings,omitempty" json:"settings.omitempty"`
}

type BearerAuthConfig

type BearerAuthConfig struct {
	Token string `yaml:"token" json:"token"`

	// username attached to request when token authorized
	Username string                 `yaml:"username,omitempty" json:"username,omitempty"`
	Settings map[string]interface{} `yaml:"settings,omitempty" json:"settings.omitempty"`
}

type Client

type Client interface {
	// Returns the server URL
	ServerURL() *url.URL

	// Call a Request message and expect a Result|Error message.
	Call(ctx context.Context, reqmsg *jsoff.RequestMessage) (jsoff.Message, error)

	// Call a Request message and unwrap the result message into a
	// given structure, when an Error message comes it is turned
	// into a golang error object typed *jsoff.ErrorBody
	UnwrapCall(ctx context.Context, reqmsg *jsoff.RequestMessage, output interface{}) error

	// Send a JSONRPC message(usually a notify) to server without
	// expecting any result.
	Send(ctx context.Context, msg jsoff.Message) error

	// Set the client tls config
	SetClientTLSConfig(cfg *tls.Config)

	// Set http header
	SetExtraHeader(h http.Header)

	// Is streaming
	IsStreaming() bool
}

Client is an abstract interface a client type must implement

func NewClient

func NewClient(serverUrl string, optlist ...ClientOptions) (Client, error)

NewClient returns an JSONRPC client whose type depends on the server url it wants to connect to. Currently there are 3 types of supported url schemes: the HTTP/1.1 client, the websocket based client and HTTP2 base client, the latter two types are streaming clients which can accept server push messages.

type ClientOptions

type ClientOptions struct {
	// client request timeout
	Timeout int `json:"timeout" yaml:"timeout"`
}

type CloseCallback

type CloseCallback func(session RPCSession)

type CloseCallback func(r *http.Request, session RPCSession)

type CloseHandler

type CloseHandler func()

type ConnectedHandler

type ConnectedHandler func()

type ContextSpec

type ContextSpec struct{}

func (ContextSpec) Check

func (self ContextSpec) Check(firstArgType reflect.Type) bool

func (ContextSpec) String

func (self ContextSpec) String() string

func (ContextSpec) Value

func (self ContextSpec) Value(req *RPCRequest) interface{}

type ContextedMsgCallback

type ContextedMsgCallback func(ctx context.Context, params []interface{}) (interface{}, error)

type FirstArgSpec

type FirstArgSpec interface {
	Check(firstArgType reflect.Type) bool
	Value(req *RPCRequest) interface{}
	String() string
}

type GatewayHandler

type GatewayHandler struct {
	Actor *Actor
	// contains filtered or unexported fields
}

shared handler serve http1/http2/websocket server over the same port using http protocol detection.

NOTE: gateway handler must work over TLS to serve h2

func NewGatewayHandler

func NewGatewayHandler(serverCtx context.Context, actor *Actor, insecure bool) *GatewayHandler

func (*GatewayHandler) ServeHTTP

func (self *GatewayHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)

type HandlerSetter

type HandlerSetter func(h *MethodHandler)

func WithSchema

func WithSchema(s jsoffschema.Schema) HandlerSetter

func WithSchemaJson

func WithSchemaJson(jsonSchema string) HandlerSetter

func WithSchemaYaml

func WithSchemaYaml(yamlSchema string) HandlerSetter

type HeaderFlags

type HeaderFlags []string

func (*HeaderFlags) Parse

func (self *HeaderFlags) Parse() (http.Header, error)

func (*HeaderFlags) Set

func (self *HeaderFlags) Set(value string) error

func (*HeaderFlags) String

func (self *HeaderFlags) String() string

type Http1Client

type Http1Client struct {
	// contains filtered or unexported fields
}

func NewHttp1Client

func NewHttp1Client(serverUrl *url.URL, optlist ...ClientOptions) *Http1Client

func (*Http1Client) Call

func (self *Http1Client) Call(rootCtx context.Context, reqmsg *jsoff.RequestMessage) (jsoff.Message, error)

func (*Http1Client) IsStreaming

func (self *Http1Client) IsStreaming() bool

func (*Http1Client) Send

func (self *Http1Client) Send(rootCtx context.Context, msg jsoff.Message) error

func (*Http1Client) ServerURL

func (self *Http1Client) ServerURL() *url.URL

func (*Http1Client) SetClientTLSConfig

func (self *Http1Client) SetClientTLSConfig(cfg *tls.Config)

func (*Http1Client) SetExtraHeader

func (self *Http1Client) SetExtraHeader(h http.Header)

func (*Http1Client) UnwrapCall

func (self *Http1Client) UnwrapCall(rootCtx context.Context, reqmsg *jsoff.RequestMessage, output interface{}) error

type Http1Handler

type Http1Handler struct {
	Actor *Actor
}

func NewHttp1Handler

func NewHttp1Handler(actor *Actor) *Http1Handler

func (*Http1Handler) ServeHTTP

func (self *Http1Handler) ServeHTTP(w http.ResponseWriter, r *http.Request)

func (Http1Handler) WriteMessage added in v0.5.8

func (self Http1Handler) WriteMessage(w http.ResponseWriter, msg jsoff.Message, code int)

type Http2Client

type Http2Client struct {
	StreamingClient

	// use h2c
	UseHttp2C bool
	// contains filtered or unexported fields
}

func NewHttp2Client

func NewHttp2Client(serverUrl *url.URL) *Http2Client

func (*Http2Client) HTTPClient

func (self *Http2Client) HTTPClient() *http.Client

func (*Http2Client) String

func (self *Http2Client) String() string

type Http2Handler

type Http2Handler struct {
	Actor *Actor

	// options
	SpawnGoroutine bool
	UseHttp2C      bool
	// contains filtered or unexported fields
}

func NewHttp2Handler

func NewHttp2Handler(serverCtx context.Context, actor *Actor) *Http2Handler

func (*Http2Handler) FallbackHandler

func (self *Http2Handler) FallbackHandler() *Http1Handler

func (*Http2Handler) Http2CHandler

func (self *Http2Handler) Http2CHandler() http.Handler

func (*Http2Handler) ServeHTTP

func (self *Http2Handler) ServeHTTP(w http.ResponseWriter, r *http.Request)

type Http2Session

type Http2Session struct {
	// contains filtered or unexported fields
}

func (Http2Session) Context added in v0.5.4

func (self Http2Session) Context() context.Context

func (*Http2Session) Send

func (self *Http2Session) Send(msg jsoff.Message)

func (Http2Session) SessionID

func (self Http2Session) SessionID() string

type JwtAuthConfig

type JwtAuthConfig struct {
	Secret string `yaml:"secret" json:"secret"`
}

type MessageHandler

type MessageHandler func(msg jsoff.Message)

type MethodHandler

type MethodHandler struct {
	// contains filtered or unexported fields
}

With method handler

type MissingCallback

type MissingCallback func(req *RPCRequest) (interface{}, error)

type MsgCallback

type MsgCallback func(params []interface{}) (interface{}, error)

type RPCRequest

type RPCRequest struct {
	// contains filtered or unexported fields
}

http rpc quest structure

func NewRPCRequest

func NewRPCRequest(ctx context.Context, msg jsoff.Message, transportType string) *RPCRequest

func (RPCRequest) Context

func (self RPCRequest) Context() context.Context

func (RPCRequest) Data

func (self RPCRequest) Data() interface{}

func (RPCRequest) HttpRequest

func (self RPCRequest) HttpRequest() *http.Request

func (RPCRequest) Log

func (self RPCRequest) Log() *log.Entry

func (RPCRequest) Msg

func (self RPCRequest) Msg() jsoff.Message

func (RPCRequest) Session

func (self RPCRequest) Session() RPCSession

func (*RPCRequest) WithHTTPRequest

func (self *RPCRequest) WithHTTPRequest(r *http.Request) *RPCRequest

func (*RPCRequest) WithSession

func (self *RPCRequest) WithSession(session RPCSession) *RPCRequest

type RPCSession

type RPCSession interface {
	Context() context.Context
	Send(msg jsoff.Message)
	SessionID() string
}

type ReqSpec

type ReqSpec struct{}

func (ReqSpec) Check

func (self ReqSpec) Check(firstArgType reflect.Type) bool

func (ReqSpec) String

func (self ReqSpec) String() string

func (ReqSpec) Value

func (self ReqSpec) Value(req *RPCRequest) interface{}

type RequestCallback

type RequestCallback func(req *RPCRequest, params []interface{}) (interface{}, error)

handler func

type SimpleResponse

type SimpleResponse struct {
	Code int
	Body []byte
}

Simple HTTP response to instant return

func (SimpleResponse) Error

func (self SimpleResponse) Error() string

type Streamable

type Streamable interface {
	Client

	Connect(ctx context.Context) error
	OnConnected(handler ConnectedHandler) error
	OnMessage(handler MessageHandler) error
	OnClose(handler CloseHandler) error
	Wait() error
}

type StreamingClient

type StreamingClient struct {
	// contains filtered or unexported fields
}

func (*StreamingClient) Call

func (self *StreamingClient) Call(rootCtx context.Context, reqmsg *jsoff.RequestMessage) (jsoff.Message, error)

func (*StreamingClient) ClientTLSConfig

func (self *StreamingClient) ClientTLSConfig() *tls.Config

func (*StreamingClient) Close

func (self *StreamingClient) Close()

func (*StreamingClient) CloseChannel

func (self *StreamingClient) CloseChannel() chan error

func (*StreamingClient) Connect

func (self *StreamingClient) Connect(rootCtx context.Context) error

func (*StreamingClient) Connected

func (self *StreamingClient) Connected() bool

func (*StreamingClient) InitStreaming

func (self *StreamingClient) InitStreaming(serverUrl *url.URL, transport Transport)

func (*StreamingClient) IsStreaming

func (self *StreamingClient) IsStreaming() bool

func (*StreamingClient) Log

func (self *StreamingClient) Log() *log.Entry

func (*StreamingClient) OnClose

func (self *StreamingClient) OnClose(handler CloseHandler) error

func (*StreamingClient) OnConnected

func (self *StreamingClient) OnConnected(handler ConnectedHandler) error

func (*StreamingClient) OnMessage

func (self *StreamingClient) OnMessage(handler MessageHandler) error

func (*StreamingClient) Reset

func (self *StreamingClient) Reset(err error)

func (*StreamingClient) Send

func (self *StreamingClient) Send(rootCtx context.Context, msg jsoff.Message) error

func (*StreamingClient) ServerURL

func (self *StreamingClient) ServerURL() *url.URL

func (*StreamingClient) SetClientTLSConfig

func (self *StreamingClient) SetClientTLSConfig(cfg *tls.Config)

func (*StreamingClient) SetExtraHeader

func (self *StreamingClient) SetExtraHeader(h http.Header)

func (*StreamingClient) UnwrapCall

func (self *StreamingClient) UnwrapCall(rootCtx context.Context, reqmsg *jsoff.RequestMessage, output interface{}) error

func (*StreamingClient) Wait

func (self *StreamingClient) Wait() error

wait connection close and return error

type TCPClient

type TCPClient struct {
	StreamingClient
}

func NewTCPClient

func NewTCPClient(serverUrl *url.URL) *TCPClient

func (*TCPClient) String

func (self *TCPClient) String() string

type TCPServer

type TCPServer struct {
	Actor *Actor
	// contains filtered or unexported fields
}

func NewTCPServer

func NewTCPServer(serverCtx context.Context, actor *Actor) *TCPServer

func (*TCPServer) Start

func (self *TCPServer) Start(rootCtx context.Context, bind string) error

func (*TCPServer) Stop added in v0.5.7

func (self *TCPServer) Stop()

type TCPSession

type TCPSession struct {
	// contains filtered or unexported fields
}

tcp session implements RPCSession

func (TCPSession) Context added in v0.5.4

func (self TCPSession) Context() context.Context

func (*TCPSession) Send

func (self *TCPSession) Send(msg jsoff.Message)

func (TCPSession) SessionID

func (self TCPSession) SessionID() string

type TLSConfig

type TLSConfig struct {
	Certfile string
	Keyfile  string
}

func (*TLSConfig) ValidateValues

func (self *TLSConfig) ValidateValues() error

type Transport

type Transport interface {
	Connect(rootCtx context.Context, serverUrl *url.URL, header http.Header) error
	Close()
	Connected() bool
	ReadMessage() (msg jsoff.Message, readed bool, err error)
	WriteMessage(msg jsoff.Message) error
}

the underline transport, currently there are websocket, h2 and net socket implementations

type VsockClient

type VsockClient struct {
	StreamingClient
}

func NewVsockClient

func NewVsockClient(serverUrl *url.URL) *VsockClient

func (*VsockClient) String

func (self *VsockClient) String() string

type VsockServer

type VsockServer struct {
	Actor *Actor
	// contains filtered or unexported fields
}

func NewVsockServer

func NewVsockServer(serverCtx context.Context, actor *Actor) *VsockServer

func (*VsockServer) Start

func (self *VsockServer) Start(rootCtx context.Context, port uint32) error

func (*VsockServer) Stop added in v0.5.7

func (self *VsockServer) Stop()

type VsockSession

type VsockSession struct {
	// contains filtered or unexported fields
}

vsock session implements RPCSession

func (VsockSession) Context added in v0.5.4

func (self VsockSession) Context() context.Context

func (*VsockSession) Send

func (self *VsockSession) Send(msg jsoff.Message)

func (VsockSession) SessionID

func (self VsockSession) SessionID() string

type WSClient

type WSClient struct {
	StreamingClient
}

func NewWSClient

func NewWSClient(serverUrl *url.URL) *WSClient

func (*WSClient) String

func (self *WSClient) String() string

type WSHandler

type WSHandler struct {
	Actor *Actor

	// options
	SpawnGoroutine bool
	// contains filtered or unexported fields
}

func NewWSHandler

func NewWSHandler(serverCtx context.Context, actor *Actor) *WSHandler

func (*WSHandler) ServeHTTP

func (self *WSHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)

type WSSession

type WSSession struct {
	// contains filtered or unexported fields
}

func (WSSession) Context added in v0.5.4

func (self WSSession) Context() context.Context

func (*WSSession) Send

func (self *WSSession) Send(msg jsoff.Message)

func (WSSession) SessionID

func (self WSSession) SessionID() string

type WrappedResponse

type WrappedResponse struct {
	Response *http.Response
	Body     []byte
}

errors non standard Response returned by endpoints

func (WrappedResponse) Error

func (self WrappedResponse) Error() string

Jump to

Keyboard shortcuts

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