/*** * The main request handler. **/ static int mapserver_handler (request_rec *r) { /* aquire the apropriate configuration for this directory */ mapserver_dir_config *conf; conf = (mapserver_dir_config*) ap_get_module_config (r->per_dir_config, &mapserver_module); /* decline the request if there's no map configured */ if (!conf || !conf->map) return DECLINED; apr_finfo_t mapstat; if (apr_stat (&mapstat, conf->mapfile_name, APR_FINFO_MTIME, r->pool) == APR_SUCCESS) { if (apr_time_sec (mapstat.mtime) > apr_time_sec (conf->mtime)) { mapObj *newmap = msLoadMap (conf->mapfile_name, NULL); if (newmap) { msFreeMap (conf->map); conf->map = newmap; conf->mtime = mapstat.mtime; } else { ap_log_error (APLOG_MARK, APLOG_WARNING, 0, NULL, "unable to reload map file %s", conf->mapfile_name); } } } else { ap_log_error (APLOG_MARK, APLOG_WARNING, 0, NULL, "%s: unable to stat file %s", __func__, conf->mapfile_name); } /* make a copy of the URI so we can modify it safely */ char *uri = apr_pstrdup (r->pool, r->uri); int len = strlen (uri); int conf_uri_len = strlen (conf->uri); /* If the URI points to a subdirectory we want to decline. */ if (len > conf_uri_len) return DECLINED; int argc = 0; char **ParamNames = NULL; char **ParamValues = NULL; char *post_data = NULL; int szMethod = -1; char *szContentType = NULL; mapservObj *mapserv = NULL; /* Try decoding the query string */ if (r->method_number == M_GET) { argc = mapserver_decode_args (r->pool, (char*) apr_pstrdup (r->pool, r->args), &ParamNames, &ParamValues); szMethod = MS_GET_REQUEST; } else if (r->method_number == M_POST) { szContentType = (char*) apr_table_get (r->headers_in, "Content-Type"); post_data = mapserver_read_post_data (r); szMethod = MS_POST_REQUEST; if (strcmp (szContentType, "application/x-www-form-urlencoded") == 0) { argc = mapserver_decode_args (r->pool, (char*) apr_pstrdup (r->pool, r->args), &ParamNames, &ParamValues); } } else return HTTP_METHOD_NOT_ALLOWED; if (!argc && !post_data) return HTTP_BAD_REQUEST; /* Now we install the IO redirection. */ if (msIO_installApacheRedirect (r) != MS_TRUE) ap_log_error (APLOG_MARK, APLOG_ERR, 0, NULL, "%s: could not install apache redirect", __func__); mapserv = msAllocMapServObj(); mapserv->request->NumParams = argc; mapserv->request->ParamNames = ParamNames; mapserv->request->ParamValues = ParamValues; mapserv->request->type = (enum MS_REQUEST_TYPE) szMethod; mapserv->request->postrequest = post_data; mapserv->request->contenttype = szContentType; //mapserv->map = msModuleLoadMap(mapserv,conf); mapserv->map = conf->map; if(!mapserv->map) { msCGIWriteError(mapserv); goto end_request; } if(msCGIDispatchRequest(mapserv) != MS_SUCCESS) { msCGIWriteError(mapserv); goto end_request; } end_request: if(mapserv) { msCGIWriteLog(mapserv,MS_FALSE); mapserv->request->ParamNames = NULL; mapserv->request->ParamValues = NULL; mapserv->request->postrequest = NULL; mapserv->request->contenttype = NULL; mapserv->map = NULL; msFreeMapServObj(mapserv); } msResetErrorList(); /* Check if status was set inside MapServer functions. If it was, we * return it's value instead of simply OK. This is to support redirects * from maptemplate.c */ if (r->status == HTTP_MOVED_TEMPORARILY) return r->status; return OK; }
int main(int argc, char *argv[]) { int iArg; int sendheaders = MS_TRUE; struct mstimeval execstarttime, execendtime; struct mstimeval requeststarttime, requestendtime; mapservObj* mapserv = NULL; /* -------------------------------------------------------------------- */ /* Initialize mapserver. This sets up threads, GD and GEOS as */ /* well as using MS_ERRORFILE and MS_DEBUGLEVEL env vars if set. */ /* -------------------------------------------------------------------- */ if( msSetup() != MS_SUCCESS ) { msCGIWriteError(mapserv); msCleanup(0); exit(0); } if(msGetGlobalDebugLevel() >= MS_DEBUGLEVEL_TUNING) msGettimeofday(&execstarttime, NULL); /* -------------------------------------------------------------------- */ /* Process arguments. In normal use as a cgi-bin there are no */ /* commandline switches, but we provide a few for test/debug */ /* purposes, and to query the version info. */ /* -------------------------------------------------------------------- */ for( iArg = 1; iArg < argc; iArg++ ) { /* Keep only "-v", "-nh" and "QUERY_STRING=..." enabled by default. * The others will require an explicit -DMS_ENABLE_CGI_CL_DEBUG_ARGS * at compile time. */ if( strcmp(argv[iArg],"-v") == 0 ) { printf("%s\n", msGetVersion()); fflush(stdout); exit(0); } else if(strcmp(argv[iArg], "-nh") == 0) { sendheaders = MS_FALSE; } else if( strncmp(argv[iArg], "QUERY_STRING=", 13) == 0 ) { /* Debugging hook... pass "QUERY_STRING=..." on the command-line */ putenv( "REQUEST_METHOD=GET" ); putenv( argv[iArg] ); } #ifdef MS_ENABLE_CGI_CL_DEBUG_ARGS else if( iArg < argc-1 && strcmp(argv[iArg], "-tmpbase") == 0) { msForceTmpFileBase( argv[++iArg] ); } else if( iArg < argc-1 && strcmp(argv[iArg], "-t") == 0) { char **tokens; int numtokens=0; if((tokens=msTokenizeMap(argv[iArg+1], &numtokens)) != NULL) { int i; for(i=0; i<numtokens; i++) printf("%s\n", tokens[i]); msFreeCharArray(tokens, numtokens); } else { msCGIWriteError(mapserv); } exit(0); } else if( strncmp(argv[iArg], "MS_ERRORFILE=", 13) == 0 ) { msSetErrorFile( argv[iArg] + 13, NULL ); } else if( strncmp(argv[iArg], "MS_DEBUGLEVEL=", 14) == 0) { msSetGlobalDebugLevel( atoi(argv[iArg] + 14) ); } #endif /* MS_ENABLE_CGI_CL_DEBUG_ARGS */ else { /* we don't produce a usage message as some web servers pass junk arguments */ } } /* -------------------------------------------------------------------- */ /* Setup cleanup magic, mainly for FastCGI case. */ /* -------------------------------------------------------------------- */ #ifndef WIN32 signal( SIGUSR1, msCleanupOnSignal ); signal( SIGTERM, msCleanupOnSignal ); #endif #ifdef USE_FASTCGI msIO_installFastCGIRedirect(); #ifdef WIN32 atexit( msCleanupOnExit ); #endif /* In FastCGI case we loop accepting multiple requests. In normal CGI */ /* use we only accept and process one request. */ while( FCGI_Accept() >= 0 ) { #endif /* def USE_FASTCGI */ /* -------------------------------------------------------------------- */ /* Process a request. */ /* -------------------------------------------------------------------- */ mapserv = msAllocMapServObj(); mapserv->sendheaders = sendheaders; /* override the default if necessary (via command line -nh switch) */ mapserv->request->NumParams = loadParams(mapserv->request, NULL, NULL, 0, NULL); if( mapserv->request->NumParams == -1 ) { msCGIWriteError(mapserv); goto end_request; } mapserv->map = msCGILoadMap(mapserv); if(!mapserv->map) { msCGIWriteError(mapserv); goto end_request; } if( mapserv->map->debug >= MS_DEBUGLEVEL_TUNING) msGettimeofday(&requeststarttime, NULL); #ifdef USE_FASTCGI if( mapserv->map->debug ) { static int nRequestCounter = 1; msDebug( "CGI Request %d on process %d\n", nRequestCounter, getpid() ); nRequestCounter++; } #endif if(msCGIDispatchRequest(mapserv) != MS_SUCCESS) { msCGIWriteError(mapserv); goto end_request; } end_request: if(mapserv) { if(mapserv->map && mapserv->map->debug >= MS_DEBUGLEVEL_TUNING) { msGettimeofday(&requestendtime, NULL); msDebug("mapserv request processing time (msLoadMap not incl.): %.3fs\n", (requestendtime.tv_sec+requestendtime.tv_usec/1.0e6)- (requeststarttime.tv_sec+requeststarttime.tv_usec/1.0e6) ); } msCGIWriteLog(mapserv,MS_FALSE); msFreeMapServObj(mapserv); } #ifdef USE_FASTCGI /* FCGI_ --- return to top of loop */ msResetErrorList(); continue; } /* end fastcgi loop */ #endif /* normal case, processing is complete */ if(msGetGlobalDebugLevel() >= MS_DEBUGLEVEL_TUNING) { msGettimeofday(&execendtime, NULL); msDebug("mapserv total execution time: %.3fs\n", (execendtime.tv_sec+execendtime.tv_usec/1.0e6)- (execstarttime.tv_sec+execstarttime.tv_usec/1.0e6) ); } msCleanup(0); #ifdef _WIN32 /* flush pending writes to stdout */ fflush(stdout); #endif exit( 0 ); }