how to call xml request in ruby using httparty? - ruby

while calling xml request api in ruby it is getting xml parser error as response.
API call
require 'httparty'
response = HTTParty.post("http://www.99acres.com/99api/v1/getmy99Response/test/uid/",
:headers => {"Accept" => "application/xml", "Content-Type" =>"application/xml"},
:body => '<?xml version="1.0"?><query>
<user_name>test</user_name><pswd>testest</pswd><start_date>2019-03-25 12:03:00</start_date><end_date>2019-04-24 12:04:00</end_date></query>'
)
Error Response
ERROR-0000XML Parsing
Error
How to call XML request API calling in ruby?.

You wrote correct request to API, but looks like they just don't give you access to API, looks like your login credential not correct, but there no problem with your code!
This response from API!
#<HTTParty::Response:0x7ff11da769b0 parsed_response={"response"=>{"code"=>"1", "msg"=>"INVALID KEY"}}, #response=#<Net::HTTPUnauthorized 401 Unauthorized readbody=true>, #headers={"server"=>["nginx"], "content-type"=>["text/xml;charset=UTF-8"], "content-length"=>["85"], "content-security-policy-report-only"=>["block-all-mixed-content; report-uri https://track.99acres.com/csp_logging.php;"], "etag"=>["\"d41d8cd98f00b204e9800998ecf8427e\""], "date"=>["Wed, 24 Apr 2019 18:46:46 GMT"], "connection"=>["close"], "set-cookie"=>["99_ab=20; expires=Thu, 23-Apr-2020 18:46:46 GMT; Max-Age=31536000; path=/"]}>

Related

Post request detected as bot with HTTPARTY but not with postman (same headers)

I am trying to fetch a public API. When I do it from the postman everything works fine however when I do it from my app I get and error message: <META NAME=\"robots\" CONTENT=\"noindex,nofollow\"
I do not understand how this is possible?
Here is are the headers variables I adjust when I make my request with postman:
Cookie:"some cookie"
Cache-Control: no-cache
Content-Type:application/json
Host:"some host"
Here is my httparty request:
response = HTTParty.post(url,
:body => body_request (same as with postman),
:headers => {
'Content-Type' => 'application/json',
'cookie' => 'same cookie as above',
'Host' => 'same host as above',
'Cache-Control' => 'no-cache'
}
)
Why would it work with postman but not with a httparty request?
Thank you
I would look into User-Agent, even if you don't explicitely set the header, your http client is still sending one.
Postman uses :
"User-Agent": "PostmanRuntime/7.26.8",
while HTTParty is simply
"User-Agent": "Ruby"
Maybe your public API (could be more precise if we knew which) has a whitelist of 'non-bot' user agents and HTTParty is not among them
Try overriding it
resp = HTTParty.get 'https://httpbin.org/headers' , headers: {'User-Agent': 'xx'}

Faraday Gem does not send fileData

I am doing an API automation in Ruby using the Faraday Gem to automate a file upload in my API.
I have the follow problem: I need to upload the file as form-data, but it is not working.
Here's the latest syntax that I'm using:
conn = Faraday.new($api['upload']) do |f|
f.request :multipart
f.adapter Faraday.default_adapter
end
formdata = { :file => Faraday::UploadIO.new('./arquivo/pequeno.pdf', 'file/pdf') }
headers = {'Content-Type' => 'multipart/form-data', 'Authorization' => 'Bearer ' + #token, 'uuidUser' => #uuid}
conn.post('/upload', formdata, headers)
Also, I cannot get the response body or code. I got the error that method body or code or status does not exist.
Do you have any idea what I may be doing wrong?
I put the the logger to see further what is happening, and this is the result:
W, [2019-11-27T11:15:15.385754 #4208] WARN -- : HTTP 500
D, [2019-11-27T11:15:15.386412 #4208] DEBUG -- : "x-content-type-options: nosniff\nx-xss-protection: 1; mode=block\ncache-control: no-cache, no-store, max-age=0, must-revalidate\npragma: no-cache\nexpires: 0\nx-frame-options: DENY\ncontent-type: application/json;charset=UTF-8\ntransfer-encoding: chunked\ndate: Wed, 27 Nov 2019 14:15:14 GMT\nconnection: close\n\n{\"exception\":\"org.springframework.web.multipart.MultipartException\",\"status\":500,\"error\":[\"Failed to parse multipart servlet request; nested exception is java.io.IOException: org.apache.tomcat.util.http.fileupload.FileUploadException: the request was rejected because no multipart boundary was found\"]}"
I solved the problem.
It was on the type of file. Instead of using 'file/pdf' I changed to 'application/pdf' and worked.
For each type of file there is a different way of usage:
pdf:
application/pdf
docx:
application/vnd.openxmlformats-officedocument.wordprocessingml.document

How to use Typhoeus::Request object using https

I'm trying to make an https request using the Typhoeus::Request object and i don't get it working.
The code i'm running is something like this:
url = "https://some.server.com/"
req_opts = {
:method => :get,
:headers => {
"Content-Type"=>"application/json",
"Accept"=>"application/json"
},
:params=>{},
:params_encoding=>nil,
:timeout=>0,
:ssl_verifypeer=>true,
:ssl_verifyhost=>2,
:sslcert=>nil,
:sslkey=>nil,
:verbose=>true
}
request = Typhoeus::Request.new(url, req_opts)
response = request.run
The response i'm getting is this:
HTTP/1.1 302 Found
Location: https://some.server.com:443/
Date: Sat, 27 Apr 2019 02:25:05 GMT
Content-Length: 5
Content-Type: text/plain; charset=utf-8
Why is this happening?
Well it's hard to know because your example is not a reachable url. But 2 things I see is that you are not passing an ssl cert or key. But also 302 indicates a redirect. You can try to follow redirection but your first problem is probably you don't need to set SSL options, why are you?
See if you try the following options:
req_opts = {
:method => :get,
:headers => {
"Content-Type"=>"application/json",
"Accept"=>"application/json"
},
:params=>{},
:params_encoding=>nil,
:timeout=>0,
:followlocation => true,
:ssl_verifypeer=>false,
:ssl_verifyhost=>0,
:verbose=>true
}
See the following sections for more info
https://github.com/typhoeus/typhoeus#following-redirections
https://github.com/typhoeus/typhoeus#ssl

Ruby: Savon SOAP Requests receives 400 and 415 errors

I am trying to make a SOAP request using the ruby library Savon.
I am using the following code:
require "savon"
Savon.configure do |config|
config.soap_version = 2 # use SOAP 1.2
config.raise_errors = false
end
wsdl_logon = Savon::Client.new do
wsdl.document = "https://api.affili.net/V2.0/Logon.svc?wsdl"
end
username = 'XXX'
password = 'YYY'
wsdl_logon.http.headers["Content-Type"] = "text/xml; charset=utf-8"
response = wsdl_logon.request "Logon" do
soap.body = {'Username' => username, 'Password' => password, 'WebServiceType' => 'Product'}
end
if response.http_error?
puts "Http Error!"
puts y response.http_error
else
puts "No Http Error!"
end
But I keep receiving 400 error messages ("bad request"). Or, if I remove the following line
wsdl_logon.http.headers["Content-Type"] = "text/xml; charset=utf-8"
I am receiving 415 error messages ("unsupported media type").
I have been using PHP to make these requests until now, and the following code always worked without problems:
$soap_logon = new SoapClient('https://api.affili.net/V2.0/Logon.svc?wsdl');
$token = $soap_logon->Logon(array(
'Username' => 'XXX',
'Password' => 'YYY',
'WebServiceType' => 'Product'
));
Can anybody point me to the right direction what a possible error source might be? I am completely lost right now.
Thank you for your help.
I did as Tom De Leu suggested, and tried to remove as many differences in the generated SOAP requests in question as possible. But I still keep receiving 400 errors. Any hint on possible reasons for this would be highly appreciated.
This is the (working) Request generated by PHP (linebreaks in XML added for clarity):
POST /V2.0/Logon.svc HTTP/1.1
Host: api.affili.net
Connection: Keep-Alive
User-Agent: PHP-SOAP/5.2.0-8+etch16
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://affilinet.framework.webservices/Svc/ServiceContract1/Logon"
Content-Length: 456
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="http://affilinet.framework.webservices/types"
xmlns:ns2="http://affilinet.framework.webservices/Svc"
>
<SOAP-ENV:Body>
<ns2:LogonRequestMsg>
<ns1:Username>xxx</ns1:Username>
<ns1:Password>yyy</ns1:Password>
<ns1:WebServiceType>Product</ns1:WebServiceType>
</ns2:LogonRequestMsg>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
This is the (not working) request generated by Ruby (again, xml linebreaks added for clarity)
SOAP request: https://api.affili.net/V2.0/Logon.svc
Content-Type: text/xml; charset=utf-8, SOAPAction: http://affilinet.framework.webservices/Svc/ServiceContract1/Logon, Content-Length: 605
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:wsdl="http://affilinet.framework.webservices/Svc"
SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="http://affilinet.framework.webservices/types"
xmlns:ns2="http://affilinet.framework.webservices/Svc"
>
<SOAP-ENV:Body>
<ns2:LogonRequestMsg>
<ns1:Username>XXX</ns1:Username>
<ns1:Password>YYY</ns1:Password>
<wsdl:WebServiceType>Product</wsdl:WebServiceType>
</ns2:LogonRequestMsg>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
HTTPI executes HTTP POST using the httpclient adapter
SOAP response (status 400):
I found that I needed to add the headers in to get past the 415 error.
Savon.client(wsdl: "www.sample_doman.com/endpoint?wsdl", headers: {'Content-Type' => 'application/soap+xml; charset=utf-8'})
I would suggest looking at the XML sent by the PHP code, then comparing it with the XML sent by the Ruby Savon code, and check where the differences are. Then see whether you can modify your ruby code to generate the correct request.
Telling Savon to use SOAP version 2 (really 1.2) and then manually setting the content type to text/xml kind of defeats the purpose.
If your web service requires SOAP 1.2, then it is expecting a content type of 'application/soap+xml', which SAVON will do for you if you set the soap_version to 2.
If you want a content type of text/xml, just set your soap_version config variable to 1

HTTParty and text/xml

I'm trying to make a POST request using HTTParty, in which I need the content-type to be text/xml. How can I make that happen? Right now the API I'm calling is complaining I'm not sending any xml. If I call it using curl I get the same error, unless I specify content-type to text/xml.
HTTParty.post url, :body => xml, :headers => {'Content-type' => 'text/xml'}

Resources