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.
go.pyspa.org/brbundle
BRBundle is an asset bundling tool for Go. It is inspired by go-assets, go.rice and so on.
It supports four options to bundle assets to help building libraries, CLI applications, web applications, mobile applications, JavaScript(Gopher.js), including debugging process.
$ go get go.pyspa.org/brbundle/...
+--------------+ Yes
| go gettable? |+------------> Embedded Bundle
+----+---------+ ^
| |
| No | Yes
v |
+----------------+ Yes +------------+ No
| Single Binary? |+----------> | Gopher.js? +---------->Exe Bundle
+----+-----------+ +------------+
|
| No
v
+--------+ Yes
| Debug? +--------------------> Folder Bundle
+----+---+
|
| No
v
Packed Bundle
by asciiflow
This tool supports 4 options to bundle assets:
Embedded Bundle
This tool generates .go file. You have to generate .go file before compiling your application. This option is go-gettable.
brbundle embedded [src-dir]
Exe Bundle
This tool appends content files to your application. You can add them after compiling your application.
brbundle bundle [exe-file] [src-dir]
Packed Bundle
This tool generates one single binary that includes content files. It can use for DLC.
brbundle pack [out-file.pb] [src-dir]
Folder Bundle
For debugging. You can access content files without any building tasks. You don't have to prepare with brbundle command except encryption is needed.
You can get contents by using Find()
function. If contents are bundled with
embedded bundle or exe bundle, you don't have to call any function to load.
import (
"go.pyspa.org/brbundle"
"image"
"image/png"
)
func main() {
file, err := brbundle.Find("file.png")
reader, err := file.Reader()
img, err := image.Decode(reader)
}
RegisterBundle()
RegisterFolder()
register external contents.
BRBundle searches the contents with the following order:
import (
"go.pyspa.org/brbundle"
)
func main() {
// load packed content
brbundle.RegisterBundle("pack.pb")
// load folder content
brbundle.RegisterFolder("static/public")
}
BRBundle uses brotli by default. brotli is higher compression ratio with faster decompression speed than gzip.
BRBundle's web application middlewares can send brotli-ed content directly.
Almost all browsers supports Content-Encoding: br
.
It also supports more faster decompression algorithm LZ4.
It supports contents encryption by AES. It uses base64 encoded 44 bytes key to encrypto. You can get your key with key-gen sub command.
Each bundles (embedded, bundle, each packed bundle files, folder bundles) can use separated encryption keys.
$ brbundle key-gen
yt6TX1eCBuG9GPRl2H6SJMbPNhPLOBxEHpb4kkaWyKUDg/tAZ2aSI3A86fw=
$ brbundle pack -c yt6TX1eCBuG9GPRl2H6SJMbPNhPLOBxEHpb4kkaWyKUDg/tAZ2aSI3A86fw= [src-dir]
BRBundle support its own middleware for famous web application frameworks.
It doesn't provide http.FileSystem
compatible interface because:
net/http
"go.pyspa.org/brbundle/brhttp"
contains http.Handler
compatible API.
package main
import (
"fmt"
"net/http"
"go.pyspa.org/brbundle"
"go.pyspa.org/brbundle/brhttp"
)
// The simplest sample
// The server only returns only brbundle's content
// "/static/index.html" returns "index.html" of bundle.
func main() {
fmt.Println("Listening at :8080")
http.ListenAndServe(":8080", brhttp.Mount())
}
// Use ServeMux sample to handle static assets with API handler
func main() {
m := http.NewServeMux()
m.Handle("/public/", http.StripPrefix("/public", brhttp.Mount()))
m.HandleFunc("/api/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello World")
})
fmt.Println("Listening at :8080")
http.ListenAndServe(":8080", m)
}
// Single Page Application sample
// BRBundle's SPA supports is configured by WebOption of Mount() function
// If no contents found in bundles, it returns the specified content.
func main() {
m := http.NewServeMux()
m.HandleFunc("/api/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello World")
})
// Single Page Application is usually served index.html at any location
// and routing errors are handled at browser.
//
// You should mount at the last line, because
// it consumes all URL requests.
m.Handle("/",
brhttp.Mount(brbundle.WebOption{
SPAFallback: "index.html",
}),
)
fmt.Println("Listening at :8080")
http.ListenAndServe(":8080", m)
}
Echo is a high performance, extensible, minimalist Go web framework.
package main
import (
"fmt"
"net/http"
"github.com/labstack/echo"
"go.pyspa.org/brbundle"
"go.pyspa.org/brbundle/brecho"
)
// The simplest sample
func main() {
e := echo.New()
// Asterisk is required!
e.GET("/*", brecho.Mount())
e.Logger.Fatal(e.Start(":1323"))
}
// Use with echo.Group
func main() {
e := echo.New()
e.GET("/api/status", func (c echo.Context) error {
return c.String(http.StatusOK, "Hello, World!")
})
g := e.Group("/assets")
// Asterisk is required!
g.GET("/*", brecho.Mount())
e.Logger.Fatal(e.Start(":1323"))
}
// Single Page Application sample
// BRBundle's SPA supports is configured by WebOption of Mount() function
// If no contents found in bundles, it returns the specified content.
//
// Single Page Application is usually served index.html at any location
// and routing errors are handled at browser.
func main() {
e := echo.New()
e.GET("/api/status", func (c echo.Context) error {
return c.String(http.StatusOK, "Hello, World!")
})
// Use brbundle works as an error handler
echo.NotFoundHandler = brecho.Mount(brbundle.WebOption{
SPAFallback: "index.html",
})
e.Logger.Fatal(e.Start(":1323"))
}
Chi router is a lightweight, idiomatic and composable router for building Go HTTP services.
package main
import (
"fmt"
"net/http"
"github.com/go-chi/chi"
"go.pyspa.org/brbundle"
"go.pyspa.org/brbundle/brchi"
)
// Use with chi.Router
func main() {
r := chi.NewRouter()
fmt.Println("You can access index.html at /public/index.html")
// Asterisk is required!
r.Get("/public/*", brchi.Mount())
r.Get("/api", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello World")
})
fmt.Println("Listening at :8080")
http.ListenAndServe(":8080", r)
}
// Single Page Application sample
// BRBundle's SPA supports is configured by WebOption of Mount() function
// If no contents found in bundles, it returns the specified content.
//
// Single Page Application is usually served index.html at any location
// and routing errors are handled at browser.
func main() {
r := chi.NewRouter()
r.Get("/api/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello World")
})
fmt.Println("You can access index.html at any location")
// Use brbundle as an error handler
r.NotFound(brchi.Mount(brbundle.WebOption{
SPAFallback: "index.html",
}))
fmt.Println("Listening at :8080")
http.ListenAndServe(":8080", r)
}
fasthttp is a fast http package. fasthttprouter is a high performance request router that scales well for fasthttp.
package main
import (
"fmt"
"github.com/buaazp/fasthttprouter"
"go.pyspa.org/brbundle"
"go.pyspa.org/brbundle/brfasthttp"
"github.com/valyala/fasthttp"
)
// The simplest sample
func main() {
fmt.Println("Listening at :8080")
fmt.Println("You can access index.html at /index.html")
fasthttp.ListenAndServe(":8080", brfasthttp.Mount())
}
// Use with fasthttprouter
func main() {
r := fasthttprouter.New()
r.GET("/api/status", func (ctx *fasthttp.RequestCtx) {
ctx.WriteString("Hello, World!")
})
// "*filepath" is required at the last fragment of path string
fmt.Println("You can access index.html at /static/index.html")
r.GET("/static/*filepath", brfasthttp.Mount())
fmt.Println("Listening at :8080")
fasthttp.ListenAndServe(":8080", r.Handler)
}
// Single Page Application sample
// BRBundle's SPA supports is configured by WebOption of Mount() function
// If no contents found in bundles, it returns the specified content.
//
// Single Page Application is usually served index.html at any location
// and routing errors are handled at browser.
func main() {
r := fasthttprouter.New()
r.GET("/api/status", func (ctx *fasthttp.RequestCtx) {
ctx.WriteString("Hello, World!")
})
fmt.Println("You can access index.html at any location")
// Use brbundle works as an error handler
r.NotFound = brfasthttp.Mount(brbundle.WebOption{
SPAFallback: "index.html",
})
fmt.Println("Listening at :8080")
fasthttp.ListenAndServe(":8080", r.Handler)
}
Gin is a HTTP web framework written in Go (Golang). It features a Martini-like API with much better performance -- up to 40 times faster.
package main
import (
"fmt"
"net/http"
"github.com/gin-gonic/gin"
"go.pyspa.org/brbundle"
"go.pyspa.org/brbundle/brgin"
)
// Use with gin's router
func main() {
r := gin.Default()
r.GET("/api/status", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"status": "ok",
})
})
fmt.Println("You can access index.html at /static/index.html")
// "*filepath" is required at the last fragment of path string
r.GET("/static/*filepath", brgin.Mount())
r.Run(":8080")
}
// Single Page Application sample
// BRBundle's SPA supports is configured by WebOption of Mount() function
// If no contents found in bundles, it returns the specified content.
//
// Single Page Application is usually served index.html at any location
// and routing errors are handled at browser.
func main() {
r := gin.Default()
r.GET("/api/status", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"status": "ok",
})
})
fmt.Println("You can access index.html at any location")
// Use brbundle works as an error handler
r.NoRoute(brgin.Mount(brbundle.WebOption{
SPAFallback: "index.html",
}))
fmt.Println("Listening at :8080")
r.Run(":8080")
}
It uses zip format to make single packed file. Embedded bundles and Exe bundles also use zip format. It doesn't use Deflate algorithm. It uses Brotli or LZ4 inside it.
BRBundle chooses compression format Brotli and LZ4 automatically.
That option you can choose is using -f
(faster) or not.
-f
-f
from size and booting speed.-f
option makes the content compressed with LZ4.
But Brotli has some cons. If the content is already compressed (like PNG, JPEG, OpenOffice formats), compression ratio is not effective. And loading compressed contents is slower than uncompressed content. Even if turned off Brotli, BRBundle fall back to LZ4. So the content like JSON becomes smaller than original and not slower than uncompressed content so much.
Now, current code skip compression if the content size after compression is not enough small:
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.