How to read the attached file in http response using ruby? - ruby

I am new to ruby programming.
I have learning about the file attachments in ruby. In this I was learned about how to attach the file in http request. But I was searched about how read and save the attached file locally in http response. But I did not get anything for this.
UPDATE :-
From ruby script I do a http request to the php program.
The source for request is,
payload={"id":"1004"}
uri = URI.parse("https://example.com/test.php")
request = Net::HTTP::Post.new(uri)
request.content_type = "application/json"
request.body = payload.to_json
# request.use_ssl = true
# request.verify_mode = OpenSSL::SSL::VERIFY_NONE
# logger.info "request body is #{request.body.inspect}"
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true, verify_mode: OpenSSL::SSL::VERIFY_NONE,:read_timeout => 25 ) { |http| http.request(request) }
From test.php, validated the id if it is valid then in response attached the file contents.
The source for this is,
$filename="test.mp3";
if (file_exists($filename)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($filename));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($filename));
ob_clean();
flush();
readfile($filename);
# exit;
}
What I want is, in the ruby script for the http request one response will be received from server. From that response I have extract the file contents and store it in locally.
I was searched about how to process the file contents in response. But I didn't get anything.
Kindly help me how to do this in ruby.

Related

How to send XML file using Post request in Ruby

I am writing a code that send http post request. Now I write xml body in my code, and its working correctly.
But if I want to send request using xml file I get
undefined method `bytesize' for #
Did you mean? bytes
My code below
require 'net/http'
request_body = <<EOF
<xml_expamle>
EOF
uri = URI.parse('http://example')
post = Net::HTTP::Post.new(uri.path, 'content-type' => 'text/xml; charset=UTF-8')
post.basic_auth 'user','passcode'
Net::HTTP.new(uri.host, uri.port).start {|http|
http.request(post, request_body) {|response|
puts response.body
}
}
**But if I want to make send file**
require 'net/http'
request_body = File.open('example/file.xml')
uri = URI.parse('http://example')
post = Net::HTTP::Post.new(uri.path, 'content-type' => 'application/xml; charset=UTF-8')
post.basic_auth 'user','passcode'
Net::HTTP.new(uri.host, uri.port).start {|http|
http.request(post, request_body) {|response|
puts response.body
}
}
I get
undefined method `bytesize' for #
Did you mean? bytes
You need to load the file content to memory if you want to use it as a request body, use #read method:
request_body = File.open('example/file.xml').read
and it'll work.

Ruby - Send GET request with headers

I am trying to use ruby with a website's api. The instructions are to send a GET request with a header. These are the instructions from the website and the example php code they give. I am to calculate a HMAC hash and include it under an apisign header.
$apikey='xxx';
$apisecret='xxx';
$nonce=time();
$uri='https://bittrex.com/api/v1.1/market/getopenorders?apikey='.$apikey.'&nonce='.$nonce;
$sign=hash_hmac('sha512',$uri,$apisecret);
$ch = curl_init($uri);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('apisign:'.$sign));
$execResult = curl_exec($ch);
$obj = json_decode($execResult);
I am simply using an .rb file with ruby installed on windows from command prompt. I am using net/http in the ruby file. How can I send a GET request with a header and print the response?
Using net/http as suggested by the question.
References:
Net::HTTP https://ruby-doc.org/stdlib-2.4.1/libdoc/net/http/rdoc/Net/HTTP.html
Net::HTTP::get https://ruby-doc.org/stdlib-2.4.1/libdoc/net/http/rdoc/Net/HTTP.html#method-c-get
Setting headers: https://ruby-doc.org/stdlib-2.4.1/libdoc/net/http/rdoc/Net/HTTP.html#class-Net::HTTP-label-Setting+Headers
Net::HTTP::Get https://ruby-doc.org/stdlib-2.4.1/libdoc/net/http/rdoc/Net/HTTP/Get.html
Net::HTTPGenericRequest https://ruby-doc.org/stdlib-2.4.1/libdoc/net/http/rdoc/Net/HTTPGenericRequest.html and Net::HTTPHeader https://ruby-doc.org/stdlib-2.4.1/libdoc/net/http/rdoc/Net/HTTPHeader.html (for methods that you can call on Net::HTTP::Get)
So, for example:
require 'net/http'
uri = URI("http://www.ruby-lang.org")
req = Net::HTTP::Get.new(uri)
req['some_header'] = "some_val"
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') { |http|
http.request(req)
}
puts res.body # <!DOCTYPE html> ... </html> => nil
Note: if your response has HTTP result state 301 (Moved permanently), see Ruby Net::HTTP - following 301 redirects
Install httparty gem, it makes requests way easier, then in your script
require 'httparty'
url = 'http://someexample.com'
headers = {
key1: 'value1',
key2: 'value2'
}
response = HTTParty.get(url, headers: headers)
puts response.body
then run your .rb file..
As of Ruby 3.0, Net::HTTP.get_response supports an optional hash for headers:
Net::HTTP.get_response(URI('http://www.example.com/index.html'), { 'Accept' => 'text/html' })
Unfortunately this does not work for Ruby 2 (up to 2.7).

Ruby Net::HTTP POST send data gzip compressed

I am using Net::HTTP::Post under JRUBY 1.9.2 to send data to a custom server (not a web server), that want the data to be gzipped compressed.
How can I tell Net::HTTP::Post to gzip compress the data it is POSTING?
Example for posting JSON:
require('zlib')
require('net/http')
require('json')
data = {my: 'data'}
uri = URI('http://example.com/api/endpoint')
headers = {
'Content-Type' => 'application/json',
'Content-Encoding' => 'gzip',
}
request = Net::HTTP::Post.new(uri, headers)
gzip = Zlib::GzipWriter.new(StringIO.new)
gzip << data.to_json
request.body = gzip.close.string
response = Net::HTTP.start(uri.hostname, uri.port) do |http|
http.request(request)
end

Sending POST request with HTTP headers

quite new to this been learning about API's in Ruby. Using an Emails service's API to create a user in a system.
This is an example of the POST:
POST http://localhost:8080/core/postgres-pages-xy/api/rest/v4/user/create?email=user003#test.invalid HTTP/1.1
Authorization: Basic bWFzdGVyQGVuubXVjLmVjaXJjbGUuZGU6aDhuc3d1cnN0
User-Agent: curl/7.29.0
Host: localhost:8080
Proxy-Connection: Keep-Alive
Content-Type:application/json
Accept:application/json
Content-Length: 86
[{"name":"user.FirstName","value":"Stan"}, {"name":"user.LastName", "value":"Laurel"}]
I think I am close(ish)? in Ruby was hoping someone would tell me how I send my authentication through. System requires login headers not sure how to do that, will be an email and a password:
require 'uri'
require 'net/http'
uri = URI("https://site.com/api/rest/v4/user/create?email=ruby1#ruby.com")
https = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Post.new(uri.path)
request.basic_auth 'email', 'pass'
request["user.FirstName"] = 'Liam'
request["user.LastName"] = 'Coates'
response = https.request(request)
puts response
Thanks for feedback or learnings.
You can enter the credentials in the URL:
url = "http://username:password#localhost:8080/core/postgres-pages-xy/api/rest/v4/user/create"
If the username and password are there, it should automatically do HTTP basic auth (source).
However supposedly this is deprecated, so there is a longer solution:
req = Net::HTTP::Post.new(uri)
req.basic_auth 'user', 'pass'
res = Net::HTTP.start(uri.hostname, uri.port) {|http|
http.request(req)
}
puts res.body

How to send form-data in Ruby http post

I'd like to send a post from my Rails app to an API. I can get this to work using POSTMAN:
If I click on Preview in POSTMAN, it shows this as the request:
POST /api/users/status HTTP/1.1
Host:
Cache-Control: no-cache
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="params"
{"pgb": "sample_token", "token": "sample_token" }
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Which is what I want to send. But I can't seem to replicate form-data when using Ruby's Net::HTTP::Post. Here's what I have so far, but this posts with x-www-form-urlencoded as the content-type:
url = URI.parse(ENV['URL'])
req = Net::HTTP::Post.new(url.path)
req.set_form_data({"params" => data.to_json})
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
https.verify_mode = OpenSSL::SSL::VERIFY_NONE
https.set_debug_output $stdout
resp = https.request(req)
response = JSON.parse(resp.body)
Is there any way to post just form-data with ruby?
you could try using some of Ruby gems like Rest client. http://rubygems.org/gems/rest-client
Just type the following
gem install rest-client
The documentation can be found here http://rubygems.org/gems/rest-client.

Resources