Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FIX] Issue 904 - Vue app doesn't take into account uri_prefix #967

Merged
merged 2 commits into from
Feb 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions cmd/tegola/cmd/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ var serverCmd = &cobra.Command{
server.URIPrefix = string(conf.Webserver.URIPrefix)
}

if conf.Webserver.ProxyProtocol != "" {
server.ProxyProtocol = string(conf.Webserver.ProxyProtocol)
}

if conf.Webserver.SSLCert+conf.Webserver.SSLKey != "" {
if conf.Webserver.SSLCert == "" {
// error
Expand Down
13 changes: 7 additions & 6 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,13 @@ type Config struct {

// Webserver represents the config options for the webserver part of Tegola
type Webserver struct {
HostName env.String `toml:"hostname"`
Port env.String `toml:"port"`
URIPrefix env.String `toml:"uri_prefix"`
Headers env.Dict `toml:"headers"`
SSLCert env.String `toml:"ssl_cert"`
SSLKey env.String `toml:"ssl_key"`
HostName env.String `toml:"hostname"`
Port env.String `toml:"port"`
URIPrefix env.String `toml:"uri_prefix"`
Headers env.Dict `toml:"headers"`
SSLCert env.String `toml:"ssl_cert"`
SSLKey env.String `toml:"ssl_key"`
ProxyProtocol env.String `toml:"proxy_protocol"`
}

// ValidateAndRegisterParams ensures configured params don't conflict with existing
Expand Down
191 changes: 175 additions & 16 deletions config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ func TestParse(t *testing.T) {
hostname = "cdn.tegola.io"
port = ":8080"
cors_allowed_origin = "tegola.io"
proxy_protocol = "https"

[webserver.headers]
Access-Control-Allow-Origin = "*"
Expand Down Expand Up @@ -181,8 +182,9 @@ func TestParse(t *testing.T) {
TileBuffer: env.IntPtr(env.Int(12)),
LocationName: "",
Webserver: config.Webserver{
HostName: "cdn.tegola.io",
Port: ":8080",
HostName: "cdn.tegola.io",
Port: ":8080",
ProxyProtocol: "https",
Headers: env.Dict{
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, OPTIONS",
Expand All @@ -201,7 +203,7 @@ func TestParse(t *testing.T) {
"database": "osm_water",
"user": "admin",
"password": "",
"layers": []map[string]interface{}{
"layers": []map[string]any{
{
"name": "water",
"geometry_fieldname": "geom",
Expand Down Expand Up @@ -345,7 +347,7 @@ func TestParse(t *testing.T) {
"database": "osm_water",
"user": "admin",
"password": "",
"layers": []map[string]interface{}{
"layers": []map[string]any{
{
"name": "water_0_5",
"geometry_fieldname": "geom",
Expand Down Expand Up @@ -477,6 +479,163 @@ func TestParse(t *testing.T) {
expected: config.Config{},
expectedErr: env.ErrEnvVar("I_AM_MISSING"),
},
"4 test empty proxy_protocol": {
config: `
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should move these inline configs to external files. it sure would make this easier to look it ;-)

[webserver]
hostname = "${ENV_TEST_HOST_1}.${ENV_TEST_HOST_2}.${ENV_TEST_HOST_3}"
port = "${ENV_TEST_WEBSERVER_PORT}"
proxy_protocol = ""

[webserver.headers]
Cache-Control = "${ENV_TEST_WEBSERVER_HEADER_STRING}"
Test = "Test"
# impossible but to test ParseDict
Impossible-Header = {"test" = "${ENV_TEST_WEBSERVER_HEADER_STRING}"}

[[providers]]
name = "provider1"
type = "postgis"
host = "localhost"
port = 5432
database = "osm_water"
user = "admin"
password = ""

[[providers.layers]]
name = "water_0_5"
geometry_fieldname = "geom"
id_fieldname = "gid"
sql = "SELECT gid, ST_AsBinary(geom) AS geom FROM simplified_water_polygons WHERE geom && !BBOX!"

[[providers.layers]]
name = "water_6_10"
geometry_fieldname = "geom"
id_fieldname = "gid"
sql = "SELECT gid, ST_AsBinary(geom) AS geom FROM simplified_water_polygons WHERE geom && !BBOX!"

[[maps]]
name = "osm"
attribution = "Test Attribution"
bounds = [-180.0, -85.05112877980659, 180.0, 85.0511287798066]
center = ["${ENV_TEST_CENTER_X}", "${ENV_TEST_CENTER_Y}", "${ENV_TEST_CENTER_Z}"]

[[maps.layers]]
name = "water"
provider_layer = "${ENV_TEST_PROVIDER_LAYER}"

[[maps.layers]]
name = "water"
provider_layer = "provider1.water_6_10"
min_zoom = 6
max_zoom = 10

[[maps]]
name = "osm_2"
attribution = "Test Attribution"
bounds = [-180.0, -85.05112877980659, 180.0, 85.0511287798066]
center = [-76.275329586789, 39.153492567373, 8.0]

[[maps.layers]]
name = "water"
provider_layer = "provider1.water_0_5"
min_zoom = 0
max_zoom = 5

[maps.layers.default_tags]
provider = "${ENV_TEST_MAP_LAYER_DEFAULT_TAG}"

[[maps.layers]]
name = "water"
provider_layer = "provider1.water_6_10"
min_zoom = 6
max_zoom = 10`,
expected: config.Config{
LocationName: "",
Webserver: config.Webserver{
HostName: ENV_TEST_HOST_CONCAT,
Port: ENV_TEST_WEBSERVER_PORT,
Headers: env.Dict{
"Cache-Control": ENV_TEST_WEBSERVER_HEADER_STRING,
"Test": "Test",
"Impossible-Header": env.Dict{
"test": ENV_TEST_WEBSERVER_HEADER_STRING,
},
},
},
Providers: []env.Dict{
{
"name": "provider1",
"type": "postgis",
"host": "localhost",
"port": int64(5432),
"database": "osm_water",
"user": "admin",
"password": "",
"layers": []map[string]interface{}{
Nactik marked this conversation as resolved.
Show resolved Hide resolved
{
"name": "water_0_5",
"geometry_fieldname": "geom",
"id_fieldname": "gid",
"sql": "SELECT gid, ST_AsBinary(geom) AS geom FROM simplified_water_polygons WHERE geom && !BBOX!",
},
{
"name": "water_6_10",
"geometry_fieldname": "geom",
"id_fieldname": "gid",
"sql": "SELECT gid, ST_AsBinary(geom) AS geom FROM simplified_water_polygons WHERE geom && !BBOX!",
},
},
},
},
Maps: []provider.Map{
{
Name: "osm",
Attribution: "Test Attribution",
Bounds: []env.Float{-180, -85.05112877980659, 180, 85.0511287798066},
Center: [3]env.Float{ENV_TEST_CENTER_X, ENV_TEST_CENTER_Y, ENV_TEST_CENTER_Z},
TileBuffer: env.IntPtr(env.Int(64)),
Layers: []provider.MapLayer{
{
Name: "water",
ProviderLayer: ENV_TEST_PROVIDER_LAYER,
MinZoom: nil,
MaxZoom: nil,
},
{
Name: "water",
ProviderLayer: "provider1.water_6_10",
MinZoom: env.UintPtr(6),
MaxZoom: env.UintPtr(10),
},
},
},
{
Name: "osm_2",
Attribution: "Test Attribution",
Bounds: []env.Float{-180, -85.05112877980659, 180, 85.0511287798066},
Center: [3]env.Float{-76.275329586789, 39.153492567373, 8.0},
TileBuffer: env.IntPtr(env.Int(64)),
Layers: []provider.MapLayer{
{
Name: "water",
ProviderLayer: "provider1.water_0_5",
MinZoom: env.UintPtr(0),
MaxZoom: env.UintPtr(5),
DefaultTags: env.Dict{
"provider": ENV_TEST_MAP_LAYER_DEFAULT_TAG,
},
},
{
Name: "water",
ProviderLayer: "provider1.water_6_10",
MinZoom: env.UintPtr(6),
MaxZoom: env.UintPtr(10),
},
},
},
},
},
},
}

for name, tc := range tests {
Expand Down Expand Up @@ -533,7 +692,7 @@ func TestValidateMutateZoom(t *testing.T) {
"database": "osm_water",
"user": "admin",
"password": "",
"layers": []map[string]interface{}{
"layers": []map[string]any{
{
"name": "water",
"geometry_fieldname": "geom",
Expand Down Expand Up @@ -577,7 +736,7 @@ func TestValidateMutateZoom(t *testing.T) {
"database": "osm_water",
"user": "admin",
"password": "",
"layers": []map[string]interface{}{
"layers": []map[string]any{
{
"name": "water",
"geometry_fieldname": "geom",
Expand Down Expand Up @@ -646,7 +805,7 @@ func TestValidate(t *testing.T) {
"database": "osm_water",
"user": "admin",
"password": "",
"layers": []map[string]interface{}{
"layers": []map[string]any{
{
"name": "water",
"geometry_fieldname": "geom",
Expand All @@ -663,7 +822,7 @@ func TestValidate(t *testing.T) {
"database": "osm_water",
"user": "admin",
"password": "",
"layers": []map[string]interface{}{
"layers": []map[string]any{
{
"name": "water",
"geometry_fieldname": "geom",
Expand Down Expand Up @@ -710,7 +869,7 @@ func TestValidate(t *testing.T) {
"database": "osm_water",
"user": "admin",
"password": "",
"layers": []map[string]interface{}{
"layers": []map[string]any{
{
"name": "water_0_5",
"geometry_fieldname": "geom",
Expand All @@ -727,7 +886,7 @@ func TestValidate(t *testing.T) {
"database": "osm_water",
"user": "admin",
"password": "",
"layers": []map[string]interface{}{
"layers": []map[string]any{
{
"name": "water_5_10",
"geometry_fieldname": "geom",
Expand Down Expand Up @@ -780,7 +939,7 @@ func TestValidate(t *testing.T) {
"database": "osm_water",
"user": "admin",
"password": "",
"layers": []map[string]interface{}{
"layers": []map[string]any{
{
"name": "water",
"geometry_fieldname": "geom",
Expand All @@ -797,7 +956,7 @@ func TestValidate(t *testing.T) {
"database": "osm_water",
"user": "admin",
"password": "",
"layers": []map[string]interface{}{
"layers": []map[string]any{
{
"name": "water",
"geometry_fieldname": "geom",
Expand Down Expand Up @@ -863,7 +1022,7 @@ func TestValidate(t *testing.T) {
"database": "osm_water",
"user": "admin",
"password": "",
"layers": []map[string]interface{}{
"layers": []map[string]any{
{
"name": "water",
"geometry_fieldname": "geom",
Expand All @@ -880,7 +1039,7 @@ func TestValidate(t *testing.T) {
"database": "osm_water",
"user": "admin",
"password": "",
"layers": []map[string]interface{}{
"layers": []map[string]any{
{
"name": "water",
"geometry_fieldname": "geom",
Expand Down Expand Up @@ -932,7 +1091,7 @@ func TestValidate(t *testing.T) {
"database": "osm_water",
"user": "admin",
"password": "",
"layers": []map[string]interface{}{
"layers": []map[string]any{
{
"name": "water",
"geometry_fieldname": "geom",
Expand All @@ -949,7 +1108,7 @@ func TestValidate(t *testing.T) {
"database": "osm_water",
"user": "admin",
"password": "",
"layers": []map[string]interface{}{
"layers": []map[string]any{
{
"name": "water",
"geometry_fieldname": "geom",
Expand Down
9 changes: 9 additions & 0 deletions server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ var (
// when the server sits behind a reverse proxy with a prefix (i.e. /tegola)
URIPrefix = "/"

// ProxyProtocol is a custom protocol that will be used to generate the URLs
// included in the capabilities endpoint responses. This is useful when he
// server sits behind a reverse proxy
// (See https://github.com/go-spatial/tegola/pull/967)
ProxyProtocol string
ARolek marked this conversation as resolved.
Show resolved Hide resolved

// DefaultCORSHeaders define the default CORS response headers added to all requests
DefaultCORSHeaders = map[string]string{
"Access-Control-Allow-Origin": "*",
Expand Down Expand Up @@ -143,6 +149,9 @@ func hostName(r *http.Request) string {
// various checks to determine if the request is http or https. the scheme is needed for the TileURLs
// r.URL.Scheme can be empty if a relative request is issued from the client. (i.e. GET /foo.html)
func scheme(r *http.Request) string {
if ProxyProtocol != "" {
return ProxyProtocol
}
if r.Header.Get("X-Forwarded-Proto") != "" {
return r.Header.Get("X-Forwarded-Proto")
} else if r.TLS != nil {
Expand Down
Loading
Loading