1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
|
#!/usr/bin/env ruby
require 'net/http'
require 'net/https'
require 'optparse'
require 'uri'
def verbose_printer(verbosity)
if verbosity
pid = Process.pid
Proc.new do |msg|
$stderr.puts "[#{pid}]: #{msg}"
end
else
Proc.new do |a|
end
end
end
def parse_option(argv)
parser = OptionParser.new
opt = Hash.new
print_help = Proc.new do |msg, *args|
exits = if args.size > 0
args.shift
else
true
end
if msg
puts msg
puts
end
puts "Usage: #{$0} [OPTIONS] HOSTNAME"
puts parser.help
if exits
exit(1)
end
end
parser.on('-h') do
print_help.call(nil)
end
# TODO: should be rewrite in cURL style option
opt[:verbose] = nil
parser.on('-v', '--verbose',
"\n\t\tverbose") do
opt[:verbose] = true
end
opt[:headers] = Hash.new
parser.on('-H', '--header HEADER',
"\n\t\tadditional HTTP header field." +
"\n\t\tuse like -h \"User-Agent: Ruby\"") do |header|
unless header =~ /^([-A-Za-z]+):\s*(.+)$/
print_help.call("Invalid HTTP header format: #{header}")
end
opt[:headers][$~[1]] = $~[2]
end
opt[:method] = 'GET'
parser.on('-m', '--method METHOD',
"\n\t\tHTTP request method"+
" (GET and POST are supported)") do |method|
unless method =~ /\A(GET|POST)\Z/
print_help.call("Not such HTTP method: #{method}")
end
opt[:method] = method
end
opt[:path] = '/'
parser.on('-P', '--path PATH',
"\n\t\tHTTP request path (default: \"/\")") do |path|
opt[:path] = path
end
opt[:encode] = nil
parser.on('-e', '--encode',
"\n\t\tpercent encode HTTP request path (default: no)") do
opt[:encode] = true
end
opt[:ssl] = nil
parser.on('-s', '--ssl', "\n\t\tuse SSL (default: no)") do
opt[:ssl] = true
end
opt[:port] = nil
parser.on('-p', '--port PORT',
"\n\t\tdestination port number" +
" (default: 80 on non-SSL, 443 on SSL)") do |port|
opt[:port] = port.to_i
puts "port: #{opt[:port]}"
end
opt[:ssl_cert] = nil
parser.on('-c', '--cert PATH',
"\n\t\tCA certificate file(*.pem)" +
" for verifying certificates") do |path|
unless File.exist?(path)
print_help.call("No such file: #{path}")
end
opt[:ssl_cert] = path
end
parser.parse!(argv)
if argv.size == 0
print_help.call('HOSTNAME required')
end
opt[:host] = argv.first
if !opt[:port]
opt[:port] = if opt[:ssl]
443
else
80
end
end
opt[:path] = URI.encode(opt[:path]) if opt[:encode]
opt
end
def print_header_string(res)
print "HTTP/#{res.http_version} #{res.code} #{res.message}"
res.canonical_each do |name,value|
print("\r\n#{name}: #{value}")
end
end
def main(argv)
Net::HTTP.version_1_2
opt = parse_option(argv)
vprint = verbose_printer(opt[:verbose])
http = Net::HTTP.new(opt[:host], opt[:port])
if opt[:ssl]
http.use_ssl = true
vprint.call("SSL enabled")
if opt[:ssl_cert]
http.ca_file = opt[:ssl_cert]
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
http.verify_depth = 5
end
end
res = nil
begin
http.start do |client|
res = case opt[:method]
when /GET/
client.get(opt[:path], opt[:headers])
when /POST/
client.post(opt[:path], opt[:headers])
end
end
end
if res
print_header_string(res)
print "\r\n\r\n"
print res.body
$stdout.flush
else
$stderr.puts "error"
end
end
if __FILE__ == $0
main(ARGV.dup)
end
|