[mapserver-commits] r10540 - trunk/mapserver
svn at osgeo.org
svn at osgeo.org
Wed Sep 29 18:56:11 EDT 2010
Author: warmerdam
Date: 2010-09-29 22:56:11 +0000 (Wed, 29 Sep 2010)
New Revision: 10540
Modified:
trunk/mapserver/HISTORY.TXT
trunk/mapserver/mapgdal.c
trunk/mapserver/maphttp.c
trunk/mapserver/mapows.h
trunk/mapserver/mapwmslayer.c
Log:
avoid writing WMS client layer results to disk (#3555)
Modified: trunk/mapserver/HISTORY.TXT
===================================================================
--- trunk/mapserver/HISTORY.TXT 2010-09-29 21:40:06 UTC (rev 10539)
+++ trunk/mapserver/HISTORY.TXT 2010-09-29 22:56:11 UTC (rev 10540)
@@ -14,6 +14,8 @@
Current Version (SVN trunk):
----------------------------
+- Support holding WMS client requests in RAM instead of writing to disk (#3555)
+
- RFC-61: Enhance MapServer Feature Style Support (#3544)
- Restrict cascaded WMS requests based on EXTENT (#3543)
Modified: trunk/mapserver/mapgdal.c
===================================================================
--- trunk/mapserver/mapgdal.c 2010-09-29 21:40:06 UTC (rev 10539)
+++ trunk/mapserver/mapgdal.c 2010-09-29 22:56:11 UTC (rev 10540)
@@ -95,7 +95,7 @@
/* things are clean before we start, and after we are done. */
/************************************************************************/
-static void CleanVSIDir( const char *pszDir )
+void CleanVSIDir( const char *pszDir )
{
char **papszFiles = CPLReadDir( pszDir );
Modified: trunk/mapserver/maphttp.c
===================================================================
--- trunk/mapserver/maphttp.c 2010-09-29 21:40:06 UTC (rev 10539)
+++ trunk/mapserver/maphttp.c 2010-09-29 22:56:11 UTC (rev 10540)
@@ -145,7 +145,9 @@
pasReqInfo[i].curl_handle = NULL;
pasReqInfo[i].fp = NULL;
-
+ pasReqInfo[i].result_data = NULL;
+ pasReqInfo[i].result_size = 0;
+ pasReqInfo[i].result_buf_size = 0;
}
}
@@ -192,6 +194,11 @@
pasReqInfo[i].pszHTTPCookieData = NULL;
pasReqInfo[i].curl_handle = NULL;
+
+ free( pasReqInfo[i].result_data );
+ pasReqInfo[i].result_data = NULL;
+ pasReqInfo[i].result_size = 0;
+ pasReqInfo[i].result_buf_size = 0;
}
}
@@ -219,7 +226,44 @@
psReq->nLayerId, size*nmemb);
}
- return fwrite(buffer, size, nmemb, psReq->fp);
+ /* Case where we are writing to a disk file. */
+ if( psReq->fp != NULL )
+ {
+ return fwrite(buffer, size, nmemb, psReq->fp);
+ }
+
+ /* Case where we build up the result in memory */
+ else
+ {
+ if( psReq->result_data == NULL )
+ {
+ psReq->result_buf_size = size*nmemb + 10000;
+ psReq->result_data = (char *) malloc( psReq->result_buf_size );
+ }
+ else if( psReq->result_size + nmemb * size > psReq->result_buf_size )
+ {
+ psReq->result_buf_size = psReq->result_size + nmemb*size + 10000;
+ psReq->result_data = (char *) realloc( psReq->result_data,
+ psReq->result_buf_size );
+ }
+
+ if( psReq->result_data == NULL )
+ {
+ msSetError(MS_HTTPERR,
+ "Unable to grow HTTP result buffer to size %d.",
+ "msHTTPWriteFct()",
+ psReq->result_buf_size );
+ psReq->result_buf_size = 0;
+ psReq->result_size = 0;
+ return -1;
+ }
+
+ memcpy( psReq->result_data + psReq->result_size,
+ buffer, size*nmemb );
+ psReq->result_size += size*nmemb;
+
+ return size*nmemb;
+ }
}
/**********************************************************************
@@ -321,8 +365,7 @@
CURL *http_handle;
FILE *fp;
- if (pasReqInfo[i].pszGetUrl == NULL ||
- pasReqInfo[i].pszOutputFile == NULL)
+ if (pasReqInfo[i].pszGetUrl == NULL )
{
msSetError(MS_HTTPERR, "URL or output file parameter missing.",
"msHTTPExecuteRequests()");
@@ -342,7 +385,7 @@
pasReqInfo[i].pszContentType = NULL;
/* Check local cache if requested */
- if (bCheckLocalCache)
+ if (bCheckLocalCache && pasReqInfo[i].pszOutputFile != NULL )
{
fp = fopen(pasReqInfo[i].pszOutputFile, "r");
if (fp)
@@ -488,15 +531,19 @@
curl_easy_setopt(http_handle, CURLOPT_NOSIGNAL, 1 );
#endif
- /* Open output file and set write handler */
- if ( (fp = fopen(pasReqInfo[i].pszOutputFile, "wb")) == NULL)
+ /* If we are writing file to disk, open the file now. */
+ if( pasReqInfo[i].pszOutputFile != NULL )
{
- msSetError(MS_HTTPERR, "Can't open output file %s.",
- "msHTTPExecuteRequests()", pasReqInfo[i].pszOutputFile);
- return(MS_FAILURE);
+ if ( (fp = fopen(pasReqInfo[i].pszOutputFile, "wb")) == NULL)
+ {
+ msSetError(MS_HTTPERR, "Can't open output file %s.",
+ "msHTTPExecuteRequests()", pasReqInfo[i].pszOutputFile);
+ return(MS_FAILURE);
+ }
+
+ pasReqInfo[i].fp = fp;
}
- pasReqInfo[i].fp = fp;
curl_easy_setopt(http_handle, CURLOPT_WRITEDATA, &(pasReqInfo[i]));
curl_easy_setopt(http_handle, CURLOPT_WRITEFUNCTION, msHTTPWriteFct);
Modified: trunk/mapserver/mapows.h
===================================================================
--- trunk/mapserver/mapows.h 2010-09-29 21:40:06 UTC (rev 10539)
+++ trunk/mapserver/mapows.h 2010-09-29 22:56:11 UTC (rev 10540)
@@ -94,6 +94,11 @@
/* Private members */
void * curl_handle; /* CURLM * handle */
FILE * fp; /* FILE * used during download */
+
+ char * result_data; /* output if pszOutputFile is NULL */
+ int result_size;
+ int result_buf_size;
+
} httpRequestObj;
typedef struct
Modified: trunk/mapserver/mapwmslayer.c
===================================================================
--- trunk/mapserver/mapwmslayer.c 2010-09-29 21:40:06 UTC (rev 10539)
+++ trunk/mapserver/mapwmslayer.c 2010-09-29 22:56:11 UTC (rev 10540)
@@ -39,7 +39,12 @@
#include <stdio.h>
#endif
+#ifdef USE_GDAL
+# include "cpl_vsi.h"
+#endif
+void CleanVSIDir( const char *pszDir );
+
/**********************************************************************
* msInitWmsParamsObj()
*
@@ -934,7 +939,7 @@
const char *pszTmp;
rectObj bbox;
int bbox_width, bbox_height;
- int nTimeout, bOkToMerge, bForceSeparateRequest;
+ int nTimeout, bOkToMerge, bForceSeparateRequest, bCacheToDisk;
wmsParamsObj sThisWMSParams;
char *pszProxyHost=NULL;
@@ -1132,9 +1137,24 @@
return(MS_FAILURE); /* An error should already have been produced */
}
}
-
/* ------------------------------------------------------------------
+ * Check if we want to use in memory images instead of writing to disk.
+ * ------------------------------------------------------------------ */
+ if ((pszTmp = msOWSLookupMetadata(&(lp->metadata),
+ "MO", "cache_to_disk")) != NULL)
+ {
+ if( strcasecmp(pszTmp,"true") == 0
+ || strcasecmp(pszTmp,"on") == 0
+ || strcasecmp(pszTmp,"yes") == 0 )
+ bCacheToDisk = MS_TRUE;
+ else
+ bCacheToDisk = atoi(pszTmp);
+ }
+ else
+ bCacheToDisk = MS_FALSE;
+
+/* ------------------------------------------------------------------
* Check if layer can be merged with previous WMS layer requests
* Metadata wms_force_separate_request can be set to 1 to prevent this
* this layer from being combined with any other layer.
@@ -1300,9 +1320,11 @@
}
pasReqInfo[(*numRequests)].pszHTTPCookieData = pszHTTPCookieData;
pszHTTPCookieData = NULL;
- pasReqInfo[(*numRequests)].pszOutputFile =msTmpFile(map->mappath,
- map->web.imagepath,
- "img.tmp");
+ if( bCacheToDisk )
+ pasReqInfo[(*numRequests)].pszOutputFile =
+ msTmpFile(map->mappath, map->web.imagepath, "img.tmp");
+ else
+ pasReqInfo[(*numRequests)].pszOutputFile = NULL;
pasReqInfo[(*numRequests)].nStatus = 0;
pasReqInfo[(*numRequests)].nTimeout = nTimeout;
pasReqInfo[(*numRequests)].bbox = bbox;
@@ -1371,6 +1393,7 @@
int currenttype;
int currentconnectiontype;
int numclasses;
+ char *mem_filename = NULL;
/* ------------------------------------------------------------------
* Find the request info for this layer in the array, based on nLayerId
@@ -1455,7 +1478,22 @@
return MS_SUCCESS;
}
+
+/* ------------------------------------------------------------------
+ * If the output was written to a memory buffer, then we will need
+ * to attach a "VSI" name to this buffer.
+ * ------------------------------------------------------------------ */
+ if( pasReqInfo[iReq].pszOutputFile == NULL )
+ {
+ CleanVSIDir( "/vsimem/msout" );
+ mem_filename = msTmpFile( NULL, "/vsimem/msout/", "img.tmp" );
+ VSIFCloseL(
+ VSIFileFromMemBuffer( mem_filename,
+ (GByte*) pasReqInfo[iReq].result_data,
+ (vsi_l_offset) pasReqInfo[iReq].result_size,
+ FALSE ) );
+ }
/* ------------------------------------------------------------------
* Prepare layer for drawing, reprojecting the image received from the
@@ -1481,7 +1519,10 @@
lp->numclasses = 0;
if (lp->data) free(lp->data);
- lp->data = strdup(pasReqInfo[iReq].pszOutputFile);
+ if( mem_filename != NULL )
+ lp->data = mem_filename;
+ else
+ lp->data = strdup(pasReqInfo[iReq].pszOutputFile);
/* #3138 If PROCESSING "RESAMPLE=..." is set we cannot use the simple case */
if (!msProjectionsDiffer(&(map->projection), &(lp->projection)) &&
@@ -1507,7 +1548,7 @@
wldfile = msBuildPath(szPath, lp->map->mappath, lp->data);
if (wldfile)
strcpy(wldfile+strlen(wldfile)-3, "wld");
- if (wldfile && (fp = fopen(wldfile, "wt")) != NULL)
+ if (wldfile && (fp = VSIFOpenL(wldfile, "wt")) != NULL)
{
double dfCellSizeX = MS_CELLSIZE(pasReqInfo[iReq].bbox.minx,
pasReqInfo[iReq].bbox.maxx,
@@ -1515,23 +1556,23 @@
double dfCellSizeY = MS_CELLSIZE(pasReqInfo[iReq].bbox.maxy,
pasReqInfo[iReq].bbox.miny,
pasReqInfo[iReq].height);
-
- fprintf(fp, "%.12f\n", dfCellSizeX );
- fprintf(fp, "0\n");
- fprintf(fp, "0\n");
- fprintf(fp, "%.12f\n", dfCellSizeY );
- fprintf(fp, "%.12f\n",
- pasReqInfo[iReq].bbox.minx + dfCellSizeX * 0.5 );
- fprintf(fp, "%.12f\n",
- pasReqInfo[iReq].bbox.maxy + dfCellSizeY * 0.5 );
- fclose(fp);
+ char world_text[5000];
+ sprintf( world_text, "%.12f\n0\n0\n%.12f\n%.12f\n%.12f\n",
+ dfCellSizeX,
+ dfCellSizeY,
+ pasReqInfo[iReq].bbox.minx + dfCellSizeX * 0.5,
+ pasReqInfo[iReq].bbox.maxy + dfCellSizeY * 0.5 );
+
+ VSIFWriteL( world_text, 1, strlen(world_text), fp );
+ VSIFCloseL( fp );
+
/* GDAL should be called to reproject automatically. */
if (msDrawLayer(map, lp, img) != 0)
status = MS_FAILURE;
if (!lp->debug)
- unlink(wldfile);
+ VSIUnlink( wldfile );
}
else
{
@@ -1545,7 +1586,7 @@
/* We're done with the remote server's response... delete it. */
if (!lp->debug)
- unlink(lp->data);
+ VSIUnlink(lp->data);
/* restore prveious type */
lp->type = currenttype;
More information about the mapserver-commits
mailing list