mtrouter

module
v0.0.0-...-457749f Latest Latest
Warning

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

Go to latest
Published: Oct 13, 2020 License: AGPL-3.0

README

MTrouter

A JSON driven, signature authentication ready, letsencrypt compatible modular router stack for multiple transports.

Current transports supported: HTTP, HTTPs WS, WSS and libp2p.

All JSON requests follows the next schema which is automatically handled by this module.

{
  "request": {
    "request": "1234",
    "timestamp": 1602582404,
  },
  "id": "1234",
  "signature": "6e1f5705f41c767d6d3ba516..."
}

The module consumer only needs to provide a compatible (types.MessageAPI) struct, as the following example:

type MyAPI struct {
	ID        string   `json:"request"`
	Method    string   `json:"method,omitempty"`
	PubKeys   []string `json:"pubKeys,omitempty"`
	Timestamp int32    `json:"timestamp"`
	Error     string   `json:"error,omitempty"`
	Reply     string   `json:"reply,omitempty"`
}

func (ma *MyAPI) GetID() string {
	return ma.ID
}

func (ma *MyAPI) SetID(id string) {
	ma.ID = id
}

func (ma *MyAPI) SetTimestamp(ts int32) {
	ma.Timestamp = ts
}

func (ma *MyAPI) SetError(e string) {
	ma.Error = e
}

func (ma *MyAPI) GetMethod() string {
	return ma.Method
}

func NewAPI() types.MessageAPI {
	return &MyAPI{}
}

So GetID(), SetID(), SetTimestamp(), SetError(), GetMethod() must be implemented.

Also a special standalone function that returns the type is required (NewApi()).

HTTP+WS

To start the HTTP(s) + Websocket stack, the endpoint package can be used, was follows.

	// API configuration
	api := &types.API{
		ListenHost: "0.0.0.0",
		ListenPort: 7788,
	}
	// Generate signing keys
	sig := ethereum.NewSignKeys()
	sig.Generate()

	// Create HTTPWS endpoint
	ep, err := endpoint.NewHttpWsEndpoint(api, sig, message.NewAPI)
	if err != nil {
		panic(err)
	}

	// Add namespace /main to the transport httpws
	ep.Router.Transports["httpws"].AddNamespace("/main")

	// And handler for namespace main and method hello
	if err := ep.Router.AddHandler("hello", "/main", hello, false, true); err != nil {
		log.Fatal(err)
    }

    // Add another not private method for adding new auth keys
	if err := ep.Router.AddHandler("addkey", "/main", addKey, false, false); err != nil {
		log.Fatal(err)
	}

	// Add a private method
	if err := ep.Router.AddHandler("getsecret", "/main", getSecret, true, false); err != nil {
		log.Fatal(err)
	}

	// Start routing
	ep.Router.Route()
HTTP+WS with TLS

In order to enable TLS encryption with letsencrypt, the API must be configured as follows:

	api := &types.API{
		ListenHost: "0.0.0.0",
        ListenPort: 443,
    	TLSdomain  "myValidDomain.com",
    	TLSdirCert "/tmp/tlsdir"
	}
Example

Find the full example on the example directory of this repository.

Start the server

$ go run example/server/server.go 
2020-10-13T14:42:54+02:00       INFO    server/server.go:34     logger construction succeeded at level debug and output stdout
2020-10-13T14:42:54+02:00       INFO    endpoint/endpoint.go:27 creating API service
2020-10-13T14:42:54+02:00       INFO    endpoint/endpoint.go:65 creating proxy service, listening on 0.0.0.0:7788
2020-10-13T14:42:54+02:00       INFO    net/proxy.go:128        starting go-chi http server
2020-10-13T14:42:54+02:00       INFO    net/proxy.go:139        proxy ready at http://[::]:7788
2020-10-13T14:42:54+02:00       DEBUG   router/router.go:45     adding new handler hello for namespace /main
2020-10-13T14:42:54+02:00       DEBUG   router/router.go:45     adding new handler addkey for namespace /main
2020-10-13T14:42:54+02:00       DEBUG   router/router.go:45     adding new handler getsecret for namespace /main

At this point you can already use curl for making http requests.

$ curl -s 127.0.0.1:7788/main -X POST -d '{"request":{"method":"hello", "request":"1234"}, "id":"1234"}'

{"request":{"reply":"hello! got your message with ID 1234","request":"1234","timestamp":1602593026},"id":"1234","signature":"5ddc0fd1a13c7612875c089feea712bae6df2d05c5cea3b4e9cfaf6e109ae3bb1d3b6915f8933f3ea20179209a076e1e7fd6328efdabc08c347d9c5807eb2bef01"}

But in order to use the signature mechanism, a more advanced client tool must be used. In this case we provide a client.go example code.

$ echo '{"method":"getsecret"}' | go run example/client/client.go -key=4f81e884843a5910af16dd85424bdd6a4bb524159abeee798ed557cd6418eb17
{"error":"invalid authentication","request":"539","timestamp":1602593846}
 $ echo '{"method":"addkey"}' | go run example/client/client.go -key=4f81e884843a5910af16dd85424bdd6a4bb524159abeee798ed557cd6418eb17

{"reply":"added new authorized address 0xD7B5E12Fbe91Efd61E06B35A7bc06028cbe0209E","request":"28","timestamp":1602593157}
$ echo '{"method":"getsecret"}' | go run example/client/client.go -key=4f81e884843a5910af16dd85424bdd6a4bb524159abeee798ed557cd6418eb17

{"reply":"the secret is foobar123456","request":"691","timestamp":1602593187}

Directories

Path Synopsis
example
Package router provides the routing and entry point for the go-dvote API
Package router provides the routing and entry point for the go-dvote API

Jump to

Keyboard shortcuts

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