Opened 17 years ago

Closed 14 years ago

#1975 closed enhancement (fixed)

loadparams doesn't work on linux

Reported by: ben.tuttle@… Owned by: aboudreault
Priority: normal Milestone: 6.0 release
Component: MapScript Version: 4.10
Severity: minor Keywords:
Cc: mapserver@…, dmorissette

Description (last modified by warmerdam)

Summary: PHP MapScript loadparams() does not work with mod_php because it does not receive the cgi environment variables. This is presumably true of other non-cgi environments like mod_python as well. This is basically unfixable, but we should likely offer a corresponding mechanism for mod_php/mod_python scripters to pass in the url to loadparams().

Ben reports:

On a linux server using php ms_newowsrequestobj() seems to return an object with numparams equal to zero. When loadparams() is called it fails. Examples of this are found below. In the script example all code satarting at the loadparams() call is commented out because including the loadparams() line causes the entire script to fail.

Example URL:

http://eogmaps.ngdc.noaa.gov/test4.php?service=WMS&version=1.1.1&Request=GetCapabilities
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
PHP Script:

<?php
dl("php_mapscript.so");
$request = ms_newowsrequestobj();
print "<br><b>Dump of request: </b>";
var_dump($request);

print "<br><b>Num Params: </b>";
echo $request->numparams;
echo $request->getname(1);

echo "<br><br><b>Environment Variables from HTTP_ENV_VARS</b><br><br>";
 reset($HTTP_ENV_VARS);
  while (list ($key, $val) = each ($HTTP_ENV_VARS)) {
 print $key . " = " . $val . "<br>";
 };
echo "<br><b>Environment Variables from HTTP_SERVER_VARS</b><br><br>";
 reset($HTTP_SERVER_VARS);
  while (list ($key, $val) = each ($HTTP_SERVER_VARS)) {
 print $key . " = " . $val . "<br>";
 };

/*
$request->loadparams();
$request->setParameter("VeRsIoN","1.1.0");
ms_ioinstallstdouttobuffer();
$oMap = ms_newMapobj("/mnt/anchor1/eogmaps/data/dmsp1.map");
$oMap->owsdispatch($request);
$contenttype = ms_iostripstdoutbuffercontenttype();
$buffer = ms_iogetstdoutbufferstring();
header('Content-type: application/xml');
echo $buffer;
ms_ioresethandlers();
*/
?>
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Output From the script:

Dump of request: object(ms_cgirequest_obj)(2) { ["_handle_"]=>
resource(2) of type (Unknown) ["numparams"]=>  int(0) }
Num Params: 0

Environment Variables from HTTP_ENV_VARS

LANG = C
TERM = xterm-color
PATH = /sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin
PWD = /
SHLVL = 1
_ = /sbin/initlog

Environment Variables from HTTP_SERVER_VARS

Host =
HTTP_HOST = eogmaps.ngdc.noaa.gov
HTTP_USER_AGENT = Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US;
rv:1.8.0.8) Gecko/20061025 Firefox/1.5.0.8
HTTP_ACCEPT =
text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
HTTP_ACCEPT_LANGUAGE = en-us,en;q=0.5
HTTP_ACCEPT_ENCODING = gzip,deflate
HTTP_ACCEPT_CHARSET = ISO-8859-1,utf-8;q=0.7,*;q=0.7
HTTP_KEEP_ALIVE = 300
HTTP_CONNECTION = keep-alive
HTTP_CACHE_CONTROL = max-age=0
PATH = /sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin
SERVER_SIGNATURE =
Apache/2.0.52 (Red Hat) Server at eogmaps.ngdc.noaa.gov Port 80

SERVER_SOFTWARE = Apache/2.0.52 (Red Hat)
SERVER_NAME = eogmaps.ngdc.noaa.gov
SERVER_ADDR = 141.174.183.20
SERVER_PORT = 80
REMOTE_ADDR = 141.174.183.3
DOCUMENT_ROOT = /mnt/anchor1/eogmaps/www/html/
SERVER_ADMIN =
SCRIPT_FILENAME = /mnt/anchor1/eogmaps/www/html/test4.php
REMOTE_PORT = 56757
GATEWAY_INTERFACE = CGI/1.1
SERVER_PROTOCOL = HTTP/1.1
REQUEST_METHOD = GET
QUERY_STRING = service=WMS&version=1.1.1&Request=GetCapabilities
REQUEST_URI = /test4.php?service=WMS&version=1.1.1&Request=GetCapabilities
SCRIPT_NAME = /test4.php
PHP_SELF = /test4.php
PATH_TRANSLATED = /mnt/anchor1/eogmaps/www/html/test4.php
argv = Array
argc = 1

Change History (22)

comment:1 by fwarmerdam, 17 years ago

Status: newassigned
Ben,

It what way does loadparams() fail? 

I have tried this script at the commandline with php on linux and it seems
to work:

warmerda@amd64[196]% echo $QUERY_STRING
SERVICE=WMS&REQUEST=GetCapabilities&VERSION=1.1.0
warmerda@amd64[197]% echo $REQUEST_METHOD 
GET
warmerda@amd64[198]% cat test2.php 
<?php

dl("php_mapscript.so");

$request = ms_newowsrequestobj();

$request->loadparams();

var_dump($request);

?>
warmerda@amd64[199]% php5 test2.php
object(ms_cgirequest_obj)#1 (2) {
  ["_handle_"]=>
  resource(4) of type (Unknown)
  ["numparams"]=>
  int(3)
}

Could you try a similar simple script at the commandline?

I have tried to get a php script working in the web environment on my
system but failed.  I can't figure out how to set the shared library
search path properly for php scripts run by mod_php so the php_mapscript.so
won't load for me.  


comment:2 by ben.tuttle@…, 17 years ago

Hi Frank-
I have not tried running it at the command line, could you let me know how you
are going about doing that? I suspect it would be something like 
>php test.php
but how do you set the query_string and such in this mode?
As for how it fails on the server the entire script returns nothing if I
uncomment the loadparams line. It also may be worth noting that echo
$request->getname(1); seems to return nothing. 
As for getting it working on your server, this is kind of a hack but I've seen
it work. Try putting the php_mapscript.so in the same directory as your php
script and just use dl("php_mapscript.so"); I've had builds where I didn't get
the shared library path correct and doing this worked.

comment:3 by ben.tuttle@…, 17 years ago

Just wanted to emphasize that it seems like loadparams probably fails because
the numparams of the owsrequestobj is 0 even if there are parameters in the
query_string. I am guessing based on this that the failure of loadparams is
based on the failure of ms_newowsrequestobj to get the parameters from the
query_string in linux. If this seems incorrect let me know, I am still trying to
wrap my head around exactly what is happening. 

comment:4 by fwarmerdam, 17 years ago

Ben,

I reported the details of the session earlier. 

Basically (assuming bash) something like:

export QUERY_STRING="SERVICE=WMS&REQUEST=GetCapabilities&VERSION=1.1.0"
export REQUEST_FORMAT=GET
php test.php



comment:5 by ben.tuttle@…, 17 years ago

I tried the following on teh command line:
<?php
dl("php_mapscript.so");
$request = ms_newowsrequestobj();
print "<br><b>Dump of request: </b>";
var_dump($request);

print "<br><b>Num Params: </b>";
echo $request->numparams;
echo $request->getname(1);
$request->loadparams();

echo "<br><br><b>Environment Variables from HTTP_ENV_VARS</b><br><br>";
  reset($HTTP_ENV_VARS);
   while (list ($key, $val) = each ($HTTP_ENV_VARS)) {
  print $key . " = " . $val . "<br>";
 };
echo "<br><b>Environment Variables from HTTP_SERVER_VARS</b><br><br>";
  reset($HTTP_SERVER_VARS);
   while (list ($key, $val) = each ($HTTP_SERVER_VARS)) {
  print $key . " = " . $val . "<br>";
 };
?>

The Results were as follows:
[btuttle@anchor html]$ export
QUERY_STRING="SERVICE=WMS&REQUEST=GetCapabilities&VERSION=1.1.0"
[btuttle@anchor html]$ export REQUEST_FORMAT=GET
[btuttle@anchor html]$ php test4.php
Content-type: text/html
X-Powered-By: PHP/4.3.9

<br><b>Dump of request: </b>object(ms_cgirequest_obj)(2) {
  ["_handle_"]=>
  resource(1) of type (Unknown)
  ["numparams"]=>
  int(0)
}
<br><b>Num Params: </b>0This script can only be used to decode form results and
should be initiated as a CGI process via a httpd server.


I notice that $request->numparams() is still 0. 

comment:6 by fwarmerdam, 17 years ago

Ben,

A typo in my last instructions.  The correct variable is REQUEST_METHOD, 
not REQUEST_FORMAT. 


comment:7 by fwarmerdam, 17 years ago

re: comment #3

The creation of the requestobj is not intended to parse the url parameters.
that is done by loadparams(). 


comment:8 by ben.tuttle@…, 17 years ago

So it seems that my configuration keeps me from running at the command line, any
thoughts on a way around this? Still not sure how to get more info on how it
fails as when I run it through a web browser adding loadparams causes the enitre
script to fail and return an empty page. Any thoughts?

[btuttle@anchor html]$ export REQUEST_METHOD=GET
[btuttle@anchor html]$ export
QUERY_STRING="SERVICE=WMS&REQUEST=GetCapabilities&VERSION=1.1.0"
[btuttle@anchor html]$ php test4.php
Status: 400
Content-type: text/html

<b>Security Alert!</b> The PHP CGI cannot be accessed directly.

<p>This PHP CGI binary was compiled with force-cgi-redirect enabled.  This
means that a page will only be served up if the REDIRECT_STATUS CGI variable is
set, e.g. via an Apache Action directive.</p>
<p>For more information as to <i>why</i> this behaviour exists, see the <a
href="http://php.net/security.cgi-bin">manual page for CGI security</a>.</p>
<p>For more information about changing this behaviour or re-enabling this webserver,
consult the installation file that came with this distribution, or visit
<a href="http://php.net/install.windows">the manual page</a>.</p>
[btuttle@anchor html]$

comment:9 by fwarmerdam, 17 years ago

Ben,

I believe there is a way of disabling this in your php.ini file.  But i'm no
PHP expert.  I only know enough about it to do a minor bit of debugging.

Sorry...

comment:10 by ben.tuttle@…, 17 years ago

Okay so teh config is not exactly the same as the server I am trying to get
going at work. However, the problem seems to occur in the same way on my server
at home.  Not sure if it will help to see it or not. However, you can know try:
http://67.172.150.199/wxs1.php?service=WMS&version=1.1.1&Request=GetCapabilities
http://67.172.150.199/wxs2.php?service=WMS&version=1.1.1&Request=GetCapabilities
WHat you should see is that before commenting out loadparams the retruned page
is completely empty. 
wxs1.php looks like:
<?php

if (dl("php_mapscript.so")){
   echo "php mapscript loaded";
} else {
   echo "php mapscript not loaded";
}

$request = ms_newOwsRequestObj();
print "<br>$request";
print "<br>Numparams = ";
echo $request->numparams;

$request->loadparams();

/*exampple on how to modify the parameters :
 forcing the version from 1.1.1 to 1.1.0 */

$request->setParameter("VeRsIoN","1.1.0");

ms_ioinstallstdouttobuffer();

$oMap = ms_newMapobj("/data/dmsp1.map");

$oMap->owsdispatch($request);

$contenttype = ms_iostripstdoutbuffercontenttype();

$buffer = ms_iogetstdoutbufferstring();

header('Content-type: application/xml');
echo $buffer;

ms_ioresethandlers();
?>
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
wxs2.php looks like:
<?php

if (dl("php_mapscript.so")){
   echo "php mapscript loaded";
} else {
   echo "php mapscript not loaded";
}

$request = ms_newOwsRequestObj();
print "<br>$request";
print "<br>Numparams = ";
echo $request->numparams;

/*
$request->loadparams();
*/
/*exampple on how to modify the parameters :
 forcing the version from 1.1.1 to 1.1.0 */
/*
$request->setParameter("VeRsIoN","1.1.0");

ms_ioinstallstdouttobuffer();

$oMap = ms_newMapobj("/data/dmsp1.map");

$oMap->owsdispatch($request);

$contenttype = ms_iostripstdoutbuffercontenttype();

$buffer = ms_iogetstdoutbufferstring();

header('Content-type: application/xml');
echo $buffer;

ms_ioresethandlers();
*/
?>


comment:11 by ben.tuttle@…, 17 years ago

Hi Frank-
Do you know exactly how loadparams() goes about trying to get the query_string?
The Docs say it gets it "from the cgi environment variables REQUEST_METHOD,
QUERY_STRING and HTTP_COOKIE", but I am wonderign exactly how it gets to them.
SInce it fails I was hoping to see if perhaps the method for getting at these
variables (which apparently works under windows from what I've read) perhaps
fails due to some difference in Linux. Thanks.

comment:12 by fwarmerdam, 17 years ago

loadparams() uses the C getenv() function to fetch the environment variables.

In retrospect, it seems plausible that this works quite differently in a
mod_php environment since we are effectively *not* being invoked using the
cgi protocol.  

I will make another attempt to get the mod_php stuff working on my system. 


comment:13 by fwarmerdam, 17 years ago

Milestone: 5.0 release
Severity: normalenhancement
I have confirmed that loadparams() uses getenv(), and that this does not 
return the desired cgi variables in a mod_php environment.  Presumably this 
would also be the case in a mod_python, or other non-cgi web environment. 

The work around is to parse the url parameters and populate the request
object "manually" in the calling script.   

We should consider a better fix for this for MapServer 5.0 - perhaps a
loadparams() that takes in the url and other required information as
arguments. 
 
I have updated the WxS howto to briefly address this issue, and summarized
back to the mailing list. 


comment:14 by mapserver@…, 17 years ago

Cc: mapserver@… added

comment:15 by ben.tuttle@…, 17 years ago

After some more use of the WxS mapscript with mod_php we have found that apache
crashes intermittently. We suspect this may be due to some of the behaviors that
are based on a cgi environment rather than a mod_php environment. Basically
every so often (we haven't been able to determine an exact percentage yet) if
you make the same request over and over apache crashes. So you might have a
request succeed three times in a row, but that exact same request might fail the
fourth and fifth time you try it. Seems like this might be related. Any thoughts?

comment:16 by dmorissette, 17 years ago

Cc: dmorissette@… added
Ben, intermittent crashes after multiple requests in a mod_php environment could
be caused by all sorts of things. Unless you can get a debugger trace that shows
that it's crashing inside loadParam because of the use of getenv() then I think
this warrants a separate bug report with a testcase to reproduce if possible.
Unfortunately bugs in long-running Apache processes are really tough to
reproduce and debug... :(

comment:17 by dmorissette, 17 years ago

Description: modified (diff)

Note once again that intermittent crashes discussed in comment:15 and comment:16 are unrelated to the main issue in this ticket and would need a separate ticket with testcase to reproduce if it the crash still happens with the latest development version.

This ticket is about fixing loadParams() to work properly in a PHP environment as per Frank's comment:13 above.

comment:18 by warmerdam, 17 years ago

Description: modified (diff)
Milestone: 5.0 releaseFUTURE
Priority: highnormal

No plan to address this for 5.0. Assigning to "FUTURE" as an enhancement.

comment:19 by dmorissette, 14 years ago

Cc: dmorissette added
Milestone: FUTURE6.0 release
Owner: changed from warmerdam to aboudreault
Status: assignednew

Alan, please have a look at this if/when you have a chance.

comment:20 by aboudreault, 14 years ago

Fixed and committed in r9950.

I've modified the loadParams() function to allow us to pass a function pointer in argument to replace the traditionnal getenv calls. This way, we can pass another function that will return the proper value for the environment variables. We can also pass the post data and its length directly. I guess a function like owsrequest_getenv could be done for the mod_python.

comment:21 by dmorissette, 14 years ago

Can we mark this ticket fixed? If not then what is left to do?

comment:22 by aboudreault, 14 years ago

Resolution: fixed
Status: newclosed

We can close it. It's only fixed for php though.

Note: See TracTickets for help on using tickets.