[mapserver-commits] r12386 - in trunk/mapserver/mapcache: . include
src
svn at osgeo.org
svn at osgeo.org
Fri Aug 26 07:21:29 EDT 2011
Author: tbonfort
Date: 2011-08-26 04:21:29 -0700 (Fri, 26 Aug 2011)
New Revision: 12386
Modified:
trunk/mapserver/mapcache/geocache.xml
trunk/mapserver/mapcache/include/geocache.h
trunk/mapserver/mapcache/src/mod_geocache.c
trunk/mapserver/mapcache/src/service_wms.c
Log:
add french grids to example geocache.xml
thomas.bonfort | 2011-06-09 13:03:55 +0200 (Thu, 09 Jun 2011)
Modified: trunk/mapserver/mapcache/geocache.xml
===================================================================
--- trunk/mapserver/mapcache/geocache.xml 2011-08-26 11:21:24 UTC (rev 12385)
+++ trunk/mapserver/mapcache/geocache.xml 2011-08-26 11:21:29 UTC (rev 12386)
@@ -500,38 +500,20 @@
each service is accessible at the url http://host/path/to/geocache/{service},
eg http://myhost/geocache/wms for OGC WMS.
-->
- <service type="wms" enabled="true"/>
+ <service type="wms" enabled="true">
+ <forwarding_rule name="foo rule">
+ <http>
+ <url>http://localhost/cgi-bin/mapserv?map=/gro1/mapserver-utils/osm.map</url>
+ </http>
+ </forwarding_rule>
+ </service>
<service type="wmts" enabled="true"/>
<service type="tms" enabled="true"/>
<service type="kml" enabled="true"/>
<service type="gmaps" enabled="true"/>
<service type="ve" enabled="true"/>
<service type="demo" enabled="true"/>
- <services>
- <!-- OGC WMS -->
- <wms>true</wms>
-
- <!-- OSGEO TMS -->
- <tms>true</tms>
-
- <!-- Virtualearth/Bing quadkey-->
- <ve>true</ve>
- <!-- kml superoverlays -->
- <kml>true</kml>
-
- <!-- OGC WMTS -->
- <wmts>true</wmts>
-
- <!-- Google Maps -->
- <gmaps>true</gmaps>
-
- <!-- demo
- interface with a simple openlayers map serving the configured layers through WMS.
- -->
- <demo>true</demo>
- </services>
-
<!-- errors
configure how error will be reported back to a client:
- log : no error is reported back, except an http error code.
Modified: trunk/mapserver/mapcache/include/geocache.h
===================================================================
--- trunk/mapserver/mapcache/include/geocache.h 2011-08-26 11:21:24 UTC (rev 12385)
+++ trunk/mapserver/mapcache/include/geocache.h 2011-08-26 11:21:29 UTC (rev 12386)
@@ -88,6 +88,7 @@
typedef struct geocache_request_get_capabilities_demo geocache_request_get_capabilities_demo;
typedef struct geocache_request_get_capabilities_wms geocache_request_get_capabilities_wms;
typedef struct geocache_request_get_capabilities_wmts geocache_request_get_capabilities_wmts;
+typedef struct geocache_forwarding_rule geocache_forwarding_rule;
typedef struct geocache_request_get_capabilities_tms geocache_request_get_capabilities_tms;
typedef struct geocache_request_get_capabilities_kml geocache_request_get_capabilities_kml;
@@ -494,8 +495,15 @@
apr_table_t *params;
};
+struct geocache_forwarding_rule {
+ char *name;
+ geocache_http *http;
+ apr_array_header_t *match_params; /* actually those are geocache_dimensions */
+};
+
+
/** \defgroup services Services*/
/** @{ */
@@ -552,6 +560,7 @@
*/
struct geocache_service_wms {
geocache_service service;
+ apr_array_header_t *forwarding_rules;
};
/**\class geocache_service_kml
Modified: trunk/mapserver/mapcache/src/mod_geocache.c
===================================================================
--- trunk/mapserver/mapcache/src/mod_geocache.c 2011-08-26 11:21:24 UTC (rev 12385)
+++ trunk/mapserver/mapcache/src/mod_geocache.c 2011-08-26 11:21:29 UTC (rev 12386)
@@ -239,7 +239,11 @@
int i;
for(i=0;i<elts->nelts;i++) {
apr_table_entry_t entry = APR_ARRAY_IDX(elts,i,apr_table_entry_t);
- apr_table_set(r->headers_out, entry.key, entry.val);
+ if(!strcasecmp(entry.key,"Content-Type")) {
+ ap_set_content_type(r,entry.val);
+ } else {
+ apr_table_set(r->headers_out, entry.key, entry.val);
+ }
}
}
Modified: trunk/mapserver/mapcache/src/service_wms.c
===================================================================
--- trunk/mapserver/mapcache/src/service_wms.c 2011-08-26 11:21:24 UTC (rev 12385)
+++ trunk/mapserver/mapcache/src/service_wms.c 2011-08-26 11:21:29 UTC (rev 12386)
@@ -295,21 +295,29 @@
int width=0, height=0;
double *bbox;
int isGetMap=0;
-
+ int errcode = 200;
+ char *errmsg = NULL;
+ geocache_service_wms *wms_service = (geocache_service_wms*)this;
+
+ *request = NULL;
+
str = apr_table_get(params,"SERVICE");
if(!str) {
- ctx->set_error(ctx,400,"received wms request with no service param");
- return;
+ errcode=400;
+ errmsg = "received wms request with no service param";
+ goto proxies;
}
if( strcasecmp(str,"wms") ) {
- ctx->set_error(ctx,400,"received wms request with invalid service param %s", str);
- return;
+ errcode = 400;
+ errmsg = apr_psprintf(ctx->pool,"received wms request with invalid service param %s", str);
+ goto proxies;
}
str = apr_table_get(params,"REQUEST");
if(!str) {
- ctx->set_error(ctx, 400, "received wms with no request");
- return;
+ errcode = 400;
+ errmsg = "received wms with no request";
+ goto proxies;
}
if( ! strcasecmp(str,"getmap")) {
@@ -319,66 +327,75 @@
*request = (geocache_request*)
apr_pcalloc(ctx->pool,sizeof(geocache_request_get_capabilities_wms));
(*request)->type = GEOCACHE_REQUEST_GET_CAPABILITIES;
- return; /* OK */
+ goto proxies; /* OK */
} else if( ! strcasecmp(str,"getfeatureinfo") ) {
//nothing
} else {
- ctx->set_error(ctx, 501, "received wms with invalid request %s",str);
- return;
+ errcode = 501;
+ errmsg = apr_psprintf(ctx->pool,"received wms with invalid request %s",str);
+ goto proxies;
}
}
str = apr_table_get(params,"BBOX");
if(!str) {
- ctx->set_error(ctx, 400, "received wms request with no bbox");
- return;
+ errcode = 400;
+ errmsg = "received wms request with no bbox";
+ goto proxies;
} else {
int nextents;
if(GEOCACHE_SUCCESS != geocache_util_extract_double_list(ctx, str,',',&bbox,&nextents) ||
nextents != 4) {
- ctx->set_error(ctx, 400, "received wms request with invalid bbox");
- return;
+ errcode = 400;
+ errmsg = "received wms request with invalid bbox";
+ goto proxies;
}
}
str = apr_table_get(params,"WIDTH");
if(!str) {
- ctx->set_error(ctx, 400, "received wms request with no width");
- return;
+ errcode = 400;
+ errmsg = "received wms request with no width";
+ goto proxies;
} else {
char *endptr;
width = (int)strtol(str,&endptr,10);
if(*endptr != 0 || width <= 0) {
- ctx->set_error(ctx, 400, "received wms request with invalid width");
- return;
+ errcode = 400;
+ errmsg = "received wms request with invalid width";
+ goto proxies;
}
}
str = apr_table_get(params,"HEIGHT");
if(!str) {
- ctx->set_error(ctx, 400, "received wms request with no height");
- return;
+ errcode = 400;
+ errmsg = "received wms request with no height";
+ goto proxies;
} else {
char *endptr;
height = (int)strtol(str,&endptr,10);
if(*endptr != 0 || height <= 0) {
- ctx->set_error(ctx, 400, "received wms request with invalid height");
- return;
+ errcode = 400;
+ errmsg = "received wms request with invalid height";
+ goto proxies;
}
}
srs = apr_table_get(params,"SRS");
if(!srs) {
- ctx->set_error(ctx, 400, "received wms request with no srs");
- return;
+ errcode = 400;
+ errmsg = "received wms request with no srs";
+ goto proxies;
}
if(isGetMap) {
str = apr_table_get(params,"LAYERS");
if(!str) {
- ctx->set_error(ctx, 400, "received wms request with no layers");
- return;
+ errcode = 400;
+ errmsg = "received wms request with no layers";
+ goto proxies;
} else {
char *last, *key, *layers;
int count=1;
@@ -397,8 +414,9 @@
key = apr_strtok(NULL, sep, &last)) {
geocache_tileset *tileset = geocache_configuration_get_tileset(config,key);
if(!tileset) {
- ctx->set_error(ctx, 404, "received wms request with invalid layer %s", key);
- return;
+ errcode = 404;
+ errmsg = apr_psprintf(ctx->pool,"received wms request with invalid layer %s", key);
+ goto proxies;
}
int i;
geocache_grid_link *grid_link = NULL;
@@ -419,9 +437,10 @@
break;
}
if(!grid_link) {
- ctx->set_error(ctx, 400,
+ errcode = 400;
+ errmsg = apr_psprintf(ctx->pool,
"received unsuitable wms request: no <grid> with suitable srs found for layer %s",tileset->name);
- return;
+ goto proxies;
}
/* verify we align on the tileset's grid */
@@ -464,8 +483,9 @@
#else
int ret = geocache_grid_get_cell(ctx, grid_link->grid, bbox, &tile->x, &tile->y, &tile->z);
if(ret != GEOCACHE_SUCCESS) {
- ctx->set_error(ctx,500,"###BUG###: grid_get_cell returned failure");
- return;
+ errcode = 500;
+ errmsg = "###BUG###: grid_get_cell returned failure";
+ goto proxies;
}
#endif
geocache_tileset_tile_validate(ctx,tile);
@@ -502,37 +522,43 @@
if(ok == GEOCACHE_SUCCESS)
apr_table_setn(dimtable,dimension->name,tmpval);
else {
- ctx->set_error(ctx,400,"dimension \"%s\" value \"%s\" fails to validate",
+ errcode = 400;
+ errmsg = apr_psprintf(ctx->pool, "dimension \"%s\" value \"%s\" fails to validate",
dimension->name, value);
- return;
+ goto proxies;
}
}
}
}
}
if(tile_req && tile_req->ntiles == 0) {
- ctx->set_error(ctx,404,"request for tile outside of restricted extent");
- return;
+ errcode = 404;
+ errmsg = "request for tile outside of restricted extent";
+ goto proxies;
}
}
} else {
//getfeatureinfo
str = apr_table_get(params,"QUERY_LAYERS");
if(!str) {
- ctx->set_error(ctx, 400, "received wms getfeatureinfo request with no query layers");
- return;
+ errcode = 400;
+ errmsg = "received wms getfeatureinfo request with no query layers";
+ goto proxies;
} else if(strstr(str,",")) {
- ctx->set_error(ctx,501, "wms getfeatureinfo not implemented for multiple layers");
- return;
+ errcode = 501;
+ errmsg = "wms getfeatureinfo not implemented for multiple layers";
+ goto proxies;
} else {
geocache_tileset *tileset = geocache_configuration_get_tileset(config,str);
if(!tileset) {
- ctx->set_error(ctx, 404, "received wms getfeatureinfo request with invalid layer %s", str);
- return;
+ errcode = 404;
+ errmsg = apr_psprintf(ctx->pool,"received wms getfeatureinfo request with invalid layer %s", str);
+ goto proxies;
}
if(!tileset->source->info_formats) {
- ctx->set_error(ctx, 404, "received wms getfeatureinfo request for unqueryable layer %s", str);
- return;
+ errcode = 404;
+ errmsg = apr_psprintf(ctx->pool,"received wms getfeatureinfo request for unqueryable layer %s", str);
+ goto proxies;
}
int i;
geocache_grid_link *grid_link = NULL;
@@ -543,35 +569,40 @@
break;
}
if(!grid_link) {
- ctx->set_error(ctx, 400,
+ errcode = 400;
+ errmsg = apr_psprintf(ctx->pool,
"received unsuitable wms request: no <grid> with suitable srs found for layer %s",tileset->name);
- return;
+ goto proxies;
}
int x,y;
str = apr_table_get(params,"X");
if(!str) {
- ctx->set_error(ctx, 400, "received wms getfeatureinfo request with no X");
- return;
+ errcode = 400;
+ errmsg = "received wms getfeatureinfo request with no X";
+ goto proxies;
} else {
char *endptr;
x = (int)strtol(str,&endptr,10);
if(*endptr != 0 || x <= 0 || x>=width) {
- ctx->set_error(ctx, 400, "received wms request with invalid X");
- return;
+ errcode = 400;
+ errmsg = "received wms request with invalid X";
+ goto proxies;
}
}
str = apr_table_get(params,"Y");
if(!str) {
- ctx->set_error(ctx, 400, "received wms getfeatureinfo request with no Y");
- return;
+ errcode = 400;
+ errmsg = "received wms getfeatureinfo request with no Y";
+ goto proxies;
} else {
char *endptr;
y = (int)strtol(str,&endptr,10);
if(*endptr != 0 || y <= 0 || y>=height) {
- ctx->set_error(ctx, 400, "received wms request with invalid Y");
- return;
+ errcode = 400;
+ errmsg = "received wms request with invalid Y";
+ goto proxies;
}
}
@@ -580,8 +611,9 @@
fi->j = y;
fi->format = apr_pstrdup(ctx->pool,apr_table_get(params,"INFO_FORMAT"));
if(!fi->format) {
- ctx->set_error(ctx, 400, "received wms getfeatureinfo request with no INFO_FORMAT");
- return;
+ errcode = 400;
+ errmsg = "received wms getfeatureinfo request with no INFO_FORMAT";
+ goto proxies;
}
if(fi->map.dimensions) {
@@ -596,9 +628,10 @@
if(ok == GEOCACHE_SUCCESS)
apr_table_setn(fi->map.dimensions,dimension->name,tmpval);
else {
- ctx->set_error(ctx,400,"dimension \"%s\" value \"%s\" fails to validate",
+ errcode = 400;
+ errmsg = apr_psprintf(ctx->pool,"dimension \"%s\" value \"%s\" fails to validate",
dimension->name, value);
- return;
+ goto proxies;
}
}
}
@@ -616,6 +649,54 @@
}
}
+
+proxies:
+ /*
+ * if we don't have a gettile or getmap request we can treat from the cache tiles, look to see if we have a rule
+ * that tells us to forward the request somewhere else
+ */
+ if(errcode == 200 &&
+ *request && (
+ ((*request)->type == GEOCACHE_REQUEST_GET_TILE) ||
+ (((*request)->type == GEOCACHE_REQUEST_GET_MAP) &&
+ ctx->config->getmap_strategy != GEOCACHE_GETMAP_ASSEMBLE)
+ )) {
+ /* if we're here, then we have succesfully parsed the request and can treat it ourselves, i.e. from cached tiles */
+ return;
+ } else {
+ /* look to see if we can proxy the request somewhere*/
+ int i,j;
+ for(i=0;i<wms_service->forwarding_rules->nelts;i++) {
+ geocache_forwarding_rule *rule = APR_ARRAY_IDX(wms_service->forwarding_rules,i,geocache_forwarding_rule*);
+ int got_a_match = 1;
+ for(j=0;j<rule->match_params->nelts;j++) {
+ geocache_dimension *match_param = APR_ARRAY_IDX(rule->match_params,j,geocache_dimension*);
+ const char *value = apr_table_get(params,match_param->name);
+ if(match_param->validate(ctx,match_param,(char**)&value) == GEOCACHE_FAILURE) {
+ got_a_match = 0;
+ break;
+ }
+ }
+ if( got_a_match == 1 ) {
+ geocache_request_proxy *req_proxy = apr_pcalloc(ctx->pool,sizeof(geocache_request_proxy));
+ *request = (geocache_request*)req_proxy;
+ (*request)->service = this;
+ (*request)->type = GEOCACHE_REQUEST_PROXY;
+ req_proxy->http = rule->http;
+ req_proxy->params = params;
+ return;
+ }
+ }
+ }
+
+ /*
+ * if we are here, then we are either in the getfeatureinfo / getcapabilities / getmap case,
+ * or there was an error parsing the request and no rules to proxy it elsewhere
+ */
+ if(errcode != 200) {
+ ctx->set_error(ctx,errcode,errmsg);
+ return;
+ }
#ifdef DEBUG
if((*request)->type != GEOCACHE_REQUEST_GET_TILE && (*request)->type != GEOCACHE_REQUEST_GET_MAP &&
(*request)->type != GEOCACHE_REQUEST_GET_FEATUREINFO ) {
@@ -627,7 +708,58 @@
void _configuration_parse_wms(geocache_context *ctx, ezxml_t node, geocache_service *gservice) {
assert(gservice->type == GEOCACHE_SERVICE_WMS);
+ geocache_service_wms *wms = (geocache_service_wms*)gservice;
+ ezxml_t rule_node;
+ for( rule_node = ezxml_child(node,"forwarding_rule"); rule_node; rule_node = rule_node->next) {
+ char *name = (char*)ezxml_attr(rule_node,"name");
+ if(!name) name = "(null)";
+ geocache_forwarding_rule *rule = apr_pcalloc(ctx->pool, sizeof(geocache_forwarding_rule));
+ rule->name = apr_pstrdup(ctx->pool,name);
+ rule->match_params = apr_array_make(ctx->pool,1,sizeof(geocache_dimension*));
+ ezxml_t http_node = ezxml_child(rule_node,"http");
+ if(!http_node) {
+ ctx->set_error(ctx,500,"rule \"%s\" does not contain an <http> block",name);
+ return;
+ }
+ rule->http = geocache_http_configuration_parse(ctx,http_node);
+ GC_CHECK_ERROR(ctx);
+
+ ezxml_t param_node;
+ for(param_node = ezxml_child(rule_node,"param"); param_node; param_node = param_node->next) {
+ char *name = (char*)ezxml_attr(param_node,"name");
+ char *type = (char*)ezxml_attr(param_node,"type");
+
+ geocache_dimension *dimension = NULL;
+
+ if(!name || !strlen(name)) {
+ ctx->set_error(ctx, 400, "mandatory attribute \"name\" not found in forwarding rule <param>");
+ return;
+ }
+
+ if(type && *type) {
+ if(!strcmp(type,"values")) {
+ dimension = geocache_dimension_values_create(ctx->pool);
+ } else if(!strcmp(type,"regex")) {
+ dimension = geocache_dimension_regex_create(ctx->pool);
+ } else {
+ ctx->set_error(ctx,400,"unknown <param> type \"%s\". expecting \"values\" or \"regex\".",type);
+ return;
+ }
+ } else {
+ ctx->set_error(ctx,400, "mandatory attribute \"type\" not found in <dimensions>");
+ return;
+ }
+
+ dimension->name = apr_pstrdup(ctx->pool,name);
+
+ dimension->parse(ctx,dimension,param_node->txt);
+ GC_CHECK_ERROR(ctx);
+
+ APR_ARRAY_PUSH(rule->match_params,geocache_dimension*) = dimension;
+ }
+ APR_ARRAY_PUSH(wms->forwarding_rules,geocache_forwarding_rule*) = rule;
+ }
}
geocache_service* geocache_service_wms_create(geocache_context *ctx) {
@@ -636,6 +768,7 @@
ctx->set_error(ctx, 500, "failed to allocate wms service");
return NULL;
}
+ service->forwarding_rules = apr_array_make(ctx->pool,0,sizeof(geocache_forwarding_rule*));
service->service.url_prefix = apr_pstrdup(ctx->pool,"");
service->service.name = apr_pstrdup(ctx->pool,"wms");
service->service.type = GEOCACHE_SERVICE_WMS;
More information about the mapserver-commits
mailing list