mirror of https://github.com/jlelse/GoBlog
parent
bf3074a54d
commit
783afc1c3e
12 changed files with 243 additions and 68 deletions
@ -0,0 +1,82 @@ |
||||
package main |
||||
|
||||
import ( |
||||
"io" |
||||
"net/http" |
||||
"strings" |
||||
|
||||
"github.com/go-chi/chi/v5" |
||||
) |
||||
|
||||
func (a *goBlog) proxyTiles(basePath string) http.HandlerFunc { |
||||
tileSource := "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" |
||||
if c := a.cfg.MapTiles; c != nil && c.Source != "" { |
||||
tileSource = c.Source |
||||
} |
||||
return func(w http.ResponseWriter, r *http.Request) { |
||||
// Create a new request to proxy to the tile server
|
||||
targetUrl := tileSource |
||||
targetUrl = strings.ReplaceAll(targetUrl, "{s}", chi.URLParam(r, "s")) |
||||
targetUrl = strings.ReplaceAll(targetUrl, "{z}", chi.URLParam(r, "z")) |
||||
targetUrl = strings.ReplaceAll(targetUrl, "{x}", chi.URLParam(r, "x")) |
||||
targetUrl = strings.ReplaceAll(targetUrl, "{y}", chi.URLParam(r, "y")) |
||||
proxyRequest, _ := http.NewRequestWithContext(r.Context(), http.MethodGet, targetUrl, nil) |
||||
proxyRequest.Header.Set(userAgent, appUserAgent) |
||||
// Copy request headers
|
||||
for _, k := range []string{ |
||||
"Accept-Encoding", |
||||
"Accept-Language", |
||||
"Accept", |
||||
"Cache-Control", |
||||
"If-Modified-Since", |
||||
"If-None-Match", |
||||
"User-Agent", |
||||
} { |
||||
proxyRequest.Header.Set(k, r.Header.Get(k)) |
||||
} |
||||
// Do the request
|
||||
res, err := a.httpClient.Do(proxyRequest) |
||||
if err != nil { |
||||
a.serveError(w, r, err.Error(), http.StatusInternalServerError) |
||||
return |
||||
} |
||||
// Copy result headers
|
||||
for _, k := range []string{ |
||||
"Accept-Ranges", |
||||
"Access-Control-Allow-Origin", |
||||
"Age", |
||||
"Cache-Control", |
||||
"Content-Length", |
||||
"Content-Type", |
||||
"Etag", |
||||
"Expires", |
||||
} { |
||||
w.Header().Set(k, res.Header.Get(k)) |
||||
} |
||||
// Copy result
|
||||
w.WriteHeader(res.StatusCode) |
||||
_, _ = io.Copy(w, res.Body) |
||||
_ = res.Body.Close() |
||||
} |
||||
} |
||||
|
||||
func (a *goBlog) getMinZoom() int { |
||||
if c := a.cfg.MapTiles; c != nil { |
||||
return c.MinZoom |
||||
} |
||||
return 0 |
||||
} |
||||
|
||||
func (a *goBlog) getMaxZoom() int { |
||||
if c := a.cfg.MapTiles; c != nil && c.MaxZoom > 0 { |
||||
return c.MaxZoom |
||||
} |
||||
return 20 |
||||
} |
||||
|
||||
func (a *goBlog) getMapAttribution() string { |
||||
if c := a.cfg.MapTiles; c != nil { |
||||
return c.Attribution |
||||
} |
||||
return `© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors` |
||||
} |
@ -0,0 +1,95 @@ |
||||
package main |
||||
|
||||
import ( |
||||
"net/http" |
||||
"testing" |
||||
|
||||
"github.com/go-chi/chi/v5" |
||||
"github.com/stretchr/testify/assert" |
||||
"github.com/stretchr/testify/require" |
||||
) |
||||
|
||||
func Test_proxyTiles(t *testing.T) { |
||||
app := &goBlog{ |
||||
cfg: &config{}, |
||||
} |
||||
|
||||
hc := &fakeHttpClient{ |
||||
handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
||||
w.Write([]byte("Hello, World!")) |
||||
}), |
||||
} |
||||
app.httpClient = hc |
||||
|
||||
// Default tile source
|
||||
|
||||
m := chi.NewMux() |
||||
m.Get("/x/tiles/{s}/{z}/{x}/{y}.png", app.proxyTiles("/x/tiles")) |
||||
|
||||
req, err := http.NewRequest(http.MethodGet, "https://example.org/x/tiles/c/8/134/84.png", nil) |
||||
require.NoError(t, err) |
||||
resp, err := doHandlerRequest(req, m) |
||||
require.NoError(t, err) |
||||
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode) |
||||
assert.Equal(t, "https://c.tile.openstreetmap.org/8/134/84.png", hc.req.URL.String()) |
||||
|
||||
// Custom tile source
|
||||
|
||||
app.cfg.MapTiles = &configMapTiles{ |
||||
Source: "https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png", |
||||
} |
||||
|
||||
m = chi.NewMux() |
||||
m.Get("/x/tiles/{s}/{z}/{x}/{y}.png", app.proxyTiles("/x/tiles")) |
||||
|
||||
req, err = http.NewRequest(http.MethodGet, "https://example.org/x/tiles/c/8/134/84.png", nil) |
||||
require.NoError(t, err) |
||||
resp, err = doHandlerRequest(req, m) |
||||
require.NoError(t, err) |
||||
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode) |
||||
assert.Equal(t, "https://c.tile.opentopomap.org/8/134/84.png", hc.req.URL.String()) |
||||
} |
||||
|
||||
func Test_getMinZoom(t *testing.T) { |
||||
app := &goBlog{ |
||||
cfg: &config{}, |
||||
} |
||||
|
||||
assert.Equal(t, 0, app.getMinZoom()) |
||||
|
||||
app.cfg.MapTiles = &configMapTiles{ |
||||
MinZoom: 1, |
||||
} |
||||
|
||||
assert.Equal(t, 1, app.getMinZoom()) |
||||
} |
||||
|
||||
func Test_getMaxZoom(t *testing.T) { |
||||
app := &goBlog{ |
||||
cfg: &config{}, |
||||
} |
||||
|
||||
assert.Equal(t, 20, app.getMaxZoom()) |
||||
|
||||
app.cfg.MapTiles = &configMapTiles{ |
||||
MaxZoom: 10, |
||||
} |
||||
|
||||
assert.Equal(t, 10, app.getMaxZoom()) |
||||
} |
||||
|
||||
func Test_getMapAttribution(t *testing.T) { |
||||
app := &goBlog{ |
||||
cfg: &config{}, |
||||
} |
||||
|
||||
assert.Equal(t, `© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors`, app.getMapAttribution()) |
||||
|
||||
app.cfg.MapTiles = &configMapTiles{ |
||||
Attribution: "attribution", |
||||
} |
||||
|
||||
assert.Equal(t, "attribution", app.getMapAttribution()) |
||||
} |
Loading…
Reference in new issue