Guzzle curl error 18 with Laravel - php

I have an api and a client that I'm developing, both in laravel and I get that error 18 when I try to connect to the api using guzzle.
In my api controller I have this:
public function index()
{
$users = User::orderBy('username', 'asc');
return Response::json(array(
'error' => false,
'users' => $users->get()->toArray()),
200
);
}
And if I do curl --user admin#admin.com:password http://myapi.api/api/v1/users
I get the info that I need correctly on my console:
{"error":false,"users":[{"id":"1","firstname":"","lastname":"","username":"admin#admin.com","created_at":"2014-10-17 15:35:10","updated_at":"2014-10-17 15:35:10","client_id":"0","enterprise_id":"0","usertype_id":"0"},{"id":"2","firstname":"","lastname":"","username":"seconduser","created_at":"2014-10-17 15:35:10","updated_at":"2014-10-17 15:35:10","client_id":"0","enterprise_id":"0","usertype_id":"0"}]}
The url even works in the browser (I get a popup for authentication and after it I get the same input on the browser). So it's only failing via guzzle.
Now on my client I have Guzzle installed and I'm trying this:
$client = new GuzzleHttp\Client();
$user='admin#admin.com';
$pass='password';
$res = $client->get('http://myapi.api/api/v1/users', array(
'auth' => array('admin#admin.com', 'password')
));
$users=$res->json();
$users=$users['users'];
And I get the error:
[curl] (#18) See http://curl.haxx.se/libcurl/c/libcurl-errors.html for an explanation of cURL errors [url] http://myapi.api/api/v1/users
What am I doing wrong?
EDIT: Using -v in the command I get:
$ curl -v --user admin#admin.com:password http://myapi.api/api/v1/users
* Hostname was NOT found in DNS cache
* Trying 127.0.0.1...
* Connected to myapi.api (127.0.0.1) port 80 (#0)
* Server auth using Basic with user 'admin#admin.com'
> GET /api/v1/users HTTP/1.1
> Authorization: Basic YWRtaW5AYWRtaW4uY29tOnBhc3N3b3Jk
> User-Agent: curl/7.37.1
> Host: myapi.api
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Mon, 20 Oct 2014 13:08:56 GMT
* Server Apache/2.2.29 (Unix) mod_fastcgi/2.4.6 mod_wsgi/3.4 Python/2.7.8 PHP/5.5.17 mod_ssl/2.2.29 OpenSSL/0.9.8za DAV/2 mod_perl/2.0.8 Perl/v5.20.0 is not blacklisted
< Server: Apache/2.2.29 (Unix) mod_fastcgi/2.4.6 mod_wsgi/3.4 Python/2.7.8 PHP/5.5.17 mod_ssl/2.2.29 OpenSSL/0.9.8za DAV/2 mod_perl/2.0.8 Perl/v5.20.0
< X-Powered-By: PHP/5.5.17
< Cache-Control: no-cache
< Set-Cookie: laravel_session=eyJpdiI6IjRPMk9TT0ZnZklTMG1uWlFDancyMWc9PSIsInZhbHVlIjoic1V1RjA5aVBJdFNLM0JLclNROEE1a0dCeHNEMWhVNFVReTlUOHdidE44WEJzRnB4WFkxdWo0V0ozcXFVSW9LYzZiZzZSSlFCNXNTTjl2Mzh4TlFtTUE9PSIsIm1hYyI6IjhlYzY0YjFkNTQzNjk5ZGMxNDk3YmY4ZjU4YTYzYzM4YzgxZjg1MzlhMWUxNWVjYWE4ZThlMmU0N2RjNWFkZGMifQ%3D%3D; expires=Mon, 20-Oct-2014 15:08:57 GMT; Max-Age=7200; path=/; httponly
< Transfer-Encoding: chunked
< Content-Type: application/json
<
* Connection #0 to host myapi.api left intact
{"error":false,"users":[{"id":"1","firstname":"","lastname":"","username":"admin#admin.com","created_at":"2014-10-17 15:35:10","updated_at":"2014-10-17 15:35:10","client_id":"0","enterprise_id":"0","usertype_id":"0"},{"id":"2","firstname":"","lastname":"","username":"seconduser","created_at":"2014-10-17 15:35:10","updated_at":"2014-10-17 15:35:10","client_id":"0","enterprise_id":"0","usertype_id":"0"}
EDIT: This question is probably too specific and even though I haven't found a solution and have gone a different way with this project because specifications have changed I will leave it here in case it can help someone.
My guess on the answer is as André Daniel suggests in a comment, that the authentication is breaking something and guzzle isn't giving me my original json thus creating the error.

On your question you said this URL works via the command line:
http://myapi.api/api/v1/users/1
But you are calling this URL via guzzle
http://myapi.api/api/v1/users
So are you sure the route you are trying to call via guzzle works via the command line?

I finally changed the approach as we needed a different authentication method, so this question is no longer relevant to my case.

I know this is pretty old, but here's what I got to work with Guzzle:
$client = new GuzzleHttp\Client();
$user = 'admin#admin.com';
$pass = 'password';
$res = $client->get('http://myapi.api/api/v1/users', [
'headers' => [
'Authorization' => 'Basic ' . base64_encode($user . ":" . $pass),
],
]);
$users = $res->json();
$users = $users['users'];
You could even store the authorization data on the Guzzle instance, like this:
$client = new GuzzleHttp\Client([
'headers' => [
'Authorization' => 'Basic ' . base64_encode($user . ":" . $pass),
],
]);
$user='admin#admin.com';
$pass='password';
$res = $client->get('http://myapi.api/api/v1/users');
$users = $res->json();
$users = $users['users'];

Related

PHP Curl Error 35 - Peer reports incompatible or unsupported protocol version

I'm attempting to make POST requests to an external API(Code below). I manage to get the curl coding working on my localhost but when I go to my staging server the curl returns error Peer reports incompatible or unsupported protocol version(35). From reading into this I need to add an error buffer to get more debugging info but the documentation is confusing.
Yet when I make a curl request directly in the servers terminal with I receive a connection successful. Which makes me extremely confused as the server is clearly capable to make curl requests.
PHP Curl Code
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode($body),
CURLOPT_HTTPHEADER => $header,
));
$response = curl_exec($curl);
$err = curl_error($curl);
echo "response: " . $response;
echo "<br><br>error: " . $err;
curl_close($curl);
Server Curl Response
curl https://support.zendesk.com/api/v2/users/create_or_update.json
* About to connect() to support.zendesk.com port 443 (#0)
* Trying 104.16.51.111...
* Connected to support.zendesk.com (104.16.51.111) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* CAfile: /etc/pki/tls/certs/ca-bundle.crt
CApath: none
* SSL connection using TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
* Server certificate:
* subject: CN= support.zendesk.com,O="CloudFlare, Inc.",L=San Francisco,ST=CA,C=US
* start date: Mar 08 00:00:00 2019 GMT
* expire date: Mar 08 12:00:00 2020 GMT
* common name: support.zendesk.com
* issuer: CN=CloudFlare Inc ECC CA-2,O="CloudFlare, Inc.",L=San Francisco,ST=CA,C=US
> GET /api/v2/users/create_or_update.json HTTP/1.1
> User-Agent: curl/7.29.0
> Host: support.zendesk.com
> Accept: */*
>
< HTTP/1.1 401 Unauthorized
< Date: Fri, 12 Apr 2019 12:52:28 GMT
< Content-Type: application/json; charset=UTF-8
< Content-Length: 37
< Connection: keep-alive
< Set-Cookie: __cfduid=da0ecd56691c96b9b3dac091df58383d51555073548; expires=Sat, 11-Apr-20 12:52:28 GMT; path=/; domain=.ralphandrussoclientcare.zendesk.com; HttpOnly
< WWW-Authenticate: Basic realm="Web Password"
< Strict-Transport-Security: max-age=31536000;
< Cache-Control: no-cache
< X-Zendesk-Origin-Server: app23.pod17.euw1.zdsys.com
< X-Request-Id: 4c65566eacc82981-DUB
< X-Runtime: 0.032000
< X-Zendesk-Request-Id: 3360f95a861586e6f414
< Set-Cookie: __cfruid=7af98f1cbac97922c1c15b82f7c133c3945a446e-1555073548; path=/; domain=.ralphandrussoclientcare.zendesk.com; HttpOnly
< Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
< Server: cloudflare
< CF-RAY: 4c65566eacc82981-DUB
<
* Connection #0 to host support.zendesk.com left intact
{"error":"Couldn't authenticate you"}
In order to solve this problem I performed a server SSL test using https://www.ssllabs.com/ssltest/ which showed me which Protocols were already open and available on the server.
From that I followed the answer to this question TLS 1.2 not working in cURL which showed me which PHP CURLOPT_SSLVERSION number to use in order to access an open protocol.
Therefore I had to add the following line of code to my Curl Array
CURLOPT_SSLVERSION => CURL_SSLVERSION_TLSv1_2

PHP Guzzle Empty Response on Post Request

I'm implementing a Drupal WebForm Handler for posting data to the PayU
Web Checkout Integration after submission, after hours of trying I started to think there was a problem with the Guzzle Client, so I took off the code from Drupal to test separately. I used a simple Rest API GET request and worked fine, however this POST request still doesn't return anything and I've tried everything from working with streams to changing Guzzle versions as mentioned here. I've used Postman as well and things work fine there.
<?php
ini_set('display_errors',1);
ini_set('display_startup_errors',1);
error_reporting(E_ALL);
require_once './vendor/autoload.php';
use GuzzleHttp\Client;
use GuzzleHttp\Psr7;
//use GuzzleHttp\Stream\Stream;
try {
$client = new Client();
//$post_url = $this->configuration['submission_url'];
$post_url = 'https://sandbox.gateway.payulatam.com/ppp-web-gateway';
//$response = $client->request('GET', $post_url);
$response = $client->request('POST', $post_url,[
'debug' => true,
'form_params' => [
'merchantId' => '508029',
'ApiKey' => '4Vj8eK4rloUd272L48hsrarnUA',
'referenceCode' => 'TestPayU',
'accountId' => '512326',
'description' => 'Test PAYU',
'amount' => '3',
'tax' => '0',
'taxReturnBase' => '0',
'currency' => 'USD',
'signature' => 'ba9ffa71559580175585e45ce70b6c37',
'test' => '1',
'buyerEmail' => 'test#test.com'
]
]);
//$response = Psr7\stream_for($response->getBody());
var_dump($response->getBody()->getContents());
}
catch(Exception $e) {
echo($e->getMessage());
}
This is the debug report. I'd appreciate any help. Thanks.
* Trying 69.20.41.99... * Connected to sandbox.gateway.payulatam.com
(69.20.41.99) port 443 (#0) * Cipher selection:
ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:#STRENGTH *
successfully set certificate verify locations: * CAfile:
/Applications/DevDesktop/common/cert/cacert.pem CApath: none * SSL
connection using TLSv1.2 / AES256-SHA256 * Server certificate: *
subject: OU=Domain Control Validated; OU=COMODO SSL Unified
Communications; CN=payulatam.com * start date: 2017-06-07 00:00:00 GMT *
expire date: 2019-06-05 23:59:59 GMT * subjectAltName:
sandbox.gateway.payulatam.com matched * issuer: C=GB; ST=Greater
Manchester; L=Salford; O=COMODO CA Limited; CN=COMODO RSA Domain
Validation Secure Server CA * SSL certificate verify ok. > POST /ppp-
web-gateway HTTP/1.1 Host: sandbox.gateway.payulatam.com User-Agent:
GuzzleHttp/6.2.1 curl/7.44.0 PHP/7.0.14 Content-Type: application/x-www-
form-urlencoded Content-Length: 234 * upload completely sent off: 234
out of 234 bytes < HTTP/1.1 302 Found < Set-Cookie:
JSESSIONID=79253C01031875A1B442649D8B824674.gateway-nodo1;
Path=/ppp-web-gateway/; Secure; HttpOnly < X-FRAME-OPTIONS:
SAMEORIGIN < Set-Cookie: cookie-pol-checkout-version_512326=V2;
Expires=Fri, 28-Sep-2018 22:54:23 GMT; Path=/ppp-web-gateway/;
Secure < Location: /ppp-web-gateway/page-redirect.zul < Content-
Length: 0 < Date: Tue, 03 Oct 2017 22:54:22 GMT < Server: PayU
server < * Connection #0 to host sandbox.gateway.payulatam.com left
intact * Found bundle for host sandbox.gateway.payulatam.com:
0x7918c650 * Re-using existing connection! (#0) with host
sandbox.gateway.payulatam.com * Connected to
sandbox.gateway.payulatam.com (69.20.41.99) port 443 (#0) > GET
/ppp-web-gateway/page-redirect.zul HTTP/1.1 Host:
sandbox.gateway.payulatam.com User-Agent: GuzzleHttp/6.2.1
curl/7.44.0 PHP/7.0.14 Content-Type: application/x-www-form-
urlencoded < HTTP/1.1 200 OK < Set-Cookie:
JSESSIONID=EF0110093412FCDF3E56DD15F1937F30.gateway-nodo1;
Path=/ppp-web-gateway/; Secure; HttpOnly < X-FRAME-OPTIONS:
SAMEORIGIN < Set-Cookie: cookie-
pol=pol_190_238_194_79_1507071263918; Domain=pagosonline.net;
Expires=Fri, 28-Sep-2018 22:54:23 GMT; Path=/; Secure < Content-
Language: en-US < Content-Length: 0 < Date: Tue, 03 Oct 2017
22:54:22 GMT < Server: PayU server < * Connection #0 to host
sandbox.gateway.payulatam.com left intact string(0) ""

Guzzle 6.x / Not getting expected result

I have a restful API. when I run POSTMAN on the following URL, I receive as response as follows:
POSTMAN RUN URL
DELETE
https://www.example.com/api/v1/Blog/blog/13
{
"status":"Failure",
"message":"The specified blog post could not be found"
}
The above is of course expected, however, I am unable to read in "status" and "message". How do I get that reply? Here is my present code:
$entry_id = $this->uri->segment(3);
$theUrl = $this->config->item('base_url').'api/v1/Blog/blog/'.$entry_id;
// tested $theUrl and works
$client = new GuzzleHttp\Client([
'base_uri' => $theUrl,
'timeout' => 3.0,
'http_errors' => FALSE
]);
$response = $client->delete($theUrl);
$code = $response->getStatusCode();
$response = $client->delete($theUrl);
$x = $response->getBody();
echo "<pre>";
echo var_dump($x); // cannot see message or status anywhere.
echo "</pre>";
Your suggestions much appreciated.
+++
I have now tried this revised code but still cannot see the STATUS or MESSAGE date in the reply:
$entry_id = $this->uri->segment(3);
$theUrl = $this->config->item('base_url').'api/v1/Blog/blog/'.$entry_id;
$client = new GuzzleHttp\Client([
'timeout' => 3.0,
'http_errors' => FALSE
]);
$response = $client->delete($theUrl, ['debug' => true]);
$code = $response->getStatusCode();
$x = $response->getBody();
echo "<pre>";
echo var_dump($x);
echo "</pre>";
die();
Here is the dump and the debug info:
https://www.example.com/api/v1/Blog/blog/6
* Hostname was found in DNS cache * Trying 104.131.132.25... * Connected to
www.example.com (104.131.132.25) port 443 (#1) * successfully set
certificate verify locations: * CAfile: none CApath: /etc/ssl/certs * SSL
connection using XXXXXXXXXXXXXXXXXXXXXXXXX* Server certificate: *
subject: CN=www.example.com * start date: 2016-10-29 05:15:00 GMT * expire
date: 2017-01-27 05:15:00 GMT * subjectAltName: www.movinghaus.com matched
* issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3 * SSL
certificate verify ok. > DELETE /api/v1/Blog/blog/6 HTTP/1.1 User-Agent:
GuzzleHttp/6.2.0 curl/7.35.0 PHP/5.5.9-1ubuntu4.11 Host: www.example.com <
HTTP/1.1 200 OK < Date: Fri, 04 Nov 2016 03:55:21 GMT * Server Apache/2.4.7
(Ubuntu) is not blacklisted < Server: Apache/2.4.7 (Ubuntu) < X-Powered-By:
PHP/5.5.9-1ubuntu4.11 < Set-Cookie:
PHPSESSID=XXXXXXXXXXXXXXXXXX; expires=Fri, 04-Nov-2016 05:55:21 GMT; Max-
Age=7200; path=/; HttpOnly < Expires: Thu, 19 Nov 1981 08:52:00 GMT <
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-
check=0 < Pragma: no-cache < Content-Length: 40 < Content-Type:
application/json; charset=utf-8 < * Connection #1 to host www.example.com
left intact
object(GuzzleHttp\Psr7\Stream)#65 (7) {
["stream":"GuzzleHttp\Psr7\Stream":private]=>
resource(50) of type (stream)
["size":"GuzzleHttp\Psr7\Stream":private]=>
NULL
["seekable":"GuzzleHttp\Psr7\Stream":private]=>
bool(true)
["readable":"GuzzleHttp\Psr7\Stream":private]=>
bool(true)
["writable":"GuzzleHttp\Psr7\Stream":private]=>
bool(true)
["uri":"GuzzleHttp\Psr7\Stream":private]=>
string(10) "php://temp"
["customMetadata":"GuzzleHttp\Psr7\Stream":private]=>
array(0) {
}
}
I think the base_uri parameter for new GuzzleHttp\Client is not needed. The base_uri parameter is used to set a base url. (http://docs.guzzlephp.org/en/latest/quickstart.html?highlight=base_uri) All calls to the client should then use relative uris. Since you are using an absolute url in the delete function call, you should not need the base_uri parameter.
Also you are calling the delete function twice: $response = $client->delete($theUrl).
In according to docs.
You should do
$x = $response->getBody()->getContents();
Or cast body to string:
$x = (string)$response->getBody()

Authenticating to webservice with Kerberos from PHP in IIS

I am writing a PHP webapplication that has to connect to a webservice using Kerberos 5 authentication (Active Directory). My PHP website is hosted on IIS 7.5 with PHP 5.5. The application pool is running under the account that is authorized in Active Directory and for the target webservice.
I tried every example code that I could find on this site and other sites but to no avail.
This is the PHP code I am using now:
$url = 'http://mywebservice/login/kerberos';
$ch = curl_init();
$options = [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_VERBOSE => true,
CURLOPT_HTTPAUTH => CURLAUTH_GSSNEGOTIATE,
CURLOPT_HTTPHEADER => ['Authorization: Negotiate'],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_USERPWD => 'myuser',
CURLOPT_URL => $url,
CURLOPT_HEADER => 1
];
curl_setopt_array( $ch, $options);
$result = curl_exec($ch);
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$header = substr($result, 0, $header_size);
$body = substr($result, $header_size);
print $result;
This gives me the following message:
HTTP/1.1 302 Found Date: Fri, 21 Oct 2016 14:49:15 GMT X-Robots-Tag: noindex,nofollow WWW-Authenticate: Location: http://mywebservice/login?login_fail Content-Length: 0
When I remove the CURLOPT_HTTPHEADER => ['Authorization: Negotiate'] l get an Internal Server error from the curl module.
When I use curl commandLine I get the following result:
curl --negotiate http://mywebservice/login/kerberos -umyuser#mydomain --verbose -c "c:\cookie.txt" -b "c:\cookie.txt"
Enter host password for user 'myuser#mydomain':
* Trying (192.168.1.1...
* Connected to mywebservice (192.168.1.1) port 80 (#0)
> GET /login/kerberos HTTP/1.1
> User-Agent: curl/7.41.0
> Host: mywebservice
> Accept: */*
> Cookie: JSESSIONID_PUBLIC=X(MASKED)XXXXXXXXXXXXXXXXX
>
< HTTP/1.1 401 Unauthorized
< Date: Fri, 21 Oct 2016 14:52:46 GMT
< X-Robots-Tag: noindex,nofollow
< WWW-Authenticate: Negotiate
< Expires: Thu, 01 Jan 1970 00:00:00 GMT
< Last-Modified: Thu, 20 Oct 2016 14:52:46 GMT
< Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
< Pragma: no-cache
< P3P: CP=CAO PSA OUR
< Content-Type: text/html; charset=UTF-8
< Content-Length: 3643
<
* Ignoring the response-body
* Connection #0 to host mywebservice left intact
* Issue another request to this URL: 'http://mywebservice/login/kerberos'
* Found bundle for host mywebservice: 0xXXXXXXX
* Re-using existing connection! (#0) with host mywebservice
* Connected to mywebservice (192.168.1.1) port 80 (#0)
* Server auth using Negotiate with user 'myuser#mydomain'
> GET /login/kerberos HTTP/1.1
> Authorization: Negotiate X(MASKED)XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXD
w==
> User-Agent: curl/7.41.0
> Host: mywebservice
> Accept: */*
> Cookie: JSESSIONID_PUBLIC=X(MASKED)XXXXXXXXXXXXXXXXX
>
< HTTP/1.1 302 Found
< Date: Fri, 21 Oct 2016 14:52:46 GMT
< X-Robots-Tag: noindex,nofollow
< WWW-Authenticate:
< Location: http://mywebservice/?login_fail
< Content-Length: 0
<
* Connection #0 to host mywebservice left intact
When I test with the KerberosAuthenticationTester tool (http://blog.michelbarneveld.nl/michel/archive/2009/12/05/kerberos-authentication-tester.aspx) it authenticates me right away when I pass the url and credentials.
I assume that it is not working because I am missing the krb5 library. I could not find it as a DLL so I tried recompiling it with the PHP source in Visual Studio. This is not working for me as well, I am missing the config.w32 file. If necessary I can elaborate on that but first I want to know if this is really needed.
I also installed MIT Kerberos but this did not help aswell.
Is it correct that I need the krb5 DLL, or am I on the wrong track? If I need this DLL, where can I get it or how can I compile it? If there is another solution I would be very happy to hear it.
Thanks everyone for taking your time for me and replying!

PHP Guzzle: Empty body response

I just started experimenting with guzzle but i am getting an empty string on the response body
$client = new Client([
'base_uri' => 'http://httpbin.org',
'timeout' => 2.0,
]);
$response = $client->request('GET', '', ['debug' => true]);
var_dump($response->getBody()->getContents());
And the response i am getting is:
* About to connect() to httpbin.org port 80 (#0)
* Trying 23.22.14.18...
* Connected to httpbin.org (23.22.14.18) port 80 (#0)
> GET / HTTP/1.1
User-Agent: GuzzleHttp/6.2.0 curl/7.29.0 PHP/5.5.34
Host: httpbin.org
HTTP/1.1 200 OK
Server: nginx
Date: Mon, 06 Jun 2016 06:48:13 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 12150
Connection: keep-alive
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
* Connection #0 to host httpbin.org left intact
string(0) ""
As you can see the body is "" but the Content-Length is correct.
There is a bad commit on the master branch of guzzlehttp/psr7. If you lock the version in your composer.json file, everything should be working as expected.
"guzzlehttp/guzzle": "6.2",
"guzzlehttp/psr7": "1.3"

Categories