Curl / Guzzle - get header / response code without body - http

To get the statuscode of a website with curl you can use the CURLOPT NOBODY.
Example:
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, 'http://www.example.com');
curl_setopt($curl , CURLOPT_NOBODY, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$status = curl_exec($curl);
curl_close($curl);
Is the following example with Guzzle as http library the same:
$guzzle = new Client();
$req = $guzzle->createRequest('GET', 'http://www.example.com');
$result = $guzzle->send($req);
$status = $result->getStatusCode();
My goal is to perform a curl/guzzle request without getting the body. Will that request with Guzzle only fetch the status code without wasting bandwith on other data?

In order to get status code of the response without downloading the whole content, you should use "head" method:
$client = new \GuzzleHttp\Client();
$response = $client->head('http://example.com/');
echo $response->getStatusCode();

Related

Make batch http request from wordpress plugin using wp_remote_post

I'm trying to make batch request from a wordpress plugin to the gmail API to download multiple messages at once. I can get them using curl function:
$BOUNDARY='gmail-message-boundary';
$body= "";
foreach ($message_ids as $message_id) {
$body.= "--$BOUNDARY\n";
$body.= "Content-Type: application/http\n\n";
$body.= 'GET https://www.googleapis.com/gmail/v1/users/'.$email_id.
'/messages/'.$message_id->id.'?metadataHeaders=From&format=metadata&key='.urlencode($gmail_api_key)."\n\n";
$post_body .= "--$BOUNDARY--\n";
$headers = [
'Content-type: multipart/mixed; boundary='.$BOUNDARY,
'Authorization: OAuth '.$auth_token
];
$curl = curl_init();
curl_setopt($curl,CURLOPT_URL, 'https://www.googleapis.com/batch/gmail/v1' );
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl,CURLOPT_CONNECTTIMEOUT , 60 ) ;
curl_setopt($curl, CURLOPT_TIMEOUT, 60 ) ;
curl_setopt($curl,CURLOPT_POSTFIELDS , $body);
curl_setopt($curl, CURLOPT_RETURNTRANSFER,TRUE);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER,0);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
$res= curl_exec($curl);
curl_close($curl);
this code works perfectly but I want to achieve the same result using only worpdress functions. Unfortunately, when I'm trying to make the request using wp_remote_post function I'm getting this response:
{
"headers":{
},
"body":"{\n \"error\": {\n \"code\": 400,\n \"message\": \"Failed to get multipart boundary.\",\n \"status\": \"INVALID_ARGUMENT\"\n }\n}\n",
"response":{
"code":400,
"message":"Bad Request"
},
"cookies":[
],
"filename":null,
"http_response":{
"data":null,
"headers":null,
"status":null
}
}
Does anyone knows how to use wordpress functions to make batch http request?

Signature mismatch. Authorization signature or client credential is wrong

Using the following code to try and create the signature and get the bearer token.
<?php
$tm=time();
$param_str = "grant_type=client_credentials&oauth_consumer_key=xxxx&oauth_nonce=xxx&oauth_signature_method=HMAC-SHA256&oauth_timestamp=".$tm."&oauth_version=1.0";
//die($param_str);
$base_str = "POST&" .urlencode("https://account.api.here.com/oauth2/token") . "&" . urlencode($param_str);
//die($base_str);
$sign_key = urlencode("xxxxxxxxxxxxxxxxxxxxxxxxx")."&";
$signature= hash_hmac("sha256",$base_str,$sign_key);
$url = "https://account.api.here.com/oauth2/token";
$ch = curl_init( $url );
$headers = [
'Content-Type: application/x-www-form-urlencoded',
'Authorization: OAuth oauth_consumer_key="xxx",oauth_nonce="xxx",oauth_signature="'.$signature.'",oauth_signature_method="HMAC-SHA256",oauth_timestamp="'.$tm.'",oauth_version="1.0"',
'Cache-Control: no-cache'
];
$payload="grant_type=client_credentials";
curl_setopt( $ch, CURLOPT_POSTFIELDS, $payload );
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
# Return response instead of printing.
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
# Send request.
$result = curl_exec($ch);
curl_close($ch);
?>
Tried various combinations. Getting the same error (Signature mismatch. Authorization signature or client credential is wrong). Even tried copying the exact url encoded string from the document, replacing relevant information and still not working. Is there something I am not understanding at all from the documentation or something I am missing here in my code.
The reason for signature mismatch is that the one you created is different than the one server created. Check the following –
Did you convert the signing key and base string into bytes before
passing it to HMAC-SHA256 hashing algorithm.
Did you convert the output of HMAC-SHA256 hashing algorithm into
base64 string.
also check this link if this can help you.

Alfresco login page bypassing

I created a valid ticket using a webservice call...code shown below
$url="http://serverip:port/alfresco/service/api/login?u=xxx&pw=xxx";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
$response =curl_exec($ch);
Now using this ticket i want to authenticate alfresco without again entering username and password.Also i want to create a valid cookie JSESSIONID inside browser with this ticket...Is it feasible??
my purpose is to integrate a php application with alfresco....php application already has an authentication system...so i want to bypass the authentication of alfresco
You need to append below parameter
alf_ticket="TICKET_WHICH_YOU_GET"
for further authentication.
Finally i resolved the issue by calling the login page url http://ip:port/share/page/ via Curl with login parameters(username and pwd)...I got JsessionId as response from curl...Now i took that JsessionId and set inside the browser...so wen u click http://ip:port/share/page/ the login page is bypassed
As per your suggestion, we are tried with below curl call but their is no JsessionId in response. can you please check and let me know the resolution
$post = [
'username' => 'user',
'password' => 'pass',
];
$ch = curl_init('http://ip:port/share/page/dologin/');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
// execute!
$response = curl_exec($ch);
// close the connection, release resources used
curl_close($ch);
// do anything you want with your response
var_dump($response);
please suggest with the solution

How to retrieve a streamed response (e.g. download a file) with Symfony test client

I am writing functional tests with Symfony2.
I have a controller that calls a getImage() function which streams an image file as follows:
public function getImage($filePath)
$response = new StreamedResponse();
$response->headers->set('Content-Type', 'image/png');
$response->setCallback(function () use ($filePath) {
$bytes = #readfile(filePath);
if ($bytes === false || $bytes <= 0)
throw new NotFoundHttpException();
});
return $response;
}
In functional testing, I try to request the content with the Symfony test client as follows:
$client = static::createClient();
$client->request('GET', $url);
$content = $client->getResponse()->getContent();
The problem is that $content is empty, I guess because the response is generated as soon as the HTTP headers are received by the client, without waiting for a data stream to be delivered.
Is there a way to catch the content of the streamed response while still using $client->request() (or even some other function) to send the request to the server?
The return value of sendContent (rather than getContent) is the callback that you've set. getContent actually just returns false in Symfony2
Using sendContent you can enable the output buffer and assign the content to that for your tests, like so:
$client = static::createClient();
$client->request('GET', $url);
// Enable the output buffer
ob_start();
// Send the response to the output buffer
$client->getResponse()->sendContent();
// Get the contents of the output buffer
$content = ob_get_contents();
// Clean the output buffer and end it
ob_end_clean();
You can read more on the output buffer here
The API for StreamResponse is here
For me didn't work like that. Instead, I used ob_start() before making the request, and after the request i used $content = ob_get_clean() and made asserts on that content.
In test:
// Enable the output buffer
ob_start();
$this->client->request(
'GET',
'$url',
array(),
array(),
array('CONTENT_TYPE' => 'application/json')
);
// Get the output buffer and clean it
$content = ob_get_clean();
$this->assertEquals('my response content', $content);
Maybe this was because my response is a csv file.
In controller:
$response->headers->set('Content-Type', 'text/csv; charset=utf-8');
The current best answer used to work well for me for some time, but for some reason it isn't anymore. The response is parsed into a DOM crawler and the binary data is lost.
I could fix that by using the internal response. Here's the git patch of my changes[1]:
- ob_start();
$this->request('GET', $uri);
- $responseData = ob_get_clean();
+ $responseData = self::$client->getInternalResponse()->getContent();
I hope this can help someone.
[1]: you just need access to the client, which is a
Symfony\Bundle\FrameworkBundle\KernelBrowser

Quick way to find out if website is down or up?

Using my wordpress functions.php file to check if every image displayed is up and running or down. I think what I want to do is to break this functions code (below) into two.
function 1: check if mirror1.com is up (instead of checking every image in loop). insert if/then statement depending on http status of mirror1.com. (if mirror1.com is down, then use mirror2.com) -- pass that into $mirror_website
function 2: simply pass in $mirror_website.. (the front end has <img src="<?php echo $mirror_website; ?>/image.png"> )
The code below works, but it's checking EVERY simple image and slows down the site.
function amazons3acctreplaceto() {
$url = 'http://www.mirror1.com';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_exec($ch);
$retcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if (200==$retcode) {
$as3replaceto = "www.mirror1.com"; // All's well
} else {
$as3replaceto = "www.mirror2.com"; // not so much
}
A simple solution might be to cache the result (eg. in the APC or memcache) with a TTL so you don't need to work out if the site is up or down for every eventuality.
eg. Here's an example that might work using APC to cache the result of the site status for 2 minutes:
function amazons3acctreplaceto() {
$as3replaceto = FALSE;
if (function_exists('apc_fetch')) {
$as3replaceto = apc_fetch('as3replaceto');
}
if ($as3replaceto === FALSE) {
$url = 'http://www.mirror1.com';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_exec($ch);
$retcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if (200==$retcode) {
$as3replaceto = "www.mirror1.com"; // All's well
} else {
$as3replaceto = "www.mirror2.com"; // not so much
}
if (function_exists('apc_store')) {
apc_store('as3replaceto', $as3replaceto, 120); //Store status for 2 minutes
}
}

Resources