// An HTTP handler which returns a tileset's `layer.json` file func LayerHandler(store stores.Storer) func(http.ResponseWriter, *http.Request) { return func(w http.ResponseWriter, r *http.Request) { var ( err error layer []byte ) defer func() { if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) log.Err(err.Error()) } }() vars := mux.Vars(r) // Try and get a `layer.json` from the stores layer, err = store.Layer(vars["tileset"]) if err == stores.ErrNoItem { err = nil // don't persist this error if store.TilesetStatus(vars["tileset"]) == stores.NOT_FOUND { http.Error(w, fmt.Errorf("The tileset `%s` does not exist", vars["tileset"]).Error(), http.StatusNotFound) return } // the directory exists: send the default `layer.json` layer = []byte(`{ "tilejson": "2.1.0", "format": "heightmap-1.0", "version": "1.0.0", "scheme": "tms", "tiles": ["{z}/{x}/{y}.terrain"] }`) } else if err != nil { return } headers := w.Header() headers.Set("Content-Type", "application/json") w.Write(layer) } }
func (this *Cache) ServeHTTP(w http.ResponseWriter, r *http.Request) { var limiter ResponseLimiter var recorder http.ResponseWriter rec := NewRecorder() // If a limiter is provided, wrap the recorder with it. if this.limiter != nil { limiter = this.limiter(rec, this.Limit) recorder = limiter } else { recorder = rec } // Write to both the recorder and original writer. tee := MultiWriter(w, recorder) this.handler.ServeHTTP(tee, r) // Only cache 200 responses. if rec.Code != 200 { return } // If the cache limit has been exceeded, don't proceed to cache the // response. if limiter != nil && limiter.LimitExceeded() { log.Debug(fmt.Sprintf("cache limit exceeded for %s", r.URL.String())) return } // Cache the response. key := this.generateKey(r) log.Debug(fmt.Sprintf("setting key: %s", key)) if err := this.mc.Set(&memcache.Item{Key: key, Value: rec.Body.Bytes()}); err != nil { log.Err(err.Error()) } return }
// An HTTP handler which returns a terrain tile resource func TerrainHandler(store stores.Storer) func(http.ResponseWriter, *http.Request) { return func(w http.ResponseWriter, r *http.Request) { var ( t stores.Terrain err error ) defer func() { if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) log.Err(err.Error()) } }() // get the tile coordinate from the URL vars := mux.Vars(r) err = t.ParseCoord(vars["x"], vars["y"], vars["z"]) if err != nil { return } // Try and get a tile from the store err = store.Tile(vars["tileset"], &t) if err == stores.ErrNoItem { if store.TilesetStatus(vars["tileset"]) == stores.NOT_FOUND { err = nil http.Error(w, fmt.Errorf("The tileset `%s` does not exist", vars["tileset"]).Error(), http.StatusNotFound) return } if t.IsRoot() { // serve up a blank tile as it is a missing root tile data, err := assets.Asset("data/smallterrain-blank.terrain") if err != nil { return } else { err = t.UnmarshalBinary(data) if err != nil { return } } } else { err = nil http.Error(w, errors.New("The terrain tile does not exist").Error(), http.StatusNotFound) return } } else if err != nil { return } body, err := t.MarshalBinary() if err != nil { return } // send the tile to the client headers := w.Header() headers.Set("Content-Type", "application/octet-stream") headers.Set("Content-Encoding", "gzip") headers.Set("Content-Disposition", "attachment;filename="+vars["y"]+".terrain") w.Write(body) } }