Research
Security News
Malicious npm Package Targets Solana Developers and Hijacks Funds
A malicious npm package targets Solana developers, rerouting funds in 2% of transactions to a hardcoded address.
github.com/bnkamalesh/webgo/v4
WebGo is a minimalistic framework for Go to build web applications (server side) with zero 3rd party dependencies. WebGo will always be Go standard library compliant; with the HTTP handlers having the same signature as http.HandlerFunc.
Router routes multiple paths/URIs to its respective HTTP handler. It supports defining URIs with the following patterns
/api/users
/api/users/:userID
userID
(named URI parameter)/api/users/johndoe/account
. It only matches till /api/users/johndoe/
/api/users/:misc*
misc
/api/users
. e.g. /api/users/a/b/c/d
If multiple patterns match the same URI, the first matching handler would be executed. Refer to the sample to see how routes are configured. A WebGo Route is defined as following:
webgo.Route{
// A name for the API (preferrably unique)
Name string
// HTTP verb, i.e. GET, POST, PUT, PATCH, HEAD, DELETE
Method string
// The URI pattern
Pattern string
// If the URI ends with a '/', should it be considered valid or not? e.g. '/api/users' vs '/api/users/'
TrailingSlash bool
// In case of chained handlers, should the execution continue after one of the handlers have
// responded to the HTTP request
FallThroughPostResponse bool
// The list of HTTP handlers
Handlers []http.HandlerFunc
}
You can access named parameters of the URI using the Context
function. Note: webgo Context is not available inside special handlers, since it serves no purpose
func helloWorld(w http.ResponseWriter, r *http.Request) {
// WebGo context
wctx := webgo.Context(r)
// URI paramaters, map[string]string
params := wctx.Params()
// route, the webgo.Route which is executing this request
route := wctx.Route
webgo.R200(
w,
fmt.Sprintf(
"Route name: '%s', params: '%s'",
route.Name,
params,
),
)
}
Handler chaining lets you execute multiple handlers for a given route. Execution of a chain can be configured to run even after a handler has written a response to the HTTP request. This is made possible by setting FallThroughPostResponse
to true
(refer sample).
webgo.Route{
Name: "chained",
Method: http.MethodGet,
Pattern: "/api",
TrailingSlash: false,
FallThroughPostResponse: true,
Handlers []http.HandlerFunc{
handler1,
handler2,
.
.
.
}
}
WebGo middlware lets you wrap all the routes with a middleware unlike handler chaining. The router exposes a method Use && UseOnSpecialHandlers to add a Middleware to the router. Following code shows how a middleware can be used.
NotFound && NotImplemented are the handlers which are considered Special
handlers. webgo.Context(r)
within special handlers will return nil
.
import (
"github.com/bnkamalesh/webgo/v4"
"github.com/bnkamalesh/webgo/v4/middleware"
)
func routes() []*webgo.Route {
return []*webgo.Route{
&webo.Route{
Name: "home",
Method: http.http.MethodGet,
Pattern: "/",
Handlers: []http.HandlerFunc{
func(w http.ResponseWriter, r *http.Request) {
webgo.R200(w, "home")
}
},
},
}
}
func main() {
router := webgo.NewRouter(*webgo.Config{
Host: "",
Port: "8080",
ReadTimeout: 15 * time.Second,
WriteTimeout: 60 * time.Second,
}, routes())
router.UseOnSpecialHandlers(middleware.AccessLog)
router.Use(middleware.AccessLog)
router.Start()
}
Any number of middleware can be added to the router, the order of execution of middleware would be LIFO (Last In First Out). i.e. in case of the following code
func main() {
router.Use(middleware.AccessLog)
router.Use(middleware.CorsWrap())
}
CorsWrap would be executed first, followed by AccessLog.
WebGo provides a few helper functions.
You can find other helper functions here.
When using Send
or SendResponse
, the response is wrapped in WebGo's response struct and is serialized as JSON.
{
"data": "<any valid JSON payload>",
"status": "<HTTP status code, of type integer>"
}
When using SendError
, the response is wrapped in WebGo's error response struct and is serialzied as JSON.
{
"errors": "<any valid JSON payload>",
"status": "<HTTP status code, of type integer>"
}
HTTPS server can be started easily, by providing the key & cert file. You can also have both HTTP & HTTPS servers running side by side.
Start HTTPS server
cfg := &webgo.Config{
Port: "80",
HTTPSPort: "443",
CertFile: "/path/to/certfile",
KeyFile: "/path/to/keyfile",
}
router := webgo.NewRouter(cfg, routes())
router.StartHTTPS()
Starting both HTTP & HTTPS server
cfg := &webgo.Config{
Port: "80",
HTTPSPort: "443",
CertFile: "/path/to/certfile",
KeyFile: "/path/to/keyfile",
}
router := webgo.NewRouter(cfg, routes())
go router.StartHTTPS()
router.Start()
Graceful shutdown lets you shutdown the server without affecting any live connections/clients connected to the server. It will complete executing all the active/live requests before shutting down.
Sample code to show how to use shutdown
func main() {
osSig := make(chan os.Signal, 5)
cfg := &webgo.Config{
Host: "",
Port: "8080",
ReadTimeout: 15 * time.Second,
WriteTimeout: 60 * time.Second,
ShutdownTimeout: 15 * time.Second,
}
router := webgo.NewRouter(cfg, routes())
go func() {
<-osSig
// Initiate HTTP server shutdown
err := router.Shutdown()
if err != nil {
fmt.Println(err)
os.Exit(1)
} else {
fmt.Println("shutdown complete")
os.Exit(0)
}
// If you have HTTPS server running, you can use the following code
// err := router.ShutdownHTTPS()
// if err != nil {
// fmt.Println(err)
// os.Exit(1)
// } else {
// fmt.Println("shutdown complete")
// os.Exit(0)
// }
}()
signal.Notify(osSig, os.Interrupt, syscall.SIGTERM)
router.Start()
for {
// Prevent main thread from exiting, and wait for shutdown to complete
time.Sleep(time.Second * 1)
}
}
WebGo exposes a singleton & global scoped logger variable LOGHANDLER with which you can plug in your custom logger by implementing the Logger interface.
type Logger interface {
Debug(data ...interface{})
Info(data ...interface{})
Warn(data ...interface{})
Error(data ...interface{})
Fatal(data ...interface{})
}
The default logger uses Go standard library's log.Logger
with os.Stdout
(for debug and info logs) & os.Stderr
(for warning, error, fatal) as default io.Writers. You can set the io.Writer as well as disable specific types of logs using the GlobalLoggerConfig(stdout, stderr, cfgs...)
function.
GlobalLoggerConfig(nil, nil, LogCfgDisableDebug, LogCfgDisableInfo...)
Usage is shown in cmd/main.go
.
A fully functional sample is provided here. You can try the following API calls with the sample app.
http://localhost:8080/
http://localhost:8080/matchall/
/matchall
will be matched because it has a wildcard variable/api/<single parameter>
If you have Go installed on your computer, open the terminal and:
$ cd $GOPATH/src
$ mkdir -p github.com/bnkamalesh
$ cd github.com/bnkamalesh
$ git clone https://github.com/bnkamalesh/webgo.git
$ cd webgo
$ go run cmd/main.go
Info 2020/06/03 12:55:26 HTTP server, listening on :8080
Or if you have Docker, open the terminal and:
$ git clone https://github.com/bnkamalesh/webgo.git
$ cd webgo
$ docker run \
-p 8080:8080 \
-v ${PWD}:/go/src/github.com/bnkamalesh/webgo/ \
-w /go/src/github.com/bnkamalesh/webgo/cmd \
--rm -ti golang:latest go run main.go
Info 2020/06/03 12:55:26 HTTP server, listening on :8080
You can view benchmark results at the following repos:
Refer here to find out details about making a contribution
Thanks to all the contributors
The gopher used here was created using Gopherize.me. WebGo stays out of developers' way, so sitback and enjoy a cup of coffee like this gopher.
FAQs
Unknown package
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
A malicious npm package targets Solana developers, rerouting funds in 2% of transactions to a hardcoded address.
Security News
Research
Socket researchers have discovered malicious npm packages targeting crypto developers, stealing credentials and wallet data using spyware delivered through typosquats of popular cryptographic libraries.
Security News
Socket's package search now displays weekly downloads for npm packages, helping developers quickly assess popularity and make more informed decisions.