Skip to content

Commit

Permalink
image/webp (#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
motiejus authored Jul 21, 2023
1 parent 601fcb2 commit dfcfe50
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 21 deletions.
28 changes: 15 additions & 13 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ import (
* along with this program; If not, see http://www.gnu.org/licenses/.
*/

var _matcher = regexp.MustCompile(`^/tile/([0-9]+)/([0-9]+)/([0-9]+).(png|webp)$`)

func findPath(baseDir, mapName string, z, x, y uint32) (metaPath string, offset uint32) {
var mask uint32
var hash [5]byte
Expand Down Expand Up @@ -63,7 +65,7 @@ func readInt(file *os.File) (uint32, error) {
return binary.LittleEndian.Uint32(b), nil
}

func readPngTile(metatile_path string, metatile_offset uint32) (*os.File, *io.SectionReader, error) {
func readTile(metatile_path string, metatile_offset uint32) (*os.File, *io.SectionReader, error) {
file, err := os.Open(metatile_path)
if err != nil {
return nil, nil, err
Expand All @@ -88,8 +90,8 @@ func readPngTile(metatile_path string, metatile_offset uint32) (*os.File, *io.Se
return file, io.NewSectionReader(file, int64(tile_offset), int64(tile_length)), nil
}

func writeTileResponse(writer http.ResponseWriter, req *http.Request, metatile_path string, metatile_offset uint32, modTime time.Time) error {
file, pngReader, err := readPngTile(metatile_path, metatile_offset)
func writeTileResponse(writer http.ResponseWriter, req *http.Request, metatile_path string, metatile_offset uint32, modTime time.Time, ext string) error {
file, tileReader, err := readTile(metatile_path, metatile_offset)
if file != nil {
defer file.Close()
}
Expand All @@ -103,15 +105,14 @@ func writeTileResponse(writer http.ResponseWriter, req *http.Request, metatile_p
return nil
}
writer.Header().Add("Cache-Control", "no-cache")
http.ServeContent(writer, req, "file.png", modTime, pngReader)
http.ServeContent(writer, req, "file."+ext, modTime, tileReader)
return nil
}

func parsePath(path string) (z, x, y uint32, err error) {
matcher := regexp.MustCompile(`^/tile/([0-9]+)/([0-9]+)/([0-9]+).png$`)
matches := matcher.FindStringSubmatch(path)
if len(matches) != 4 {
return 0, 0, 0, errors.New("could not match path")
func parsePath(path string) (z, x, y uint32, ext string, err error) {
matches := _matcher.FindStringSubmatch(path)
if len(matches) != 5 {
return 0, 0, 0, "", errors.New("could not match path")
}
zInt, err := strconv.Atoi(matches[1])
if err != nil {
Expand All @@ -125,20 +126,21 @@ func parsePath(path string) (z, x, y uint32, err error) {
if err != nil {
return
}
ext = matches[4]
z = uint32(zInt)
x = uint32(xInt)
y = uint32(yInt)
return
}

func handleRequest(resp http.ResponseWriter, req *http.Request, data_dir, map_name, renderd_socket string, renderd_timeout time.Duration, tile_expiration time.Duration) {
z, x, y, err := parsePath(req.URL.Path)
z, x, y, ext, err := parsePath(req.URL.Path)
if err != nil {
resp.WriteHeader(http.StatusBadRequest)
resp.Write([]byte(err.Error()))
return
}
resp.Header().Add("Content-Type", "image/png")
resp.Header().Add("Content-Type", "image/"+ext)
metatile_path, metatile_offset := findPath(data_dir, map_name, z, x, y)
fileInfo, statErr := os.Stat(metatile_path)
if statErr != nil {
Expand Down Expand Up @@ -172,8 +174,8 @@ func handleRequest(resp http.ResponseWriter, req *http.Request, data_dir, map_na
}
}
modTime := fileInfo.ModTime()
errPng := writeTileResponse(resp, req, metatile_path, metatile_offset, modTime)
if errPng != nil {
errTile := writeTileResponse(resp, req, metatile_path, metatile_offset, modTime, ext)
if errTile != nil {
resp.WriteHeader(http.StatusInternalServerError)
}
}
Expand Down
16 changes: 8 additions & 8 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import (
)

func TestParse(t *testing.T) {
z, x, y, err := parsePath("/tile/4/3/2.png")
z, x, y, ext, err := parsePath("/tile/4/3/2.webp")
if err != nil {
t.Error(err)
}
if z != 4 || x != 3 || y != 2 {
if z != 4 || x != 3 || y != 2 || ext != "webp" {
t.Fail()
}
}
Expand All @@ -32,7 +32,7 @@ func TestParseError(t *testing.T) {
"/tile/abc/3/2.png",
}
for _, path := range invalid_paths {
_, _, _, err := parsePath(path)
_, _, _, _, err := parsePath(path)
if err == nil {
t.Errorf("expected error for path %s", path)
}
Expand All @@ -46,13 +46,13 @@ func TestParseError(t *testing.T) {
// 22 microsecond and 13microsecond avg. response time is really nothing worth optimizing
func BenchmarkPngRead(b *testing.B) {
for i := 0; i < b.N; i++ {
readPngTile("mock_data/0.meta", 0)
readTile("mock_data/0.meta", 0)
}
}

func BenchmarkParsePath(b *testing.B) {
for i := 0; i < b.N; i++ {
_, _, _, err := parsePath("/tile/4/3/2.png")
_, _, _, _, err := parsePath("/tile/4/3/2.png")
if err != nil {
b.Error(err)
}
Expand All @@ -67,7 +67,7 @@ func TestWriteTileResponse(t *testing.T) {

// Call writeTileResponse function
modTime := time.Now()
err := writeTileResponse(w, req, "mock_data/0.meta", 0, modTime)
err := writeTileResponse(w, req, "mock_data/0.meta", 0, modTime, "png")
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -100,7 +100,7 @@ func TestWriteTileResponse(t *testing.T) {
func TestWriteTileResponse404(t *testing.T) {
req := httptest.NewRequest("GET", "http://example.com/", bytes.NewReader([]byte{}))
resp := httptest.ResponseRecorder{}
if err := writeTileResponse(&resp, req, "mock_data/404.meta", 0, time.Now()); err != nil {
if err := writeTileResponse(&resp, req, "mock_data/404.meta", 0, time.Now(), "png"); err != nil {
t.Error(err)
}
if resp.Code != 404 {
Expand All @@ -111,7 +111,7 @@ func TestWriteTileResponse404(t *testing.T) {
func TestWriteTileResponseOutOfBounds(t *testing.T) {
req := httptest.NewRequest("GET", "http://example.com/", bytes.NewReader([]byte{}))
resp := httptest.ResponseRecorder{}
if err := writeTileResponse(&resp, req, "mock_data/0.meta", 65, time.Now()); err != nil {
if err := writeTileResponse(&resp, req, "mock_data/0.meta", 65, time.Now(), "png"); err != nil {
t.Error(err)
}
if resp.Code != 500 {
Expand Down

0 comments on commit dfcfe50

Please sign in to comment.