webapi

package
v0.11.0-dev.1 Latest Latest
Warning

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

Go to latest
Published: Jun 6, 2023 License: AGPL-3.0 Imports: 31 Imported by: 0

Documentation

Index

Constants

View Source
const (
	LoggerTag     = "WEB_API"
	TransportName = "webapi"
)

Variables

This section is empty.

Functions

This section is empty.

Types

type AddressBook

type AddressBook interface {
	Consumers(ctx context.Context) ([]string, error)
}

AddressBook provides a list of addresses to which the messages should be sent.

type Config

type Config struct {
	// ListenAddr is the address of the HTTP server that is used to receive
	// messages. If used with TOR, server should listen on localhost.
	//
	// Ignored if Server is not nil.
	//
	// Cannot be empty if Server is nil.
	ListenAddr string

	// AddressBook provides the list of message consumers. All produced messages
	// will be sent only to consumers from the address book.
	//
	// Cannot be nil.
	AddressBook AddressBook

	// Topics is a list of subscribed topics. A value of the map a type of
	// message given as a nil pointer, e.g.: (*Message)(nil).
	Topics map[string]transport.Message

	// AuthorAllowlist is a list of allowed message authors. Only messages from
	// these addresses will be accepted.
	AuthorAllowlist []types.Address

	// FlushTicker specifies how often the producer will flush messages
	// to the consumers. If FlushTicker is nil, default ticker with 1 minute
	// interval is used.
	//
	// Flush interval must be less or equal to timeout.
	FlushTicker *timeutil.Ticker

	// Signer used to sign messages.
	// If not provided, message broadcast will not be available.
	Signer wallet.Key

	// Timeout is a timeout for HTTP requests.
	//
	// If timeout is zero, default value will be used (60 seconds).
	Timeout time.Duration

	// Server is an optional custom HTTP server that will be used to receive
	// messages. If provided, ListenAddr and Timeout are ignored.
	Server *httpserver.HTTPServer

	// Client is an optional custom HTTP client that will be used to send
	// messages. If provided, Timeout is ignored.
	Client *http.Client

	// Rand is an optional random number generator. If not provided, Reader
	// from crypto/rand package will be used.
	Rand io.Reader

	// MaxClockSkew is the maximum allowed clock skew between the consumer
	// and the producer. If not provided, default value will be used (10 seconds).
	MaxClockSkew time.Duration

	// Logger is a custom logger instance. If not provided then null
	// logger is used.
	Logger log.Logger
}

Config is a configuration of WebAPI.

type EthereumAddressBook

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

EthereumAddressBook is an AddressBook implementation that uses an Ethereum contract to store the list of addresses.

func NewEthereumAddressBook

func NewEthereumAddressBook(r rpc.RPC, addr types.Address, cacheTTL time.Duration) *EthereumAddressBook

NewEthereumAddressBook creates a new instance of EthereumAddressBook. The cacheTTL parameter specifies how long the list of addresses should be cached before it is fetched again from the Ethereum contract.

func (*EthereumAddressBook) Consumers

func (c *EthereumAddressBook) Consumers(ctx context.Context) ([]string, error)

Consumers implements the AddressBook interface.

type MultiAddressBook

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

MultiAddressBook is an implementation of AddressBook that merges the addresses from multiple AddressBook instances.

func NewMultiAddressBook

func NewMultiAddressBook(books ...AddressBook) *MultiAddressBook

NewMultiAddressBook creates a new instance of MultiAddressBook.

func (*MultiAddressBook) Consumers

func (m *MultiAddressBook) Consumers(ctx context.Context) ([]string, error)

Consumers implements the AddressBook interface.

type StaticAddressBook

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

StaticAddressBook is an implementation of AddressBook that returns a static list of addresses.

func NewStaticAddressBook

func NewStaticAddressBook(addresses []string) *StaticAddressBook

NewStaticAddressBook creates a new instance of StaticAddressBook.

func (*StaticAddressBook) Consumers

func (c *StaticAddressBook) Consumers(_ context.Context) ([]string, error)

Consumers implements the AddressBook interface.

type WebAPI

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

WebAPI is transport that uses HTTP API to send and receive messages. It is designed to use over secure network, e.g. Tor, I2P or VPN.

Transport involves two main actors: message producers and consumers.

Message producers are responsible for sending messages to the message consumers. List of addresses of message consumers is stored in the address book. Address book must implement the AddressBook interface.

Message producers prepares a batch of messages and send them periodically to the message consumers. The batch is sent as a single HTTP POST request. Each request is signed using the private key of the producer. The signature is sent in the query string of the request. The signature is calculated using the following formula:

signature = sign(timestamp + rand)

Where timestamp is the current UNIX timestamp in seconds encoded as a 10-base string, rand is a random 16-byte string encoded as a hex string. The sign function is provided by the Signer interface.

Signature is stored in three query parameters:

s - hex encoded signature
t - timestamp in seconds encoded as a 10-base string
r - 16-byte random string encoded as a hex string

Consumer verifies the signature and checks if message producer is on the allowlist. Timestamp must be within following ranges:

now - maxClockSkew <= timestamp <= now + flushInterval + maxClockSkew
lastRequest <= now + flushInterval - maxClockSkew

Where now is the current UNIX timestamp in seconds, lastRequest is the timestamp of the last request received from the message producer and timestamp is the timestamp from the t query parameter.

The purpose of the signature is to prevent replay attacks and to allow message consumers to quickly verify if the identity of the message producer.

The request body is a protobuf message (see pb/tor.proto) that contains the following fields:

messages - a list of messages grouped by topic
signature - signature of the message pack

The signature of the request body is calculated using Signer interface. The signing data is a concatenation of all messages in the batch prefixed with the topic name. Topics are sorted using sort.Strings function.

The author recovered from the signature must be the same as the author recovered from the signature in the query string. Otherwise, the request is rejected.

Request body is compressed using gzip compression. Requests that are not compressed or are not have a valid gzip header are rejected.

All request must have Content-Type header set to application/x-protobuf.

The HTTP server returns HTTP 200 OK response if the request is valid. Otherwise, it returns 429 Too Many Requests response if producer sends messages too often or 400 Bad Request response for any other error.

func New

func New(cfg Config) (*WebAPI, error)

New returns a new instance of WebAPI.

func (*WebAPI) Broadcast

func (w *WebAPI) Broadcast(topic string, message transport.Message) error

Broadcast implements the transport.Transport interface.

func (*WebAPI) Messages

func (w *WebAPI) Messages(topic string) <-chan transport.ReceivedMessage

Messages implements the transport.Transport interface.

func (*WebAPI) Start

func (w *WebAPI) Start(ctx context.Context) error

Start implements the supervisor.Supervisor interface.

func (*WebAPI) Wait

func (w *WebAPI) Wait() <-chan error

Wait implements the supervisor.Supervisor interface.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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