HTTP request failed! HTTP/1.1 400 Bad Request - php

I am trying to create a issue in Jira .
I am able to make a GET request with a proper response, but the problem arises when i make a POST request.Here is the code.
<?php
$userName ='xxxxxxxxxxxxxxxx';
$password ='xxxxxxxxxxxx';
$data = ['fields' => ['projects'=>['key'=>'ABC'],'summary'=>'abc','description'=>'abc','issuetype'=>['name'=>'Task']]];
$data = http_build_query($data);
$context =
array("http"=>
array(
"method" => "POST",
"header" => "Authorization: Basic " . base64_encode($userName.':'.$password) . "\r\n".
'Accept: application/json'."\r\n".
"Content-Length: ".strlen($data)."\r\n".
'Content-Type: application/json'."\r\n",
'content' => $data,
'verify_peer'=>false,
'verify_peer_name'=>false,
)
);
$context = stream_context_create($context);
$result = file_get_contents("https://xxxxx.atlassian.net/rest/api/2/issue/", false, $context);
echo "The result is ", $result;
?>
I get the following error:
Warning:file_get_contents(https://xxxxx.atlassian.net/rest/api/2/issue/):
failed to open stream: HTTP request failed! HTTP/1.1 400 Bad Request in
/var/www/html/test/new.php on line 27
Could any one help me out? Thanks
P.S
I dont want to use curl as an alternative to http-streams as google app engine does not support curl.

http_build_query() generates a url-encoded string. However, the API requires JSON. You should be using json_encode() instead.
Change:
$data = http_build_query($data);
To:
$data = json_encode($data);
While maybe not your only problem, this is definitely one problem that would result in an 400 Bad Request.

Could you have a typo in your code?
$data=array('fields' => array ('project' => array ('key' => 'WOIS',),'summary' => 'ABC','description' => 'ABC','issuetype' => array ('name' => 'Task',),),);
vs
$data = ['fields' => ['projects'=>['key'=>'WOIS'],'summary'=>'adfsdf','descriptio‌​n'=>'adfefsa','issue‌​type'=>['name'=>'Tas‌​k']]];
the first line says project while the second line says projects

Related

HTTP request failed! with file get contents

I used OAuth for Dropbox to get access token: https://blogs.dropbox.com/developers/2012/07/using-oauth-1-0-with-the-plaintext-signature-method/
But I got error message:
Warning: file_get_contents(https://api.dropbox.com/1/oauth/request_token): failed to open stream: HTTP request failed! HTTP/1.1 400 Bad Request
My PHP Code:
$Header = json_encode(array('Authorization: OAuth oauth_version="1.0"', "oauth_signature_method" => "PLAINTEXT", "oauth_consumer_key" => "XX", "oauth_signature" => "XX"));
$Options = array('http' =>
array(
'method' => 'POST',
'header' => $Header,
)
);
$Context = stream_context_create($Options);
$Result = file_get_contents("https://api.dropbox.com/1/oauth/request_token", false, $Context);
print_r($Result);
Based on the documentation at http://php.net/manual/en/context.http.php, it looks like the header option is just a normal string, not json_encoded. Alternatively, you should be able to use a numerically indexed array of headers, like so:
$Header = array(
"Authorization: OAuth oauth_version=\"1.0\", oauth_signature_method=\"PLAINTEXT\", oauth_consumer_key=\"XXXXX\", oauth_signature=\"XXXXX&\"\r\n"
);
$Options = array('http' =>
array(
'method' => 'POST',
'header' => $Header,
)
);
This is wrong:
$Header = json_encode(array('Authorization: OAuth oauth_version="1.0"', "oauth_signature_method" => "PLAINTEXT", "oauth_consumer_key" => "XX", "oauth_signature" => "XX"));
The header paramter in an http stream is either a simple single string containing one single header key: value, or an array of key: value strings. You're stuffing in a single json string as your header, meaning it's NOT a valid http header.
Remove the json_encode() part completely. $Header = array(...) is all you need.

doing a REST PUT in PHP

I hope my question will be understood, my english is a not so good.
I'm nearly new with PHP and I just discovered REST APIs: I'm trying to use a REST API from my PHP script. Docs for the API can be found here
My final goal is to get a single product from this webservice and update it by adding the wholesalePrices array.
I've already managed to perform a GET request using file_get_contents(), in order to get the product ID i want to update. Now I have such id but can't understand how to perform the PUT request: as far I can understand, there are mainly two ways to do REST calls in PHP: one with file_get_contents, another by using cURL.
Since I used file_get_contents for my GET request, I continued with this approach, but my code:
$wholesalePrices = json_encode($wholesalePrices);
$dataRAW = array(
"wholesalePrices" => $wholesalePrices
);
$dataToPut = http_build_query($dataRAW);
$context = [
'http' => [
'method' => 'PUT',
'header' => "Authorization: apikeystring\r\n" . "Content-Length: " . strlen($dataToPut) . "\r\n" . "Content-Type: application/json\r\n",
'content' => $dataToPut
]
];
$context = stream_context_create($context);
$url = "https://app.ecwid.com/api/v3/xxxxxxx/products/".urlencode($productId)."?token=".urlencode(myToken);
$result = file_get_contents ($url, false, $context);
returns a PHP warning:
Warning: file_get_contents(https://app.ecwid.com/api/v3/xxxxxxxxx/products/xxxxxxxxx?token=xxxxxxxxxxx): failed to open stream: HTTP request failed! HTTP/1.1 400 Wrong JSON format: A JSONObject text must begin with '{' at 1 [character 2 line 1] in upload.php on line 95
var_dumping $wholesalePrices just after the json_encode() results in
string '[{"quantity":1,"price":0},{"quantity":5,"price":6},{"quantity":25,"price":12},{"quantity":100,"price":25}]' (length=106)
where am I wrong?
ok, I tried using RamRaider approach and now my code is this
$data = json_encode(array('wholesalePrices' => $wholesalePrices)/*, JSON_FORCE_OBJECT*/);
$dataRAW = array(
"wholesalePrices" => $wholesalePrices
);
$dataToPut = $dataRAW;
$dataToPut = http_build_query($dataRAW);
$context = array('http' => array('method' => 'PUT',
'header' => "Authorization: apikeystring\r\nContent-Length: ".strlen($data)."\r\nContent-Type: application/json\r\n",
'content' => $data));
$context = stream_context_create($context);
$url = "https://app.ecwid.com/api/v3/".urlencode(MY_STORE_ID)."/products/".urlencode($productId)."?token=".urlencode(MY_TOKEN);
$result = file_get_contents ($url, false, $context);
But I obtain a HTTP request failed! HTTP/1.1 400 Field Product.wholesalePrices should be an array message.
If I comment the , JSON_FORCE_OBJECT instead, the HTTP message becomes 409 Conflict and it refers at the line with $result = file_get_contents ($url, false, $context); so perhaps I am on the right track, but how can I troubleshoot such error?
ok, done some mods: now - after the json_encode() - my dataToPut (which I put in "Content" in the HTTP request) var_dumps as following (WPPair is a class I specifically created to reproduce the format required):
object(stdClass)[3]
public 'wholesalePrices' =>
array (size=3)
1 =>
object(WPpair)[5]
public 'quantity' => int 5
public 'price' => int 6
2 =>
object(WPpair)[4]
public 'quantity' => int 25
public 'price' => int 12
3 =>
object(WPpair)[6]
public 'quantity' => int 100
public 'price' => int 25
so I think it has to be right for the api. But I still get a HTTP request failed! HTTP/1.1 400 Bad Request
Ok, finally I managed to form a (perhaps) right structure for my JSON, all the more so as Postman validates my dataToPut with an HTTP
200 OK
And my test record results updated.
This is the print_r() output on dataToPut after json_encode():
string
'{"id":56782231,"wholesalePrices":[{"quantity":5,"price":5.64},{"quantity":25,"price":5.28},{"quantity":100,"price":4.5}]}'
(length=121)
However, if I try to send the same JSON from my PHP page, I still get a
failed to open stream: HTTP request failed!
and in fact, my records still aren't updated.
Here's my code:
$dataToPut = $dataRAW;
$dataRAW = http_build_query($dataRAW);
$context = [
'http' => [
'method' => 'PUT',
'header' => "Authorization: apikeystring\r\n" . "Content-Length: ".sizeof($dataToPut)."\r\n" . "Content-Type: application/json\r\n",
'content' => $dataToPut
]
];
$context = stream_context_create($context);
$url = "https://app.ecwid.com/api/v3/xxxxxxx/products/".urlencode($productId)."?token=".urlencode(myToken);
$dataToPut = json_encode($dataToPut);
$result = file_get_contents($url, false, $context);
Where am I wrong this time?
After rewriting my code by using cURL instead of file_get_contents to connect to the API, I managed to get it to work.
Now the API call part looks like this:
$dataToPut = $dataRAW;
$dataRAW = http_build_query($dataRAW);
$context = [
'http' => [
'method' => 'PUT',
'header' => "Authorization: apikeystring\r\n" . "Content-Length: ".sizeof($dataToPut)."\r\n" . "Content-Type: application/json\r\n",
'content' => $dataToPut
]
];
$context = stream_context_create($context);
$url = "https://app.ecwid.com/api/v3/xxxxxxx/products/".urlencode($productId)."?token=".urlencode($myToken);
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Host: app.ecwid.com','Content-Type: application/json;charset=utf-8','Cache-Control: no-cache'));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $dataToPut);
// Make the REST call, returning the result
$response = curl_exec($curl);
echo ($response."<br/>");
if (!$response) {
echo("Connection Failure: ".curl_error($curl));
die();
}
curl_close($curl);
Without seeing the documentation for their api I might be leading you astray but the error message does suggest that their api expects json data whereas you encode the data and then add to an array which seems back to front somehow.
$data = json_encode( array( 'wholesalePrices' => $wholesalePrices ), JSON_FORCE_OBJECT );
/* Perhaps this also is not required */
#$data = http_build_query( $data );
$context = array(
'http' => array(
'method' => 'PUT',
'header' => "Authorization: apikeystring\r\nContent-Length: " . strlen( $data ) . "\r\nContent-Type: application/json\r\n",
'content' => $data
)
);
$context = stream_context_create( $context );
$url = "https://app.ecwid.com/api/v3/7560546/products/".urlencode( $productId )."?token=".urlencode( myToken );
$result = file_get_contents( $url, false, $context );
Having had a quick look at the api documentation I found the following:
PUT https://app.ecwid.com/api/v3/{storeId}/products/{productId}?token={token}
Request body
A JSON object of type 'Product’ with the following fields:
wholesalePrices -> Array<WholesalePrice>
described as: "Sorted array of wholesale price tiers (quantity limit and price pairs)"
The given example request to update a product is:
PUT /api/v3/4870020/products/39766764?token=123456789abcd HTTP/1.1
Host: app.ecwid.com
Content-Type: application/json;charset=utf-8
Cache-Control: no-cache
{
"compareToPrice": 24.99,
"categoryIds": [
9691094
]
}
So using test data
$wholesalePrices=array(
array('quantity'=>10,'price'=>1000),
array('quantity'=>2,'price'=>43),
array('quantity'=>43,'price'=>34),
array('quantity'=>7,'price'=>5),
array('quantity'=>9,'price'=>63),
);
$data = json_encode( array( 'wholesalePrices' => $wholesalePrices ) );
echo '<pre>',$data,'</pre>';
Gives data in the format:
{
"wholesalePrices":[
{"quantity":10,"price":1000},
{"quantity":2,"price":43},
{"quantity":43,"price":34},
{"quantity":7,"price":5},
{"quantity":9,"price":63}
]
}

Bad request using file_get_contents for PUT request in PHP

This api call works fine using Postman (a REST Client),
but when making the request on the server in my GAE application I am currently getting the following error:
HTTP request failed! in C:\Projects\app\file.php on line 26
failed to open stream: HTTP request failed! HTTP/1.0 400 Bad Request in C:\Projects\app\file.php on line 26
Here is the code from my application, which makes a call to the rest api method /exampleMethod
$dataraw = [
'email' => 'email#ex.com',
'first_name' => 'firstname',
'last_name' => 'lastname',
'fEmail' => 'email#ex.com',
'message' => 'test'
];
$data = http_build_query ( $dataraw );
$context = [
'http' => [
'method' => 'PUT',
'header' => "Authorization: apikeystring\r\n" . "Content-Length: " . strlen($data) . "\r\n" . "Content-Type: application/json\r\n",
'content' => $data,
'proxy' => 'tcp://euproxy.example.com:0000'
]
];
$context = stream_context_create ( $context );
$result = file_get_contents ( $GLOBALS ['REST_API_URL'] . '/exampleMethod', false, $context );
In the application I have successfully used file_get_contents for GET requests, but with this PUT request I am getting a 400 bad request which is not coming from the Rest Api.
Change mb_strlen(serialize($dataraw), '8bit') to strlen($data)

PHP POST API call

Trying to make a POST API call and I get the error file_get_contents(http://api.turfgame.com/v4/users): failed to open stream: HTTP request failed! HTTP/1.1 400 Bad Request. API info can be found at http://api.turfgame.com
<?php
$data = array("name" => "DIProgan");
$url = 'http://api.turfgame.com/v4/users';
$options = array(
'http' => array(
'method' => 'POST',
'content' => json_encode( $data ),
'header'=> "Content-Type: application/json\r\n" .
"Accept: application/json\r\n"
)
);
$context = stream_context_create( $options );
$result = file_get_contents( $url, false, $context );
$response = json_decode( $result );
var_dump($response);
?>
Using XAMPP & PHP 5.4.4. I tried using "requests for PHP" since I liked the Python version of it but it just complains about not finding hook functions. People seem to hate cURL and from the little I need it seemed easier without it. Maybe not. Help?
It seems like you have just created an array where you have put your parameter. It should be stored within an object first.

PHP set protocol_version for stream_context_create

I want to access an oauth server with a php script, the remote server requires the following request:
POST /oauth/token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 81
Authorization: Basic CHAINE_ENCODEE
grant_type=password&username=USERNAME&password=PASSWORD&scope=all
So I wrote the following code:
$params = array ('grant_type' => 'password',
'username' => 'USERNAME',
'password' => hash('sha256', 'PASSWORD'),
'scope' => 'all',
);
$query = http_build_query ($params);
$contextData = array (
'protocol_version'=> '1.1',
'method' => 'POST',
'header' => "Connection: close\r\n".
"Content-Type: application/x-www-form-urlencoded\r\n".
"Content-Length: 81\r\n".
"Authorization: Basic ".base64_encode('APPIDENTIFIER:SECRET'),
'content' => $query );
$context = stream_context_create (array ( 'http' => $contextData ));
$result = file_get_contents (
'https://rest2.some-url.net/oauth/token', // page url
false,
$context);
return $result;
But this gives me the following error:
Warning: file_get_contents(https://rest2.some-url.net/oauth/token): failed to open stream:
HTTP request failed! HTTP/1.0 500 Internal Server Error
My guess is that the problem comes from the protocol_version which I set to 1.1 as required by the api. But the error apparently uses HTTP/1.0
I have tried every possible way, i have seen no one saying it was not working for them so I guess I am missing something. Why is not the HTTP set to HTTP/1.1?

Categories