Apache returns 404 when trying to load file with AJAX or Flash

Firstly, if you are not using SSL for all your sites, you should step it up! NameCheap's SSL certificates start at only $9. There's no excuse!
Firstly, if you have not tried Digital Ocean's SSD Virtual Servers for only $5/mo, I highly recommend them!

If an Apache instance is really locked down, mod_security will deny requests if the request’s content-type is “weird”. The first time you come across this you’ll be baffled because Apache returns a 404 Not Found instead of something like a 401 or 403 Forbidden. Then you’ll open the offending file in a browser and it will load just fine. I came across this problem with Drupal and WordPress. In Drupal, I was making AMF calls and Apache didn’t like that my request content-type was application/x-amf. In WordPress, it was wp-admin/admin-ajax.php that pissed it off.

If you can AllowOverride in Apache, just put this in an .htaccess file to loosen up the security. (Actually, this completely unties it)

<IfModule mod_security.c>
    SecFilterInheritance Off
</IfModule>

If not, you need to edit your Apache conf to allow the needed content-type. Something like this:

SecFilterSelective HTTP_Content-Type "!(^$|^application/x-www-form-urlencoded$|^application/x-amf)"

I have a php script to prove your server has this issue. This is useful when trying to convince stubborn sys admin the 404 is his problem. View it after the jump…

<?php
$url= 'http://'.$_SERVER['SERVER_NAME'];

$ch = curl_init( $url );
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_POST, true);

curl_setopt($ch, CURLOPT_HTTPHEADER, array( 'Content-Type: application/x-www-form-urlencoded' ));
$response1 = curl_exec($ch);   

curl_setopt($ch, CURLOPT_HTTPHEADER, array( 'Content-Type: application/xml' ));
$response2 = curl_exec($ch);
?>
<html>
	<head>
		<style>
            * { font-family: arial;	font-size: 11px;}
            textarea { width:100%; height: 600px; }
            table { width:100%; }
            td { width:45%; }
        </style>
	</head>
	<body>
		<table><tr><td>
			POST to <b><?php echo $url; ?></b> with Content-Type: application/x-www-form-urlencoded<br/>
			<textarea><?php echo $response1;?></textarea>
		</td><td>
			POST to <b><?php echo $url; ?></b> with Content-Type: application/xml<br/>
			<textarea><?php echo $response2;?></textarea>
		</tr></table>
	</body>
</html>

About this entry


Good Reads