package http

import "github.com/Diarkis/diarkis/server/http"

Package http ▷

HTTP - Client entry point and router

Routes clients to UDP/RUDP, and/or TCP servers.

Configurations

HTTP configurations are explained below.

{
  "address": "127.0.0.1",
  "port": "7000",
  "enableEncryption": true,
  "useFixedPort": false,
  "timeout": 5
}

▶︎ Configuration Values

address - Default is "127.0.0.1"

Address for HTTP server to bind with.

port - Default is "7000"

Outbound port for the UDP/RUDP server to communicate with the client. The value of port will be used as the starting point if the given port is not available to look for available port automatically. By setting useFixedPort to true will disable the auto discovery of port.

enableEncryption - Default is true

Enable or disable packet encryption and decryption of UDP/RDUP and TCP server. The configuration must match the UDP/RUDP and TCP server to function correctly.

useFixedPort - Default is false

Enable or disable auto discovery of port. If set to true, the server will not look for available port if the given port is not available. If you are planning of having multiple HTTP servers running in your Diarkis application cluster, make sure to set this value to false.

timeout - Defines request timeout in seconds. Default is 5 seconds.

If the server takes longer than the timeout defined, the server will respond with status 500.

Endpoint API

HTTP server serves as the gateway for UDP and/or TCP servers. The client may fetch the server endpoint based on the server type.

Standard endpoint fetching and a new user creation:

The request shown below will create a new user on one of the requested server type server process and the response will contain the endpoint for that server along with encryption keys.

▶︎ DGS node/server role

Endpoint API does NOT allow DGS to be queried.

GET /endpoint/type/$(ServerType)/user/$(UserID)

▶︎ Response JSON

{
	"serverType":       "$(ServerType)",
	"serverHost":       "$(ServerHost)",
	"serverPort":       $(ServerPort)
	"encryptionKey":    "xxxx",
	"encryptionIV":     "yyyy",
	"encryptionMacKey": "zzzz",
	"sid":              "aaaa"
}

The POST endpoint request will work exactly the same with GET request, but all the request body will be automatically stored as user properties so that you may use them once you make the connection.

POST /endpoint/type/$(ServerType)/user/$(UserID)

▶︎ Request Body format:

Request body will follow name=value format and separated by an & if there will be more than one name and value set.

[IMPORTANT] Currently user data does NOT automatically URL decode request body data if URL encoded.

▶︎ Example With Form:

foo=foo&bar=1234567&flag=true

The above will be translated to the following as user property data. Each value is stored as a string.

foo  = "foo"
bar  = "123456"
flag = "true"

▶︎ Example With JSON (Content-Type:application/json header must be provided):

If Content-Type:application/json header is provided, The API will read the request body as JSON.

{ "foo": "foo", "bar": 123456, "flag": true }

The above JSON request body will be translated to the following as user property data:

All values will be interface{} and they must be type asserted before using them.

foo  = "foo"
bar  = 123456
flag = true

Health Check API

HTTP server comes with an API for health check. The API returns "OK" as a response with HTTP status code 200.

GET /healthcheck

Metrics API

HTTP server also serves as metrics API endpoint. The metrics is formatted for Prometheus data structure or JSON.

▶︎ Metrics provides a snapshot of every 2 seconds.

For Prometheus version <= 2.3.2

GET /metrics/prometheus

For Prometheus version > 2.3.2 and < 2.31

GET /metrics/prometheus/v/2

For Prometheus version > 2.31

GET /metrics/prometheus/v/3

SharedData API

SharedData API allows you to manipulate mesh module's SharedData.

▶︎ Set SharedData

POST /shareddata/set/name/:name/value/:value

▶︎ Remove SharedData

POST /shareddata/remove/name/:name

Index

Constants

const Bad = 400

Bad HTTP status code 400

const Err = 500

Err HTTP status code 500

const NoService = 503

NoService HTTP status code 503

const NotFound = 404

NotFound HTTP status code 404

const Ok = 200

Ok HTTP status code 200

const Type = "HTTP"

Type Mesh network server type for HTTP server

Functions

func Command

func Command(method string, uri string, handler func(*Response, *Request, *Params, func(error)))

Command Registers a handler for a given URL

func CommandWithoutAuth

func CommandWithoutAuth(method string, uri string, handler func(*Response, *Request, *Params, func(error)))

CommandWithoutAuth Registers a handler for a given URL which does not require a client key to be provided

func Delete

func Delete(uri string, handler func(*Response, *Request, *Params, func(error)))

Delete Registers a handler for a DELETE method URL

func ExposeDebugAPI

func ExposeDebugAPI()

ExposeDebugAPI exposes debug APIs

--------------------------------------------------

Get the list of available server addresses.

The addresses are public addresses.

GET /debug/server/list/type/:serverType

serverType - TCP, UDP or custom server type.

--------------------------------------------------

Get the endpoint of the server by its public address.

The API allows you to choose which server to create a new user on.

GET /debug/endpoint/type/:serverType/user/:uid/address/:addr

POST /debug/endpoint/type/:serverType/user/:uid/address/:addr

serverType - TCP, UDP or custom server type.

uid - User ID

addr - Server address and port: format 0.0.0.0:8888

POST Request

▶︎ Request Body format:

Request body will follow name=value format and separated by an & if there will be more than one name and value set.

[IMPORTANT] Currently user data does NOT automatically URL decode request body data if URL encoded.

▶︎ Example With Form:

foo=foo&bar=1234567&flag=true

The above will be translated to the following as user property data. Each value is stored as a string.

foo  = "foo"
bar  = "123456"
flag = "true"

▶︎ Example With JSON (Content-Type:application/json header must be provided):

If Content-Type:application/json header is provided, The API will read the request body as JSON.

{ "foo": "foo", "bar": 123456, "flag": true }

The above JSON request body will be translated to the following as user property data:

All values will be interface{} and they must be type asserted before using them.

foo  = "foo"
bar  = 123456
flag = true

--------------------------------------------------

func ForceEndPointAPIV1Response

func ForceEndPointAPIV1Response()

ForceEndPointAPIV1Response forces the response format of /endpoint/type/:type/user/:user to be the same as when the request contains "ResponseVersion:v1" header.

This is only for the purpose of backward compatibility support.

func Get

func Get(uri string, handler func(*Response, *Request, *Params, func(error)))

Get Registers a handler for a GET method URL

func GetCCUByNodeAddress

func GetCCUByNodeAddress(addr string) int

GetCCUByNodeAddress returns CCU of a remote node by its mesh address

func GetRealTimeNodeEndpoint

func GetRealTimeNodeEndpoint(list []string) string

GetRealTimeNodeEndpoint returns a WebSocket/TC/UDP server endpoint Returns a node endpoint that is not taken and online

func GetRoomNumbersByNodeAddress

func GetRoomNumbersByNodeAddress(addr string) int

GetRoomNumbersByNodeAddress returns the number of rooms on a remote node by its mesh address

func HandleStaticFiles

func HandleStaticFiles(uriRoot string, fsPath string)

HandleStaticFiles handle static files

func Head(uri string, handler func(*Response, *Request, *Params, func(error)))

Head Registers a handler for a HEAD method URL

func Offline

func Offline()

Offline Sets mesh network status to offline

func OnAuthRequest

func OnAuthRequest(handler func(res *Response, req *Request, params *Params, next func(error)))

OnAuthRequest hooks a request handler function to auth request. If invoked before SetupAsAuthServer(), the hook will be called BEFORE the actual auth handling. If invoked after SetupAsAuthServer(), the hook will be called AFTER.

func OnEndPointAPIResponse

func OnEndPointAPIResponse(cb func(string, string, string, string) (string, interface{}))

OnEndPointAPIResponse assigns a callback on /endpoint/type/:type/user/:user API to add extra data to the response JSON.

func OnEndPointValidation

func OnEndPointValidation(cb func(uid string, serverType string, jsonBody map[string]interface{}) (resBody map[string]interface{}, ok bool))

OnEndPointValidation assigns a callback on /endpoint/type/:type/user/:user API to validate the request JSON body. return false to response with HTTP status code 400 and the response JSON.

func Online

func Online()

Online Sets mesh network status to online

func Options

func Options(uri string, handler func(*Response, *Request, *Params, func(error)))

Options Registers a handler for an OPTIONS method URL

func Post

func Post(uri string, handler func(*Response, *Request, *Params, func(error)))

Post Registers a handler for a POST method URL

func Put

func Put(uri string, handler func(*Response, *Request, *Params, func(error)))

Put Registers a handler for a PUT method URL

func SetAllowOrigin

func SetAllowOrigin(origin string)

SetAllowOrigin sets Access-Control-Allow-Origin response header for CORS

func SetCustomNodeSelector

func SetCustomNodeSelector(selector func([]string) string)

SetCustomNodeSelector replaces the default node selector with custom selector for Auth

func Setup

func Setup(confpath string)

Setup Loads configuration file into memory - pass an empty string to load nothing

func SetupAsAuthServer

func SetupAsAuthServer(path string)

SetupAsAuthServer Sets Up HTTP server as Auth server for TCP/UDP - pass an empty string to load nothing

func ShutdownHTTP

func ShutdownHTTP(ctx context.Context, done func(error))

ShutdownHTTP Stops HTTP server

func Start

func Start(next func(error))

Start Starts HTTP server

Types

type Params

type Params struct {
	Values map[string]string
}

Params URL parameter data structure

func (*Params) GetAsBool

func (params *Params) GetAsBool(name string) (bool, error)

GetAsBool Returns a URL parameter value as a boolean

func (*Params) GetAsFloat64

func (params *Params) GetAsFloat64(name string) (float64, error)

GetAsFloat64 Returns a URL parameters value as a float64

func (*Params) GetAsInt

func (params *Params) GetAsInt(name string) (int, error)

GetAsInt Returns a URL parameter value as an int

func (*Params) GetAsInt16

func (params *Params) GetAsInt16(name string) (int16, error)

GetAsInt16 Returns a URL parameter value as an int16

func (*Params) GetAsInt32

func (params *Params) GetAsInt32(name string) (int32, error)

GetAsInt32 Returns a URL parameter value as an int32

func (*Params) GetAsInt64

func (params *Params) GetAsInt64(name string) (int64, error)

GetAsInt64 Returns a URL parameter value as an int64

func (*Params) GetAsInt8

func (params *Params) GetAsInt8(name string) (int8, error)

GetAsInt8 Returns a URL parameter value as an int8

func (*Params) GetAsString

func (params *Params) GetAsString(name string) (string, error)

GetAsString a URL parameter value as a string

func (*Params) GetAsUint16

func (params *Params) GetAsUint16(name string) (uint16, error)

GetAsUint16 Returns a URL parameter value as a uint16

func (*Params) GetAsUint32

func (params *Params) GetAsUint32(name string) (uint32, error)

GetAsUint32 Returns a URL parameter value as a uint32

func (*Params) GetAsUint64

func (params *Params) GetAsUint64(name string) (uint64, error)

GetAsUint64 Returns a URL parameter value as a uint64

func (*Params) GetAsUint8

func (params *Params) GetAsUint8(name string) (uint8, error)

GetAsUint8 Returns a URL parameter value as a uint8

type Request

type Request struct {
	// Method represents request method such as GET, POST, etc.
	Method string
	// URL represents the request URL.
	URL string
	// Queries contains all query strings of the request.
	Queries map[string][]string
	// Req represents the request struct instance provided by net/http.
	Req *http.Request
	// JSONBody contains unmarshaled JSON encoded data as a map.
	// This will be nil if Content-Type:application/json header is not provided.
	JSONBody map[string]interface{}
}

Request Request data structure

func (*Request) GetPostData

func (req *Request) GetPostData(name string) string

GetPostData Returns postMethod body data by name

type Response

type Response struct {
	Method   string
	URI      string
	Writer   http.ResponseWriter
	Finished atomic.Bool
	sync.RWMutex
}

Response Response data structure

func (*Response) Respond

func (res *Response) Respond(data string, status int)

Respond Sends a response packet and HTTP status code

func (*Response) SendBytes

func (res *Response) SendBytes(data []byte, status int)

SendBytes sends a response as binary data

func (*Response) SetHeader

func (res *Response) SetHeader(name, value string)

SetHeader sets a custom response header

type ResponseData

type ResponseData struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

ResponseData represents an HTTP response JSON data.

func NewResponseData

func NewResponseData() *ResponseData

NewResponseData creates a new HTTP ResponseData.

func (*ResponseData) Add

func (rd *ResponseData) Add(key string, value interface{}) bool

Add adds a key and value to be encoded into JSON. The value data type supported is only primitive data types.

func (*ResponseData) JSON

func (rd *ResponseData) JSON() string

JSON encodes added keys and values into JSON.

type Route

type Route struct {
	Route      string
	Finder     *regexp.Regexp
	Extractor  *regexp.Regexp
	Handlers   []func(*Response, *Request, *Params, func(error))
	ParamNames []string
	NeedAuth   bool
}

Route URL route data structure