Skip to content

Commit

Permalink
Embed default assets
Browse files Browse the repository at this point in the history
  • Loading branch information
maddie committed Sep 17, 2021
1 parent 83d25e0 commit 7204ae2
Show file tree
Hide file tree
Showing 12 changed files with 54 additions and 37 deletions.
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,16 @@ Works with mobile versions too.

## Installation

You need Go 1.13+ to compile the binary. If you have an older version of Go and don't want to install the tarball
You need Go 1.16+ to compile the binary. If you have an older version of Go and don't want to install the tarball
manually, you can install newer version of Go into your `GOPATH`:

0. Install Go 1.14
0. Install Go 1.17

```
$ go get golang.org/dl/go1.14.2
# Assuming your GOPATH is default (~/go), Go 1.14.2 will be installed in ~/go/bin
$ ~/go/bin/go1.14.2 version
go version go1.14.2 linux/amd64
$ go get golang.org/dl/go1.17.1
# Assuming your GOPATH is default (~/go), Go 1.17.1 will be installed in ~/go/bin
$ ~/go/bin/go1.17.1 version
go version go1.17.1 linux/amd64
```

1. Clone this repository:
Expand Down Expand Up @@ -98,6 +98,7 @@ manually, you can install newer version of Go into your `GOPATH`:
ipinfo_api_key=""
# assets directory path, defaults to `assets` in the same directory
# if the path cannot be found, embedded default assets will be used
assets_path="./assets"
# password for logging into statistics page, change this to enable stats page
Expand Down
3 changes: 1 addition & 2 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ type Config struct {
}

var (
configFile string = ""
configFile string
loadedConfig *Config = nil
)

Expand All @@ -40,7 +40,6 @@ func init() {
viper.SetDefault("enable_cors", false)
viper.SetDefault("statistics_password", "PASSWORD")
viper.SetDefault("redact_ip_addresses", false)
viper.SetDefault("assets_path", "./assets")
viper.SetDefault("database_type", "postgresql")
viper.SetDefault("database_hostname", "localhost")
viper.SetDefault("database_name", "speedtest")
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/librespeed/speedtest

go 1.13
go 1.16

require (
github.com/fsnotify/fsnotify v1.5.1 // indirect
Expand Down
File renamed without changes.
File renamed without changes.
33 changes: 15 additions & 18 deletions results/telemetry.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
package results

import (
_ "embed"
"encoding/json"
"image"
"image/color"
"image/draw"
"image/png"
"io/ioutil"
"math/rand"
"net"
"net/http"
"path/filepath"
"regexp"
"strings"
"time"
Expand All @@ -37,6 +36,12 @@ const (
labelUpload = "Upload"
)

//go:embed fonts/NotoSansDisplay-Medium.ttf
var fontMediumBytes []byte

//go:embed fonts/NotoSansDisplay-Light.ttf
var fontLightBytes []byte

var (
ipv4Regex = regexp.MustCompile(`(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)`)
ipv6Regex = regexp.MustCompile(`(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4})?:)?((25[0-5]|(2[0-4]|1?[0-9])?[0-9])\.){3}(25[0-5]|(2[0-4]|1?[0-9])?[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1?[0-9])?[0-9])\.){3}(25[0-5]|(2[0-4]|1?[0-9])?[0-9]))`)
Expand Down Expand Up @@ -83,25 +88,17 @@ type IPInfoResponse struct {
func Initialize(c *config.Config) {
// changed to use Noto Sans instead of OpenSans, due to issue:
// https://github.com/golang/freetype/issues/8
if b, err := ioutil.ReadFile(filepath.Join(c.AssetsPath, "NotoSansDisplay-Light.ttf")); err != nil {
log.Fatalf("Error opening NotoSansDisplay-Light font: %s", err)
} else {
f, err := freetype.ParseFont(b)
if err != nil {
log.Fatalf("Error parsing NotoSansDisplay-Light font: %s", err)
}
fontLight = f
fLight, err := freetype.ParseFont(fontLightBytes)
if err != nil {
log.Fatalf("Error parsing NotoSansDisplay-Light font: %s", err)
}
fontLight = fLight

if b, err := ioutil.ReadFile(filepath.Join(c.AssetsPath, "NotoSansDisplay-Medium.ttf")); err != nil {
log.Fatalf("Error opening NotoSansDisplay-Medium font: %s", err)
} else {
f, err := freetype.ParseFont(b)
if err != nil {
log.Fatalf("Error parsing NotoSansDisplay-Medium font: %s", err)
}
fontBold = f
fMedium, err := freetype.ParseFont(fontMediumBytes)
if err != nil {
log.Fatalf("Error parsing NotoSansDisplay-Medium font: %s", err)
}
fontBold = fMedium

pingJitterLabelFace = truetype.NewFace(fontBold, &truetype.Options{
Size: 12,
Expand Down
6 changes: 3 additions & 3 deletions settings.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ listen_port=8989
# proxy protocol port, use 0 to disable
proxyprotocol_port=0
# Server location
server_lat=0
server_lng=0
server_lat=1
server_lng=1
# ipinfo.io API key, if applicable
ipinfo_api_key=""

# assets directory path, defaults to `assets` in the same directory
assets_path="./assets"
assets_path=""

This comment has been minimized.

Copy link
@maddie

maddie Sep 18, 2021

Author Collaborator

If you check the code in web/web.go:

speedtest-go/web/web.go

Lines 55 to 65 in 42cc774

var assetFS http.FileSystem
if fi, err := os.Stat(conf.AssetsPath); os.IsNotExist(err) || !fi.IsDir() {
log.Warnf("Configured asset path %s does not exist or is not a directory, using default assets", conf.AssetsPath)
sub, err := fs.Sub(defaultAssets, "assets")
if err != nil {
log.Fatalf("Failed when processing default assets: %s", err)
}
assetFS = http.FS(sub)
} else {
assetFS = justFilesFilesystem{fs: http.Dir(conf.AssetsPath), readDirBatchSize: 2}
}

It checks for the configured path to see if it exists and is a directory, and use it for static assets, just like before. Or else it will use the embedded ones.

This comment has been minimized.

Copy link
@MattKobayashi

MattKobayashi Sep 19, 2021

Yep, I figured it out after the fact, thanks! :)


# password for logging into statistics page
statistics_password="PASSWORD"
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
34 changes: 27 additions & 7 deletions web/web.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package web

import (
"embed"
"encoding/json"
"io"
"io/fs"
"io/ioutil"
"net"
"net/http"
"os"
"regexp"
"strconv"
"strings"
Expand All @@ -26,6 +29,9 @@ const (
chunkSize = 1048576
)

//go:embed assets
var defaultAssets embed.FS

var (
// generate random data for download test on start to minimize runtime overhead
randomData = getRandomData(chunkSize)
Expand All @@ -46,9 +52,21 @@ func ListenAndServe(conf *config.Config) error {
r.Use(middleware.NoCache)
r.Use(middleware.Recoverer)

var assetFS http.FileSystem
if fi, err := os.Stat(conf.AssetsPath); os.IsNotExist(err) || !fi.IsDir() {
log.Warnf("Configured asset path %s does not exist or is not a directory, using default assets", conf.AssetsPath)
sub, err := fs.Sub(defaultAssets, "assets")
if err != nil {
log.Fatalf("Failed when processing default assets: %s", err)
}
assetFS = http.FS(sub)
} else {
assetFS = justFilesFilesystem{fs: http.Dir(conf.AssetsPath), readDirBatchSize: 2}
}

addr := net.JoinHostPort(conf.BindAddress, conf.Port)
log.Infof("Starting backend server on %s", addr)
r.Get("/*", pages)
r.Get("/*", pages(assetFS))
r.HandleFunc("/empty", empty)
r.HandleFunc("/backend/empty", empty)
r.Get("/garbage", garbage)
Expand Down Expand Up @@ -96,14 +114,16 @@ func listenProxyProtocol(conf *config.Config, r *chi.Mux) {
}
}

func pages(w http.ResponseWriter, r *http.Request) {
if r.RequestURI == "/" {
r.RequestURI = "/index.html"
func pages(fs http.FileSystem) http.HandlerFunc {
fn := func(w http.ResponseWriter, r *http.Request) {
if r.RequestURI == "/" {
r.RequestURI = "/index.html"
}

http.FileServer(fs).ServeHTTP(w, r)
}

conf := config.LoadedConfig()
fs := justFilesFilesystem{fs: http.Dir(conf.AssetsPath), readDirBatchSize: 2}
http.FileServer(fs).ServeHTTP(w, r)
return fn
}

func empty(w http.ResponseWriter, r *http.Request) {
Expand Down

0 comments on commit 7204ae2

Please sign in to comment.