How can i get the length of a curl Post body - php

I am trying to log in to a remote website which requires me to post username password and login via post. I am using the Curl Option
curl_setopt($ch, CURLOPT_POSTFIELDS , $postData);
and assign my info like this
$postData['email'] = 'smart#acme.com';
$postData['password'] = 'Secret';
$postData['Submit']='Login';
But the remote server complains about
HTTP Error 411. The request must be chunked or have a content length.
So how can i tell the content length of my postData ?

To get the length of PostData, you can use PHP's function count to get it.
Try:
#Get the length
$postData_len = count($postData);
#Set Curl Header with Content Length
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Length: '.$postData_len));
The above code with calculate the length of the postData array and then set the Curl header, if you're looking for 1 line of code, try this:
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Length: '.count($postData)));

Not sure this will work for you or not? but you need something like this with strlen() to set Content-Length.
$postData= array("email" => "smart#acme.com", "password" => "Secret","Submit"=>"Login");
$data_string = json_encode($postData);
$ch = curl_init('http://api.remote.com');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($data_string))
);
$result = curl_exec($ch);

$ch = curl_init();
$data['email'] = 'smart#acme.com';
$data['password'] = 'Secret';
$data['Submit']='Login';
curl_setopt($ch, CURLOPT_URL, '****/upload.php');
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_exec($ch);
the header of the request is
[CONTENT_LENGTH] => 357
[CONTENT_TYPE] => multipart/form-data; boundary=------------------------aac448045c2fe517
however if we pass the args through string like this
$ch = curl_init();
$data['email'] = 'smart#acme.com';
$data['password'] = 'Secret';
$data['Submit']='Login';
echo strlen(http_build_query($data));
curl_setopt($ch, CURLOPT_URL, '*/upload.php');
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_exec($ch);
and the header of this request is
[CONTENT_LENGTH] => 51
[CONTENT_TYPE] => application/x-www-form-urlencoded
so it is better to use application/x-www-form-urlencoded than multipart/form-data for it is easy to calculate content-length

Related

I get an authentication error with a json post

I am trying to authenticate, the result of my request is returned incorrectly.
Request Model
Method: Post, Endpoint: /api/authenticate, Header Variables:
[{"key":"Content-Type","value":"application/json","enabled":true}],
Body Parameters: username: string, password: string,
authenticationType: string
Sample Request
POST /api/authenticate
Host: mpop-sit.hepsiburada.com
Content-Type: application/json
{
"username": "xyz_dev",
"password": "XYZ_dev123!",
"authenticationType": "INTEGRATOR"
}
Request i sent
$url = 'https://mpop-sit.hepsiburada.com//api/authenticate';
$ch = curl_init($url);
$header = array(
'Content-Type: application/json',
'Authorization: Bearer '. base64_encode('xyz_dev:XYZ_dev123!:INTEGRATOR'),
);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$result = curl_exec($ch);
$return=json_decode($result,true);
print_r($return);
This is the result of the query returned and the error I received.
Where do you think I might be making a mistake?
Array ( [timestamp] => 2020-02-07T09:01:47.426+0000 [status] => 500
[error] => Internal Server Error [exception] =>
io.jsonwebtoken.MalformedJwtException [message] => JWT strings must
contain exactly 2 period characters. Found: 0 [path] =>
//api/authenticate )
Do you need the authentication header for this endpoint?
Because what the sample request wants you to send the parameters in the request body like this:
$post = [
'username' => 'xyz_dev',
'password' => 'XYZ_dev123!',
'authenticationType' => 'INTEGRATOR'
];
$url = 'https://mpop-sit.hepsiburada.com//api/authenticate';
$ch = curl_init($url);
$header = array('Content-Type: application/json');
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$result = curl_exec($ch);
$return=json_decode($result,true);
print_r($return);
So no need fot the Authentication: Bearer ... header, it would also be created differently.
This should work fine! I get access denied error, so, that means codes works fine.
Note you might need to change http_build_query($fields) to $fields
$url = "https://mpop-sit.hepsiburada.com/api/authenticate/";
$token = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
$fields = array(
"username" => "xyz_dev",
"password" => "XYZ_dev123!"
);
$header = array(
'Content-Type: application/json',
'Authorization' => 'Bearer ' . $token,
);
//open curl connection
$ch = curl_init();
//set the url, fields, vars
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_POST, true);
curl_setopt($ch,CURLOPT_POSTFIELDS, http_build_query($fields));
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false); // SSL false if not required
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false); //False if not required
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//execute fields
$result = curl_exec($ch);
//return result echo $result; if you need
echo curl_error($ch);
//close curl connection
curl_close($ch);
Please let me know if it works!
UPDATE : if you want to use ssl which is saving you from hacks.
Follow steps in this answer to activate ssl : https://stackoverflow.com/a/59919558/12232340
2 slashes here, so it does not work:
$url = 'https://mpop-sit.hepsiburada.com//api/authenticate';

OAuth returns bad request message

I am trying to generate a token using OAuth 2.0
I redirect the user to the given URL,
User logs in, grants permission,
and then user is returned to my RETURN_URL
Below is the code for my RETURN_URL, and it gives following error:
{"code":400,"status":"Bad Request","timestamp":"2018-11-06T17:41:08+05:30","message":"Bad Request","error":{"reason":"Something wrong in request"}}
$code= $_GET[code];
$url = 'https://api.example.com/index/oauth/token';
$auth = $API_KEY.":".$API_SECRET ;
$header = array();
$header[] = 'Content-Type: application/json';
$header[] = 'x-api-key: '.$API_KEY;
$header[] = 'Authorization: Basic '. base64_encode($auth);
$data = array(
'code' => $code,
'grant_type' => 'authorization_code',
'redirect_uri' => $RETURN_URL
);
$data = trim(http_build_query($data));
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data );
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
//curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
//curl_setopt($ch, CURLOPT_USERPWD, $API_KEY.":".$API_SECRET );
//curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
//curl_setopt($curl, CURLOPT_USERPWD, "$API_KEY:$API_SECRET" );
curl_setopt($ch, CURLOPT_HEADER, 0);
$result= curl_exec($ch);
$error = curl_error($ch);
echo $result; exit;
curl_close($ch);
This is what their docs are saying for required parameters:
curl \
-u {your_api_key}:{your_api_secret} \
-H 'Content-Type: application/json' \
-H 'x-api-key: {your_api_key}' \
-d '{"code" : "{code_from_login_response}", "grant_type" : "authorization_code", "redirect_uri" : "{your_redirect_uri}"}' \
The reason you are getting a 400 bad request is because the API server that you are hitting is unable to understand the $data you sent and JSON decode it. Hence, below steps might help in sending a proper POST request with proper JSON-
Change $_GET[code] to $_GET['code']. It works without the single quotes but it does generate a notice of undefined constant 'code'. Also, you might want to filter this data for security reasons.
remove $data = trim(http_build_query($data));.
Change this line curl_setopt($ch, CURLOPT_POSTFIELDS, $data ); to curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data) ); and you should be good to go.
The reason why this might be happening as far as I see is because probably API Server you are hitting is receiving your JSON data as $json = file_get_contents('php://input');, kind of like a webhook. So, when you made a request, it wasn't able to parse your data as JSON and hence sent you a bad request error.

Curl request works in Rested chrome extension but not in php

everyone, i am requesting data from some other website but I am unable to request through curl it shows error 500 but when I do the same request through chrome RESTED extension it shows me output
$url = "XXXXXXXXXXX";
// what post fields?
$fields = array(
'roll_number' => '123456',
'full_name' => 'aaaaaa',
'mother_name' => 'bbbbbbb',
'_token' => 'xxxxxxxxxxxxxxxx'
);
// build the urlencoded data
$postvars = http_build_query($fields);
// open connection
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded'));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,$postvars);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Request should be by post method and data should be JSON encoded or URL encoded I have tried both but none of them worked
Not sure if this is the cause, but shouldn't your HTTPHEADER be application/json? Also, you're not encoding the data as JSON - you might need to change $postvars = http_build_query($fields); to $postvars = json_encode($fields);
I'd also take a look at https://lornajane.net/posts/2011/posting-json-data-with-php-curl

PHP CURL Using POST Raw JSON Data

I am working with PHP curl for post, for some reason I couldn't post the form successfully.
$ch = curl_init();
$headers = [
'x-api-key: XXXXXX',
'Content-Type: text/plain'
];
$postData = array (
'data1: value1',
'data2: value2'
);
curl_setopt($ch, CURLOPT_URL,"XXXXXX");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$server_output = curl_exec ($ch);
When I try using the same in post it works, but not with PHP.
var_dump($server_output) ==> string(67) ""require data1 and data2 or check the post parameters""
var_dump(curl_error($ch)) ==> string(0) ""
If you wanna use Content-type: application/json and raw data, seem your data should be in json format
$ch = curl_init();
$headers = [
'x-api-key: XXXXXX',
'Content-Type: application/json'
];
$postData = [
'data1' => 'value1',
'data2' => 'value2'
];
curl_setopt($ch, CURLOPT_URL,"XXXXXX");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($postData));
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec ($ch);
$statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
If you want an arranged and explained format, see the code below.
// Set The API URL
$url = 'http://www.example.com/api';
// Create a new cURL resource
$ch = curl_init($url);
// Setup request to send json via POST`
$payload = json_encode(array(
'data1' => 'value1',
'data2' => 'value2'
)
);
// Attach encoded JSON string to the POST fields
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
// Set the content type to application/json
curl_setopt($ch, CURLOPT_HTTPHEADER, array('x-api-key: XXXXXX', 'Content-Type: application/json'));
// Return response instead of outputting
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Execute the POST request
$result = curl_exec($ch);
// Get the POST request header status
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
// If header status is not Created or not OK, return error message
if ( $status !== 201 || $status !== 200 ) {
die("Error: call to URL $url failed with status $status, response $result, curl_error " . curl_error($ch) . ", curl_errno " . curl_errno($ch));
}
// Close cURL resource
curl_close($ch);
// if you need to process the response from the API further
$response = json_decode($result, true);
I hope this helps someone

Passing JSON to PHP CURL [duplicate]

I have been working on building an Rest API for the hell of it and I have been testing it out as I go along by using curl from the command line which is very easy for CRUD
I can successfully make these call from the command line
curl -u username:pass -X GET http://api.mysite.com/pet/1
curl -d '{"dog":"tall"}' -u username:pass -X GET http://api.mysite.com/pet
curl -d '{"dog":"short"}' -u username:pass -X POST http://api.mysite.com/pet
curl -d '{"dog":"tall"}' -u username:pass -X PUT http://api.mysite.com/pet/1
The above calls are easy to make from the command line and work fine with my api, but now I want to use PHP to create the curl. As you can see, I pass data as a json string. I have read around and I think I can probably do the POST and include the POST fields, but I have not been able to find out how to pass http body data with GET. Everything I see says you must attached it to the url, but it doesn't look that way on the command line form. Any way, I would love it if someone could write the correct way to do these four operations in PHP here on one page. I would like to see the simplest way to do it with curl and php. I think I need to pass everything through the http body because my php api catching everything with php://input
PUT
$data = array('username'=>'dog','password'=>'tall');
$data_json = json_encode($data);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json','Content-Length: ' . strlen($data_json)));
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_POSTFIELDS,$data_json);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
POST
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,$data_json);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
GET
See #Dan H answer
DELETE
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_setopt($ch, CURLOPT_POSTFIELDS,$data_json);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
You can use this small library: https://github.com/ledfusion/php-rest-curl
Making a call is as simple as:
// GET
$result = RestCurl::get($URL, array('id' => 12345678));
// POST
$result = RestCurl::post($URL, array('name' => 'John'));
// PUT
$result = RestCurl::put($URL, array('$set' => array('lastName' => "Smith")));
// DELETE
$result = RestCurl::delete($URL);
And for the $result variable:
$result['status'] is the HTTP response code
$result['data'] an array with the JSON response parsed
$result['header'] a string with the response headers
Hope it helps
For myself, I just encode it in the url and use $_GET on the destination page. Here's a line as an example.
$ch = curl_init();
$this->json->p->method = "whatever";
curl_setopt($ch, CURLOPT_URL, "http://" . $_SERVER['SERVER_NAME'] . $this->json->path . '?json=' . urlencode(json_encode($this->json->p)));
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$output = curl_exec($ch);
curl_close($ch);
EDIT: Adding the destination snippet... (EDIT 2 added more above at OPs request)
<?php
if(!isset($_GET['json']))
die("FAILURE");
$json = json_decode($_GET['json']);
$method = $json->method;
...
?>
I was Working with Elastic SQL plugin.
Query is done with GET method using cURL as below:
curl -XGET http://localhost:9200/_sql/_explain -H 'Content-Type: application/json' \
-d 'SELECT city.keyword as city FROM routes group by city.keyword order by city'
I exposed a custom port at public server, doing a reverse proxy with Basic Auth set.
This code, works fine plus Basic Auth Header:
$host = 'http://myhost.com:9200';
$uri = "/_sql/_explain";
$auth = "john:doe";
$data = "SELECT city.keyword as city FROM routes group by city.keyword order by city";
function restCurl($host, $uri, $data = null, $auth = null, $method = 'DELETE'){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $host.$uri);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
if ($method == 'POST')
curl_setopt($ch, CURLOPT_POST, 1);
if ($auth)
curl_setopt($ch, CURLOPT_USERPWD, $auth);
if (strlen($data) > 0)
curl_setopt($ch, CURLOPT_POSTFIELDS,$data);
$resp = curl_exec($ch);
if(!$resp){
$resp = (json_encode(array(array("error" => curl_error($ch), "code" => curl_errno($ch)))));
}
curl_close($ch);
return $resp;
}
$resp = restCurl($host, $uri); //DELETE
$resp = restCurl($host, $uri, $data, $auth, 'GET'); //GET
$resp = restCurl($host, $uri, $data, $auth, 'POST'); //POST
$resp = restCurl($host, $uri, $data, $auth, 'PUT'); //PUT
set one more property curl_setopt($ch, CURLOPT_SSL_VERIFYPEER , false);

Categories