mirror of
https://github.com/openstreetmap/mod_tile.git
synced 2025-08-20 13:21:06 +00:00
[mod_tile] support storage of gzip compressed content in metatiles
In some cases (e.g. geojson vector tiles) storing the content of metatiles in compressed form can be benefitial. In this case, make sure that the Content-Encoding header is set to gzip, so that clients can correctly decode the data. Wether data in a metatile is stored in compressed form or not is defined by the first 4 magic bytes, which are either META for uncompressed data or METZ for compressed date. Currently mod_tile does not yet support decompressing the data it self. So if a client doesn't send the Accept-Encoding: gzip header, they will get jumbled (still compressed) content back.
This commit is contained in:
14
mod_tile.c
14
mod_tile.c
@ -929,6 +929,7 @@ static int tile_handler_serve(request_rec *r)
|
||||
unsigned char err_msg[4096];
|
||||
unsigned char *buf;
|
||||
int len;
|
||||
int compressed;
|
||||
apr_status_t errstatus;
|
||||
|
||||
ap_conf_vector_t *sconf = r->server->module_config;
|
||||
@ -961,8 +962,19 @@ static int tile_handler_serve(request_rec *r)
|
||||
}
|
||||
|
||||
err_msg[0] = 0;
|
||||
len = tile_read(scfg->tile_dir, cmd->xmlname, cmd->x, cmd->y, cmd->z, buf, tile_max, err_msg);
|
||||
len = tile_read(scfg->tile_dir, cmd->xmlname, cmd->x, cmd->y, cmd->z, buf, tile_max, &compressed, err_msg);
|
||||
if (len > 0) {
|
||||
if (compressed) {
|
||||
const char* accept_encoding = apr_table_get(r->headers_in,"Accept-Encoding");
|
||||
if (accept_encoding && strstr(accept_encoding,"gzip")) {
|
||||
r->content_encoding = "gzip";
|
||||
} else {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
|
||||
"Tile data is compressed, but user agent doesn't support Content-Encoding and we don't know how to decompress it server side");
|
||||
//TODO: decompress the output stream before sending it to client
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Set default Last-Modified and Etag headers
|
||||
ap_update_mtime(r, r->finfo.mtime);
|
||||
|
21
store.c
21
store.c
@ -24,7 +24,7 @@
|
||||
#include "protocol.h"
|
||||
|
||||
#ifdef METATILE
|
||||
int read_from_meta(const char *tilepath, const char *xmlconfig, int x, int y, int z, unsigned char *buf, size_t sz, unsigned char * log_msg)
|
||||
int read_from_meta(const char *tilepath, const char *xmlconfig, int x, int y, int z, unsigned char *buf, size_t sz, int * compressed, unsigned char * log_msg)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
int meta_offset, fd;
|
||||
@ -61,10 +61,14 @@ int read_from_meta(const char *tilepath, const char *xmlconfig, int x, int y, in
|
||||
return -3;
|
||||
}
|
||||
if (memcmp(m->magic, META_MAGIC, strlen(META_MAGIC))) {
|
||||
snprintf(log_msg,1024, "Meta file %s header magic mismatch\n", path);
|
||||
close(fd);
|
||||
return -4;
|
||||
}
|
||||
if (memcmp(m->magic, META_MAGIC_COMPRESSED, strlen(META_MAGIC_COMPRESSED))) {
|
||||
snprintf(log_msg,1024, "Meta file %s header magic mismatch\n", path);
|
||||
close(fd);
|
||||
return -4;
|
||||
} else {
|
||||
*compressed = 1;
|
||||
}
|
||||
} else *compressed = 0;
|
||||
#if 1
|
||||
// Currently this code only works with fixed metatile sizes (due to xyz_to_meta above)
|
||||
if (m->count != (METATILE * METATILE)) {
|
||||
@ -142,12 +146,12 @@ int read_from_file(const char *tilepath, const char *xmlconfig, int x, int y, in
|
||||
return pos;
|
||||
}
|
||||
|
||||
int tile_read(const char *tilepath, const char *xmlconfig, int x, int y, int z, unsigned char *buf, int sz, unsigned char *err_msg)
|
||||
int tile_read(const char *tilepath, const char *xmlconfig, int x, int y, int z, unsigned char *buf, int sz, int * compressed, unsigned char *err_msg)
|
||||
{
|
||||
#ifdef METATILE
|
||||
int r;
|
||||
|
||||
r = read_from_meta(tilepath, xmlconfig, x, y, z, buf, sz, err_msg);
|
||||
r = read_from_meta(tilepath, xmlconfig, x, y, z, buf, sz, compressed, err_msg);
|
||||
if (r >= 0)
|
||||
return r;
|
||||
#endif
|
||||
@ -320,6 +324,7 @@ void process_unpack(const char *tilepath, const char *name)
|
||||
const int buf_len = 1024 * 1024;
|
||||
unsigned char *buf;
|
||||
struct stat s;
|
||||
int compressed;
|
||||
|
||||
// path_to_xyz is valid for meta tile names as well
|
||||
if (path_to_xyz(tilepath, name, xmlconfig, &x, &y, &z))
|
||||
@ -336,7 +341,7 @@ void process_unpack(const char *tilepath, const char *name)
|
||||
for (ox=0; ox < limit; ox++) {
|
||||
for (oy=0; oy < limit; oy++) {
|
||||
err_msg[0] = 0;
|
||||
int len = read_from_meta(tilepath, xmlconfig, x + ox, y + oy, z, buf, buf_len, err_msg);
|
||||
int len = read_from_meta(tilepath, xmlconfig, x + ox, y + oy, z, buf, buf_len, &compressed, err_msg);
|
||||
|
||||
if (len <= 0)
|
||||
fprintf(stderr, "Failed to get tile x(%d) y(%d) z(%d)\n %s", x + ox, y + oy, z, err_msg);
|
||||
|
5
store.h
5
store.h
@ -7,9 +7,10 @@ extern "C" {
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "render_config.h"
|
||||
int tile_read(const char *tilepath, const char *xmlconfig, int x, int y, int z, unsigned char *buf, int sz, unsigned char * err_msg);
|
||||
int tile_read(const char *tilepath, const char *xmlconfig, int x, int y, int z, unsigned char *buf, int sz, int * compressed, unsigned char * err_msg);
|
||||
|
||||
#define META_MAGIC "META"
|
||||
#define META_MAGIC_COMPRESSED "METZ"
|
||||
//static const char meta_magic[4] = { 'M', 'E', 'T', 'A' };
|
||||
|
||||
struct entry {
|
||||
@ -30,7 +31,7 @@ struct meta_layout {
|
||||
int read_from_file(const char *tilepath, const char *xmlconfig, int x, int y, int z, unsigned char *buf, size_t sz);
|
||||
|
||||
#ifdef METATILE
|
||||
int read_from_meta(const char *tilepath, const char *xmlconfig, int x, int y, int z, unsigned char *buf, size_t sz, unsigned char * log_msg);
|
||||
int read_from_meta(const char *tilepath, const char *xmlconfig, int x, int y, int z, unsigned char *buf, size_t sz, int * compressed, unsigned char * log_msg);
|
||||
void process_meta(const char *tilepath, const char *xmlconfig, int x, int y, int z);
|
||||
void process_pack(const char *tilepath, const char *name);
|
||||
void process_unpack(const char *tilepath, const char *name);
|
||||
|
Reference in New Issue
Block a user