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
Related
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'}
I'm trying to automate actions I can take manually in an iPhone app using Ruby, but when I do, I get a 502 bad gateway error.
Using Charles Proxy I got the request the iPhone app is making:
POST /1.1/user/-/friends/invitations HTTP/1.1
Host: redacted.com
Accept-Locale: en_US
Accept: */*
Authorization: Bearer REDACTED
Content-Encoding: gzip
Accept-Encoding: br, gzip, deflate
Accept-Language: en_US
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Content-Length: 66
Connection: keep-alive
X-App-Version: 814
invitedUserId=REDACTED&source=PROFILE_INVITATION
I wrote the following code in Ruby to send this same request:
#header_post = {
"Host" => "redacted.com",
"Accept-Locale" => "en_US",
"Accept" => "*/*",
"Authorization" => "Bearer REDACTED",
"Content-Encoding" => "gzip",
"Accept-Encoding" => "br, gzip, deflate",
"Accept-Language" => "en_US",
"Content-Type" => "application/x-www-form-urlencoded; charset=UTF-8",
"Connection" => "keep-alive",
"X-App-Version" => "814"
}
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
path = '/1.1/user/-/friends/invitations'
data = "invitedUserId=REDACTED&source=PROFILE_INVITATION"
resp, data = http.post(path, data, #header_post)
Unfortunately I get a 502 Bad Gateway Error when running this code.
One thing I noticed which I think is key to the solution here is that, in the POST request the mobile app is making, the content length is 66. But the length of the string "invitedUserId=REDACTED&source=PROFILE_INVITATION" with un-redacted userId is only 46.
Am I missing another form variable with format "¶m=value" which has length 20? Or am I missing something else?
Thank you in advance!
This is probably not directly tied to the body length you're sending.
I see possibly 2 problems here :
the 502 error : are your uri.host and port correct ? A 502 error means there is something wrong on the server side. Also try by removing the Host header.
body content is not gzipped
You're defining an header Content-Encoding: gzip but you didn't compress the data (Net::Http doesn't do that automatically).
Try with something like that :
require "gzip"
#header_post = {
# ...
}
http = Net::HTTP.new(uri.host, uri.port)
path = '/1.1/user/-/friends/invitations'
data = "invitedUserId=REDACTED&source=PROFILE_INVITATION"
# instanciate a new gzip buffer
gzip = Zlib::GzipWriter.new(StringIO.new)
# append your data
gzip << data
# get the gzip body and use it in your request
body = gzip.close.string
resp, data = http.post(path, body, #header_post)
Alternatively, maybe the server is accepting a non-gzipped content. You could try simply by deleting the Content-Encoding
error from your original code.
However if it was the only mistake, the server should not send a 502 but a 4xx error. So I'm guessing there is another issue there with the uri config like a suggested above.
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
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=/"]}>
this is my code and I don't know how to debug it because I just get an "internal server error":
I am trying to HTTP POST to an external ASPX:
def upload
uri = 'https://api.postalmethods.com/2009-02-26/PostalWS.asmx' #postalmethods URI
#https://api.postalmethods.com/2009-02-26/PostalWS.asmx?op=UploadFile
#http://www.postalmethods.com/method/2009-02-26/UploadFile
#postalcard = Postalcard.find(:last)
#Username=string&Password=string&MyFileName=string&FileBinaryData=string&FileBinaryData=string&Permissions=string&Description=string&Overwrite=string
filename = #postalcard.postalimage.original_filename
filebinarydata = File.open("#{#postalcard.postalimage.path}",'rb')
body = "Username=me&Password=sekret&MyFileName=#{filename}&FileBinaryData=#{filebinarydata}"
#response = RestClient.post(uri,
body, #body as string
{"Content-Type" => 'application/x-www-form-urlencoded',
"Content-Length" => #postalcard.postalimage.size} # end headers
) #close arguments to Restclient.post
end
Turns on PostalMethods had an error and bug on their HTTP POST.
It only takes SOAP so I would need Savon.