Search code examples
phphttp-status-code-400

HTTP/1.1 400 Bad Request between an AWS server to another AWS server but HTTP/1.1 200 between my local server and the same AWS server


Reference

PHP App1 AWS instances

AWSApp1Live (64bit Amazon Linux 2015.03 v1.4.6 running PHP 5.5)

AWSApp1Test (64bit Amazon Linux 2015.03 v1.3.2 running PHP 5.6)

PHP App2 AWS instances

AWSApp2Live (64bit Amazon Linux 2016.09 v2.3.2 running PHP 5.6)

AWSApp2Test (64bit Amazon Linux 2015.09 v2.0.4 running PHP 5.5)

Local App1 instance

LocalApp1 (Windows 10 running XAMPP Control Panel v3.2.1)


Overview

I have two PHP applications: PHP App1 and PHP App2 which work together by communicating with eachother using internal POST requests. PHP App1 sends a request using

$query = http_build_query($data);
$context = stream_context_create(array(
    'http' => array(
        'method' => 'POST',
        'header' => 'Content-Type: application/x-www-form-urlencoded' . PHP_EOL .
        'Cv-Forwarded-For: ' . $_SERVER["REMOTE_ADDR"] . PHP_EOL,
        'content' => $query,
    ),
    'ssl'=>array(
        'verify_peer'=>false,
        'verify_peer_name'=>false
    )
));

$response = @file_get_contents(
    $target = $this->api_target.$action,
    $use_include_path = false,
    $context
);

PHP App2 is running a RESTful API service which responds to the requests sent from PHP App1. The response is a JSON string.


Problem

I have loaded these PHP applications onto four different AWS instances as mentioned above. The following combinations of request/respone

AWSApp1Live communicating with AWSApp2Live

(HTTP/1.1 400 Bad Request)

AWSApp1Test communicating with AWSApp2Live

(HTTP/1.1 400 Bad Request)

AWSApp1Test communicating with AWSApp2Test

(HTTP/1.1 200 OK)

LocalApp1 communicating with AWSApp2Live

(HTTP/1.1 200 OK)

So as you can see, PHP App2 when loaded onto AWSApp2Test and sent a request from AWSApp1Test, it responds with (HTTP/1.1 200 OK). But when loaded onto AWSApp2Live and given the same request from either AWSApp1Live or AWSApp1Test it responds with (HTTP/1.1 400 Bad Request). The only time AWSApp2Live responds with (HTTP/1.1 200 OK) is when the request was sent from LocalApp1.


Attempts to fix so far

  1. We thought there might be something to do with the Zlib output compression setting on the AWSApp2Live software configuration, but the response was still the same.

  2. We've done an nslookup from the LocalApp1 server and the AWSApp2Test server for the AWSApp2Live server and both of them returned the same IP addresses to rule out any DNS issues

  3. We SSH'd into the AWSApp1Test server and did a wget for one of the API commands on the AWSApp2Live server and we got back a JSON response which meant it is reaching the PHP application on that server.

  4. There are no logs being generated on the AwsApp2Live server for me to see why the server is treating some requests as bad requests and others as not.

  5. Using Postman (https://www.getpostman.com/) I was able to successfully communicate with the API on AWSApp2Live so the application is running as expected.


Any help would be greatly appreciated!

We are not sure where to look for any further clues as to what might be happening. If you need any further information please let us know. Thank you so much.


Solution

  • There's nothing in the documentation, but I think headers should be passed as a string only if there's a single one of them. Otherwise use an array:

    $context = stream_context_create(array(
        'http' => array(
            'method' => 'POST',
            'header' => array(
                'Content-Type: application/x-www-form-urlencoded',
                'Cv-Forwarded-For: ' . $_SERVER["REMOTE_ADDR"]
            ),
            'content' => $query,
        ),
        'ssl'=>array(
            'verify_peer'=>false,
            'verify_peer_name'=>false
        )
    ));