[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