Skip to content

Commit

Permalink
Merge pull request go-spatial#212 from terranodo/issue199_hostNameFixup
Browse files Browse the repository at this point in the history
Issue199 host name fixup
  • Loading branch information
ARolek authored Dec 11, 2017
2 parents 0817b4b + c10146b commit 9f92ad0
Show file tree
Hide file tree
Showing 4 changed files with 235 additions and 20 deletions.
169 changes: 166 additions & 3 deletions server/handle_capabilities_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

"github.com/dimfeld/httptreemux"

"github.com/terranodo/tegola"
"github.com/terranodo/tegola/atlas"
"github.com/terranodo/tegola/server"
)
Expand All @@ -19,14 +20,16 @@ func TestHandleCapabilities(t *testing.T) {
testcases := []struct {
handler http.Handler
hostname string
port string
uri string
uriPattern string
reqMethod string
expected server.Capabilities
}{
// With empty hostname and no port specified in config, urls should have host:port matching
// request uri.
{
handler: server.HandleCapabilities{},
hostname: "",
uri: "http://localhost:8080/capabilities",
uriPattern: "/capabilities",
reqMethod: "GET",
Expand All @@ -37,7 +40,7 @@ func TestHandleCapabilities(t *testing.T) {
Name: "test-map",
Attribution: "test attribution",
Center: [3]float64{1.0, 2.0, 3.0},
Bounds: [4]float64{-180.0, -85.0511, 180.0, 85.0511},
Bounds: tegola.WGS84Bounds,
Capabilities: "http://localhost:8080/capabilities/test-map.json",
Tiles: []string{
"http://localhost:8080/maps/test-map/{z}/{x}/{y}.pbf",
Expand All @@ -64,9 +67,12 @@ func TestHandleCapabilities(t *testing.T) {
},
},
},
// With hostname set and port set to "none" in config, urls should have host "cdn.tegola.io"
// debug layers turned on
{
handler: server.HandleCapabilities{},
hostname: "cdn.tegola.io",
port: "none", // Set to none or port 8080 from uri will be used.
uri: "http://localhost:8080/capabilities?debug=true",
uriPattern: "/capabilities",
reqMethod: "GET",
Expand All @@ -77,7 +83,7 @@ func TestHandleCapabilities(t *testing.T) {
Name: "test-map",
Attribution: "test attribution",
Center: [3]float64{1.0, 2.0, 3.0},
Bounds: [4]float64{-180.0, -85.0511, 180.0, 85.0511},
Bounds: tegola.WGS84Bounds,
Capabilities: "http://cdn.tegola.io/capabilities/test-map.json?debug=true",
Tiles: []string{
"http://cdn.tegola.io/maps/test-map/{z}/{x}/{y}.pbf?debug=true",
Expand Down Expand Up @@ -120,12 +126,169 @@ func TestHandleCapabilities(t *testing.T) {
},
},
},
{
handler: server.HandleCapabilities{},
uri: "http://localhost:8080/capabilities",
uriPattern: "/capabilities",
reqMethod: "GET",
expected: server.Capabilities{
Version: serverVersion,
Maps: []server.CapabilitiesMap{
{
Name: "test-map",
Attribution: "test attribution",
Center: [3]float64{1.0, 2.0, 3.0},
Bounds: tegola.WGS84Bounds,
Capabilities: "http://localhost:8080/capabilities/test-map.json",
Tiles: []string{
"http://localhost:8080/maps/test-map/{z}/{x}/{y}.pbf",
},
Layers: []server.CapabilitiesLayer{
{
Name: testLayer1.MVTName(),
Tiles: []string{
fmt.Sprintf("http://localhost:8080/maps/test-map/%v/{z}/{x}/{y}.pbf", testLayer1.MVTName()),
},
MinZoom: testLayer1.MinZoom,
MaxZoom: testLayer3.MaxZoom, // layer 1 and layer 3 share a name in our test so the zoom range includes the entire zoom range
},
{
Name: testLayer2.MVTName(),
Tiles: []string{
fmt.Sprintf("http://localhost:8080/maps/test-map/%v/{z}/{x}/{y}.pbf", testLayer2.MVTName()),
},
MinZoom: testLayer2.MinZoom,
MaxZoom: testLayer2.MaxZoom,
},
},
},
},
},
},
// With hostname set in config, port unset in config, and no port in request uri,
// urls should have host from config and no port: "cdn.tegola.io"
{
handler: server.HandleCapabilities{},
hostname: "cdn.tegola.io",
port: "none", // Set to none or port 8080 from uri will be used.
uri: "http://localhost/capabilities?debug=true",
uriPattern: "/capabilities",
reqMethod: "GET",
expected: server.Capabilities{
Version: serverVersion,
Maps: []server.CapabilitiesMap{
{
Name: "test-map",
Attribution: "test attribution",
Center: [3]float64{1.0, 2.0, 3.0},
Bounds: tegola.WGS84Bounds,
Capabilities: "http://cdn.tegola.io/capabilities/test-map.json?debug=true",
Tiles: []string{
"http://cdn.tegola.io/maps/test-map/{z}/{x}/{y}.pbf?debug=true",
},
Layers: []server.CapabilitiesLayer{
{
Name: "debug-tile-outline",
Tiles: []string{
"http://cdn.tegola.io/maps/test-map/debug-tile-outline/{z}/{x}/{y}.pbf?debug=true",
},
MinZoom: 0,
MaxZoom: atlas.MaxZoom,
},
{
Name: "debug-tile-center",
Tiles: []string{
"http://cdn.tegola.io/maps/test-map/debug-tile-center/{z}/{x}/{y}.pbf?debug=true",
},
MinZoom: 0,
MaxZoom: atlas.MaxZoom,
},
{
Name: testLayer1.MVTName(),
Tiles: []string{
fmt.Sprintf("http://cdn.tegola.io/maps/test-map/%v/{z}/{x}/{y}.pbf?debug=true", testLayer1.MVTName()),
},
MinZoom: testLayer1.MinZoom,
MaxZoom: testLayer3.MaxZoom, // layer 1 and layer 3 share a name in our test so the zoom range includes the entire zoom range
},
{
Name: "test-layer-2-name",
Tiles: []string{
fmt.Sprintf("http://cdn.tegola.io/maps/test-map/%v/{z}/{x}/{y}.pbf?debug=true", testLayer2.MVTName()),
},
MinZoom: testLayer2.MinZoom,
MaxZoom: testLayer2.MaxZoom,
},
},
},
},
},
},
// With hostname set and port unset in config, urls should have host from config and
// port from uri: "cdn.tegola.io:8080"
{
handler: server.HandleCapabilities{},
hostname: "cdn.tegola.io",
uri: "http://localhost:8080/capabilities?debug=true",
uriPattern: "/capabilities",
reqMethod: "GET",
expected: server.Capabilities{
Version: serverVersion,
Maps: []server.CapabilitiesMap{
{
Name: "test-map",
Attribution: "test attribution",
Center: [3]float64{1.0, 2.0, 3.0},
Bounds: tegola.WGS84Bounds,
Capabilities: "http://cdn.tegola.io:8080/capabilities/test-map.json?debug=true",
Tiles: []string{
"http://cdn.tegola.io:8080/maps/test-map/{z}/{x}/{y}.pbf?debug=true",
},
Layers: []server.CapabilitiesLayer{
{
Name: "debug-tile-outline",
Tiles: []string{
"http://cdn.tegola.io:8080/maps/test-map/debug-tile-outline/{z}/{x}/{y}.pbf?debug=true",
},
MinZoom: 0,
MaxZoom: atlas.MaxZoom,
},
{
Name: "debug-tile-center",
Tiles: []string{
"http://cdn.tegola.io:8080/maps/test-map/debug-tile-center/{z}/{x}/{y}.pbf?debug=true",
},
MinZoom: 0,
MaxZoom: atlas.MaxZoom,
},
{
Name: testLayer1.MVTName(),
Tiles: []string{
fmt.Sprintf("http://cdn.tegola.io:8080/maps/test-map/%v/{z}/{x}/{y}.pbf?debug=true", testLayer1.MVTName()),
},
MinZoom: testLayer1.MinZoom,
MaxZoom: testLayer3.MaxZoom, // layer 1 and layer 3 share a name in our test so the zoom range includes the entire zoom range
},
{
Name: "test-layer-2-name",
Tiles: []string{
fmt.Sprintf("http://cdn.tegola.io:8080/maps/test-map/%v/{z}/{x}/{y}.pbf?debug=true", testLayer2.MVTName()),
},
MinZoom: testLayer2.MinZoom,
MaxZoom: testLayer2.MaxZoom,
},
},
},
},
},
},
}

for i, test := range testcases {
var err error

server.HostName = test.hostname
server.Port = test.port

// setup a new router. this handles parsing our URL wildcards (i.e. :map_name, :z, :x, :y)
router := httptreemux.New()
Expand Down
3 changes: 3 additions & 0 deletions server/handle_map_capabilities_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ func TestHandleMapCapabilities(t *testing.T) {
testcases := []struct {
handler http.Handler
hostName string
port string
uri string
uriPattern string
reqMethod string
Expand Down Expand Up @@ -81,6 +82,7 @@ func TestHandleMapCapabilities(t *testing.T) {
{
handler: server.HandleCapabilities{},
hostName: "cdn.tegola.io",
port: "none",
uri: "http://localhost:8080/capabilities/test-map.json?debug=true",
uriPattern: "/capabilities/:map_name",
reqMethod: "GET",
Expand Down Expand Up @@ -161,6 +163,7 @@ func TestHandleMapCapabilities(t *testing.T) {
var err error

server.HostName = test.hostName
server.Port = test.port

// setup a new router. this handles parsing our URL wildcards (i.e. :map_name, :z, :x, :y)
router := httptreemux.New()
Expand Down
40 changes: 31 additions & 9 deletions server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package server
import (
"log"
"net/http"
"strings"

"github.com/dimfeld/httptreemux"
"github.com/terranodo/tegola/atlas"
Expand All @@ -18,8 +19,10 @@ const (
var (
// set at runtime from main
Version string
// configurable via the tegola config.toml file
// configurable via the tegola config.toml file (set in main.go)
HostName string
// configurable via the tegola config.toml file (set in main.go)
Port string
// reference to the version of atlas to work with
Atlas *atlas.Atlas
)
Expand Down Expand Up @@ -57,17 +60,36 @@ func Start(port string) {
log.Fatal(http.ListenAndServe(port, r))
}

// determins the hostname to return based on the following hierarchy
// - HostName var as configured via the config file
// - The request host
// determines the hostname:port to return based on the following hierarchy
// - HostName / Port vars as configured via the config file
// - The request host / port if config HostName or Port is missing
func hostName(r *http.Request) string {
// configured
if HostName != "" {
return HostName
var requestHostname string
var requestPort string
substrs := strings.Split(r.Host, ":")
switch len(substrs) {
case 1:
requestHostname = substrs[0]
case 2:
requestHostname = substrs[0]
requestPort = substrs[1]
default:
log.Printf("multiple colons (':') in host string: %v", r.Host)
}

// default to the Host provided in the request
return r.Host
retHost := HostName
if HostName == "" {
retHost = requestHostname
}

if Port != "" && Port != "none" {
return retHost + Port
}
if requestPort != "" && Port != "none" {
return retHost + ":" + requestPort
}

return retHost
}

// various checks to determin if the request is http or https. the scheme is needed for the TileURLs
Expand Down
43 changes: 35 additions & 8 deletions server/server_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,61 @@ package server
import (
"crypto/tls"
"net/http"
"net/url"
"testing"
)

func TestHostName(t *testing.T) {
testcases := []struct {
request http.Request
url string
hostName string
port string
expected string
}{
{
request: http.Request{
Host: "localhost",
},
hostName: "",
expected: "localhost",
// With hostname & port unset in config, expect host:port matching URL
url: "http://localhost:8080/capabilities",
expected: "localhost:8080",
},
{
request: http.Request{},
// With hostname set and port set to "none" in config, expect "cdn.tegola.io"
url: "http://localhost:8080/capabilities",
hostName: "cdn.tegola.io",
port: "none",
expected: "cdn.tegola.io",
},
{
// Hostname set, no port in config, but port in url. Expect <config_host>:<url_port>.
url: "http://localhost:8080/capabilities",
hostName: "cdn.tegola.io",
expected: "cdn.tegola.io:8080",
},
{
// Hostname set, no port in config or url, expect hostname to match config.
url: "http://localhost/capabilities",
hostName: "cdn.tegola.io",
expected: "cdn.tegola.io",
},
{
// Hostname unset, no port in config or url, expect hostname to match url host.
url: "http://localhost/capabilities",
expected: "localhost",
},
}

for i, tc := range testcases {
// set the package variable
HostName = tc.hostName
Port = tc.port

url, err := url.Parse(tc.url)
if err != nil {
t.Errorf("testcase (%v) failed. could not create url.URL from (%v): %v", i, tc.url, err)
}

req := http.Request{URL: url, Host: url.Host}

output := hostName(&tc.request)
output := hostName(&req)
if output != tc.expected {
t.Errorf("testcase (%v) failed. expected (%v) does not match result (%v)", i, tc.expected, output)
}
Expand Down

0 comments on commit 9f92ad0

Please sign in to comment.