views:

388

answers:

7

I have some Ajax that has been working on a live site, now it has stopped working. The Ajax should be returning a page but is returning a 500 error (internal server error).

The strange thing is I can navigate and post to the page the Ajax is calling, so the page is only not working via an Ajax call ($.post).

Another strange thing is it is working fine locally, but not live. Also all the other Ajax on the site is working.

Anyone have the foggiest what this might be? By the way it's all jQuery with CakePHP.

Edit:

The apache error logs are saying: "Premature end of script headers: php-script, referer..."

Edit 2:

It all happened when I switched the server over to SSL. It says above error and then "Port 80".

+4  A: 

Check your apache and php error logs! it will be in there


The most common cause of this problem is the script dying before sending the complete set of headers, or possibly any at all, to the server. To see if this is the case, try running the script standalone from an interactive session, rather than as a script under the server. If you get error messages, this is almost certainly the cause of the "premature end of script headers" message. Even if the CGI runs fine from the command line, remember that the environment and permissions may be different when running under the web server. The CGI can only access resources allowed for the User and Group specified in your Apache configuration. In addition, the environment will not be the same as the one provided on the command line, but it can be adjusted using the directives provided by mod_env.

The second most common cause of this (aside from people not outputting the required headers at all) is a result of an interaction with Perl's output buffering. To make Perl flush its buffers after each output statement, insert the following statements around the print or write statements that send your HTTP headers:

{
    local ($oldbar) = $|;
    $cfh = select (STDOUT);
    $| = 1;
    #
    # print your HTTP headers here
    #
    $| = $oldbar;
    select ($cfh);
}

This is generally only necessary when you are calling external programs from your script that send output to stdout, or if there will be a long delay between the time the headers are sent and the actual content starts being emitted. To maximize performance, you should turn buffer-flushing back off (with $| = 0 or the equivalent) after the statements that send the headers, as displayed above.

If your script isn't written in Perl, do the equivalent thing for whatever language you are using (e.g., for C, call fflush() after writing the headers).

Another cause for the "premature end of script headers" message are the RLimitCPU and RLimitMEM directives. You may get the message if the CGI script was killed due to a resource limit.

In addition, a configuration problem in suEXEC, mod_perl, or another third party module can often interfere with the execution of your CGI and cause the "premature end of script headers" message.


CPHP:

RobertPitt
yeah.. didn't think of the apache log, it's says...Premature end of script headers: php-script, referer
Smickie
Updated with some information that may help you resolve it!
RobertPitt
The premature end of script headers, or probably in your case no header at all, can be caused by the same origin policy I noted below.
dacracot
A: 

You can use Fidler to examine what the server returned during that $.post. It will contain the webpage which would've been returned if you were to run that same method directly in your browser.

Marko
This is irrelivent as the error is being caused by the internal server, CakePHP
RobertPitt
Yes but he can at least investigate the error page
Marko
@RobertPitt - what a ridiculous thing to say. The OP has said "so the page is only not working via an Ajax call" - you don't think it is worth examining exactly what is being sent by the Ajax call, and comparing it to what you expect it to send?
Rob Levine
The OP said "500 error (internal server error)." he already knows what the page is returning. not a 404 so it cant be the URI, its an Internal error witch means jsFiddle would not help in the matter
RobertPitt
But intercepting with Fiddler set to middle-man the HTTPS can give a view on the error page, which would indeed have been useful, and given the same information that was found by searching the server logs.
Jon Hanna
A: 

This error is a bit of a problematic one because it can be caused by so many things.

What is your page doing...? Here are some suggestions.

If your page is like an auto-complete page, so you pass a bit of information and get a filtered list of results back... Maybe your AJAX script isn't passing back the data item and your page is trying to return everything. Really bulky PHP scripts (i.e. intensive / recursive operations) can cause this error.

The normal advice for dealing with this particular error is to strip back to a stable page and then start adding stuff back in - so perhaps point your AJAX script at a page that has this...

<?php
    echo 'If this appears, we\'re stable!';
?>

Then gradually add in blocks of your code until you hit a problem. My suggested version 2 of this page would be...

<?php
    print_r($_POST);
?>

As this will allow you to check what is coming back in the form post.

Failing all of the above, please supply the following...

1) A description of what your PHP page does, or maybe an example of the code. 2) The JavaScript code that calls the PHP page.

Sohnee
A: 

Perhaps the production site violates the same origin policy.

The URL in the browser up to the third slash, must match exactly the URL in your AJAX POST, else the browsers security constraints for Javascript will refuse the response. The server may actually see the request and respond correctly, but the browser hands an empty string back to the AJAX call.

dacracot
I don't think that this is the problem. The `XMLHttpRequest` `send` method would simply fail if the requested URL was not to the "same origin" of the current document.
Daniel Trebbien
I have witnessed XMLHttpRequest returning a readyState of 4 (loaded) and then a status of 0 (undefined) with no headers or payload given a same origin violation. You would think it would fail and give a 400 or 500 level status, but it does not.
dacracot
+5  A: 

First off, this has nothing to do with jQuery, AJAX, POST, CakePHP, or HTTP headers. The complete error message is "Premature end of script", which means that the PHP process that Apache is using to run the PHP script terminated unexpectedly (i.e., before the PHP process finished its part of the Fast CGI protocol). This generally means that the PHP process crashed or caused a "segmentation fault".

PHP segmentation faults can be difficult to troubleshoot, and they should never happen; PHP should never crash. The reason why it is crashing could be due to a number of things. Maybe it is a simple fix, though.

The first thing that I would do is completely uninstall PHP and install the latest stable version. If you are running PHP 5.3 and Windows, then you should only use the VC6 binaries (the "VC6 x86 Thread Safe" package); the VC9 package will cause PHP to crash when used by Apache. Reinstalling might fix your problem because extension DLLs/SOs of older releases of PHP might still exist in your extensions directory on the live server.

If on Windows and using MySQL, the next thing that I would do is make sure that the MySQL bin directory is in the live server's Path. The reason for doing this is to make sure that libmySQL.dll can be "found" by the OS. You should be able to SSH into the live server, type mysql --help, and see the MySQL CLI client's usage message. Restart Apache if you add the MySQL bin directory to Path.

If both of these suggestions do not solve the problem, then please update your question with answers to the following:

  1. Are you using a web host or does a company IT team manage a server for your use?
  2. If using a web host, are you leasing a dedicated server?
  3. What operating system are you running?
  4. What version of PHP are you using?
  5. What PHP extensions are being loaded?
  6. Do you load a Zend extension?
  7. Do you ever use dl?
Daniel Trebbien
A: 

I'd like to throw my 2 cents in, but it comes from a slightly different direction and you may or may not have direct resources for troubleshooting - but it's worth thinking about.

Generally speaking, though, it is a PHP error and we can rule out client side issues. On top of that, in my day job (network troubleshooting), If something is working and then stops, I immediately think "what changed". If you didn't add anything to the script and there's no way for a user to affect the script at runtime, then I would immediately start thinking "uh-oh, what's up with the infrastructure". This is especially true if something works locally, but not over the internet.

Have you checked for bad memory on the server or bad NICs (if bad NICs, that would explain why it works one one interface and not another). Do you have access to this or is it hosted (can your host check)?

Next I would start thinking, ok, server memory's fine and it's not likely faulty NIC related otherwise it would fail sporatically and at different places. Still could be networking, though. Is there a security device that can mangle packets anywhere in the mix (NIDS/HIDS, WAF, proxy, etc?) Do you see any network problems with packets (duplicates, out of order, Do Not Fragment, etc...).

I'll be honest, if someone called my desk and described your issues to me, first thing I would say is "check the IPS logs" about 85% that's the issue. False positives can do this and all it takes is one auto update on the firewall...

I hope that helps.

Tim
+1  A: 

Taken from http://henrik.nyh.se/2007/04/premature-end-of-script-headers-for-cgi-can-be-directory-permissions

Other than the reasons outlined in the Apache FAQ, the error log message "Premature end of script headers" for a CGI script (in my case a Ruby script on Dreamhost) can also mean that the directory containing the script is world-writable.

So folder permissions like drwxr-xrwx can cause this error. chmod 755 mydir would change those permissions to drwxr-xr-x and all is well.

I suppose Apache/suEXEC takes issue with running stuff that any evil user can edit.

Is worth checking the directory permissions.

On a separate note, you say that the issue occurred when changing the site to use SSL, however the error mentions port 80. Port 80 is used for standard HTTP traffic however port 443 is used for SSL traffic - if traffic is going via port 80 there could be a server misconfiguration, an HTTP where there should be an HTTPS, or an issue with your certificate. I have seen similar errors occur when a certificate expires. Are both the URLs (the calling page and the script) using SSL?

Macros