I'm trying to use Shoes' download() method to pass a username and password in the HTTP header to authenticate the HTTP request (talking to a Rails app).
I'm a bit of a newb when it comes to this stuff.
I havn't quite understood whether I should be automatically able to use the below syntax (username:pwd#) or whether the username and password should be created manually inside the HTTP header (which I think I can also access using :headers of the download method).
download "http://username:pwd#127.0.0.1:3000/authenticate", :method => "POST" do |result|
# process result.response.body here
end
Any help would be appreciated
Can I answer my own question?
This seems to do the trick:
require 'base64'
< ... snip ... >
# create the headers
headers = {}
headers['Authorization'] = 'Basic ' + encode64("#{#login.text()}:#{#pword.text()}").chop
# run the download
download "#{$SITE_URL}/do_something", :method => "GET", :headers => headers do |result|
#status.text = "The result is #{result.response.body}"
end
Related
I am trying to do a multipart post with parameters in ruby securely using https. All the examples I have seen are only http without parameters in addition to the file. However, I can't seem to modify them to get them to work with https and additional parameters (or find documentation showing a good example). How can I do a multipart POST using HTTPS in ruby with parameters? I have tried modify the code from Nick Sieger as shown below but to no avail. Where do I add parameters that I need to pass in in JSON format in addition to the file?
# push file to rest service
url = URI.parse('https://some.url.test/rs/test')
File.open(tm.created_file_name) do |txt|
req = Net::HTTP::Post::Multipart.new url.path,
'file' => UploadIO.new(txt, 'text/plain', tm.created_file_name)
n = Net::HTTP.new(url.host, url.port)
n.use_ssl = true
p req.body_stream
res = n.start do |http|
response = http.request(req)
p response.body
end
end
I figured out to do a multipart form post using https and parameters. Here is the code:
require 'rest-client'
url = 'https://some.url/rs/FileUploadForm'
#res = RestClient.post url, {:multipart=>true,:tieBreakerOptions=>1,
:myFileName=>'file.txt',
:myFile=>File.new('data/file.txt','r')}
response = JSON.parse(#res)
I was trying to write a ruby script which would use the rest API.
However am stuck at the auth step ( am using basic auth ).
From what I thought I understood i was supposed to base 64 encode my login:password then pass it with header Authorization along with my
request but its getting me nowhere but 403 forbidden errors.
enc = Base64.encode64('username:passs')
my_url = 'http://intenthq.atlassian.net/rest/api/2/application-properties'
my_key = 'Basic '+ enc
puts enc
puts 'Authorization ' + my_key
RestClient::Request.execute(
:method => :get,
:url => my_url,
:headers => {'Authorization' => my_key}
)
what am I doing wrong ?
Am I even using the correct methods ?
managed to sort it out by using github.com/sumoheavy/jira-ruby
thanks Coderhs :)
I am trying to send a file via a HTTP PUT request. Curl allows this like:
http://curl.haxx.se/docs/httpscripting.html#PUT
What's the correct way of doing this with Typheous?
FWIW this is what I think was the complete (but not necessarily shortest) answer to the question.
Curl allows the uploading of files w/ PUT; the invocation is:
$ curl --upload-file filename url
where url may be something like:
http://someurl/script.php?var=value&anothervar=val&...
Typhoeus provides the same functionality, but the right way to pass url, params and their values as well as the file body is buried in the ethon docs:
request = Typhoeus::Request.new(
url, :method => :put, :params => params_hash,
:body => File.open(filename) { |io| io.read })
Use request object to get response, etc.
You couldn't have looked very hard:
Examples:
Make put request.
Typhoeus.put("www.example.com")
Parameters:
base_url (String) — The url to request.
options (options) (defaults to: {}) — The options.
Options Hash (options):
:params (Hash) — Params hash which is attached to the base_url.
:body (Hash) — Body hash which becomes a PUT request body.
http://rubydoc.info/github/typhoeus/typhoeus/Typhoeus/Request/Actions#put-instance_method
I need collect all "title" from all pages from site.
Site have HTTP Basic Auth configuration.
Without auth I do next:
require 'anemone'
Anemone.crawl("http://example.com/") do |anemone|
anemone.on_every_page do |page|
puts page.doc.at('title').inner_html rescue nil
end
end
But I have some problem with HTTP Basic Auth...
How I can collected titles from site with HTTP Basic Auth?
If I try use "Anemone.crawl("http://username:password#example.com/")" then I have only first page title, but other links have http://example.com/ style and I received 401 error.
HTTP Basic Auth works via HTTP headers. Client, willing to access restricted resource, must provide authentication header, like this one:
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
It contains name and password, Base64-encoded. More info is in Wikipedia article: Basic Access Authentication.
I googled a little bit and didn't find a way to make Anemone accept custom request headers. Maybe you'll have more luck.
But I found another crawler that claims it can do it: Messie. Maybe you should give it a try
Update
Here's the place where Anemone sets its request headers: Anemone::HTTP. Indeed, there's no customization there. You can monkeypatch it. Something like this should work (put this somewhere in your app):
module Anemone
class HTTP
def get_response(url, referer = nil)
full_path = url.query.nil? ? url.path : "#{url.path}?#{url.query}"
opts = {}
opts['User-Agent'] = user_agent if user_agent
opts['Referer'] = referer.to_s if referer
opts['Cookie'] = #cookie_store.to_s unless #cookie_store.empty? || (!accept_cookies? && #opts[:cookies].nil?)
retries = 0
begin
start = Time.now()
# format request
req = Net::HTTP::Get.new(full_path, opts)
response = connection(url).request(req)
finish = Time.now()
# HTTP Basic authentication
req.basic_auth 'your username', 'your password' # <<== tweak here
response_time = ((finish - start) * 1000).round
#cookie_store.merge!(response['Set-Cookie']) if accept_cookies?
return response, response_time
rescue Timeout::Error, Net::HTTPBadResponse, EOFError => e
puts e.inspect if verbose?
refresh_connection(url)
retries += 1
retry unless retries > 3
end
end
end
end
Obviously, you should provide your own values for the username and password params to the basic_auth method call. It's quick and dirty and hardcode, yes. But sometimes you don't have time to do things in a proper manner. :)
The Merb Open Source Book has a chapter on authentication. However, the testing an authenticated request section example only shows what you can do for forms based authentication. I have a web service that I want to test with HTTP basic authentication. How would I do that?
After posting my question, I tried a few more things and found my own answer. You can do something like the following:
response = request('/widgets/2222',
:method => "GET",
"X_HTTP_AUTHORIZATION" => 'Basic ' + ["myusername:mypassword"].pack('m').delete("\r\n"))
I may get around to updating the book, but at least this info is here for Google to find and possibly help someone else.
Here is an example for HTTP basic auth from inside a controller:
class MyMerbApp < Application
before :authenticate, :only=>[:admin]
def index
render
end
def admin
render
end
protected
def authenticate
basic_authentication("Protected Area") do |username, password|
username == "name" && password == "secret"
end
end
end
you'll need to define the merb_auth_slice in config/router.rb if it's not already done for you:
Merb::Router.prepare do
slice(:merb_auth_slice_password, :name_prefix => nil, :path_prefix => "")
end