Question

I have four arguments taken from user input in the script. All other string interpolation arguments work fine except for URI.parse.

Snippets from the code are:

require 'net/http'

#ARGVs:
prompt   = 'test: '
url      = ARGV[0]
user     = ARGV[1]
pass     = ARGV[2]
xml_user = ARGV[3]

# User supplied input:
puts "Whats the URL?"
print prompt
url = STDIN.gets.chomp()

# HTTP connection
uri = URI.parse('#{url}')
req = Net::HTTP.new(uri.hostname, uri.port)

# Header: Creds to get a session
user_and_pass = "#{user}" + ':' + "#{pass}"
base64user_and_pass = Base64.encode64(user_and_pass)

# POST method
res = req.post(uri.path, xml_data, {'Content-Type'  => 'text/xml', 'Content-Length' => xml_data.length.to_s, 
                                    'Authorization' => "Basic #{base64user_and_pass}", "Connection" => "keep-alive" })
puts res.body

Error:

Ruby200-x64/lib/ruby/2.0.0/uri/common.rb:176:in `split': bad URI(is not URI?): #{url} (URI::InvalidURIError)

A point in the right direction would be appreciated.

Was it helpful?

Solution

uri = URI.parse('#{url}')

should be:

uri = URI.parse(url)

OTHER TIPS

Here's a bit more idiomatic-Ruby version of the code:

require 'net/http'

PROMPT = 'test: '

# ARGVs:
url, user, pass, xml_user = ARGV[0, 4]

# User supplied input:
puts "Whats the URL?"
print PROMPT
url = STDIN.gets.chomp()

# HTTP connection
uri = URI.parse(url)
req = Net::HTTP.new(uri.hostname, uri.port)

# Header: Creds to get a session
base64user_and_pass = Base64.encode64("#{ user }:#{ pass }")

# POST method
res = req.post(
  uri.path,
  xml_data,
  {
    'Content-Type'   => 'text/xml',
    'Content-Length' => xml_data.length.to_s,
    'Authorization'  => "Basic #{ base64user_and_pass }",
    "Connection"     => "keep-alive"
  }
)

puts res.body

Don't do things like:

user_and_pass = "#{user}" + ':' + "#{pass}"

and:

uri = URI.parse('#{url}')

user, pass and url are already strings, so sticking them inside a string and interpolating their values is a waste of CPU. As developers we need to be aware of our data-types.

It could be written as one of these:

user_and_pass = user + ':' + pass
user_and_pass = '%s:%s' % [user, pass]
user_and_pass = [user, pass].join(':')

But it's more idiomatic to see it how I wrote it above.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top