[mapserver-commits] r12702 - in trunk/mapserver/mapcache: include src

svn at osgeo.org svn at osgeo.org
Wed Oct 26 10:08:04 EDT 2011


Author: tbonfort
Date: 2011-10-26 07:08:04 -0700 (Wed, 26 Oct 2011)
New Revision: 12702

Modified:
   trunk/mapserver/mapcache/include/mapcache.h
   trunk/mapserver/mapcache/src/configuration_xml.c
   trunk/mapserver/mapcache/src/core.c
   trunk/mapserver/mapcache/src/fastcgi_mapcache.c
   trunk/mapserver/mapcache/src/mod_mapcache.c
   trunk/mapserver/mapcache/src/service_wmts.c
   trunk/mapserver/mapcache/src/services.c
   trunk/mapserver/mapcache/src/util.c
Log:
add WMTS service exception creation


Modified: trunk/mapserver/mapcache/include/mapcache.h
===================================================================
--- trunk/mapserver/mapcache/include/mapcache.h	2011-10-26 12:52:44 UTC (rev 12701)
+++ trunk/mapserver/mapcache/include/mapcache.h	2011-10-26 14:08:04 UTC (rev 12702)
@@ -156,6 +156,8 @@
      * \param message human readable message of what happened
      */
     void (*set_error)(mapcache_context *ctx, int code, char *message, ...);
+    
+    void (*set_exception)(mapcache_context *ctx, char *key, char *message, ...);
 
     /**
      * \brief query context to know if an error has occured
@@ -189,6 +191,8 @@
     char *_errmsg;
     int _errcode;
     mapcache_cfg *config;
+    mapcache_service *service;
+    apr_table_t *exceptions;
 };
 
 void mapcache_context_init(mapcache_context *ctx);
@@ -636,6 +640,9 @@
      * parse advanced configuration options for the selected service
      */
     void (*configuration_parse_xml)(mapcache_context *ctx, ezxml_t xml, mapcache_service * service, mapcache_cfg *config);
+    
+    void (*format_error)(mapcache_context *ctx, mapcache_service * service, char *err_msg,
+          char **err_body, apr_table_t *headers);
 };
 
 /**\class mapcache_service_wms
@@ -1247,7 +1254,7 @@
 mapcache_http_response* mapcache_core_get_featureinfo(mapcache_context *ctx, mapcache_request_get_feature_info *req_fi);
 
 mapcache_http_response* mapcache_core_proxy_request(mapcache_context *ctx, mapcache_request_proxy *req_proxy);
-mapcache_http_response* mapcache_core_respond_to_error(mapcache_context *ctx, mapcache_service *service);
+mapcache_http_response* mapcache_core_respond_to_error(mapcache_context *ctx);
 
 
 /* in grid.c */

Modified: trunk/mapserver/mapcache/src/configuration_xml.c
===================================================================
--- trunk/mapserver/mapcache/src/configuration_xml.c	2011-10-26 12:52:44 UTC (rev 12701)
+++ trunk/mapserver/mapcache/src/configuration_xml.c	2011-10-26 14:08:04 UTC (rev 12702)
@@ -36,6 +36,7 @@
 #include <apr_tables.h>
 #include <apr_file_io.h>
 #include <apr_file_info.h>
+#include <math.h>
 
 
 void parseMetadata(mapcache_context *ctx, ezxml_t node, apr_table_t *metadata) {

Modified: trunk/mapserver/mapcache/src/core.c
===================================================================
--- trunk/mapserver/mapcache/src/core.c	2011-10-26 12:52:44 UTC (rev 12701)
+++ trunk/mapserver/mapcache/src/core.c	2011-10-26 14:08:04 UTC (rev 12702)
@@ -241,7 +241,7 @@
 #ifdef DEBUG
       if(!basemap->encoded_data) {
          ctx->set_error(ctx,500,"###BUG### core_get_map failed with null encoded_data");
-         return;
+         return NULL;
       }
 #endif
       response->data = basemap->encoded_data;
@@ -337,7 +337,7 @@
    return response;
 }
 
-mapcache_http_response* mapcache_core_respond_to_error(mapcache_context *ctx, mapcache_service *service) {
+mapcache_http_response* mapcache_core_respond_to_error(mapcache_context *ctx) {
    //TODO: have the service format the error response
    mapcache_http_response *response = mapcache_http_response_create(ctx->pool);
    
@@ -350,15 +350,20 @@
       msg = "an unspecified error has occured";
    }
    ctx->log(ctx,MAPCACHE_ERROR,msg);
+
   
 
    if(ctx->config && ctx->config->reporting == MAPCACHE_REPORT_MSG) {
+      char *err_body = msg;
+      apr_table_set(response->headers, "Content-Type", "text/plain");
+      if(ctx->service && ctx->service->format_error) {
+         ctx->service->format_error(ctx,ctx->service,msg,&err_body,response->headers);
+      }
       /* manually populate the mapcache_buffer with the error message */
       response->data = mapcache_buffer_create(0,ctx->pool);
-      response->data->size = strlen(msg);
-      response->data->buf = msg;
+      response->data->size = strlen(err_body);
+      response->data->buf = err_body;
       response->data->avail = response->data->size;
-      apr_table_set(response->headers, "Content-Type", "text/plain");
    } else if(ctx->config && ctx->config->reporting == MAPCACHE_REPORT_EMPTY_IMG) {
       response->data = ctx->config->empty_image;
       apr_table_set(response->headers, "Content-Type", ctx->config->default_image_format->mime_type);

Modified: trunk/mapserver/mapcache/src/fastcgi_mapcache.c
===================================================================
--- trunk/mapserver/mapcache/src/fastcgi_mapcache.c	2011-10-26 12:52:44 UTC (rev 12701)
+++ trunk/mapserver/mapcache/src/fastcgi_mapcache.c	2011-10-26 14:08:04 UTC (rev 12702)
@@ -225,7 +225,7 @@
       if(!ctx->config || ctx->config->autoreload) {
          load_config(ctx,conffile);
          if(GC_HAS_ERROR(ctx)) {
-            fcgi_write_response(globalctx, mapcache_core_respond_to_error(ctx,NULL));
+            fcgi_write_response(globalctx, mapcache_core_respond_to_error(ctx));
             goto cleanup;
          }
       }
@@ -237,7 +237,7 @@
       params = mapcache_http_parse_param_string(ctx, getenv("QUERY_STRING"));
       mapcache_service_dispatch_request(ctx,&request,pathInfo,params,ctx->config);
       if(GC_HAS_ERROR(ctx) || !request) {
-         fcgi_write_response(globalctx, mapcache_core_respond_to_error(ctx,(request)?request->service:NULL));
+         fcgi_write_response(globalctx, mapcache_core_respond_to_error(ctx));
          goto cleanup;
       }
       
@@ -284,13 +284,13 @@
 #endif
       }
       if(GC_HAS_ERROR(ctx)) {
-         fcgi_write_response(globalctx, mapcache_core_respond_to_error(ctx,request->service));
+         fcgi_write_response(globalctx, mapcache_core_respond_to_error(ctx));
          goto cleanup;
       }
 #ifdef DEBUG
       if(!http_response) {
          ctx->set_error(ctx,500,"###BUG### NULL response");
-         fcgi_write_response(globalctx, mapcache_core_respond_to_error(ctx,request->service));
+         fcgi_write_response(globalctx, mapcache_core_respond_to_error(ctx));
          goto cleanup;
       }
 #endif

Modified: trunk/mapserver/mapcache/src/mod_mapcache.c
===================================================================
--- trunk/mapserver/mapcache/src/mod_mapcache.c	2011-10-26 12:52:44 UTC (rev 12701)
+++ trunk/mapserver/mapcache/src/mod_mapcache.c	2011-10-26 14:08:04 UTC (rev 12702)
@@ -233,7 +233,7 @@
    mapcache_service_dispatch_request(global_ctx,&request,r->path_info,params,global_ctx->config);
    if(GC_HAS_ERROR(global_ctx) || !request) {
       return write_http_response(apache_ctx,
-            mapcache_core_respond_to_error(global_ctx,(request)?request->service:NULL));
+            mapcache_core_respond_to_error(global_ctx));
    }
 
    mapcache_http_response *http_response = NULL;
@@ -284,7 +284,7 @@
 
    if(GC_HAS_ERROR(global_ctx)) {
       return write_http_response(apache_ctx,
-            mapcache_core_respond_to_error(global_ctx,request->service));
+            mapcache_core_respond_to_error(global_ctx));
    }
    return write_http_response(apache_ctx,http_response);
 }

Modified: trunk/mapserver/mapcache/src/service_wmts.c
===================================================================
--- trunk/mapserver/mapcache/src/service_wmts.c	2011-10-26 12:52:44 UTC (rev 12701)
+++ trunk/mapserver/mapcache/src/service_wmts.c	2011-10-26 14:08:04 UTC (rev 12702)
@@ -313,16 +313,20 @@
    apr_table_t *dimtable = NULL;
    mapcache_tileset *tileset = NULL;
    int row,col,level;
+   int kvp = 0;
    service = apr_table_get(params,"SERVICE");
    if(service) {
       /*KVP Parsing*/
+      kvp = 1;
       if( strcasecmp(service,"wmts") ) {
          ctx->set_error(ctx,400,"received wmts request with invalid service param %s", service);
+         ctx->set_exception(ctx,"InvalidParameterValue","service");
          return;
       }
       str = apr_table_get(params,"REQUEST");
       if(!str) {
          ctx->set_error(ctx, 400, "received wmts request with no request");
+         ctx->set_exception(ctx,"MissingParameterValue","request");
          return;
       }
       if( ! strcasecmp(str,"getcapabilities") ) {
@@ -341,11 +345,13 @@
          layer = apr_table_get(params,"LAYER");
          if(!layer) { /*we have to validate this now in order to be able to extract dimensions*/
             ctx->set_error(ctx, 400, "received wmts request with no layer");
+            ctx->set_exception(ctx,"MissingParameterValue","layer");
             return;
          } else {
             tileset = mapcache_configuration_get_tileset(config,layer);
             if(!tileset) {
                ctx->set_error(ctx, 400, "received wmts request with invalid layer %s",layer);
+               ctx->set_exception(ctx,"InvalidParameterValue","layer");
                return;
             }
          }
@@ -370,11 +376,18 @@
             fi_j = apr_table_get(params,"J");
             if(!infoformat || !fi_i || !fi_j) {
                ctx->set_error(ctx, 400, "received wmts featureinfo request with missing infoformat, i or j");
+               if(!infoformat)
+                  ctx->set_exception(ctx,"MissingParameterValue","infoformat");
+               if(!fi_i)
+                  ctx->set_exception(ctx,"MissingParameterValue","i");
+               if(!fi_j)
+                  ctx->set_exception(ctx,"MissingParameterValue","j");
                return;
             }
          }
       } else {
          ctx->set_error(ctx, 501, "received wmts request with invalid request %s",str);
+         ctx->set_exception(ctx,"InvalidParameterValue","request");
          return;
       }
    } else {
@@ -478,6 +491,7 @@
 
    if(!style || strcmp(style,"default")) {
       ctx->set_error(ctx,404, "received request with invalid style \"%s\" (expecting \"default\")",style);
+      if(kvp) ctx->set_exception(ctx,"InvalidParameterValue","style");
       return;
    }
    
@@ -485,6 +499,7 @@
    if(tileset->dimensions) {
       if(!dimtable) {
          ctx->set_error(ctx,404, "received request with no dimensions");
+         if(kvp) ctx->set_exception(ctx,"InvalidParameterValue","dim");
          return;
       }
       int i;
@@ -493,6 +508,7 @@
          const char *value = apr_table_get(dimtable,dimension->name);
          if(!value) {
             ctx->set_error(ctx,404,"received request with no value for dimension \"%s\"",dimension->name);
+            if(kvp) ctx->set_exception(ctx,"MissingParameterValue","%s",dimension->name);
             return;
          }
          char *tmpval = apr_pstrdup(ctx->pool,value);
@@ -501,6 +517,7 @@
          if(ok != MAPCACHE_SUCCESS) {
             ctx->set_error(ctx,404,"dimension \"%s\" value \"%s\" fails to validate",
                   dimension->name, value);
+            if(kvp) ctx->set_exception(ctx,"InvalidParameterValue","%s",dimension->name);
             return;
          }
          
@@ -512,6 +529,7 @@
 
    if(!matrixset) {
       ctx->set_error(ctx, 404, "received wmts request with no TILEMATRIXSET");
+      if(kvp) ctx->set_exception(ctx,"MissingParameterValue","tilematrixset");
       return;
    } else {
       int i;
@@ -523,42 +541,49 @@
       }
       if(!grid_link) {
          ctx->set_error(ctx, 404, "received wmts request with invalid TILEMATRIXSET %s",matrixset);
+         if(kvp) ctx->set_exception(ctx,"InvalidParameterValue","tilematrixset");
          return;
       }
    }
 
    if(!matrix) {
       ctx->set_error(ctx, 404, "received wmts request with no TILEMATRIX");
+      if(kvp) ctx->set_exception(ctx,"MissingParameterValue","tilematrix");
       return;
    } else {
       char *endptr;
       level = (int)strtol(matrix,&endptr,10);
       if(*endptr != 0 || level < grid_link->minz || level >= grid_link->maxz) {
          ctx->set_error(ctx, 404, "received wmts request with invalid TILEMATRIX %s", matrix);
+         if(kvp) ctx->set_exception(ctx,"InvalidParameterValue","tilematrix");
          return;
       }
    }
    
    if(!tilerow) {
       ctx->set_error(ctx, 404, "received wmts request with no TILEROW");
+      if(kvp) ctx->set_exception(ctx,"MissingParameterValue","tilerow");
       return;
    } else {
       char *endptr;
       row = (int)strtol(tilerow,&endptr,10);
       if(*endptr != 0 || row < 0) {
          ctx->set_error(ctx, 404, "received wmts request with invalid TILEROW %s",tilerow);
+         if(kvp) ctx->set_exception(ctx,"InvalidParameterValue","tilerow");
          return;
       }
    }
 
    if(!tilecol) {
       ctx->set_error(ctx, 404, "received wmts request with no TILECOL");
+      if(kvp) ctx->set_exception(ctx,"MissingParameterValue","tilecol");
       return;
    } else {
       char *endptr;
       col = (int)strtol(tilecol,&endptr,10);
       if(endptr == tilecol || col < 0) {
          ctx->set_error(ctx, 404, "received wmts request with invalid TILECOL %s",tilecol);
+         if(kvp) ctx->set_exception(ctx,"InvalidParameterValue","tilecol");
          return;
       }
    }
@@ -597,6 +622,7 @@
       req->tiles[0] = mapcache_tileset_tile_create(ctx->pool, tileset, grid_link);
       if(!req->tiles[0]) {
          ctx->set_error(ctx, 500, "failed to allocate tile");
+         if(kvp) ctx->set_exception(ctx,"NoApplicableCode","");
          return;
       }
 
@@ -616,7 +642,10 @@
       req->tiles[0]->z = level;
 
       mapcache_tileset_tile_validate(ctx,req->tiles[0]);
-      GC_CHECK_ERROR(ctx);
+      if(GC_HAS_ERROR(ctx)) {
+         if(kvp) ctx->set_exception(ctx,"TileOutOfRange","");
+         return;
+      }
 
       *request = (mapcache_request*)req;
       return;
@@ -629,6 +658,7 @@
       char *endptr;
       if(!tileset->source || !tileset->source->info_formats) {
          ctx->set_error(ctx,400,"tileset %s does not support featureinfo requests", tileset->name);
+         if(kvp) ctx->set_exception(ctx,"OperationNotSupported","");
          return;
       }
       mapcache_request_get_feature_info *req_fi = (mapcache_request_get_feature_info*)apr_pcalloc(
@@ -652,11 +682,13 @@
       fi->i = (int)strtol(fi_i,&endptr,10);
       if(*endptr != 0 || fi->i < 0 || fi->i >= grid_link->grid->tile_sx) {
          ctx->set_error(ctx, 404, "received wmts featureinfo request with invalid I %s",fi_i);
+         if(kvp) ctx->set_exception(ctx,"PointIJOutOfRange","i");
          return;
       }
       fi->j = (int)strtol(fi_j,&endptr,10);
       if(*endptr != 0 || fi->j < 0 || fi->j >= grid_link->grid->tile_sy) {
          ctx->set_error(ctx, 404, "received wmts featureinfo request with invalid J %s",fi_j);
+         if(kvp) ctx->set_exception(ctx,"PointIJOutOfRange","j");
          return;
       }
       fi->map.width = grid_link->grid->tile_sx;
@@ -670,6 +702,34 @@
    }
 }
 
+void _error_report_wmts(mapcache_context *ctx, mapcache_service *service, char *msg,
+      char **err_body, apr_table_t *headers) {
+   char *template = "\
+<?xml version=\"1.0\" encoding=\"UTF-8\"?>\
+   <ExceptionReport xmlns=\"http://www.opengis.net/ows/2.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.opengis.net/ows/2.0 owsExceptionReport.xsd\" version=\"1.0.0\" xml:lang=\"en\">\
+   <!-- %s -->\
+   %s\
+</ExceptionReport>";
+   if(!ctx->exceptions) {
+      *err_body = msg;
+      return;
+   }
+   char *exceptions="";
+
+   const apr_array_header_t *array = apr_table_elts(ctx->exceptions);
+   apr_table_entry_t *elts = (apr_table_entry_t *) array->elts;
+   int i;
+   for (i = 0; i < array->nelts; i++) {
+      exceptions = apr_pstrcat(ctx->pool,exceptions,apr_psprintf(ctx->pool,
+               "<Exception exceptionCode=\"%s\" locator=\"%s\"/>",elts[i].key,elts[i].val),NULL);
+   }
+
+   *err_body = apr_psprintf(ctx->pool,template,msg,exceptions);
+   apr_table_set(headers, "Content-Type", "application/xml");
+
+
+}
+
 mapcache_service* mapcache_service_wmts_create(mapcache_context *ctx) {
    mapcache_service_wmts* service = (mapcache_service_wmts*)apr_pcalloc(ctx->pool, sizeof(mapcache_service_wmts));
    if(!service) {
@@ -681,6 +741,7 @@
    service->service.type = MAPCACHE_SERVICE_WMTS;
    service->service.parse_request = _mapcache_service_wmts_parse_request;
    service->service.create_capabilities_response = _create_capabilities_wmts;
+   service->service.format_error = _error_report_wmts;
    return (mapcache_service*)service;
 }
 

Modified: trunk/mapserver/mapcache/src/services.c
===================================================================
--- trunk/mapserver/mapcache/src/services.c	2011-10-26 12:52:44 UTC (rev 12701)
+++ trunk/mapserver/mapcache/src/services.c	2011-10-26 14:08:04 UTC (rev 12702)
@@ -56,6 +56,7 @@
       if(!service) continue; /* skip an unconfigured service */
       prefixlen = strlen(service->url_prefix);
       if(strncmp(service->url_prefix,pathinfo, prefixlen)) continue; /*skip a service who's prefix does not correspond */
+      ctx->service = service;
       //if(*(pathinfo+prefixlen)!='/' && *(pathinfo+prefixlen)!='\0') continue; /*we matched the prefix but there are trailing characters*/
       pathinfo += prefixlen; /* advance pathinfo to after the service prefix */
       service->parse_request(ctx,service,request,pathinfo,params,config);

Modified: trunk/mapserver/mapcache/src/util.c
===================================================================
--- trunk/mapserver/mapcache/src/util.c	2011-10-26 12:52:44 UTC (rev 12701)
+++ trunk/mapserver/mapcache/src/util.c	2011-10-26 14:08:04 UTC (rev 12702)
@@ -132,6 +132,18 @@
     return ctx->_errmsg;
 }
 
+void _mapcache_context_set_exception_default(mapcache_context *ctx, char *key, char *msg, ...) {
+   if(!ctx->exceptions) {
+      ctx->exceptions = apr_table_make(ctx->pool,1);
+   }
+   char *fullmsg;
+   va_list args;
+   va_start(args,msg);
+   fullmsg = apr_pvsprintf(ctx->pool,msg,args);
+   va_end(args);
+   apr_table_set(ctx->exceptions,key,fullmsg);
+}
+
 void _mapcache_context_set_error_default(mapcache_context *ctx, int code, char *msg, ...) {
     char *fmt;
     va_list args;
@@ -150,6 +162,9 @@
 void _mapcache_context_clear_error_default(mapcache_context *ctx) {
    ctx->_errcode = 0;
    ctx->_errmsg = NULL;
+   if(ctx->exceptions) {
+      apr_table_clear(ctx->exceptions);
+   }
 }
 
 
@@ -159,6 +174,7 @@
     ctx->get_error = _mapcache_context_get_error_default;
     ctx->get_error_message = _mapcache_context_get_error_msg_default;
     ctx->set_error = _mapcache_context_set_error_default;
+    ctx->set_exception = _mapcache_context_set_exception_default;
     ctx->clear_errors = _mapcache_context_clear_error_default;
 }
 



More information about the mapserver-commits mailing list