#!/usr/local/bin/ruby # shttpservのget-url.rbのまね require "socket" class URL def set_proxy(proxyServ, proxyPort) if proxyServ and proxyPort @proxy = [proxyServ.to_s, proxyPort.to_i] else @proxy = nil end end module_function :set_proxy def initialize(url) @url = url.dup if @proxy @server = proxy[0] @port = proxy[1] @target = url.to_s @proto = 'http' else @server, @port, @target, @proto = parse_url(url) end end attr :server attr :port attr :target attr :proto def parse_url(url) url = url.dup if url.sub!(/^([^\/]+):\/\//, '') proto = $1 else proto = nil end case proto when "http", nil port = 80 when "ftp" port = 21 else # raise port = nil end url =~ /([^\/]*)(.*)/ server, target = $1, $2 if server =~ /([^:]+):(\d+)/ server, port = $1, $2.to_i end target = "/" if target == "" [server, port, target, proto] end private :parse_url def open TCPsocket.open(server, port) end def to_s @url end def site_and_basename # http://host:port/dir/dir/file str = @url.dup if str.sub!(/^(http:\/\/[^\/]+)\//, '') site = $1 if str.size > 0 # FIXME base = str.rindex('/') else base = nil end [site, base] else nil end end end module WebUA def restrict(proc) @restrict = proc end module_function :restrict def post(urlstr, body, reqOpts = []) url = URL.new(urlstr) doget('POST', url, reqOpts, body) end def get(urlstr, reqOpts = []) url = URL.new(urlstr) doget('GET', url, reqOpts) end def head(urlstr, reqOpts = []) url = URL.new(urlstr) doget('HEAD', url, reqOpts) end module_function :post, :get, :head def doget(method, url, reqOpts, body=nil) server = url.server port = url.port target = url.target proto = url.proto raise "unknown protocol '#{proto}'" if proto && (proto != "http") req_heads = ["#{method} #{target} HTTP/1.0"] + reqOpts req_heads << "Accept: */*" req_heads << "Connection: Close" req_heads << "Content-length: #{body.length.to_s}" if body request_header = req_heads.join("\r\n")+"\r\n\r\n" sock = TCPsocket.open(server, port) sock.print request_header sock.print body if body head = sock.gets("\r\n\r\n") if (method == 'HEAD') return head end if @restrict and not @restrict.call(head) return [head, nil] end len = if head =~ /^Content-length:\s*(\S+)/i Integer($1) else nil end if len body = sock.read(len) else body = sock.read end print head if $debug sock.close [head, body] end module_function :doget private :doget end if __FILE__ == $0 url = ARGV.shift opt = [] while a = ARGV.shift opt << a end onlyText = Proc.new { |h| h =~ /^Content-type:\s*text\//i } WebUA.restrict(onlyText) tmp = URL.new(url) p tmp.site_and_basename print WebUA.head(url, opt) print WebUA.get(url, opt)[1] end