简体   繁体   中英

HTTP request failed in PHP Bad Request

I can request a URL web service 'WS' directly from the browser, but when I use file_get_contents() or fopen methods in my code I get an error message. Does someone have a solution without using curl?

public function sendHttpRequest($data) {
   ini_set('user_agent', 'PHP');

    $context_options = array(
        'http' => array(
            'method' => 'POST',
            'header' => "Content-Type: application/x-www-form-urlencoded\r\n",
            'content' => json_encode($data)
        )
    );


    $context = stream_context_create($context_options);

    //line error "line 196"
    $result = file_get_contents($this->WS, false, $context);
}

Error message:

failed to open stream: HTTP request failed! HTTP/1.1 400 Bad Request in /mnt/hgfs/case/src/bat/abc/send-entry.php on line 196

NULL

i've changed the context options to this, but still getting the HTTP/1.1 400 Bad Request

$context_options = array(
        'http' => array(
            'method' => 'POST',
            'header' => "Date: " . gmdate("D, d M Y H:i:s T", time()) . "\r\n"
            . get_headers($this->WS)[2] . "\r\n"
            . " x-powered-by: PHP/" . phpversion() . "\r\n"
            . " " . get_headers($this->WS)[5] . "\r\n"
            . " Pragma: no-cache" . "\r\n"
            . " Content-Length: " . strlen($this->content) . "\r\n"
            . " Content-Type: text/xml" . "\r\n"
            . " " .get_headers($this->WS)[9] . "\r\n"
            . " Connection: close",
            'content' => $this->content
        )

var_dump(get_headers($this->WS))

the data is sent to a server with adress http://192.168.xxx.xxx/WS

here is a var_dump of the array to send

array(16) {
  ["method"]=>
  string(24) "WS"
  ["LOGIN"]=>
  string(12) "xxx"
  ["DATE1"]=>
  string(10) "1970-01-01"
  ["DATE2"]=>
  string(0) ""
  ["TRANSMISSION"]=>
  INT(8)
  ["REF"]=>
  int(206)
  ["FORMAT"]=>
  int(7)
  ["DOMAIN"]=>
  int(3)
  ["TYPE1"]=>
  int(15)
  ["TYPE2"]=>
  NULL
  ["NAME"]=>
  string(12) "JDOE"
  ["ADRESSE"]=>
  string(0) ""
  ["ADRESSE2"]=>
  string(0) ""
  ["ADRESSE3"]=>
  string(0) ""
  ["ADRESSE4"]=>
  string(0) ""
  ["REF2"]=>
  string(0) ""
}

here is the full message error

Warning: file_get_contents( http://192.168.xxx.xxx/WS ): failed to open stream: HTTP request failed! HTTP/1.1 400 Bad Request in /mnt/hgfs/case/src/bat/abc/send-entry.php on line 182

the working code:

    $context_options1 = array(
        'http' => array(
            'method' => 'POST',
            'header' => "Date: " . gmdate("D, d M Y H:i:s T", time())
            . "Accept: application/xml"
            . "Content-Type: application/xml"
            . "Content-Length: " . strlen($this->content),
            'content' => $this->content
        )
    );

A POST request needs a Content-Length header:

$content = json_encode($data);
$context_options = array(
        'http' => array(
            'method' => 'POST',
            'header' => "Content-Type: application/x-www-form-urlencoded\r\n" 
                         . "Content-Length: " . strlen($content) . "\r\n",
            'content' => $content
        )
    );

This is apparently done by the wrapper automagically, so there's something else. Perhaps omit the last linebreak ("\\r\\n") in headers.

Emulate your browser first. Check whith Developer tools which headers it sends exactly to Service. And emulate it. It will help to find where you get wrong.

For example, Service may need "Content-type: multipart/form-data" instead of Application/x-form type. Maybe required Content-encoding or something else to be provided.

I have a suspicion this is due to a mismatch between the announced mediatype and the actual payload. The proper status code to that would be 415: Unprocessable Entity , but 400 may appear as well.

To take your first example: You are announcing urlencoded data from a html form followed by JSON. I think the correct code here were this:

public function sendHttpRequest($data) {
    $data = json_encode($data)

    $context = stream_context_create(array(
        'http' => array(
            'method' => 'POST',
            'header' => array(
                'Content-Type: application/json',
                'Content-Length: ' . strlen($data),
                'Connection: close',
            ),
            'content' => $data,
        ),
    ));

    $result = file_get_contents($this->WS, false, $context);
}

You also seem to put a lot of headers into your request that simply do not belong there such as Pragma and other cache-control headers. Those should really be sent by the server, not the client.

Also, per this answer make sure whatever $this->WS contains is encoded soundly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM