Webmock not responding to stub_request - webmock

In features/support/webmock.rb, I have
stub_request(:get, /(http\:\/\/catalog\.viglink\.com\/vigcatalog\/products\.xml\?include_identifiers=true&key=.*&keyword_upc=628586348097&results_per_page=20)/).
with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'User-Agent'=>'Ruby'}).
to_return(:status => 200, :body => File.open('spec/support/628586348097.txt'))
I have two cucumber scenarios in which this stub should be called. In one scenario, the stub is recognized, and the test passes. In the other scenario, I receive the following:
Real HTTP connections are disabled. Unregistered request: GET http://catalog.viglink.com/vigcatalog/products.xml?include_identifiers=true&key=key&keyword_upc=628586348097&results_per_page=20 with headers {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate', 'User-Agent'=>'Ruby'}
You can stub this request with the following snippet:
stub_request(:get, "http://catalog.viglink.com/vigcatalog/products.xml?include_identifiers=true&key=key&keyword_upc=628586348097&results_per_page=20").
with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate', 'User-Agent'=>'Ruby'}).
to_return(:status => 200, :body => "", :headers => {})
Any suggestions as to why webmock is not recognizing the stub request?

In the webmock.rb file, be sure to put the stub_requests in a Before block. Otherwise, you'll need to include them in your steps...
require 'webmock/cucumber'
Before do
WebMock.disable_net_connect! #A precaution to avoid webmock making real http calls
stub_request(:get, /.*url*/).to_return(:body => File.new("#{::Rails.root}/support/webmock/listing.json")
end

Related

How to serve same response from HttpClient in my controller using Symfony?

I have a Controller that must forward the received request (changing some query parameters) to another server, and returns it's response (with same headers, status and body).
I decided to use HttpClient for doing that.
The problem is that HttpClient converts the content (i.e.: deflating gzip requests), and it breaks the output response.
Here is part of the example:
$response = $client->request($request->getMethod(), $extUrl, [
'headers' => $reqHeaders,
'timeout' => 45,
'verify_host' => false,
'verify_peer' => false,
'body' => $request->getContent(),
]);
#response data
$body = $response->getContent(false);
$statusCode = $response->getStatusCode();
$headers = $response->getHeaders(false);
return new Response($body, $statusCode, $headers);
Considering the second server returns a gzipped content, the response is broken, because it would keep the response header (content-type) but the $body will not be exactly the same, because HttpClient do me the favor of deflate the content.
The question is: is there a way to tell HttpClient to do not touch in my response body?
Or: is there a better way to make this "proxy" controller action?
I found that if accept-encoding is defined in the request headers, it's not inflated by CurlResponse class...
#\Symfony\Component\HttpClient\Response\ResponseTrait::$inflate
$this->inflate = !isset($options['normalized_headers']['accept-encoding']);
And
#\Symfony\Component\HttpClient\Response\response
$response->inflate = \extension_loaded('zlib') && $response->inflate && 'gzip' === ($response->headers['content-encoding'][0] ?? null) ? inflate_init(ZLIB_ENCODING_GZIP) : null;
So, I specified some empty encoding for those cases.
if (empty($request->headers->get('accept-encoding'))) {
//adding some accept-encoding will make httpclient response not to deflate the response (gzdecode) automatically
$request->headers->add(['accept-encoding'=> '']);
}
I still don't know if this is the best approach to forward a request and it's response in the controller, but the above solution solved my problem.

How to fix 401 Unauthorized response WP Rest API

Im making a request to another wordpress site on our network as below.
//Send the request to update the submission post
$response = wp_remote_request( $this->urls->assign_url, array(
'headers' => array(
'Content-Type' => 'application/json; charset=utf-8',
'Authentication' => 'Basic '.base64_encode('somename:somepassword')
),
'body' => json_encode($array),
'method' => 'POST',
'data_format' => 'body'
)
);
Im making this request via ajax.
The callback function is being called and sends back data.
Im also logged into the remote site.
Im using a nonce and the user being authorised in the headers is a valid user.
All I keep getting back is:
body: "{"code":"rest_not_logged_in","message":"You are not currently logged in.","data":{"status":401}}"
Ive only just started getting this since I updated the remote wordpress version. It was working fine before that.
Any thoughts.
I believe in order to authenticate the way you want to, you need to use a plugin - the built-in authentication method is not ideal for offsite requests since it is cookie based.
https://developer.wordpress.org/rest-api/using-the-rest-api/authentication/#authentication-plugins

How to deal with OPTION request?

I have the following code:
window.fetch(myServerURL, {
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
method: "POST",
body: JSON.stringify(app.jsonRequest)
})
.then(res => res.json())
.then(json => {
if (json.affectedRows === 1) {
okMessage("Be welcome and check your email!");
} else {
errorMessage('Sorry! Please try again later.');
}
})
which is entitled to send a post message to my backend server and register a new user to my system using a MySQL database. And this is working fine, but my messages are not showing.
(Yes, I konw I should test more than just json.affectedRows to make sure the register was inserted fine, but I am simplifying the problem to make things clear here.)
It happens than I am detecing a preflight request OPTIONS and this is making my logic blow away, 'cause it seems it receives the OPTIONS answer first and do NOT have an affectedRows to compare. In fact, the OPTIONS request generates just OK, since server-side is configured with CORS.
On the other hand, when I write
.then(json => {
console.log(json);
}
to try to capture this OK answer to the OPTIONS request, the answer is
{"fieldCount":0,"affectedRows":1,"insertId":1845,"serverStatus":2,"warningCount":0,"message":"","protocol41":true,"changedRows":0}
as if there had been no OPTIONS request.
After trying other possible solutions with no success, Id would like to ask you all how should I deal with this in order to get my messages shown?

Computer Vision API - v1.0 Recognize Handwritten Text returns empty response

I am trying to start using the computer vision API but I keep getting an empty response. My request in php (as exported by Postman) looks like this:
<?php
$request = new HttpRequest();
$request->setUrl('https://westcentralus.api.cognitive.microsoft.com/vision/v1.0/recognizeText');
$request->setMethod(HTTP_METH_POST);
$request->setQueryData(array(
'language' => 'en',
'handwriting' => 'true'
));
$request->setHeaders(array(
'Postman-Token' => '442d04f7-49a0-4262-9d0f-666fe5240cc7',
'Cache-Control' => 'no-cache',
'Content-Type' => 'application/octet-stream',
'Ocp-Apim-Subscription-Key' => 'KEY'
));
try {
$response = $request->send();
echo $response->getBody();
} catch (HttpException $ex) {
echo $ex;
}
The above code works fine with the ocr endpoint!
The file is passed as binary using Postman.
Edit: I also tried to copy/paste the code from here: https://learn.microsoft.com/en-gb/azure/cognitive-services/computer-vision/quickstarts/php#ocr-php-example-request and if I change the ocr endpoint to recognizeText I get an empty response as well!
Unlike the other Computer Vision endpoints, RecognizeText is an asynchronous operation. Barring some issue with the image, you will get a 202 response instead of the usual 200 response. 202 responses customarily contain an empty response body. In this particular case you can find the URL where you can query for completion of the task. The documentation is here. The header you're looking for is Operation-Location.

Logstash and Flowdock integration

I'm trying to send a subset of messages to Flowdock as output from Logstash. Unfortunately, due to this issue I get essentially nothing back about why my messages aren't making it. Stripping down to a basic example, I see the problem even if I change my output config to the following:
output {
http {
http_method => "post"
url => "https://api.flowdock.com/v1/messages/team_inbox/API_TOKEN"
format => "message"
content_type => "application/json"
message => "{\"source\":\"logstash\",\"from_address\":\"me#example.com\", \"subject\":\"Log Message\", \"content\":\"test\"}"
}
}
I know, though, that output is generally working because if I add the following to output I see log messages written to the file:
file {
path => "/mnt/test.log"
}
I also know that the http message I'm sending to Flowdock should work since
curl -X POST https://api.flowdock.com/v1/messages/team_inbox/API_TOKEN -d "{\"source\":\"logstash\",\"from_address\":\"me#example.com\",\"subject\":\"Log Message\",\"content\":\"test\"}" -H "Content-Type: application/json"
results in a message being posted to the team inbox.
Are there any ways to work around this issue to determine why my output from logstash is failing?
I would start debugging the issue by first sending the requests from Logstash to a service that just outputs the received request, for example RequestBin.
Something like:
output {
http {
http_method => "post"
url => "http://requestb.in/<created_id>"
format => "message"
content_type => "application/json"
message => "{\"source\":\"logstash\",\"from_address\":\"me#example.com\",\"subject\":\"Log Message\", \"content\":\"test\"}"
}
}
After you've made sure that the request Logstash is making is correct, take that request (preferably the exact data) and try to send it to Flowdock using curl or some other means.
At this point you should be able to tell why the request fails in either end and notify the party accordingly (i.e. open a ticket to https://logstash.jira.com/secure/Dashboard.jspa or send an email to support#flowdock.com).

Resources