POST with guzzle returns 417 - php

I created an API to post JSON data to another API, but for some JSON it returns 417 error code.
I checked these JSONs and tried to re-post them, but i got the 417 again, the post is only working if i delete some values from the JSON.
The JSONs is always valid and it's around 1.5KB of data, but i cant figure it out why it's happening.
Guzzle version: 7.0, PHP version: 7.4
$guzzle = new \GuzzleHttp\Client([
'verify' => false,
'expect' => false
]);
$request = null;
$request = $guzzle->post(
$request_url,
[
'auth' => [self::$API_USERNAME, self::$API_PASSWORD],
'json' => [$request_body]
]
);

I've created a postman request and send the invalid JSON to the API direct without the middleware, now i can see the full error related to the invalid email address format.

Related

PHP Soap Client to handle multipart/related

I am developing an application that needs to access a SOAP api. The soap API should return a base64 encoded zip file, and it does so when being fired from SOAPUI. However I am trying to read this result programatically therefore I would need to get the file with a request fired from PHP.
$client = new MTOMSoapClient($url, array("soap_version" => SOAP_1_1,"trace" => 1));
$user_param = array (
'DealerCode' => "1234",
'Hash' => "asjdfasjda1231231231",
'Password' => "somerandompassword",
'UserName' => "somerandomusername"
);
var_dump(
$client->__soapCall(
"DownloadOffer",
array($user_param)
)
);
var_dump($client->__getLastRequest());
I also extended PHP's soap client like shown here without the proper results: https://gist.github.com/pkmishra/2243055
The same error is shown in postman:
SoapFault: Cannot process the message because the content type 'text/xml; charset=utf-8' was not the expected type 'multipart/related; type="application/xop+xml"'. in file /app/app/Http/Middleware/MTOMSoapClient.php on line 8
Any advice, library, way to get the response or at least the reason behind the error is greatly apreciated.

"Empty Payload. JSON content expected" error calling Microsoft Graph (Guzzle & PHP)

I am trying to call the Microsoft Graph API to reset a passcode on a device registered with Intune. Unfortunately when I go to make the call, I receive an error stating that the JSON Payload is empty. The specific endpoint does not require a JSON payload, in fact it says to not include a body at all.
I attempted to add some JSON to see if that would satisfy the error, and I still receive the same error message.
Here is the call I am making:
$client = new Client();
try{
$client->post('https://graph.microsoft.com/beta/managedDevices/12345resetPasscode', [
'headers' => [
'Authorization' => 'Bearer 12345',
'Accept' => 'application/json',
'Content-Type' => 'application/json',
'json' => json_encode(['hello' => 'world']),
]
]);
} catch (\GuzzleHttp\Exception\ClientException $e) {
dd($e->getResponse()->getBody()->getContents());
}
Here is the error I am receiving:
"Bad Request: Empty Payload. JSON content expected."
https://i.stack.imgur.com/gwwtJ.png
Here is the API Documentation I am working off: https://developer.microsoft.com/en-us/graph/docs/api-reference/beta/api/intune_devicefe_manageddevice_resetpasscode
Using PHP 7 & Guzzle 6
Any help is appreciated!
I'm an engineer on the Microsoft Intune team, working on the integration between Microsoft Graph and Intune.
It looks like there is an error in the documentation (I will make sure that is fixed). The correct URL You should be using is:
https://graph.microsoft.com/beta/managedDevices/12345/resetPasscode
Where 12345 is a the id of the device.
Hope that resolves your issue
Peter

Getting "Invalid user credentials supplied" when sending request with Guzzle PHP

I am sending the absolutely same request to an endpoint with Guzzle PHP and Postman extension for Chrome.
When sending the request with Postman - I do recieve the response, but when I am sending the same request with Guzzle I get "Invalid user credentials supplied".
I have the Auth type Basic and supply the same username/password for both apps. Here is the code that I use for guzzle:
$credentials = [$client->api_username, $client->decrypted_password, 'basic'];
$result = $this->client->get($fullUrl, [
'auth' => $credentials
]);
I have dumped the credentials - it is the correct array. I have double checked the Guzzle docs. Funny thing is that when I am trying to send request for another user for the same endpoint - I do recieve the correct response, which made me think, that I might have typos in credentials - but I have rechecked - and even copy pasted from Postman - still cant recieve the response :/
Would you love to share what your variable $credentials has as data?
In case try the code below it was tested and works:
$client = new Client();
$this->results = $client->request('GET/POST', $uri, [
'debug' => true,
'query' => $arguments,
'auth' => [$username, $password],
'verify' => false
])->getBody();
And if you ask about the other arguments such as verify, this property tells guzzle to disable certificate verification.
Read below: http://docs.guzzlephp.org/en/stable/request-options.html#verify
For more information about auth: http://docs.guzzlephp.org/en/stable/request-options.html#auth
Could you compare the Authentication header from Postman and from Guzzle? If you get an exception from Guzzle, you can get it like $exception->getRequest()->getHeader('Authentication').

Using Oauth with GuzzleHttp and Magento API in PHP

I'm trying to access Magento's REST API in PHP, using Oauth and GuzzleHttp.
I'm basing my example off of this Twitter example:
https://github.com/guzzle/oauth-subscriber
My code so far is:
use GuzzleHttp\Subscriber\Oauth\Oauth1;
use GuzzleHttp\Client;
$client = new Client(array(
'base_url' => 'http://magento',
'defaults' => array('auth' => 'oauth')
));
$oauth = new Oauth1(array(
'consumer_key' => 'magento_key',
'consumer_secret' => 'magento_secret'
));
$client->getEmitter()->attach($oauth);
$response = $client->post('/oauth/initiate');
print_r($response);die();
My host is http://magento. I'm trying to POST my key and secret to /oauth/initiate like is says in the Magento docs.
http://www.magentocommerce.com/api/rest/authentication/oauth_authentication.html#OAuthAuthentication-AuthenticationEndpoints
Does anyone have any insight on what I might be doing wrong? I'm getting a 500 error using Firefox's RESTClient to make this call.
EDIT:
I'm now getting this exception thrown
{
"response": "Client error response [url] http://magento/oauth/initiate [status code] 400 [reason phrase] Bad Request"
}
It's getting a 400 from http://magento/oauth/initiate but this is only when using GuzzleHttp and Oauth. If I make the POST directly within RESTClient as http://magento/oauth/initiate, I get an error response from Magento itself (so it does not 400), and if I add all the necessary params I get the appropriate token responses.
UPDATE:
After inspecting the exception being thrown I'm seeing my authorization array does not conain my callback url. This is suppose to be http://magento/oauth/authorize which I've adde in the RESTClient and it works with the token response. Iv'e tried adding this in my $oauth array as 'callback' and 'oauth_callback' but neither seem to work. I can see this appears in the exception, under my data array, but not in the [authorize] array which I believe it needs to be. I tihnk that's what's missing, if someone has an idea of where it needs to be placed.

Salesforce creates record but responds with a 405

I've written a Wordpress Plug-in that interacts with Salesforce via the REST API. It successfully gets an Instance URL and an Authentication Token using a username/password.
I'm able to submit queries and create objects using wp_remote_post with GET and POST respectively.
However, when creating objects, though successfully created in the Salesforce instance, I get the following in response to my POST:
{"message":"HTTP Method 'POST' not allowed. Allowed are HEAD,GET,PATCH,DELETE","errorCode":"METHOD_NOT_ALLOWED"}
Using the same json body content from these requests, I am able to submit and create via the Salesforce Workbench with no problems at all. I get a proper response that looks like this:
{
"id" : "003E000000OubjkIAB",
"success" : true,
"errors" : [ ]
}
Is there something in the Headers that I'm sending that Salesforce only partially disagrees with? Here are some other arguments that are getting sent as a result of using wp_remote_post - http://codex.wordpress.org/HTTP_API#Other_Arguments
Here's the php code that's calling it:
$connInfo['access_token'] = get_transient('npsf_access_token');
$connInfo['instance_url'] = get_transient('npsf_instance_url');
$url = $connInfo['instance_url'] . $service;
$sfResponse = wp_remote_post($url, array(
'method' => $method,
'timeout' => 5,
'redirection' => 5,
'httpversion' => 1.0,
'blocking' => true,
'headers' => array("Authorization" => "OAuth ". $connInfo['access_token'], "Content-type" => "application/json"),
'body' => $content,
'cookies' => array()
)
);
The $content is being encoded via json_encode before it gets to this point.
Update:
It is specific to one of the extra CURL options being sent by the WP_Http_Curl class. I haven't yet narrowed down which one Salesforce is having a problem with.
The solution is disable redirection in the request. You have it as 5 (the default) -- it needs to be set to 0 for this to work.
The initial request works but Salesforce sends a location header as a part of the response (the URL of the newly created object). WordPress thinks it is being told that the URL moved and that it should try again at this new URL. The response you're seeing is the result of that second request to the actual object you just created. That URL doesn't accept POST requests apparently.
It's a bit odd for Salesforce to be sending such a header, but there's also some discussion going on on the WordPress side that WordPress shouldn't follow location headers for non-301/302 responses which would solve this.
Thanks for posting this by the way. You update made me start debugging WP_Http_Curl which made me realize it was actually making a second HTTP request.

Categories