How to keep LineFeed in GuzzleHttp Response Body - php

I am doing and cUrl request using Guzzle.
$client = new GuzzleHttp\Client();
try {
$response = $client->get($url);
} catch (\GuzzleHttp\Exception\RequestException $ex) {
// handle error.
}
The server response is formatted like this:
"field1","field2","field3"\n
"value1","value2","value3"\n
"value4","","value5"\n
Using GuzzleHttp\Client, I receive the following response body
"field1","field2","field3""value1","value2","value3""value4","","value5"\n
Is it possible to set the Guzzle Client not to replace line feed chars in the response body?

We don't know what your response looks like.
We don't know how you are viewing the response.
In the presence of these two details I would have to guess that you might have to implement some type of stream decorator so that only single lines of the response are read in at a time.

Related

getHeader from getInternalResponse in Symfony Panther always return an empty array

By using Symfony Panther, I sent a request and I wanted to get the response. I was able to get the body and the status code but for the header I just got an empty array.
$client = Client::createChromeClient();
$client->request('GET', 'https://google.com');
$client->getInternalResponse()->getHeaders(); // returned empty array!!!
Panther does not have access to the HTTP response as explained in this github issue https://github.com/symfony/panther/issues/17.
But if you read carefuly, you'll see that this is not a limitation of Panther but a limitation of Selenium WebDriver. See this post How to get HTTP Response Code using Selenium WebDriver.
This means that the answer to the question "Can I have access to the HTTP response code or the HTTP header using Symfony Panther?" is "No, it's not possible".
While this is not possible the workaround I found was to create an HttpClient and use it to make a request and get the response from it.
<?php
use Symfony\Component\HttpClient\HttpClient;
$client = HttpClient::create();
$response = $client->request('GET', $this->myBaseUri);
$statusCode = $response->getStatusCode();
$headers = $response->getHeaders();
Here's the documentation for HTTP Client (Symfony Docs) if you want to try this way.
According to this issue: https://github.com/symfony/panther/issues/67, it seems that status code is not managed ( HTTP 200 will always get returned, no matter what the request actually responded.)
And same for the headers, I'm afraid. If you look at class
Symfony\Component\Panther\Client and method get($url) you can see that:
$this->internalResponse = new Response($this->webDriver->getPageSource());
while Response's constructor accepts:
public function __construct(string $content = '', int $status = 200, array $headers = [])
Having these said, no matter what happens, you always get HTTP 200 and empty header array.

GuzzleHttp disable UrlEncoding

I should send some JSON in my Get request and the server returns some data in application/json as response:
$url='http://example.com/var1=123&var2={'id':123,satrt:342,end:987,using:"abc"}';
and I use this code:
$client = new \GuzzleHttp\Client;
$response = $client->get($url);
$data = json_decode((string)$response->getBody(), true);
but it send a request to:
http://example.com/var1=123&var2=%7B'id':123,satrt:342,end:987,using:"abc"%7D
I see this answer about $response->getQuery()->useUrlEncoding(false) but it do nothing.
how can I tell GuzzleHttp not to url encode the { and }?
IMO you should not want to do that. The remote server must decode the query string, so it will receive the original string in the end. BTW, it's better to use query option to manage query string parameters.
If you want to do it anyway, try to construct an instance of Uri class manually.

Guzzle and Stack Exchange API, parsing error "JSON_ERROR_UTF8"

I'm trying to consume the Stack Exchange API with Guzzle. I am facing an issue where I can't get the JSON response back: it apparently fails when parsing it.
Here is my code:
$client = new GuzzleHttp\Client();
$parameters = ['pagesize'=>'2','order'=>'desc','sort'=> 'activity','q'=>'laravel eloquent','site'=>'stackoverflow'];
$response = $client->get('http://api.stackexchange.com/2.2/search/advanced',['query' => $parameters ]);
The resultant effective URL that Guzzle creates is correct: if you open the link in your browser you'll see that it works fine and returns the requested data.
However, Guzzle fails with this error when trying to access the JSON with $response->json():
GuzzleHttp \ Exception \ ParseException
Unable to parse JSON data: JSON_ERROR_UTF8 - Malformed UTF-8 characters, possibly incorrectly encoded
After reading the documentation again, I believe that the request is compressed and I am not passing the appropriate content header. If this is so, can you please let me know which header I should be passing to get the correct response?
Ok so the following code works for me.
$client = new GuzzleHttp\Client();
$parameters = ['pagesize'=>'2','order'=>'desc','sort'=> 'activity','q'=>'laravel eloquent','site'=>'stackoverflow'];
$params = http_build_query($parameters);
$request = $client->createRequest('GET', 'http://api.stackexchange.com/2.2/search/advanced?'.$params);
$request->addHeader('Accept-Encoding','GZIP');
$request->addHeader('Content-Type','application/json');
$response = $client->send($request);
var_dump($response->json());

Empty or too short HTTP message using HTTPRequest

I have an app that responds to a POST request with files:
https://docxgenjs.herokuapp.com/
It just echoes out (in JSON format) the files that were posted to that URL.
You can test it using a REST Console (on chrome web store).
Howewer, when I request that page using PHP, it doesn't work out:
try {
$url = 'https://docxgenjs.herokuapp.com/';
$request = new HTTPRequest($url, HTTP_METH_POST);
$request->addPostFile("config",app_path()."\\docxgen\\config.json");
$request->addPostFile("docx",app_path()."\\docxgen\\tagExample.docx");
$request->send();
$response = $request->getResponseBody();
var_dump($response);
}
catch(Exception $e)
{
var_dump($e->getMessage()); var_dump($e->getCode());
}
I get the following exception:
string(35) "Empty or too short HTTP message: ''"
int(2)
What's different between the two POST Requests, and how can I fix that ?
If I remove the two lines:
$request->addPostFile("config",app_path()."\\docxgen\\config.json");
$request->addPostFile("docx",app_path()."\\docxgen\\tagExample.docx");
They is no exception and the response of the server is the expected response {}
The issue was that the paths had to be written with / rather than \\

Calling ASP.NET Web Api method with PHP

I have the following web method in my web api controller
public HttpResponseMessage PostMakeBooking(FacilityBookingRequest bookingRequest)
{
var returnStatus = HttpStatusCode.OK;
var json = new JavaScriptSerializer().Serialize(bookingRequest);
var response = Request.CreateResponse<CardholderResponse>(returnStatus, cardholderResponse);
return response;
}
When I make this call from my .NET app, my json string appears correctly when I seralize it
{"correlationId":null,"RequestId":"7ec5092a-342a-4e32-9311-10e7df3e3683","BookingId":"BK-123102","CardholderId":"123456","BookingFrom":"\/Date(1370512706448)\/","BookingUntil":"\/Date(1370523506449)\/","DeviceId":"ACU-01-R2","Action":"Add","LoginId":"tester","Password":"tester"}
However, when I made to call from my php script
public function web_request(){
$guid =self::getGUID();
$replace = array("{","}");
$guid = str_replace($replace, "", $guid);
$client = new Zend_Rest_Client("http://203.92.72.221");
$request= new myZendCommon_FacilityBookingRequest();
$request->RequestId =$guid;
$request->BookingFrom ="27/03/2013 05:30";
$request->BookingUntil ="27/03/2013 06:30";
$request->CardholderId ="E0185963";
$request->DeviceId ="ACU-B2-01-R1";
$request->BookingId ="111";
$request->Action ="Add";
$request->LoginId ="tester";
$request->correlationId ="(null)";
$request->Password ="tester";
$request = json_encode($request);
$response = $client->restPost("/ibsswebapi/api/facilitybooking",$request);
print_r($response);
exit();
The call goes to my web method, but when I serialize it using JavaScriptSerializer().Serialize(bookingRequest)
{"correlationId":null,"RequestId":null,"BookingId":null,"CardholderId":null,"BookingFrom":"\/Date(-62135596800000)\/","BookingUntil":"\/Date(-62135596800000)\/","DeviceId":null,"Action":null,"LoginId":null,"Password":null}
All the values are null.
Is something wrong with the script?
I believe Kiran is right. Not sure why some one has felt his answer is not useful. Anyways, my understanding is that you are creating a JSON string and doing a form post of the same. I guess in this case the content type is sent as application/www-form-urlencoded but request body is a JSON string. You can use Fiddler to see how the request is being sent by the PHP script. I don't have the PHP knowledge to tell you how you can post JSON but my guess is that if you just remove the JSON encoding line $request = json_encode($request);, it should be okay.
From ASP.NET Web API point of view, if the request has Content-Type: application/json header and the body has the right JSON or if the request has Content-Type:application/www-form-urlencoded header and the body has the form url encoded content like RequestId=7ec5092a-342a-4e32-9311-10e7df3e3683&BookingId=BK-123102 and so on, web API will absolutely have no problem in binding. Currently, the request is not being sent in the right format for web API to bind.
Are you sending the header Content-Type:application/json in your request?
Also add the following piece of code to catch any model state validation errors:
.
if (!ModelState.IsValid)
{
throw new HttpResponseException(
Request.CreateErrorResponse(HttpStatusCode.BadRequest, this.ModelState));
}

Categories