From: rubikitch Date: 2001-05-17T05:26:19+09:00 Subject: [ruby-list:29692] Re: rnet.rb 〜高レベルネットライブラリ〜 From: 堀川 久 Subject: [ruby-list:29523] Re: rnet.rb 〜高レベルネットライブラリ〜 Date: Sun, 6 May 2001 11:01:09 +0900 るびきちです。 遅くなりましたが、rnet.rb更新しました。 >  HTTP/1.1では303 See OtherのときはGETで取り直し,それ以外のときはPOST > メソッドにすることになってるようですね。 > >  pre-HTTP/1.1では302 FoundのときにGETで取り直す実装が多いらしい。 情報ありがとうございます。 たまたまこの状況にあるページを見つけたので修正も楽でした。 # URbはまだリリースされてないみたいですね。 #!/usr/bin/env ruby =begin = RNet $Id: rnet.rb,v 1.7 2001/05/02 04:42:54 takashi Exp takashi $ 高レベルネットクラス。要uri.rb。 URIで指定してネットワークをいじくる。 == メソッド --- RNet.new(arg) RNetオブジェクトを作る。 argは文字列かURIオブジェクトでURIを指定。 URIによりスキームを決定し、それに応じたメソッドが使えるようになる。 === HTTP --- RNet.head(header0={}) HEADリクエストを発行。HTTPResponseオブジェクトを返す。 --- RNet.get(header0={}) GETリクエストを発行。HTTPResponseオブジェクトを返す。 --- RNet.post(data, header0={}) POSTリクエストを発行。dataは文字列かハッシュ。 HTTPResponseオブジェクトを返す。 =end require 'uri' require 'kconv' require 'cgi' class RNet TMail_lib = 'tmail/tmail' class RNetRedirectionLoopError < RuntimeError; end module Http @@HeadHeader = {} @@GetHeader = { 'User-Agent'=>'w3m/0.2.1', 'Accept'=> 'text/*, image/*, audio/*, application/*', 'Accept-Language'=> 'ja; q=1.0, en; q=0.5', } @@PostHeader = { 'User-Agent'=>'w3m/0.2.1', 'Accept'=> 'text/*, image/*, audio/*, application/*', 'Accept-Language'=> 'ja; q=1.0, en; q=0.5', 'Content-type'=>'application/x-www-form-urlencoded', } end module Ftp end end class RNet def initialize(arg) parse_url(arg) extend self.type.const_get(@uri.scheme.capitalize) setup end def parse_url(arg) case arg when URI @uri = arg when String @uri = URI::create(arg) else raise TypeError, "RNet.new expected URI or String" end end private :parse_url ################ HTTP module Http def setup require 'net/http' (@redirections ||= []).push @uri @host, @port, @path, @query = @uri.host, @uri.port, @uri.path, @uri.query @net = Net::HTTP::new @host, @port end private :setup def full_uri(url) begin URI::create(url) rescue URI::create(@uri, url) end end def head(header0={}) header = @@HeadHeader.dup.update(header0) res = @net.head2 @path, header res.extend HTTPResponseExtension res end def get(header0={}) header = @@GetHeader.dup.update(header0) STDERR.puts "GET #{@uri}" if $DEBUG @net.get2("#{@path}?#{@query}", header) do |res| res.extend HTTPResponseExtension if res.code =~ /^3[0-9][0-9]$/ return redirection(res['location'], header0) end end end def redirection(location, header0, request = :get) parse_url(full_uri(location)) @redirections.find{|x| x == @uri} and raise RNetRedirectionLoopError setup send(request, header0) end private :redirection def hash2data(hash) data = '' hash.each_pair do |name, value| case value when Array value.each do |vv| data << "#{name}=#{CGI::escape(Kconv::tosjis vv)}&" end when NilClass else data << "#{name}=#{CGI::escape(Kconv::tosjis value)}&" end end data.chop! data end private :hash2data def post(data, header0={}) case data when String datastr = data when Hash datastr = hash2data(data) else raise TypeError, "RNet#post: expected String or Hash!" end header = @@PostHeader.dup.update(header0) STDERR.puts "POST #{@uri}" if $DEBUG @net.post2("#{@path}?#{@query}", datastr, header) do |res| res.extend HTTPResponseExtension case res.code when '303' return redirection(res['location'], header0, :get) when /^3[0-9][0-9]$/ return redirection(res['location'], header0, :post) end end end module HTTPResponseExtension def content_type; self['content-type']; end #def content_length; self['content-length']; end def server; self['server']; end def date2time(header) require TMail_lib self[header] and TMail::DateH.new("Date", self[header]).date end def last_modified; date2time('last-modified'); end def date; date2time('date'); end end end end if __FILE__ == $0 get = RNet::new('http://www.ruby-lang.org/~rubikitch').get # get = RNet::new('http://www.ruby-lang.org/~rubikitch/tmp/l1.mrb').get get.body p get.code get.each do |h,v| p [h,v] end p get.last_modified p get.date p get.content_length p get.server end