Rest API get Content-Length of Body - php

I got a Problem. Im working on a Datatransfer to a Restful API at the Moment. All the arrays and everything and json objects should be fine, but i just do not understand how to determine the Content-Length of my Body?
$http = new Client([
'headers' => ['Authorization' => 'Bearer ' . $token["access_token"], 'Transfer-Encoding' => 'chunked', 'Content-Encoding' => 'chunked']
]);
This is my code at the moment. But the Answer thats coming back is always
HTTP Error 400. There is an invalid content length or chunk length in the request.
Can you help me to determine the right Content-Length?
Cheers!

There are at least 2 ways to do it.
If you have content in variable then add to your headers array 'Content-Length' => strlen($var)
You can also use output buffering and get length with function ob_get_length()
'Content-Length' => ob_get_length()
Here you will find example

Related

Guzzle making a GET request instead of POST

I'm sure this is going to be marked as a duplicate, but I've looked through all the given questions on the same subject and tried many of the suggested solutions, and they haven't worked.
I'm in a laravel project and I have a post request going out through guzzle.
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', $url, [
'headers' => [
'Authorization' => 'Bearer ' . $apiToken,
'Accept' => 'application/json',
'Content-Type' => 'application/json',
'allow_redirects' => false,
// 'allow_redirects'=>['strict'=>true]
],
'json' => json_decode($logText, true)
]);
I keep on getting the response back "message": "The GET method is not supported for this route. Supported methods: POST."
I've checked and indeed, it's sending a GET request to the same $url specified above.
I didn't have those allow_redirects settings at first, but both settings were offered up as potential solutions when I googled around. Unfortunately, both options result in the same error message: The GET method is not supported for this route.
Why in the world is my POST request changing to a GET request?
I've also tried $client->post instead, and THAT became a GET request as well.
I've also double checked that the GET error message isn't actually coming from inside the POST request: it's not. The POST route isn't being hit at all.
PHP version 7.2, Laravel version 6.0.2, Guzzle version 6.5.3
Check for redirects on the server, such as HTTP -> HTTPS. Redirects are always a GET request, which will mess up non-GET routing. Using the correct protocol all the way through (such as always use HTTPS) will bypass the redirect.

Guzzle HTTP, can't parse response to JSON

So I'm integrating an API from a 3rd party company and I'm facing this strange situation.
I fetch the endpoint with the following code
$client = $this->client = new Client([
'base_uri' => 'https://xxx.xxxxxxxxxx.com/api/',
'timeout' => 15
]);
$this->requestConfig = [
'auth' => [
'xxxx#xx.xxx',
'xxxxx'
],
'headers' => [
'cache-control' => 'no-cache',
'content-type' => 'application/x-www-form-urlencoded'
],
];
$response = $this->client->get($url, $this->requestConfig);
$content = $response->getBody()->getContents();
Now the fun comes, if I var_dump content I get:
string(66) ""[{\"ExternalId\":\"38\",\"AgencyReference\":\"45436070356676\"}]""
Now I know this response is bad, response type if not set a json, json is URL encoded and everything smells bad.
I've been trying to parse this string for a while.
urldecode doesn't work either.
Question is simple, given a response like that, how can I get a normal array?
Currently using PHP 7.1
So finally found this:
Remove backslash \ from string using preg replace of php
To solve my issue.
In this case it was that the escaped quotes where malforming the json. My final code looks like this.
$response = $response->getBody()->getContents();
$clean = stripslashes($response);
$clean = substr($clean, 1, -1);
dd(json_decode($clean));
Please never write your API's like this...
Just looks awfull
BTW, Content-Type makes sense when you send (in request or response) some content. But you send a GET request, that has no content.
And to specify preferred content type for the response, you should use Accept HTTP header, Accept: application/json for example.
I'm not sure this will solve your problem, but just make things clear and correct ;)

Open URL with Authorization header with PHP

I have a URL that if I add an Authorization key in the headers,it shows me a payment page
I have to open this URL with PHP only.
How do I add the header key and echo the page content after I open it?
I tried to use CURL and file_get_contents but neither is working.
Thanks
I suggest using a sophisticated library to do that, like guzzle:
http://docs.guzzlephp.org/en/stable/
you can set headers like this :
// Set various headers on a request
$client->request('GET', '/get', [
'headers' => [
'User-Agent' => 'testing/1.0',
'Accept' => 'application/json',
'X-Foo' => ['Bar', 'Baz']
]
]);
You can use curl_setopt() a la How to set custom request header keys with curl and PHP?

Guzzle 5.3: Unable to POST JSON body if larger than ~1MB

I'm using Guzzle 5.3 via Guzzle Services (via https://github.com/ticketevolution/ticketevolution-php) to attempt to POST to an API endpoint with a JSON body that includes a PDF encoded as base64. When the body is less than ~1MB it works fine. When the body is larger it seems that the body is never sent.
I have tested this with and without the Expect: 100 header and it does not seem to make a difference.
I have tested with Transfer-Encoding: chunked, but because the API needs the entire POST body in order to authenticate using chunked does not work.
We have tested with and without the load balance between the client and the appservers.
From everything we can tell the body just doesn't get sent when it is larger than ~1MB.
Does anyone have any ideas on how to get Guzzle 5.3 to send the body even when it is larger than 1MB?
Below is the log output
[2015-09-01 16:15:43] TEvoAPIClientLogger.CRITICAL:
>>>>>>>>
POST /v9/orders/2100732/deliver_etickets HTTP/1.1
Host: api.ticketevolution.com
User-Agent: ticketevolution-php/3.0.0dev Guzzle/5.3.0 curl/7.44.0 PHP/5.5.28
Content-Type: application/json
Content-Length: 1387036
X-Token: b47dsd8c0ab80a1e2bc24sc341415a2f
X-Signature: SwBOkdUOqG3SDtjVwi2etosdP+gppwuV5dCq8yMw9lM=
{"etickets":[{"item_id":1513651,"eticket":"JVBERi0xLjQKJeLjz9MKNCAwIG9iaiBbXQplb… [a whole lot of base64 snipped] …NwolJUVPRgo="}]}
<<<<<<<< --------
cURL error 52: Empty reply from server
Running into the same problem, a bit of debugging resulted in ending up at GuzzleHttp\Ring\Client\CurlFactory::applyBody(), and then this fixed the problem for me:
Setting a default configuration on the client
$client = new \GuzzleHttp\Client([
'defaults' => [
'config' => [
'curl' => [
'body_as_string' => true,
],
],
],
]);
Setting the configuration when issuing the request
$client->post('https://example.com', [
'json' => $json,
'config' => [
'curl' => [
'body_as_string' => true,
],
],
]);
Rewinding the previously fetched actual content stream
Since I'm fetching content from a remote server, this article by Matt Downling helped me in finding out that I need to rewind the actual stream before using it as a part of the multipart/form-data request:
$response->getBody()->seek(0);

Cakephp hanging after post request via httpsocket containing json data

at the moment I am fighting with a http post request within cakePHP.
I am using the code below to communicate with an external API that requires Authorization.
The problem is, as soon as I add the body with the JSON context, the whole application is hanging. It's loading forever in the browser, not coming back with any results. Have to stop and start Apache to come back to normal. Tested on different machines, same effect.
If I don't send the (JSON) body, I am getting obviously a 500 server error, but it's telling me that the authorization is working otherwise I would get an unauthorized.
If I do a "GET" request to the same API, it's working fine and coming back with a result.
The JSON syntax is clean, if I process the variable and the other information using an API tester it's working (https://apigee.com/console).
UPDATE: It is working if the request is valid. However, on the API tester it's giving me a "400 Bad Request". I would need to handle that within my application but in this case the situation described above is happening. Expectation would be that it's returning the error.
$options = array(
'body' => $json_order,
'header' => array(
'Authorization' =>'123456',
'Content-Type' => 'application/json; charset=utf-8',
),
);
$result=$HttpSocket->post('https://<address>',null,$options);
debug($HttpSocket->request);
same effect if I would do it the other way
$options = array(
'header' => array(
'Authorization' =>'123456',
'Content-Type' => 'application/json; charset=utf-8',
),
);
$result=$HttpSocket->post('https://<address>',$json_order,$options);
debug($HttpSocket->request);
Any help would be more than appreciated!
To clear that up: The problem was on the far end not responding correctly with an error code. =

Categories