Skip to content
Browse files

Merge branch 'config-nginx'

  • Loading branch information...
2 parents d677d36 + c28bb04 commit 7d4d9788314b8be579802b04a1fdd303583db3dd @tbonfort committed Apr 24, 2012
Showing with 117 additions and 15 deletions.
  1. +9 −3 configure
  2. +3 −0 configure.in
  3. +4 −0 include/mapcache.h
  4. +8 −3 lib/core.c
  5. +4 −0 lib/tileset.c
  6. +43 −0 nginx/README
  7. +1 −1 nginx/config.in
  8. +24 −0 nginx/nginx.conf
  9. +21 −8 nginx/ngx_http_mapcache_module.c
View
12 configure
@@ -653,11 +653,13 @@ PKGCONFIG
SQLITE_ENABLED
SQLITE_LIB
SQLITE_INC
+APU_LDLIBS
APU_LIBS
APU_INCDIR
APU_INC
MEMCACHE_ENABLED
APUCONFIG
+APR_LDLIBS
APR_LIBS
APR_INCDIR
APR_INC
@@ -12222,7 +12224,9 @@ $as_echo "yes" >&6; }
APR_INCDIR=`$APRCONFIG --includedir`
- APR_LIBS=`$APRCONFIG --link-ld`
+ APR_LIBS=`$APRCONFIG --link-libtool`
+
+ APR_LDLIBS=`$APRCONFIG --link-ld`
@@ -12362,7 +12366,8 @@ $as_echo "yes" >&6; }
if test -z "$APUCONFIG"; then
as_fn_error $? "apu-config utility not found" "$LINENO" 5
else
- APU_LIBS=`$APUCONFIG --link-ld`
+ APU_LIBS=`$APUCONFIG --link-libtool`
+ APU_LDLIBS=`$APUCONFIG --link-ld`
APU_INC=`$APUCONFIG --includes`
APU_INCDIR=`$APUCONFIG --includedir`
fi
@@ -12372,6 +12377,7 @@ $as_echo "yes" >&6; }
+
# Check whether --enable-memcache was given.
if test "${enable_memcache+set}" = set; then :
enableval=$enable_memcache;
@@ -12386,7 +12392,7 @@ fi
if test -z "$APUCONFIG"; then
as_fn_error $? "memcache check failed: apu-config utility not found" "$LINENO" 5
fi
- OLDLDFLAGS="$LDFLAGS" ; LDFLAGS="$LDFLAGS `$APUCONFIG --ldflags --libs --link-ld`"
+ OLDLDFLAGS="$LDFLAGS" ; LDFLAGS="$LDFLAGS `$APUCONFIG --ldflags --libs --link-libtool`"
OLDCPPFLAGS="$CPPFLAGS" ; CPPFLAGS="$CPPFLAGS `$APUCONFIG --includes`"
#check we can link against the memcache functions (i.e. is apr-util recent enough)
View
3 configure.in
@@ -346,13 +346,15 @@ AC_DEFUN([APU_CHECK],[
AC_MSG_ERROR(apu-config utility not found)
else
APU_LIBS=`$APUCONFIG --link-libtool`
+ APU_LDLIBS=`$APUCONFIG --link-ld`
APU_INC=`$APUCONFIG --includes`
APU_INCDIR=`$APUCONFIG --includedir`
fi
AC_SUBST(APUCONFIG)
AC_SUBST(APU_INC)
AC_SUBST(APU_INCDIR)
AC_SUBST(APU_LIBS)
+ AC_SUBST(APU_LDLIBS)
])
AC_DEFUN([APR_CHECK],[
@@ -411,6 +413,7 @@ AC_DEFUN([APR_CHECK],[
AC_SUBST(APR_INC,`$APRCONFIG --includes`)
AC_SUBST(APR_INCDIR,`$APRCONFIG --includedir`)
AC_SUBST(APR_LIBS,`$APRCONFIG --link-libtool`)
+ AC_SUBST(APR_LDLIBS,`$APRCONFIG --link-ld`)
])
AC_DEFUN([PCRE_CHECK],[
View
4 include/mapcache.h
@@ -996,6 +996,10 @@ struct mapcache_cfg {
as in that case the apache LogLevel directive is
used. */
mapcache_mode mode;
+
+ /* return 404 on potentially blocking operations (proxying, source getmaps,
+ locks on metatile waiting, ... Used for nginx module */
+ int non_blocking;
};
/**
View
11 lib/core.c
@@ -81,7 +81,7 @@ void mapcache_prefetch_tiles(mapcache_context *ctx, mapcache_tile **tiles, int n
#if !APR_HAS_THREADS
int i;
for(i=0;i<ntiles;i++) {
- mapcache_tileset_tile_get(ctx, tiles[i]);
+ mapcache_tileset_tile_get(ctx, tiles[i], readonly);
GC_CHECK_ERROR(ctx);
}
#else
@@ -157,6 +157,7 @@ void mapcache_prefetch_tiles(mapcache_context *ctx, mapcache_tile **tiles, int n
/* fetch the tiles that did not get a thread launched for them */
if(thread_tiles[i].launch) continue;
mapcache_tileset_tile_get(ctx, tiles[i]);
+ GC_CHECK_ERROR(ctx);
}
#else
/* experimental version using a threadpool, disabled for stability reasons */
@@ -291,7 +292,7 @@ mapcache_http_response *mapcache_core_get_tile(mapcache_context *ctx, mapcache_r
return response;
}
-void mapcache_fetch_maps(mapcache_context *ctx, mapcache_map **maps, int nmaps, mapcache_resample_mode mode ) {
+void mapcache_fetch_maps(mapcache_context *ctx, mapcache_map **maps, int nmaps, mapcache_resample_mode mode) {
mapcache_tile ***maptiles;
int *nmaptiles;
mapcache_tile **tiles;
@@ -316,6 +317,7 @@ void mapcache_fetch_maps(mapcache_context *ctx, mapcache_map **maps, int nmaps,
}
}
mapcache_prefetch_tiles(ctx,tiles,ntiles);
+ GC_CHECK_ERROR(ctx);
for(i=0;i<nmaps;i++) {
int j;
for(j=0;j<nmaptiles[i];j++) {
@@ -370,7 +372,7 @@ mapcache_http_response *mapcache_core_get_map(mapcache_context *ctx, mapcache_re
if(overlaymap->mtime > basemap->mtime) basemap->mtime = overlaymap->mtime;
if(!basemap->expires || overlaymap->expires<basemap->expires) basemap->expires = overlaymap->expires;
}
- } else /*if(ctx->config->getmap_strategy == MAPCACHE_GETMAP_FORWARD)*/ {
+ } else if(!ctx->config->non_blocking && req_map->getmap_strategy == MAPCACHE_GETMAP_FORWARD) {
int i;
for(i=0;i<req_map->nmaps;i++) {
if(!req_map->maps[i]->tileset->source) {
@@ -400,6 +402,9 @@ mapcache_http_response *mapcache_core_get_map(mapcache_context *ctx, mapcache_re
if(!basemap->expires || overlaymap->expires<basemap->expires) basemap->expires = overlaymap->expires;
}
}
+ } else {
+ ctx->set_error(ctx,400,"failed getmap, readonly mode");
+ return NULL;
}
if(basemap->raw_image) {
View
4 lib/tileset.c
@@ -543,6 +543,10 @@ void mapcache_tileset_tile_get(mapcache_context *ctx, mapcache_tile *tile) {
if(ret == MAPCACHE_CACHE_MISS) {
/* bail out straight away if the tileset has no source */
+ if(ctx->config->non_blocking) {
+ ctx->set_error(ctx,404,"tile not in cache, and configured for readonly mode");
+ return;
+ }
if(!tile->tileset->source) {
ctx->set_error(ctx,404,"tile not in cache, and no source configured for tileset %s",
tile->tileset->name);
View
43 nginx/README
@@ -17,3 +17,46 @@ to parse the incoming requests.
before running nginx, set LD_LIBRARY_PATH to where libmapcache was installed if that
is a non standard location.
+
+Note that nginx processes are scarse and would be locked when mapcache is doing
+a curl request for a metatile, or when waiting for a metatile to be rendered.
+So as not to lock down the whole nginx server in this case, mapcache will fail
+with a 404 error if a requested tile cannot be found in it's cache. It is up to
+the administrator of the server to forward these failed requests to an external
+fastcgi or apache mapcache instance running with the same configuration file.
+
+
+Here is a configuration block which forwards these 404 requests:
+
+ location ~ ^/mapcache(?<path_info>/.*|$) {
+ set $url_prefix "/mapcache";
+ mapcache /path/to/etc/mapcache.xml;
+ #error_page 404 = @apache_mapcache;
+ error_page 404 = @fcgi_mapcache;
+ }
+
+#proxy for a mapcache instance running on another server
+ location @apache_mapcache {
+ proxy_pass http://localhost:8081;
+# this supposes you have mapcache as a module running in an apache httpd server, where
+# you would have set the httpd.conf to contain:
+# MapcacheAlias /mapcache /path/to/etc/mapcache.xml;
+ }
+
+#mapcache as fcgi running with an external spawning manager (e.g. spawn-fcgi or fcgistarter)
+#(make sure mapcache is built with fastcgi support)
+#eg:
+# export MAPCACHE_CONFIG_FILE=/path/to/etc/mapcache.xml
+# /usr/local/httpd-2.4/bin/fcgistarter -c /usr/local/bin/mapcache -p 9001 -N 20
+
+ location @fcgi_mapcache {
+ fastcgi_pass localhost:9001;
+ fastcgi_param QUERY_STRING $query_string;
+ fastcgi_param REQUEST_METHOD $request_method;
+ fastcgi_param CONTENT_TYPE $content_type;
+ fastcgi_param CONTENT_LENGTH $content_length;
+ fastcgi_param PATH_INFO $path_info;
+ }
+
+
+
View
2 nginx/config.in
@@ -1,6 +1,6 @@
ngx_addon_name=ngx_http_mapcache_module
HTTP_MODULES="$HTTP_MODULES ngx_http_mapcache_module"
NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_mapcache_module.c"
-CORE_LIBS="$CORE_LIBS -Wl,-rpath,@prefix@/lib -L@prefix@/lib -lmapcache @APR_LIBS@ @APU_LIBS@"
+CORE_LIBS="$CORE_LIBS -Wl,-rpath,@prefix@/lib -L@prefix@/lib -lmapcache @APR_LDLIBS@ @APU_LDLIBS@"
CFLAGS="$CFLAGS @MISC_ENABLED@ @MEMCACHE_ENABLED@ @PCRE_ENABLED@ @OGR_ENABLED@ @GEOS_ENABLED@ @SQLITE_ENABLED@ @PIXMAN_ENABLED@ @TIFF_ENABLED@ @GEOTIFF_ENABLED@ @MAPSERVER_ENABLED@"
CORE_INCS="$CORE_INCS @APU_INCDIR@ @APR_INCDIR@"
View
24 nginx/nginx.conf
@@ -60,6 +60,30 @@ http {
mapcache /home/tbonfort/dev/mapserver-trunk/mapcache/mapcache.xml;
}
+ location ~ ^/mapcache(?<path_info>/.*|$) {
+ set $url_prefix "/mapcache";
+ mapcache /home/tbonfort/dev/mapcache/mapcache-local.xml;
+#don't render uncached tiles ourself, forward them to fcgi or apache instance
+ #error_page 404 = @apache_mapcache;
+ error_page 404 = @fcgi_mapcache;
+ }
+
+#proxy for a mapcache instance running on another server
+ location @apache_mapcache {
+ proxy_pass http://localhost:8081;
+ }
+
+#mapcache as fcgi running with an external spawning manager (e.g. spawn-fcgi or fcgistarter)
+ location @fcgi_mapcache {
+ fastcgi_pass localhost:9001;
+ fastcgi_param QUERY_STRING $query_string;
+ fastcgi_param REQUEST_METHOD $request_method;
+ fastcgi_param CONTENT_TYPE $content_type;
+ fastcgi_param CONTENT_LENGTH $content_length;
+ fastcgi_param PATH_INFO $path_info;
+ }
+
+
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
View
29 nginx/ngx_http_mapcache_module.c
@@ -3,6 +3,7 @@
#include <ngx_http.h>
#include "../include/mapcache.h"
#include <apr_date.h>
+#include <apr_strings.h>
static char *ngx_http_mapcache(ngx_conf_t *cf, ngx_command_t *cmd,
@@ -181,6 +182,7 @@ static ngx_int_t urlprefix_index;
static ngx_int_t
ngx_http_mapcache_handler(ngx_http_request_t *r)
{
+ int ret = NGX_HTTP_OK;
if (!(r->method & (NGX_HTTP_GET))) {
return NGX_HTTP_NOT_ALLOWED;
}
@@ -192,7 +194,7 @@ ngx_http_mapcache_handler(ngx_http_request_t *r)
mapcache_request *request = NULL;
mapcache_http_response *http_response;
- ngx_http_variable_value_t *pathinfovv = ngx_http_get_indexed_variable(r, pathinfo_index);
+ ngx_http_variable_value_t *pathinfovv = ngx_http_get_indexed_variable(r, pathinfo_index);
char* pathInfo = apr_pstrndup(ctx->pool, (char*)pathinfovv->data, pathinfovv->len);
char *sparams = apr_pstrndup(ctx->pool, (char*)r->args.data, r->args.len);
@@ -219,22 +221,24 @@ ngx_http_mapcache_handler(ngx_http_request_t *r)
} else if( request->type == MAPCACHE_REQUEST_GET_TILE) {
mapcache_request_get_tile *req_tile = (mapcache_request_get_tile*)request;
http_response = mapcache_core_get_tile(ctx,req_tile);
- } else if( request->type == MAPCACHE_REQUEST_PROXY ) {
- mapcache_request_proxy *req_proxy = (mapcache_request_proxy*)request;
- http_response = mapcache_core_proxy_request(ctx, req_proxy);
} else if( request->type == MAPCACHE_REQUEST_GET_MAP) {
mapcache_request_get_map *req_map = (mapcache_request_get_map*)request;
http_response = mapcache_core_get_map(ctx,req_map);
+#ifdef NGINX_RW
+ } else if( request->type == MAPCACHE_REQUEST_PROXY ) {
+ mapcache_request_proxy *req_proxy = (mapcache_request_proxy*)request;
+ http_response = mapcache_core_proxy_request(ctx, req_proxy);
} else if( request->type == MAPCACHE_REQUEST_GET_FEATUREINFO) {
mapcache_request_get_feature_info *req_fi = (mapcache_request_get_feature_info*)request;
http_response = mapcache_core_get_featureinfo(ctx,req_fi);
+#endif
#ifdef DEBUG
} else {
ctx->set_error(ctx,500,"###BUG### unknown request type");
#endif
}
if(GC_HAS_ERROR(ctx)) {
- ngx_http_mapcache_write_response(ctx,r, mapcache_core_respond_to_error(ctx));
+ // ngx_http_mapcache_write_response(ctx,r, mapcache_core_respond_to_error(ctx));
goto cleanup;
}
#ifdef DEBUG
@@ -246,10 +250,12 @@ ngx_http_mapcache_handler(ngx_http_request_t *r)
#endif
ngx_http_mapcache_write_response(ctx,r,http_response);
cleanup:
+ if(GC_HAS_ERROR(ctx))
+ ret = ctx->_errcode?ctx->_errcode:500;
ctx->clear_errors(ctx);
apr_pool_destroy(ctx->pool);
ctx->pool = main_pool;
- return NGX_HTTP_OK;
+ return ret;
}
@@ -262,9 +268,16 @@ ngx_http_mapcache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
char *conffile = (char*)value[1].data;
ctx->config = mapcache_configuration_create(ctx->pool);
mapcache_configuration_parse(ctx,conffile,ctx->config,1);
- if(GC_HAS_ERROR(ctx)) return NGX_CONF_ERROR;
+ if(GC_HAS_ERROR(ctx)) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,ctx->get_error_message(ctx));
+ return NGX_CONF_ERROR;
+ }
mapcache_configuration_post_config(ctx, ctx->config);
- if(GC_HAS_ERROR(ctx)) return NGX_CONF_ERROR;
+ if(GC_HAS_ERROR(ctx)) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,ctx->get_error_message(ctx));
+ return NGX_CONF_ERROR;
+ }
+ ctx->config->non_blocking = 1;
ngx_http_core_loc_conf_t *clcf;

0 comments on commit 7d4d978

Please sign in to comment.
Something went wrong with that request. Please try again.