[mapserver-commits] r12955 - in trunk/mapserver/mapcache: . nginx
svn at osgeo.org
svn at osgeo.org
Tue Jan 3 13:05:20 EST 2012
Author: tbonfort
Date: 2012-01-03 10:05:20 -0800 (Tue, 03 Jan 2012)
New Revision: 12955
Added:
trunk/mapserver/mapcache/acinclude.m4
trunk/mapserver/mapcache/nginx/
trunk/mapserver/mapcache/nginx/config.in
trunk/mapserver/mapcache/nginx/ngx_http_mapcache_module.c
Modified:
trunk/mapserver/mapcache/configure
trunk/mapserver/mapcache/configure.in
Log:
first stab at getting mapcache running as an nginx native module
Added: trunk/mapserver/mapcache/acinclude.m4
===================================================================
Modified: trunk/mapserver/mapcache/configure
===================================================================
--- trunk/mapserver/mapcache/configure 2012-01-03 15:02:52 UTC (rev 12954)
+++ trunk/mapserver/mapcache/configure 2012-01-03 18:05:20 UTC (rev 12955)
@@ -636,11 +636,13 @@
SQLITE_LIB
SQLITE_INC
APU_LIBS
+APU_INCDIR
APU_INC
MEMCACHE_ENABLED
APUCONFIG
LIBTOOL
APR_LIBS
+APR_INCDIR
APR_INC
APR_CFLAGS
APRCONFIG
@@ -4083,8 +4085,10 @@
APR_INC=`$APRCONFIG --includes`
- APR_LIBS=`$APRCONFIG --link-libtool`
+ APR_INCDIR=`$APRCONFIG --includedir`
+ APR_LIBS=`$APRCONFIG --link-ld`
+
LIBTOOL=`$APRCONFIG --apr-libtool`
@@ -4225,14 +4229,16 @@
if test -z "$APUCONFIG"; then
as_fn_error $? "apu-config utility not found" "$LINENO" 5
else
- APU_LIBS=`$APUCONFIG --link-libtool`
+ APU_LIBS=`$APUCONFIG --link-ld`
APU_INC=`$APUCONFIG --includes`
+ APU_INCDIR=`$APUCONFIG --includedir`
fi
+
# Check whether --enable-memcache was given.
if test "${enable_memcache+set}" = set; then :
enableval=$enable_memcache;
@@ -5820,7 +5826,7 @@
# Write config.status and the Makefile
-ac_config_files="$ac_config_files Makefile.inc"
+ac_config_files="$ac_config_files Makefile.inc nginx/config"
cat >confcache <<\_ACEOF
@@ -6542,6 +6548,7 @@
do
case $ac_config_target in
"Makefile.inc") CONFIG_FILES="$CONFIG_FILES Makefile.inc" ;;
+ "nginx/config") CONFIG_FILES="$CONFIG_FILES nginx/config" ;;
*) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
esac
Modified: trunk/mapserver/mapcache/configure.in
===================================================================
--- trunk/mapserver/mapcache/configure.in 2012-01-03 15:02:52 UTC (rev 12954)
+++ trunk/mapserver/mapcache/configure.in 2012-01-03 18:05:20 UTC (rev 12955)
@@ -348,11 +348,13 @@
if test -z "$APUCONFIG"; then
AC_MSG_ERROR(apu-config utility not found)
else
- APU_LIBS=`$APUCONFIG --link-libtool`
+ APU_LIBS=`$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)
])
@@ -410,7 +412,8 @@
AC_SUBST(APRCONFIG)
AC_SUBST(APR_CFLAGS,`$APRCONFIG --cppflags --cflags`)
AC_SUBST(APR_INC,`$APRCONFIG --includes`)
- AC_SUBST(APR_LIBS,`$APRCONFIG --link-libtool`)
+ AC_SUBST(APR_INCDIR,`$APRCONFIG --includedir`)
+ AC_SUBST(APR_LIBS,`$APRCONFIG --link-ld`)
AC_SUBST(LIBTOOL, `$APRCONFIG --apr-libtool`)
])
@@ -987,6 +990,6 @@
CURL_CHECK
# Write config.status and the Makefile
-AC_CONFIG_FILES(Makefile.inc)
+AC_CONFIG_FILES(Makefile.inc nginx/config)
AC_OUTPUT
Added: trunk/mapserver/mapcache/nginx/config.in
===================================================================
--- trunk/mapserver/mapcache/nginx/config.in (rev 0)
+++ trunk/mapserver/mapcache/nginx/config.in 2012-01-03 18:05:20 UTC (rev 12955)
@@ -0,0 +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 -L at prefix@/lib -lmapcache @APR_LIBS@ @APU_LIBS@"
+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@"
Added: trunk/mapserver/mapcache/nginx/ngx_http_mapcache_module.c
===================================================================
--- trunk/mapserver/mapcache/nginx/ngx_http_mapcache_module.c (rev 0)
+++ trunk/mapserver/mapcache/nginx/ngx_http_mapcache_module.c 2012-01-03 18:05:20 UTC (rev 12955)
@@ -0,0 +1,293 @@
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_http.h>
+#include "../include/mapcache.h"
+#include <apr_date.h>
+
+
+static char *ngx_http_mapcache(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf);
+
+static ngx_command_t ngx_http_mapcache_commands[] = {
+
+ { ngx_string("mapcache"),
+ NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+ ngx_http_mapcache,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ 0,
+ NULL },
+
+ ngx_null_command
+};
+
+
+static void
+ngx_http_mapcache_cleanup(void *data)
+{
+}
+
+static void ngx_mapcache_context_log(mapcache_context *c, mapcache_log_level level, char *message, ...) {
+ va_list args;
+ if(!c->config || level >= c->config->loglevel) {
+ va_start(args,message);
+ fprintf(stderr,"%s\n",apr_pvsprintf(c->pool,message,args));
+ va_end(args);
+ }
+}
+
+static mapcache_context* ngx_mapcache_context_clone(mapcache_context *ctx) {
+ mapcache_context *nctx = (mapcache_context*)apr_pcalloc(ctx->pool,
+ sizeof(mapcache_context));
+ mapcache_context_copy(ctx,nctx);
+ apr_pool_create(&nctx->pool,ctx->pool);
+ return nctx;
+}
+
+
+static void *
+ngx_http_mapcache_create_conf(ngx_conf_t *cf)
+{
+ ngx_pool_cleanup_t *cln;
+ apr_pool_t *pool;
+ apr_initialize();
+ atexit(apr_terminate);
+ apr_pool_initialize();
+ apr_pool_create(&pool,NULL);
+ mapcache_context *ctx = apr_pcalloc(pool, sizeof(mapcache_context));
+ ctx->pool = pool;
+ mapcache_context_init(ctx);
+ ctx->log = ngx_mapcache_context_log;
+ ctx->clone = ngx_mapcache_context_clone;
+ ctx->config = NULL;
+
+ cln = ngx_pool_cleanup_add(cf->pool, 0);
+ if (cln == NULL) {
+ return NULL;
+ }
+
+ cln->handler = ngx_http_mapcache_cleanup;
+ cln->data = pool;
+
+ return ctx;
+}
+
+
+static void ngx_http_mapcache_write_response(mapcache_context *ctx, ngx_http_request_t *r,
+ mapcache_http_response *response) {
+ /*
+ if(response->mtime) {
+ ap_update_mtime(r, response->mtime);
+ char *timestr = apr_palloc(r->pool, APR_RFC822_DATE_LEN);
+ apr_rfc822_date(timestr, response->mtime);
+ //apr_table_setn(r->headers_out, "Last-Modified", timestr);
+ }
+ */
+ if(response->mtime) {
+ time_t if_modified_since;
+ if(r->headers_in.if_modified_since) {
+ if_modified_since = ngx_http_parse_time(r->headers_in.if_modified_since->value.data,
+ r->headers_in.if_modified_since->value.len);
+ if (if_modified_since != NGX_ERROR) {
+ apr_time_t apr_if_m_s;
+ apr_time_ansi_put ( &apr_if_m_s, if_modified_since);
+ if(apr_if_m_s<response->mtime) {
+ r->headers_out.status = NGX_HTTP_NOT_MODIFIED;
+ ngx_http_send_header(r);
+ return;
+ }
+ }
+ }
+ char *datestr;
+ datestr = apr_palloc(ctx->pool, APR_RFC822_DATE_LEN);
+ apr_rfc822_date(datestr, response->mtime);
+ apr_table_setn(response->headers,"Last-Modified",datestr);
+ }
+ if(response->headers && !apr_is_empty_table(response->headers)) {
+ const apr_array_header_t *elts = apr_table_elts(response->headers);
+ int i;
+ for(i=0;i<elts->nelts;i++) {
+ apr_table_entry_t entry = APR_ARRAY_IDX(elts,i,apr_table_entry_t);
+ if(!strcasecmp(entry.key,"Content-Type")) {
+ r->headers_out.content_type.len = strlen(entry.val);
+ r->headers_out.content_type.data = (u_char*)entry.val;
+ } else {
+ ngx_table_elt_t *h;
+ h = ngx_list_push(&r->headers_out.headers);
+ if (h == NULL) {
+ return;
+ }
+ h->key.len = strlen(entry.key) ;
+ h->key.data = (u_char*)entry.key ;
+ h->value.len = strlen(entry.val) ;
+ h->value.data = (u_char*)entry.val ;
+ h->hash = 1;
+ }
+ }
+ }
+ if(response->data) {
+ r->headers_out.content_length_n = response->data->size;
+ }
+ r->headers_out.status = response->code;
+ ngx_http_send_header(r);
+ if(response->data) {
+ ngx_buf_t *b;
+ ngx_chain_t out;
+ b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
+ if (b == NULL) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "Failed to allocate response buffer.");
+ return;
+ }
+ b->pos = response->data->buf;
+ b->last = b->pos + response->data->size;
+ b->memory = 1;
+ b->last_buf = 1;
+ out.buf = b;
+ out.next = NULL;
+ ngx_http_output_filter(r, &out);
+ }
+
+}
+
+
+static ngx_http_module_t ngx_http_mapcache_module_ctx = {
+ NULL, /* preconfiguration */
+ NULL, /* postconfiguration */
+
+ NULL, /* create main configuration */
+ NULL, /* init main configuration */
+
+ NULL, /* create server configuration */
+ NULL, /* merge server configuration */
+
+ ngx_http_mapcache_create_conf, /* create location configuration */
+ NULL /* merge location configuration */
+};
+
+ngx_module_t ngx_http_mapcache_module = {
+ NGX_MODULE_V1,
+ &ngx_http_mapcache_module_ctx, /* module context */
+ ngx_http_mapcache_commands, /* module directives */
+ NGX_HTTP_MODULE, /* module type */
+ NULL, /* init master */
+ NULL, /* init module */
+ NULL,/* init process */
+ NULL, /* init thread */
+ NULL, /* exit thread */
+ NULL, /* exit process */
+ NULL, /* exit master */
+ NGX_MODULE_V1_PADDING
+};
+
+
+static ngx_int_t
+ngx_http_mapcache_handler(ngx_http_request_t *r)
+{
+ if (!(r->method & (NGX_HTTP_GET))) {
+ return NGX_HTTP_NOT_ALLOWED;
+ }
+ mapcache_context *ctx = ngx_http_get_module_loc_conf(r, ngx_http_mapcache_module);
+ apr_pool_t *main_pool = ctx->pool;
+ apr_pool_create(&(ctx->pool),main_pool);
+ mapcache_request *request = NULL;
+ mapcache_http_response *http_response;
+
+ char* pathInfo = "/";
+ char *sparams = apr_pstrndup(ctx->pool, (char*)r->args.data, r->args.len);
+ apr_table_t *params = mapcache_http_parse_param_string(ctx, sparams);
+ mapcache_service_dispatch_request(ctx,&request,pathInfo,params,ctx->config);
+ if(GC_HAS_ERROR(ctx) || !request) {
+ ngx_http_mapcache_write_response(ctx,r, mapcache_core_respond_to_error(ctx));
+ goto cleanup;
+ }
+
+ http_response = NULL;
+ if(request->type == MAPCACHE_REQUEST_GET_CAPABILITIES) {
+ mapcache_request_get_capabilities *req = (mapcache_request_get_capabilities*)request;
+ char *host = getenv("SERVER_NAME");
+ char *port = getenv("SERVER_PORT");
+ char *fullhost;
+ char *url;
+ if(getenv("HTTPS")) {
+ if(!port || !strcmp(port,"443")) {
+ fullhost = apr_psprintf(ctx->pool,"https://%s",host);
+ } else {
+ fullhost = apr_psprintf(ctx->pool,"https://%s:%s",host,port);
+ }
+ } else {
+ if(!port || !strcmp(port,"80")) {
+ fullhost = apr_psprintf(ctx->pool,"http://%s",host);
+ } else {
+ fullhost = apr_psprintf(ctx->pool,"http://%s:%s",host,port);
+ }
+ }
+ url = apr_psprintf(ctx->pool,"%s%s/",
+ fullhost,
+ getenv("SCRIPT_NAME")
+ );
+ http_response = mapcache_core_get_capabilities(ctx,request->service,req,url,pathInfo,ctx->config);
+ } 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);
+ } 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);
+#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));
+ goto cleanup;
+ }
+#ifdef DEBUG
+ if(!http_response) {
+ ctx->set_error(ctx,500,"###BUG### NULL response");
+ ngx_http_mapcache_write_response(ctx,r, mapcache_core_respond_to_error(ctx));
+ goto cleanup;
+ }
+#endif
+ ngx_http_mapcache_write_response(ctx,r,http_response);
+cleanup:
+ ctx->clear_errors(ctx);
+ apr_pool_destroy(ctx->pool);
+ ctx->pool = main_pool;
+ return NGX_HTTP_OK;
+
+ /*
+ cv.value.len = sizeof(ngx_empty_gif);
+ cv.value.data = ngx_empty_gif;
+ r->headers_out.last_modified_time = 23349600;
+
+ return ngx_http_send_response(r, NGX_HTTP_OK, &ngx_http_gif_type, &cv);
+ */
+}
+
+
+static char *
+ngx_http_mapcache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+ mapcache_context *ctx = conf;
+ ngx_str_t *value;
+ value = cf->args->elts;
+ 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;
+ mapcache_configuration_post_config(ctx, ctx->config);
+ if(GC_HAS_ERROR(ctx)) return NGX_CONF_ERROR;
+
+ ngx_http_core_loc_conf_t *clcf;
+
+ clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
+ clcf->handler = ngx_http_mapcache_handler;
+
+ return NGX_CONF_OK;
+}
More information about the mapserver-commits
mailing list