Add Proxy Protocol support

Closes #9
This commit is contained in:
Maddie Zhan 2020-08-19 17:02:37 +08:00
parent b76ebec8d0
commit a0a6db8597
7 changed files with 36 additions and 11 deletions

View File

@ -23,6 +23,7 @@ Works with mobile versions too.
* Results sharing (optional) * Results sharing (optional)
* Multiple Points of Test (optional) * Multiple Points of Test (optional)
* Compatible with PHP frontend predefined endpoints (with `.php` suffixes) * Compatible with PHP frontend predefined endpoints (with `.php` suffixes)
* Supports [Proxy Protocol](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt)
![Screencast](https://speedtest.zzz.cat/speedtest.webp) ![Screencast](https://speedtest.zzz.cat/speedtest.webp)
@ -88,6 +89,8 @@ manually, you can install newer version of Go into your `GOPATH`:
bind_address="127.0.0.1" bind_address="127.0.0.1"
# backend listen port, default is 8989 # backend listen port, default is 8989
listen_port=8989 listen_port=8989
# proxy protocol port, use 0 to disable
proxyprotocol_port=0
# Server location, use zeroes to fetch from API automatically # Server location, use zeroes to fetch from API automatically
server_lat=0 server_lat=0
server_lng=0 server_lng=0

View File

@ -8,11 +8,12 @@ import (
) )
type Config struct { type Config struct {
BindAddress string `mapstructure:"bind_address"` BindAddress string `mapstructure:"bind_address"`
Port string `mapstructure:"listen_port"` Port string `mapstructure:"listen_port"`
ServerLat float64 `mapstructure:"server_lat"` ProxyProtocolPort string `mapstructure:"proxyprotocol_port"`
ServerLng float64 `mapstructure:"server_lng"` ServerLat float64 `mapstructure:"server_lat"`
IPInfoAPIKey string `mapstructure:"ipinfo_api_key"` ServerLng float64 `mapstructure:"server_lng"`
IPInfoAPIKey string `mapstructure:"ipinfo_api_key"`
StatsPassword string `mapstructure:"statistics_password"` StatsPassword string `mapstructure:"statistics_password"`
RedactIP bool `mapstructure:"redact_ip_addresses"` RedactIP bool `mapstructure:"redact_ip_addresses"`
@ -34,6 +35,7 @@ var (
func init() { func init() {
viper.SetDefault("listen_port", "8989") viper.SetDefault("listen_port", "8989")
viper.SetDefault("proxyprotocol_port", "0")
viper.SetDefault("download_chunks", 4) viper.SetDefault("download_chunks", 4)
viper.SetDefault("distance_unit", "K") viper.SetDefault("distance_unit", "K")
viper.SetDefault("enable_cors", false) viper.SetDefault("enable_cors", false)

2
go.mod
View File

@ -8,9 +8,9 @@ require (
github.com/go-chi/render v1.0.1 github.com/go-chi/render v1.0.1
github.com/go-sql-driver/mysql v1.5.0 github.com/go-sql-driver/mysql v1.5.0
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0
github.com/gorilla/websocket v1.4.2
github.com/lib/pq v1.3.0 github.com/lib/pq v1.3.0
github.com/oklog/ulid/v2 v2.0.2 github.com/oklog/ulid/v2 v2.0.2
github.com/pires/go-proxyproto v0.1.3
github.com/sirupsen/logrus v1.4.2 github.com/sirupsen/logrus v1.4.2
github.com/spf13/viper v1.6.2 github.com/spf13/viper v1.6.2
go.etcd.io/bbolt v1.3.3 go.etcd.io/bbolt v1.3.3

4
go.sum
View File

@ -47,8 +47,6 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
@ -83,6 +81,8 @@ github.com/oklog/ulid/v2 v2.0.2/go.mod h1:mtBL0Qe/0HAx6/a4Z30qxVIAL1eQDweXq5lxOE
github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o= github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o=
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pires/go-proxyproto v0.1.3 h1:2XEuhsQluSNA5QIQkiUv8PfgZ51sNYIQkq/yFquiSQM=
github.com/pires/go-proxyproto v0.1.3/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=

View File

@ -7,7 +7,6 @@ import (
"github.com/librespeed/speedtest/database" "github.com/librespeed/speedtest/database"
"github.com/librespeed/speedtest/results" "github.com/librespeed/speedtest/results"
"github.com/librespeed/speedtest/web" "github.com/librespeed/speedtest/web"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
) )

View File

@ -2,6 +2,8 @@
bind_address="" bind_address=""
# backend listen port # backend listen port
listen_port=8989 listen_port=8989
# proxy protocol port, use 0 to disable
proxyprotocol_port=0
# Server location # Server location
server_lat=0 server_lat=0
server_lng=0 server_lng=0

View File

@ -14,6 +14,7 @@ import (
"github.com/go-chi/chi/middleware" "github.com/go-chi/chi/middleware"
"github.com/go-chi/cors" "github.com/go-chi/cors"
"github.com/go-chi/render" "github.com/go-chi/render"
"github.com/pires/go-proxyproto"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/librespeed/speedtest/config" "github.com/librespeed/speedtest/config"
@ -46,7 +47,8 @@ func ListenAndServe(conf *config.Config) error {
r.Use(middleware.Logger) r.Use(middleware.Logger)
r.Use(middleware.Recoverer) r.Use(middleware.Recoverer)
log.Infof("Starting backend server on %s", net.JoinHostPort(conf.BindAddress, conf.Port)) addr := net.JoinHostPort(conf.BindAddress, conf.Port)
log.Infof("Starting backend server on %s", addr)
r.Get("/*", pages) r.Get("/*", pages)
r.HandleFunc("/empty", empty) r.HandleFunc("/empty", empty)
r.HandleFunc("/backend/empty", empty) r.HandleFunc("/backend/empty", empty)
@ -75,7 +77,24 @@ func ListenAndServe(conf *config.Config) error {
r.HandleFunc("/stats.php", results.Stats) r.HandleFunc("/stats.php", results.Stats)
r.HandleFunc("/backend/stats.php", results.Stats) r.HandleFunc("/backend/stats.php", results.Stats)
return http.ListenAndServe(net.JoinHostPort(conf.BindAddress, conf.Port), r) go listenProxyProtocol(conf, r)
return http.ListenAndServe(addr, r)
}
func listenProxyProtocol(conf *config.Config, r *chi.Mux) {
if conf.ProxyProtocolPort != "0" {
addr := net.JoinHostPort(conf.BindAddress, conf.ProxyProtocolPort)
l, err := net.Listen("tcp", addr)
if err != nil {
log.Fatal("Cannot listen on proxy protocol port %s: %s", conf.ProxyProtocolPort, err)
}
pl := &proxyproto.Listener{Listener: l}
defer pl.Close()
log.Infof("Starting proxy protocol listener on %s", addr)
log.Fatal(http.Serve(pl, r))
}
} }
func pages(w http.ResponseWriter, r *http.Request) { func pages(w http.ResponseWriter, r *http.Request) {