4

I have a curl put request that works fine on my localhost but on the live server it throws back a 500 error. Here is my code:

public static function send( $xml )
{
    $xml = str_replace( "\n", "", $xml );

    //Write to temporary file
    $put_data = tmpfile();
    fwrite( $put_data, $xml );  
    fseek( $put_data, 0 );

    $options = array(
            CURLOPT_URL => 'http://*****************/cgi-bin/commctrl.pl?SessionId=' . Xml_helper::generate_session_id() . '&SystemId=live',
            CURLOPT_RETURNTRANSFER => 1,
            CURLOPT_HTTPHEADER => array( 'Content-type: text/xml' ),
            CURLOPT_PUT => TRUE,
                CURLOPT_INFILE => $put_data,
            CURLOPT_INFILESIZE => strlen( $xml )
        );

        $curl = curl_init();
        curl_setopt_array( $curl, $options );
        $result = curl_exec( $curl );
        curl_close( $curl );

        return $result;
    }

I do have curl enabled on the server!

Does anyone have any ideas why it is not working on the server? I am on shared hosting if that helps.

I also have enabled error reporting at the top of the file but no errors show after the curl has completed. I just get the generic 500 error page.

Thanks

UPDATE:

I have been in contact with the client and they have confirmed that the information that is sent is received by them and inserted into their back office system. So it must be something to do with the response that is the cause. It is a small block of xml that is suppose to be returned.

ANOTHER UPDATE

I have tried the same script on a different server and heroku and I still get the same result.

ANOTHER UPDATE

I think I may have found the route of the issue. The script seems to be timing out because of a timeout on FastCGI and because I am on shared hosting I can not change it. Can any one confirm this?

FINAL UPDATE

I got in contact with my hosting provider and they confirmed that the script was timing out due to the timeout value on the server not the one I can access with any PHP function or ini_set().

David Jones
  • 4,275
  • 6
  • 27
  • 51
  • 3
    The error 500 is generated on the server, here `http://************/cgi-bin/commctrl.pl?SessionId=...`, it is not generated by curl. What you need to do is to look at the error log on your distant host, not on the one running the curl script. – Lorenz Meyer Nov 18 '13 at 16:56
  • Thanks for the feedback, how comes it works on my localhost though? Wouldn't it return a 500 error no matter where I access it from??? – David Jones Nov 18 '13 at 17:00
  • Does your non-local server have curl lib installed? – Artur Nov 18 '13 at 17:03
  • Yes it does, I mentioned that in the post – David Jones Nov 18 '13 at 17:05
  • you have die( $result ); before return $result; – Aris Nov 18 '13 at 17:52
  • Yes I am trying to view what the curl request returns – David Jones Nov 18 '13 at 17:56
  • so, you're saying that when you run this script from your local machine, it works, but when you run it from another, you get the 500 error. It is the same script? You are not trying to access a different URL? – Benubird Dec 05 '13 at 10:42
  • Yes on my localhost it works fine, but when I try the exact same code from our server I get a 500 error. No the same URL as well. – David Jones Dec 05 '13 at 11:57
  • So are you sure now that there's nothing you can do with your script to solve this? – brandonscript Dec 10 '13 at 00:35
  • Yes that is correct, the issue was due to the shared server timeout limit and the API that was taking too long to respond. – David Jones Dec 10 '13 at 09:01
  • The local configuration (php version etc..) and the remote are the same? –  Dec 10 '13 at 22:58
  • Have you considered switching providers? There are piles out there that if you need to do what you're doing might provide an alternative. If not, good luck! – brandonscript Dec 11 '13 at 16:13

5 Answers5

6

If the error is, like you think it is, to do with a script timeout and you do not have access to the php.ini file - there is an easy fix

simply use set_time_limit(INT) where INT is the number of seconds, at the beginning of your script to override the settings in the php.ini file

Setting a timeout of set_time_limit(128) should solve all your problems and is generally accepted as a reasonable upper limit

More info can be found here http://php.net/manual/en/function.set-time-limit.php

Dan Green-Leipciger
  • 3,776
  • 1
  • 19
  • 29
  • Hi, I have tried that and it did not work. I got in contact with my hosting provider and they confirmed that the script was timing out due to the timeout value on the server not the one I can access with any PHP function or ini_set(). Thanks anyway. – David Jones Dec 09 '13 at 17:39
  • So does that mean there is nothing you can do? – Dan Green-Leipciger Dec 09 '13 at 17:58
  • Yep, we need to move the site to our dedicated server as the API we are accessing is extremely slow. It takes 49 seconds to get a response and the max execution time is 30 on our shared hosting. – David Jones Dec 09 '13 at 18:00
  • Sucks, what a waste of 250 rep points. At least you got it figured out – Dan Green-Leipciger Dec 09 '13 at 18:16
3

Here are a few things to try:

  1. Remove the variability in the script - for testing, hardcode the session id, so that the curl curl is the same. You cannot reliably test something, if it changes each time you run it.

  2. Try using curl directly from the command line, via something like curl http://*****************/cgi-bin/commctrl.pl?SessionId=12345&SystemId=live. This will show you if the problem is really due to the computer itself, or something to do with PHP.

  3. Check the logs on your server, probably something like /var/log/apache/error.log depending on what OS your server uses. Also look at the access log, so that you can see whether you are actually receiving the same request.

  4. Finally, if you really run out of ideas, you can use a program like wireshark or tcpdump/WinDump to monitor the connection, so that you can compare the packets being sent from each computer. This will give you an idea of how they are different - are they being mangled by a firewall? Is php adding extra headers to one of them? Are different CURL defaults causing different data to be included?

Benubird
  • 18,551
  • 27
  • 90
  • 141
  • 1. The session ID needs to change for each request. Although I did try a few times with it hardcoded and they all failed. 2. I tried this and it returned the expected response. Does this mean the server is the issue? 3. The error log and the access log does not show anything to help us. 4. I have installed wireshark, nice tool tbh. I have checked the response when sending requests from my localhost and they are exected what I expect. Am i able to see what comes back from the server we are having issues on?? – David Jones Dec 05 '13 at 12:11
  • 1. If the session needs to change with each request, then maybe the problem is that the session id it generates is wrong? 2. If the command line curl works and the php doesn't, then the problem is with the php code; if the command line doesn't work either, then the problem is with the connection between computers. 4. Yes, Wireshark should show packets sent and received, it just can be confusing to configure. – Benubird Dec 06 '13 at 13:04
1

I suspect your server does not support tmpfile(). Just to verify:

public static function send( $xml ) {
$xml = str_replace( "\n", "", $xml );

//Write to temporary file
$put_data = tmpfile();
if (!$put_data) die('tmpfile failed');
...

If you are on GoDaddy server check this out... https://stackoverflow.com/questions/9957397/tmpfile-returns-false-on-godaddy-server

Community
  • 1
  • 1
Amit Kriplani
  • 682
  • 5
  • 12
0

Which server is actually showing the 500 ? from your code it seems the local server rather than the remote. change

public static function send( $xml )
{

to

public static function send( $xml )
{
    error_reporting(E_ALL);
    if(!function_exists('curl_exec')) {
        var_dump("NO CURL");
        return false;
     }

does that work ?

exussum
  • 18,275
  • 8
  • 32
  • 65
  • For a start you are missing a semi colon on the var_dump and I said that curl is enabled in the post. Thanks. – David Jones Dec 05 '13 at 11:28
  • Yeh the one for our server doesn't indicate a error occurred when submitting data – David Jones Dec 05 '13 at 11:57
  • does the error reporting show any more ? From the code you have posted your never getting the status code from there server. Just the outpu. Is there an error processing the xml ? – exussum Dec 05 '13 at 12:06
  • No it is the execution of curl that triggers the 500 error. If I remove the curl_exec() call the script works fine. I have error reporting on but it still shows the generic 500 internal error page. – David Jones Dec 05 '13 at 12:13
  • It really sounds like curl exec isnt allowed for some reason. Is `php5-curl` installed ? is ``curl_exec` in the `disable_functions` list ? Can you post a php info page ? – exussum Dec 05 '13 at 12:18
  • also commenting the ` $result = curl_exec( $curl );` wouldnt rule out a processing error – exussum Dec 05 '13 at 12:19
  • It must be because the data sent is received by the clients back office system, and there is no mention of php5-curl in the phpinfo. – David Jones Dec 05 '13 at 12:28
  • Add error_reporting to show all errors, and make sure what ever functuions you need for processing are there. Or just skip processing to be sure – exussum Dec 05 '13 at 12:34
  • I have error reporting enabled at the top of the file but no errors show. I just get the generic 500 error page. – David Jones Dec 05 '13 at 12:51
  • That means there is a syntax errror unless something else it making that page. PHP versions match ? – exussum Dec 05 '13 at 12:59
  • No there isnt a syntax error, its the curl execution that makes the page error – David Jones Dec 05 '13 at 13:20
  • curl will either execute, return false or throw a function not found. Your saying its executing due to the other end getting the info. The only one of the options which will cause an error is the function not found .... – exussum Dec 05 '13 at 13:23
  • But the function is there because if I try and get the google home page it works fine. – David Jones Dec 05 '13 at 14:53
  • var_dump($result), then change function to just return what $return contains – exussum Dec 05 '13 at 14:57
  • The point I am trying to make is the function curl_exec() is causing the 500 error. So there is no $result to dump because the script breaks. – David Jones Dec 05 '13 at 15:04
  • The point i was making is it doesnt die with no trace. curl exec will never causea script to break. – exussum Dec 05 '13 at 15:21
  • This is part of my confusion because there is no reason, with my code and no apparent reason with my server that the code should break. Do you think it could be a issue with the service I am communicating with? – David Jones Dec 05 '13 at 15:32
  • There will be a logged reason somewhere. What OS is the server ? Is there any way i can replicate the issue ? are the PHP versions the same ? – exussum Dec 05 '13 at 15:38
  • We are on a Linux server and the PHP versions are both 5.2. No sorry, my client would not let me give details of their API out. – David Jones Dec 06 '13 at 09:22
  • can you run the php file from the command line with php filename.php if so do `strace php filename.php ` and see if anything pops up – exussum Dec 06 '13 at 11:36
0

This is almost certainly NOT the php timeout setting. If you are using FastCGI as you have stated then you need to edit this file:

/etc/httpd/conf.d/fcgid.conf

And change:

FcgidIOTimeout 3600

Then do:

service httpd restart

This was driving me insane for 3 days. The top voted answer to this is wrong!

wbinky
  • 160
  • 1
  • 11
  • Yes I know its not the PHP timeout setting, it was established somewhere in the comments. I solved it by putting it on a dedicated server where I am able to change the settings. – David Jones Jan 05 '14 at 16:55