I have code which validates whether a URL is OK, starting with get_headers() with a variety of user agents and then trying CURL. If I try:
get_headers('https://www.ticketmaster.com/');
This hangs for a long time and then returns false.
The equivalent CURL call behaves similarly.
If I open a Mac terminal window and try:
wget('https://www.ticketmaster.com');
It says it's connected to www.ticketmaster.com, but hangs while awaiting the response and eventually times out.
The URL works fine in a browser (obviously), and it's also considered OK by SSL Checker.
Any ideas for what Ticketmaster are doing weirdly, and how to check for it?
Related
Inside a Slave site I have a script that performs a cURL request vs a server of mine (Master).
Locally, I have installed those two sites and I'd wish to debug what happens on Master when Slave tries to connect it.
Ideally, the perfect solution would be to attach my own request to PHPStorm debugger, so I can actually see what's going on.
I tried to start the debug, but then PHPStorm attaches to the calling script, and not the receiving site.
Do you have any suggestions on how can I actually debug it, without the need to rely on the good old var_dump();die();?
Well, in the end of the day, PHPStorm relies on a cookie to attach to the incoming request.
By default, such cookie has the following value: XDEBUG_SESSION=PHPSTORM.
This means that you simply have to add the following line to your code:
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Cookie: XDEBUG_SESSION=PHPSTORM"));
and PHPStorm will "see" the incoming request, allowing you to debug it.
Additional Tip
The previous trick works everywhere!
If you are trying to debug a cURL request from command line, once again you simply have to pass the cookie param and PHPStorm will attach to the request:
--cookie "XDEBUG_SESSION=PHPSTORM"
I have written a script in PHP whose purpose is simply to query a DB and then send an email with the results.
I can invoke the script with a browser by simply requesting the URL with the query string, e.g. typing into the address bar
http://localhost/myapp/index.php?model=manage&view=main
This invokes the script and everything works fine.
note: some HTML is produced by the script - which is caused by the fact my script is hooking into a larger application.
When I try to invoke the script from the bash command line with:
curl http://localhost/myapp/index.php?model=manage&view=main
curl displays the HTML that is generated by the script, but the curl process doesnt complete - I have to ctrl + c out of the curl process and also script is not processed properly and the email is not sent
apache access log output
it seems Apache is truncating the 2nd variable in the query string
127.0.0.1 - - [08/Apr/2015:01:28:47 +1200] "GET /myapp/index.php?model=manage HTTP/1.1" 200 23549 "-" "curl/7.35.0"
You need to escape the & character e.g by putting the URL in double quotes as in:
curl "http://localhost/myapp/index.php?model=manage&view=main"
that will preserve the second query parameter.
The way I solved this was to request the URL in chrome with dev tools open.
I watched for the request in the network tab, then right-clicked the request and selected the "save as curl option".
I then pasted the (long) curl command into the terminal - which contained the options and parameters necessary to get the curl request to work.
if i call a php file via jquery ajax, that contains a script to do some stuff that takes a while — for instance uploading a big video — and then I close the page: does the php script keep loading the video or not?
See here:
http://php.net/manual/en/function.ignore-user-abort.php
int ignore_user_abort ([ bool $value ] )
Sets whether a client disconnect should cause a script to be aborted.
When running PHP as a command line script, and the script's tty goes away without the script being terminated then the script will die the next time it tries to write anything, unless value is set to TRUE
There also is a PHP configuration option of the same name:
http://php.net/manual/en/misc.configuration.php
By default, if you do nothing, according to the PHP manual the default is to abort the script.
http://php.net/manual/en/features.connection-handling.php
NECESSARY UPDATE
It seems I (unknowingly) tricked my way to "reputation points", because I did NOT supply the (correct) answer, but here it is now thanks to testing and continued nudging from "mellamokb":
Quote:
"Ok, I took a look at the PHP source code and, if I didn't miss anything, I now have the answer. The "ignore_user_abort" flag is only checked when PHP receive an error trying to output something to the user. So, in my understanding, there is no way to interrupt code which doesn't produce any output."
Okay, I wasn't totally off, but it is important to know that it all depends on whether or not your script produced any output!
If you read THIS, also DO check out the comments below.
A PHP Script running through a web server will not stop until:
someone kill the server
the server kill the php scrip
When the user abort the script, PHP will continue until it try to send something back to the browser.
For example still script will continue fore ever even if the user abort:
while(true){
echo 'go'.PHP_EOL;
}
It will go on forever because the "echo", will write into the buffer, and the buffer will not be sent to the browser until the script finish, which will never happen.
The following script will stop as soon as the user abort:
while(true){
echo 'go'.PHP_EOL;
flush();
ob_flush();
}
This script will stop, because flush() and ob_flush() will force PHP to send its buffer to the browser, which will stop the PHP script if the user has aborted.
The function ignore-user-abort() will force PHP to ignore the abort in this case.
Moreover if you are using PHP session, they are another tricky situation.
For example, if you are doing AJAX, and you actually send two AJAX request to a PHP script and that PHP script has need of session with session_start().
The first AJAX query will work normally, however the second one will have to wait until the first call is finish, because the first script has a locked on the session.
The first script could eventually prematurely release the session with session_write_close();
By default no. See Connection Handling documentation, especially:
You can decide whether or not you want
a client disconnect to cause your
script to be aborted. Sometimes it is
handy to always have your scripts run
to completion even if there is no
remote browser receiving the output.
The default behaviour is however for
your script to be aborted when the
remote client disconnects.
The script will run the time set by max_execution_time (default is 30s)
Warning This function has no effect when PHP is running in safe mode.
There is no workaround other than turning off safe mode or changing
the time limit in the php.ini.
Note: The set_time_limit() function and
the configuration directive max_execution_time only affect the
execution time of the script itself. Any time spent on activity that
happens outside the execution of the script such as system calls using
system(), stream operations, database queries, etc. is not included
when determining the maximum time that the script has been running.
This is not true on Windows where the measured time is real.
quote from http://php.net/manual/en/function.set-time-limit.php
you can test this by running
<?php
unlink('cocorico.txt');
while(true){
file_put_contents('cocorico.txt', microtime(true).PHP_EOL, FILE_APPEND);
}
and it will stop after 30s (despite you close your browser or not)
you can get you default exec time by echo ini_get('max_execution_time'); and can be set like set_time_limit(3);
The answer marked as accepted is only correct about the ignore_user_abort but don't panic that your "fail" scripts will run forever if you don't set max exec time to 0 - unlimited;
From my little understanding of how these stuff works. By the point of view of the HTTP protocol I would say yes, the script would keep running, because the browser just sends a request to the server asking for the page, then the server starts executing the script and does not sends or receives information from the browser untill the script is done loading and producing the html output, and just then the server sends the resulting output to the browser and has done the job.
See, there is no way for a browser to "tell" the server that the user is not viewing the page anymore through the HTTP protocol. However, the HTTP protocol runs on top of the TCP connection through stream sockets, the TCP connection is kept alive till one of the ends choses to abort the connection (or a certain timeout is reached), now I really don't know how the browser handles this. The browser could just open a connection, send a request and close the connection, then the server waits for the script and sends the response on another connection. Or the browser could open a connection, KEEP this connection alive till the server responds on the same connection. If the thing works that way then the server would really have a way to know if the user is not viewing the page anymore simply by checking if the connection is still alive or has been shutdown by the client. So that would be a no.
Dunno much about that tho.
I am trying to track down an issue with a cURL call in PHP. It works fine in our test environment, but not in our production environment. When I try to execute the cURL function, it just hangs and never ever responds. I have tried making a cURL connection from the command line and the same thing happens.
I'm wondering if cURL logs what is happening somewhere, because I can't figure out what is happening during the time the command is churning and churning. Does anyone know if there is a log that tracks what is happening there?
I think it is connectivity issues, but our IT guy insists I should be able to access it without a problem. Any ideas? I'm running CentOS and PHP 5.1.
Updates: Using verbose mode, I've gotten an error 28 "Connect() Timed Out". I tried extending the timeout to 100 seconds, and limiting the max-redirs to 5, no change. I tried pinging the box, and also got a timeout. So I'm going to present this back to IT and see if they will look at it again. Thanks for all the help, hopefully I'll be back in a half-hour with news that it was their problem.
Update 2: Turns out my box was resolving the server name with the external IP address. When IT gave me the internal IP address and I replaced it in the cURL call, everything worked great. Thanks for all the help everybody.
In your php, you can set the CURLOPT_VERBOSE variable:
curl_setopt($curl, CURLOPT_VERBOSE, TRUE);
This then logs to STDERR, or to the file specified using CURLOPT_STDERR (which takes a file pointer):
curl_setopt($curl, CURLOPT_STDERR, $fp);
From the command line, you can use the following switches:
--verbose to report more info to the command line
--trace <file> or --trace-ascii <file> to trace to a file
You can use --trace-time to prepend time stamps to verbose/file outputs
You can also use curl_getinfo() to get information about your specific transfer.
http://in.php.net/manual/en/function.curl-getinfo.php
Have you tried setting CURLOPT_MAXREDIRS? I've found that sometimes there will be an 'infinite' redirect loop for some websites that a normal browser user doesn't see.
If at all possible, try sudo ing as the user PHP runs under (possibly the one Apache runs under).
The curl problem could have various reasons that require a user input, for example an untrusted certificate that is stored in the trusted certificates cache of the root user, but not the PHP one. In that case, the command would be waiting for an input that never happens.
Update: This applies only if you run curl externally using exec - maybe it doesn't apply.
I have a PHP script that calls a .bat file using system(). The output is written to the screen and I derive some values from parsing this output. This is running on windows 2003 IIS server. PHP v5.2.0
Specifically I am using this script to launch an Amazon EC2 instance and assign an IP address to it. It has worked great for me so far but recently the problem started.
Here is the code
$resultBatTemp = system("cmd /C C:\Inetpub\ec2\my_batch_file_to_launch_instance.bat");
$resultBat = (string)$resultBatTemp;
$instanceId = substr($resultBat, 9, 10);
...
Once I have this instace Id I can run another batch file that calls associates an ip address with this instance. It would appear that the instance does get launched but I never get the output on the screen.
For some reason this has all stopped working, the page freezes and never refreshes. I also need to completely exit safari or mozilla otherwise all pages from the website fail to load. Only when I relaunch the browser can i view the website again. I've connected to the webserver that hosts these scripts and checked PHP error log but nothing shows there. I've opened a DOS prompt and entered the code from the bat file that way and it connects to amazon and launches the instance fine. Ive isolated this bit of code and removed the system command and the rest of the script runs fine, so it appears that the hold up is with outputting the results of the bat file.
Recently I have purchased a new domain name for the site so this script is running from this domain. Might this cause the problem?
thanks
------------------------------------------------UPDATE-----------------------------------------------
Well hope this helps someone, I didnt find out what was wrong but created a new PHP file with a simple system command that called a .bat file, and a non-existent .bat file expecting to get an error back but nothing - just the usual hang for ages. So I restarted IIS and this fixed the problem. Dont know what was wrong but that did the trick.
Maybe first check what the system() call returns. According to documentation it will return FALSE in case of failure. Also, including your my_batch_file_to_launch_instance.bat in the question might help in solving it.
Try using the passthru function
Also make sure that all your commands are safe use escapeshellarg() or escapeshellcmd() to ensure that users cannot trick the system into executing arbitrary commands.