Php – HTTP POST request over SSL between 2 websites on the same server failing if more than 1kb of data is sent

PHPPROXYssl

NOTE: Although there's some PHP code below, I really believe this belongs to ServerFault more than StackOverflow, esentially, because this worked and it stopped working after we changed servers.

I have the following situation:

  • There's 2 public websites with different functionalities (UPDATE: both websites are on the same physical server). A user can fill up a huge signup form in Website A to get registered to website B.
  • When a user registers in Website A, I send an Ajax request to a PHP script in Website A to validate the data.
  • This script is esentially a proxy that sends all that data to Website B, and B responds with "OK", or with a bunch of validation errors. It only exists because I can't do cross-domain Ajax directly.
  • All these are HTTP POSTs over SSL

This was working beautifully, until we migrated our server, in the same hosting company, to a bigger one. They hosting people took care of all the migration, and the idea was that the new server would end up with the same configuration as the old one.

Now, after this migration, when the information submitted to the proxy, converted to an "HTTP POST string", takes more than 1024 bytes, the server-side request from Website A to B fails silently. It works, it executes all the lines of code, there are no errors, notices or exceptions that I can see. It just goes all the way to the end, as if website B had responded with an empty string.

If, however, the POST is less than 1024 bytes, it all works great, and I either get the correct validation errors, or "OK" back.

Sending the full POST to Website B directly, without the proxy, works correctly, so the problem is definitely on the proxy call.

I have no rationalization for this behaviour, this makes absolutely no sense to me.

Has any of you ever encountered something like this before?
Any pointers on where I could look?

For reference, this is the proxy code:


$CustomersValidateURL = "https://WebsiteB.com/validatescript";
echo do_post_request($CustomersValidateURL, http_build_query($_POST));

// =========================================================================
function do_post_request($url, $data, $optional_headers = null){

    $params = array('http' => array('method' => 'POST', 'content' => $data));

    if ($optional_headers !== null){
        $params['http']['header'] = $optional_headers;
    }

    $ctx = stream_context_create($params);
    $fp = @fopen($url, 'rb', false, $ctx);

    if (!$fp){
        throw new Exception("Problem with $url, $php_errormsg");
    }

    $response = @stream_get_contents($fp);

    if ($response === false) {
        throw new Exception("Problem reading data from $url, $php_errormsg");
    }

    return $response;
}

This is the result of running a tracepath from that server to "Website B", in the same server:

tracepath customers.xxx.com
 1:  server.xxx.com (208.92.xxx.xxx)      0.144ms pmtu 16436
 1:  server.xxx.com (208.92.xxx.xxx)      0.093ms reached
     Resume: pmtu 16436 hops 1 back 1

Best Answer

In the end, I ended up rewriting the script to use cURL instead. I don't know what happened, but cURL works. This is one of the weirdest things I've found...