mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	This commit was manufactured by cvs2svn to create branch 'ruby_1_6'.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_6@2000 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
		
							parent
							
								
									f682ef0571
								
							
						
					
					
						commit
						2730d89899
					
				
					 8 changed files with 2296 additions and 0 deletions
				
			
		
							
								
								
									
										41
									
								
								lib/uri.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								lib/uri.rb
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,41 @@ | ||||||
|  | # | ||||||
|  | # $Id$ | ||||||
|  | # | ||||||
|  | # Copyright (c) 2001 akira yamada <akira@ruby-lang.org> | ||||||
|  | # You can redistribute it and/or modify it under the same term as Ruby. | ||||||
|  | # | ||||||
|  | 
 | ||||||
|  | =begin | ||||||
|  | 
 | ||||||
|  |   Copyright (c) 2001 akira yamada <akira@ruby-lang.org> | ||||||
|  |   You can redistribute it and/or modify it under the same term as Ruby. | ||||||
|  | 
 | ||||||
|  | = URI - URI support for Ruby | ||||||
|  | 
 | ||||||
|  | =end | ||||||
|  | 
 | ||||||
|  | module URI | ||||||
|  |   VERSION_CODE = '000904'.freeze | ||||||
|  |   VERSION = VERSION_CODE.scan(/../).collect{|n| n.to_i}.join('.').freeze | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | =begin | ||||||
|  | 
 | ||||||
|  | == Components | ||||||
|  | 
 | ||||||
|  |   * ((<URI>)) Module | ||||||
|  |   * ((<URI::Generic>)) Class | ||||||
|  |   * ((<URI::FTP>)) Class | ||||||
|  |   * ((<URI::HTTP>)) Class | ||||||
|  |   * ((<URI::HTTPS>)) Class | ||||||
|  |   * ((<URI::LDAP>)) Class | ||||||
|  |   * ((<URI::MailTo>)) Class | ||||||
|  | 
 | ||||||
|  | =end | ||||||
|  | require 'uri/common' | ||||||
|  | require 'uri/generic' | ||||||
|  | require 'uri/ftp' | ||||||
|  | require 'uri/http' | ||||||
|  | require 'uri/https' | ||||||
|  | require 'uri/ldap' | ||||||
|  | require 'uri/mailto' | ||||||
							
								
								
									
										419
									
								
								lib/uri/common.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										419
									
								
								lib/uri/common.rb
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,419 @@ | ||||||
|  | # | ||||||
|  | # $Id$ | ||||||
|  | # | ||||||
|  | # Copyright (c) 2001 akira yamada <akira@ruby-lang.org> | ||||||
|  | # You can redistribute it and/or modify it under the same term as Ruby. | ||||||
|  | # | ||||||
|  | 
 | ||||||
|  | =begin | ||||||
|  | 
 | ||||||
|  | == URI | ||||||
|  | 
 | ||||||
|  | =end | ||||||
|  | 
 | ||||||
|  | module URI | ||||||
|  |   module REGEXP | ||||||
|  |     module PATTERN | ||||||
|  |       # RFC 2396 (URI Generic Syntax) | ||||||
|  |       # RFC 2732 (IPv6 Literal Addresses in URL's) | ||||||
|  |       # RFC 2373 (IPv6 Addressing Architecture) | ||||||
|  | 
 | ||||||
|  |       # alpha         = lowalpha | upalpha | ||||||
|  |       ALPHA = "a-zA-Z" | ||||||
|  |       # alphanum      = alpha | digit | ||||||
|  |       ALNUM = "#{ALPHA}\\d" | ||||||
|  | 
 | ||||||
|  |       # hex           = digit | "A" | "B" | "C" | "D" | "E" | "F" | | ||||||
|  |       #                         "a" | "b" | "c" | "d" | "e" | "f" | ||||||
|  |       HEX     = "a-fA-F\\d" | ||||||
|  |       # escaped       = "%" hex hex | ||||||
|  |       ESCAPED = "%[#{HEX}]{2}" | ||||||
|  |       # mark          = "-" | "_" | "." | "!" | "~" | "*" | "'" | | ||||||
|  |       #                 "(" | ")" | ||||||
|  |       # unreserved    = alphanum | mark | ||||||
|  |       UNRESERVED = "-_.!~*'()#{ALNUM}" | ||||||
|  |       # reserved      = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | | ||||||
|  |       #                 "$" | "," | ||||||
|  |       # reserved      = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |  | ||||||
|  |       #                 "$" | "," | "[" | "]" (RFC 2732) | ||||||
|  |       RESERVED = ";/?:@&=+$,\\[\\]" | ||||||
|  | 
 | ||||||
|  |       # uric          = reserved | unreserved | escaped | ||||||
|  |       URIC = "(?:[#{UNRESERVED}#{RESERVED}]|#{ESCAPED})" | ||||||
|  |       # uric_no_slash = unreserved | escaped | ";" | "?" | ":" | "@" | | ||||||
|  |       #                 "&" | "=" | "+" | "$" | "," | ||||||
|  |       URIC_NO_SLASH = "(?:[#{UNRESERVED};?:@&=+$,]|#{ESCAPED})" | ||||||
|  |       # query         = *uric | ||||||
|  |       QUERY = "#{URIC}*" | ||||||
|  |       # fragment      = *uric | ||||||
|  |       FRAGMENT = "#{URIC}*" | ||||||
|  | 
 | ||||||
|  |       # domainlabel   = alphanum | alphanum *( alphanum | "-" ) alphanum | ||||||
|  |       DOMLABEL = "(?:[#{ALNUM}](?:[-#{ALNUM}]*[#{ALNUM}])?)" | ||||||
|  |       # toplabel      = alpha | alpha *( alphanum | "-" ) alphanum | ||||||
|  |       TOPLABEL = "(?:[#{ALPHA}](?:[-#{ALNUM}]*[#{ALNUM}])?)" | ||||||
|  |       # hostname      = *( domainlabel "." ) toplabel [ "." ] | ||||||
|  |       HOSTNAME = "(?:#{DOMLABEL}\\.)*#{TOPLABEL}\\.?" | ||||||
|  | 
 | ||||||
|  |       # RFC 2373, APPENDIX B: | ||||||
|  |       # IPv6address = hexpart [ ":" IPv4address ] | ||||||
|  |       # IPv4address   = 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT | ||||||
|  |       # hexpart = hexseq | hexseq "::" [ hexseq ] | "::" [ hexseq ] | ||||||
|  |       # hexseq  = hex4 *( ":" hex4) | ||||||
|  |       # hex4    = 1*4HEXDIG | ||||||
|  |       # | ||||||
|  |       # XXX: This definition has a flaw. "::" + IPv4address must be | ||||||
|  |       # allowed too.  Here is a replacement. | ||||||
|  |       # | ||||||
|  |       # IPv4address = 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT | ||||||
|  |       IPV4ADDR = "\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}" | ||||||
|  |       # hex4     = 1*4HEXDIG | ||||||
|  |       HEX4 = "[#{HEX}]{1,4}" | ||||||
|  |       # lastpart = hex4 | IPv4address | ||||||
|  |       LASTPART = "(?:#{HEX4}|#{IPV4ADDR})" | ||||||
|  |       # hexseq1  = *( hex4 ":" ) hex4 | ||||||
|  |       HEXSEQ1 = "(?:#{HEX4}:)*#{HEX4}" | ||||||
|  |       # hexseq2  = *( hex4 ":" ) lastpart | ||||||
|  |       HEXSEQ2 = "(?:#{HEX4}:)*#{LASTPART}" | ||||||
|  |       # IPv6address = hexseq2 | [ hexseq1 ] "::" [ hexseq2 ] | ||||||
|  |       IPV6ADDR = "(?:#{HEXSEQ2}|(?:#{HEXSEQ1})?::(?:#{HEXSEQ2})?)" | ||||||
|  | 
 | ||||||
|  |       # IPv6prefix  = ( hexseq1 | [ hexseq1 ] "::" [ hexseq1 ] ) "/" 1*2DIGIT | ||||||
|  |       # unused | ||||||
|  | 
 | ||||||
|  |       # ipv6reference = "[" IPv6address "]" (RFC 2732) | ||||||
|  |       IPV6REF = "\\[#{IPV6ADDR}\\]" | ||||||
|  | 
 | ||||||
|  |       # host          = hostname | IPv4address | ||||||
|  |       # host          = hostname | IPv4address | IPv6reference (RFC 2732) | ||||||
|  |       HOST = "(?:#{HOSTNAME}|#{IPV4ADDR}|#{IPV6REF})" | ||||||
|  |       # port          = *digit | ||||||
|  |       PORT = "\d*" | ||||||
|  |       # hostport      = host [ ":" port ] | ||||||
|  |       HOSTPORT = "#{HOST}(?:#{PORT})?" | ||||||
|  | 
 | ||||||
|  |       # userinfo      = *( unreserved | escaped | | ||||||
|  |       #                    ";" | ":" | "&" | "=" | "+" | "$" | "," ) | ||||||
|  |       USERINFO = "(?:[#{UNRESERVED};:&=+$,]|#{ESCAPED})*" | ||||||
|  | 
 | ||||||
|  |       # pchar         = unreserved | escaped | | ||||||
|  |       #                 ":" | "@" | "&" | "=" | "+" | "$" | "," | ||||||
|  |       PCHAR = "(?:[#{UNRESERVED}:@&=+$,]|#{ESCAPED})" | ||||||
|  |       # param         = *pchar | ||||||
|  |       PARAM = "#{PCHAR}*" | ||||||
|  |       # segment       = *pchar *( ";" param ) | ||||||
|  |       SEGMENT = "#{PCHAR}*(?:;#{PARAM})*" | ||||||
|  |       # path_segments = segment *( "/" segment ) | ||||||
|  |       PATH_SEGMENTS = "#{SEGMENT}(?:/#{SEGMENT})*" | ||||||
|  | 
 | ||||||
|  |       # server        = [ [ userinfo "@" ] hostport ] | ||||||
|  |       SERVER = "(?:#{USERINFO}@)?#{HOSTPORT}" | ||||||
|  |       # reg_name      = 1*( unreserved | escaped | "$" | "," | | ||||||
|  |       #                     ";" | ":" | "@" | "&" | "=" | "+" ) | ||||||
|  |       REG_NAME = "(?:[#{UNRESERVED}$,;+@&=+]|#{ESCAPED})+" | ||||||
|  |       # authority     = server | reg_name | ||||||
|  |       AUTHORITY = "(?:#{SERVER}|#{REG_NAME})" | ||||||
|  | 
 | ||||||
|  |       # rel_segment   = 1*( unreserved | escaped | | ||||||
|  |       #                     ";" | "@" | "&" | "=" | "+" | "$" | "," ) | ||||||
|  |       REL_SEGMENT = "(?:[#{UNRESERVED};@&=+$,]|#{ESCAPED})+" | ||||||
|  | 
 | ||||||
|  |       # scheme        = alpha *( alpha | digit | "+" | "-" | "." ) | ||||||
|  |       SCHEME = "[#{ALPHA}][-+.#{ALPHA}\\d]*" | ||||||
|  | 
 | ||||||
|  |       # abs_path      = "/"  path_segments | ||||||
|  |       ABS_PATH = "/#{PATH_SEGMENTS}" | ||||||
|  |       # rel_path      = rel_segment [ abs_path ] | ||||||
|  |       REL_PATH = "#{REL_SEGMENT}(?:#{ABS_PATH})?" | ||||||
|  |       # net_path      = "//" authority [ abs_path ] | ||||||
|  |       NET_PATH   = "//#{AUTHORITY}(?:#{ABS_PATH})?" | ||||||
|  | 
 | ||||||
|  |       # hier_part     = ( net_path | abs_path ) [ "?" query ] | ||||||
|  |       HIER_PART   = "(?:#{NET_PATH}|#{ABS_PATH})(?:\\?(?:#{QUERY}))?" | ||||||
|  |       # opaque_part   = uric_no_slash *uric | ||||||
|  |       OPAQUE_PART = "#{URIC_NO_SLASH}#{URIC}*" | ||||||
|  | 
 | ||||||
|  |       # absoluteURI   = scheme ":" ( hier_part | opaque_part ) | ||||||
|  |       ABS_URI   = "#{SCHEME}:(?:#{HIER_PART}|#{OPAQUE_PART})" | ||||||
|  |       # relativeURI   = ( net_path | abs_path | rel_path ) [ "?" query ] | ||||||
|  |       REL_URI = "(?:#{NET_PATH}|#{ABS_PATH}|#{REL_PATH})(?:\\?#{QUERY})?" | ||||||
|  | 
 | ||||||
|  |       # URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ] | ||||||
|  |       URI_REF = "(?:#{ABS_URI}|#{REL_URI})?(?:##{FRAGMENT})?" | ||||||
|  | 
 | ||||||
|  |       # XXX: | ||||||
|  |       X_ABS_URI = " | ||||||
|  | 	(#{PATTERN::SCHEME}):                     (?# 1: scheme) | ||||||
|  | 	(?: | ||||||
|  | 	   (?: | ||||||
|  | 	     //(?: | ||||||
|  | 		 (?:(?:(#{PATTERN::USERINFO})@)?  (?# 2: userinfo) | ||||||
|  | 		   (?:(#{PATTERN::HOST})(?::(\\d*))?))?(?# 3: host, 4: port) | ||||||
|  | 	       | | ||||||
|  | 		 (#{PATTERN::REG_NAME})           (?# 5: registry) | ||||||
|  | 	       ) | ||||||
|  | 	       (#{PATTERN::ABS_PATH})?            (?# 6: path) | ||||||
|  | 	   )(?:\\?(#{PATTERN::QUERY}))?           (?# 7: query) | ||||||
|  | 	| | ||||||
|  | 	   (#{PATTERN::OPAQUE_PART})              (?# 8: opaque) | ||||||
|  | 	) | ||||||
|  | 	(?:\\#(#{PATTERN::FRAGMENT}))?            (?# 9: fragment) | ||||||
|  |       " | ||||||
|  |       X_REL_URI = " | ||||||
|  |         (?: | ||||||
|  |           (?: | ||||||
|  |             // | ||||||
|  |             (?: | ||||||
|  |               (?:(#{PATTERN::USERINFO})@)?       (?# 1: userinfo) | ||||||
|  |                 (#{PATTERN::HOST})?(?::(\\d*))?  (?# 2: host, 3: port) | ||||||
|  |             | | ||||||
|  |               (#{PATTERN::REG_NAME})             (?# 4: registry) | ||||||
|  |             ) | ||||||
|  |           ) | ||||||
|  |         | | ||||||
|  |           (#{PATTERN::REL_SEGMENT})              (?# 5: rel_segment) | ||||||
|  |         )? | ||||||
|  |         (#{PATTERN::ABS_PATH})?                  (?# 6: abs_path) | ||||||
|  |         (?:\\?(#{PATTERN::QUERY}))?              (?# 7: query) | ||||||
|  |         (?:\\#(#{PATTERN::FRAGMENT}))?           (?# 8: fragment) | ||||||
|  |       " | ||||||
|  |     end # PATTERN | ||||||
|  | 
 | ||||||
|  |     # for URI::split | ||||||
|  |     ABS_URI = Regexp.new('^' + PATTERN::X_ABS_URI + '$', #' | ||||||
|  | 			 Regexp::EXTENDED, 'N').freeze | ||||||
|  |     REL_URI = Regexp.new('^' + PATTERN::X_REL_URI + '$', #' | ||||||
|  | 			 Regexp::EXTENDED, 'N').freeze | ||||||
|  | 
 | ||||||
|  |     # for URI::extract | ||||||
|  |     URI_REF     = Regexp.new(PATTERN::URI_REF, false, 'N').freeze | ||||||
|  |     ABS_URI_REF = Regexp.new(PATTERN::X_ABS_URI, Regexp::EXTENDED, 'N').freeze | ||||||
|  |     REL_URI_REF = Regexp.new(PATTERN::X_REL_URI, Regexp::EXTENDED, 'N').freeze | ||||||
|  | 
 | ||||||
|  |     # for URI::escape/unescape | ||||||
|  |     ESCAPED = Regexp.new(PATTERN::ESCAPED, false, 'N').freeze | ||||||
|  |     UNSAFE  = Regexp.new("[^#{PATTERN::UNRESERVED}#{PATTERN::RESERVED}]", | ||||||
|  | 			 false, 'N').freeze | ||||||
|  | 
 | ||||||
|  |     # for Generic#initialize | ||||||
|  |     SCHEME   = Regexp.new("^#{PATTERN::SCHEME}$", false, 'N').freeze #" | ||||||
|  |     USERINFO = Regexp.new("^#{PATTERN::USERINFO}$", false, 'N').freeze #" | ||||||
|  |     HOST     = Regexp.new("^#{PATTERN::HOST}$", false, 'N').freeze #" | ||||||
|  |     PORT     = Regexp.new("^#{PATTERN::PORT}$", false, 'N').freeze #" | ||||||
|  |     OPAQUE   = Regexp.new("^#{PATTERN::OPAQUE_PART}$", false, 'N').freeze #" | ||||||
|  |     REGISTRY = Regexp.new("^#{PATTERN::REG_NAME}$", false, 'N').freeze #" | ||||||
|  |     ABS_PATH = Regexp.new("^#{PATTERN::ABS_PATH}$", false, 'N').freeze #" | ||||||
|  |     REL_PATH = Regexp.new("^#{PATTERN::REL_PATH}$", false, 'N').freeze #" | ||||||
|  |     QUERY    = Regexp.new("^#{PATTERN::QUERY}$", false, 'N').freeze #" | ||||||
|  |     FRAGMENT = Regexp.new("^#{PATTERN::FRAGMENT}$", false, 'N').freeze #" | ||||||
|  |   end # REGEXP | ||||||
|  | 
 | ||||||
|  |   module Util | ||||||
|  |     def make_components_hash(klass, array_hash) | ||||||
|  |       tmp = {} | ||||||
|  |       if array_hash.kind_of?(Array) && | ||||||
|  | 	  array_hash.size == klass.component.size - 1 | ||||||
|  | 	klass.component[1..-1].each_index do |i| | ||||||
|  | 	  begin | ||||||
|  | 	    tmp[klass.component[i + 1]] = array_hash[i].clone | ||||||
|  | 	  rescue TypeError | ||||||
|  | 	    tmp[klass.component[i + 1]] = array_hash[i] | ||||||
|  | 	  end | ||||||
|  | 	end | ||||||
|  | 
 | ||||||
|  |       elsif array_hash.kind_of?(Hash) | ||||||
|  | 	array_hash.each do |key, value| | ||||||
|  | 	  begin | ||||||
|  | 	    tmp[key] = value.clone | ||||||
|  | 	  rescue TypeError | ||||||
|  | 	    tmp[key] = value | ||||||
|  | 	  end | ||||||
|  | 	end | ||||||
|  |       else | ||||||
|  | 	raise ArgumentError,  | ||||||
|  | 	  "expected Array of or Hash of compornents of #{klass.to_s} (#{klass.component[1..-1].join(', ')})" | ||||||
|  |       end | ||||||
|  |       tmp[:scheme] = klass.to_s.sub(/\A.*::/, '').downcase | ||||||
|  | 
 | ||||||
|  |       return tmp | ||||||
|  |     end | ||||||
|  |     module_function :make_components_hash | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   module Escape | ||||||
|  |     include REGEXP | ||||||
|  | 
 | ||||||
|  |     def escape(str, unsafe = UNSAFE) | ||||||
|  |       unless unsafe.kind_of?(Regexp) | ||||||
|  | 	# perhaps unsafe is String object | ||||||
|  | 	unsafe = Regexp.new(Regexp.quote(unsafe), false, 'N') | ||||||
|  |       end | ||||||
|  |       str.gsub(unsafe) do |us| | ||||||
|  | 	tmp = '' | ||||||
|  | 	us.each_byte do |uc| | ||||||
|  | 	  tmp << sprintf('%%%02X', uc) | ||||||
|  | 	end | ||||||
|  | 	tmp | ||||||
|  |       end | ||||||
|  |     end | ||||||
|  |     alias encode escape | ||||||
|  | 
 | ||||||
|  |     def unescape(str) | ||||||
|  |       str.gsub(ESCAPED) do | ||||||
|  | 	$&[1,2].hex.chr | ||||||
|  |       end | ||||||
|  |     end | ||||||
|  |     alias decode unescape | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   include REGEXP | ||||||
|  |   extend Escape | ||||||
|  | 
 | ||||||
|  |   @@schemes = {} | ||||||
|  | 
 | ||||||
|  |   class Error < StandardError; end | ||||||
|  |   class InvalidURIError < Error; end # it is not URI. | ||||||
|  |   class InvalidComponentError < Error; end # it is not component of URI. | ||||||
|  |   class BadURIError < Error; end # the URI is valid but it is bad for the position. | ||||||
|  | 
 | ||||||
|  | =begin | ||||||
|  | 
 | ||||||
|  | === Methods | ||||||
|  | 
 | ||||||
|  | --- URI::split(uri) | ||||||
|  | 
 | ||||||
|  | =end | ||||||
|  | 
 | ||||||
|  |   def self.split(uri) | ||||||
|  |     case uri | ||||||
|  |     when '' | ||||||
|  |       # null uri | ||||||
|  | 
 | ||||||
|  |     when ABS_URI | ||||||
|  |       scheme, userinfo, host, port,  | ||||||
|  | 	registry, path, query, opaque, fragment = $~[1..-1] | ||||||
|  | 
 | ||||||
|  |       # URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ] | ||||||
|  | 
 | ||||||
|  |       # absoluteURI   = scheme ":" ( hier_part | opaque_part ) | ||||||
|  |       # hier_part     = ( net_path | abs_path ) [ "?" query ] | ||||||
|  |       # opaque_part   = uric_no_slash *uric | ||||||
|  | 
 | ||||||
|  |       # abs_path      = "/"  path_segments | ||||||
|  |       # net_path      = "//" authority [ abs_path ] | ||||||
|  | 
 | ||||||
|  |       # authority     = server | reg_name | ||||||
|  |       # server        = [ [ userinfo "@" ] hostport ] | ||||||
|  | 
 | ||||||
|  |       if !scheme | ||||||
|  | 	raise InvalidURIError,  | ||||||
|  | 	  "bad URI(absolute but no scheme): #{uri}" | ||||||
|  |       end | ||||||
|  |       if !opaque && (!path && (!host && !registry)) | ||||||
|  | 	raise InvalidURIError, | ||||||
|  | 	  "bad URI(absolute but no path): #{uri}"  | ||||||
|  |       end | ||||||
|  | 
 | ||||||
|  |     when REL_URI | ||||||
|  |       scheme = nil | ||||||
|  |       opaque = nil | ||||||
|  | 
 | ||||||
|  |       userinfo, host, port, registry,  | ||||||
|  | 	rel_segment, abs_path, query, fragment = $~[1..-1] | ||||||
|  |       if rel_segment && abs_path | ||||||
|  | 	path = rel_segment + abs_path | ||||||
|  |       elsif rel_segment | ||||||
|  | 	path = rel_segment | ||||||
|  |       elsif abs_path | ||||||
|  | 	path = abs_path | ||||||
|  |       end | ||||||
|  | 
 | ||||||
|  |       # URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ] | ||||||
|  | 
 | ||||||
|  |       # relativeURI   = ( net_path | abs_path | rel_path ) [ "?" query ] | ||||||
|  | 
 | ||||||
|  |       # net_path      = "//" authority [ abs_path ] | ||||||
|  |       # abs_path      = "/"  path_segments | ||||||
|  |       # rel_path      = rel_segment [ abs_path ] | ||||||
|  | 
 | ||||||
|  |       # authority     = server | reg_name | ||||||
|  |       # server        = [ [ userinfo "@" ] hostport ] | ||||||
|  | 
 | ||||||
|  |     else | ||||||
|  |       raise InvalidURIError, "bad URI(is not URI?): #{uri}" | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     path = '' if !path && !opaque # (see RFC2396 Section 5.2) | ||||||
|  |     ret = [ | ||||||
|  |       scheme,  | ||||||
|  |       userinfo, host, port, 	# X | ||||||
|  |       registry,			# X | ||||||
|  |       path, 			# Y | ||||||
|  |       opaque,			# Y | ||||||
|  |       query, | ||||||
|  |       fragment | ||||||
|  |     ] | ||||||
|  |     return ret | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  | =begin | ||||||
|  | 
 | ||||||
|  | --- URI::parse(uri_str) | ||||||
|  | 
 | ||||||
|  | =end | ||||||
|  |   def self.parse(uri) | ||||||
|  |     scheme, userinfo, host, port,  | ||||||
|  |       registry, path, opaque, query, fragment = self.split(uri) | ||||||
|  | 
 | ||||||
|  |     if scheme && @@schemes.include?(scheme.upcase) | ||||||
|  |       @@schemes[scheme.upcase].new(scheme, userinfo, host, port,  | ||||||
|  | 				   registry, path, opaque, query,  | ||||||
|  | 				   fragment) | ||||||
|  |     else | ||||||
|  |       Generic.new(scheme, userinfo, host, port,  | ||||||
|  | 		  registry, path, opaque, query,  | ||||||
|  | 		  fragment) | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  | =begin | ||||||
|  | 
 | ||||||
|  | --- URI::extract(str[, schemes]) | ||||||
|  | 
 | ||||||
|  | =end | ||||||
|  |   def self.extract(str, schemes = []) | ||||||
|  |     urls = [] | ||||||
|  |     if schemes.size > 0 | ||||||
|  |       tmp = Regexp.new('(?:' + schemes.collect{|s|  | ||||||
|  | 			 Regexp.quote(s + ':') | ||||||
|  | 		       }.join('|') + ')',  | ||||||
|  | 		       Regexp::IGNORECASE, 'N') | ||||||
|  |       str.scan(tmp) { | ||||||
|  | 	tmp_str = $& + $' | ||||||
|  | 	if ABS_URI_REF =~ tmp_str | ||||||
|  | 	  if block_given? | ||||||
|  | 	    yield($&) | ||||||
|  | 	  else | ||||||
|  | 	    urls << $& | ||||||
|  | 	  end | ||||||
|  | 	end | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |     else | ||||||
|  |       str.scan(ABS_URI_REF) { | ||||||
|  | 	if block_given? | ||||||
|  | 	  yield($&) | ||||||
|  | 	else | ||||||
|  | 	  urls << $& | ||||||
|  | 	end | ||||||
|  |       } | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     if block_given? | ||||||
|  |       return nil | ||||||
|  |     else | ||||||
|  |       return urls | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  | end # URI | ||||||
							
								
								
									
										149
									
								
								lib/uri/ftp.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										149
									
								
								lib/uri/ftp.rb
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,149 @@ | ||||||
|  | # | ||||||
|  | # $Id$ | ||||||
|  | # | ||||||
|  | # Copyright (c) 2001 akira yamada <akira@ruby-lang.org> | ||||||
|  | # You can redistribute it and/or modify it under the same term as Ruby. | ||||||
|  | # | ||||||
|  | 
 | ||||||
|  | require 'uri/generic' | ||||||
|  | 
 | ||||||
|  | module URI | ||||||
|  | 
 | ||||||
|  | =begin | ||||||
|  | 
 | ||||||
|  | == URI::FTP | ||||||
|  | 
 | ||||||
|  | === Super Class | ||||||
|  | 
 | ||||||
|  | ((<URI::Generic>)) | ||||||
|  | 
 | ||||||
|  | =end | ||||||
|  | 
 | ||||||
|  |   # RFC1738 section 3.2. | ||||||
|  |   class FTP < Generic | ||||||
|  |     DEFAULT_PORT = 21 | ||||||
|  | 
 | ||||||
|  |     COMPONENT = [ | ||||||
|  |       :scheme,  | ||||||
|  |       :userinfo, :host, :port, | ||||||
|  |       :path, :typecode | ||||||
|  |     ].freeze | ||||||
|  | 
 | ||||||
|  |     TYPECODE = ['a', 'i', 'd'].freeze | ||||||
|  |     TYPECODE_PREFIX = ';type='.freeze | ||||||
|  | 
 | ||||||
|  | =begin | ||||||
|  | 
 | ||||||
|  | === Class Methods | ||||||
|  | 
 | ||||||
|  | --- URI::FTP::build | ||||||
|  |     Create a new URI::FTP object from components of URI::FTP with | ||||||
|  |     check.  It is scheme, userinfo, host, port, path and typecode. It | ||||||
|  |     provided by an Array or a Hash. typecode is "a", "i" or "d". | ||||||
|  | 
 | ||||||
|  | --- URI::FTP::new | ||||||
|  |     Create a new URI::FTP object from ``generic'' components with no | ||||||
|  |     check. | ||||||
|  | 
 | ||||||
|  | =end | ||||||
|  | 
 | ||||||
|  |     def self.new2(user, password, host, port, path,  | ||||||
|  | 		  typecode = nil, arg_check = true) | ||||||
|  |       typecode = nil if typecode.size == 0 | ||||||
|  |       if typecode && !TYPECODE.include?(typecode) | ||||||
|  | 	raise ArgumentError, | ||||||
|  | 	  "bad typecode is specified: #{typecode}" | ||||||
|  |       end | ||||||
|  | 
 | ||||||
|  |       # do escape | ||||||
|  | 
 | ||||||
|  |       self.new('ftp', | ||||||
|  | 	       [user, password],  | ||||||
|  | 	       host, port, nil,  | ||||||
|  | 	       typecode ? path + TYPECODE_PREFIX + typecode : path,  | ||||||
|  | 	       nil, nil, nil, arg_check) | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     def self.build(args) | ||||||
|  |       tmp = Util::make_components_hash(self, args) | ||||||
|  | 
 | ||||||
|  |       if tmp[:typecode] | ||||||
|  | 	if tmp[:typecode].size == 1 | ||||||
|  | 	  tmp[:typecode] = TYPECODE_PREFIX + tmp[:typecode]  | ||||||
|  | 	end | ||||||
|  | 	tmp[:path] << tmp[:typecode] | ||||||
|  |       end | ||||||
|  | 
 | ||||||
|  |       return super(tmp) | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     def initialize(*arg) | ||||||
|  |       super(*arg) | ||||||
|  |       @typecode = nil | ||||||
|  |       tmp = @path.index(TYPECODE_PREFIX) | ||||||
|  |       if tmp | ||||||
|  | 	typecode = @path[tmp + TYPECODE_PREFIX.size..-1] | ||||||
|  | 	self.set_path(@path[0..tmp - 1]) | ||||||
|  | 	 | ||||||
|  | 	if arg[-1] | ||||||
|  | 	  self.typecode = typecode | ||||||
|  | 	else | ||||||
|  | 	  self.set_typecode(typecode) | ||||||
|  | 	end | ||||||
|  |       end | ||||||
|  |     end | ||||||
|  |     attr_reader :typecode | ||||||
|  | 
 | ||||||
|  |     # | ||||||
|  |     # methods for typecode | ||||||
|  |     # | ||||||
|  | 
 | ||||||
|  |     def check_typecode(v) | ||||||
|  |       if TYPECODE.include?(v) | ||||||
|  | 	return true | ||||||
|  |       else | ||||||
|  | 	raise InvalidComponentError, | ||||||
|  | 	  "bad typecode(expected #{TYPECODE.join(', ')}): #{v}" | ||||||
|  |       end | ||||||
|  |     end | ||||||
|  |     private :check_typecode | ||||||
|  | 
 | ||||||
|  |     def set_typecode(v) | ||||||
|  |       @typecode = v | ||||||
|  |     end | ||||||
|  |     protected :set_typecode | ||||||
|  | 
 | ||||||
|  |     def typecode=(typecode) | ||||||
|  |       check_typecode(typecode) | ||||||
|  |       set_typecode(typecode) | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  | =begin | ||||||
|  | =end | ||||||
|  |     def merge(oth) | ||||||
|  |       tmp = super(oth) | ||||||
|  |       if self != tmp | ||||||
|  | 	tmp.set_typecode(oth.typecode) | ||||||
|  |       end | ||||||
|  | 
 | ||||||
|  |       return tmp | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  | =begin | ||||||
|  | =end | ||||||
|  |     def to_str | ||||||
|  |       save_path = nil | ||||||
|  |       if @typecode | ||||||
|  | 	save_path = @path | ||||||
|  | 	@path = @path + TYPECODE_PREFIX + @typecode | ||||||
|  |       end | ||||||
|  |       str = super | ||||||
|  |       if @typecode | ||||||
|  | 	@path = save_path | ||||||
|  |       end | ||||||
|  | 
 | ||||||
|  |       return str | ||||||
|  |     end | ||||||
|  |   end # FTP | ||||||
|  |   @@schemes['FTP'] = FTP | ||||||
|  | end # URI | ||||||
							
								
								
									
										1087
									
								
								lib/uri/generic.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1087
									
								
								lib/uri/generic.rb
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										76
									
								
								lib/uri/http.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								lib/uri/http.rb
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,76 @@ | ||||||
|  | # | ||||||
|  | # $Id$ | ||||||
|  | # | ||||||
|  | # Copyright (c) 2001 akira yamada <akira@ruby-lang.org> | ||||||
|  | # You can redistribute it and/or modify it under the same term as Ruby. | ||||||
|  | # | ||||||
|  | 
 | ||||||
|  | require 'uri/generic' | ||||||
|  | 
 | ||||||
|  | module URI | ||||||
|  | 
 | ||||||
|  | =begin | ||||||
|  | 
 | ||||||
|  | == URI::HTTP | ||||||
|  | 
 | ||||||
|  | === Super Class | ||||||
|  | 
 | ||||||
|  | ((<URI::Generic>)) | ||||||
|  | 
 | ||||||
|  | =end | ||||||
|  | 
 | ||||||
|  |   # RFC1738 section 3.3. | ||||||
|  |   class HTTP < Generic | ||||||
|  |     DEFAULT_PORT = 80 | ||||||
|  | 
 | ||||||
|  |     COMPONENT = [ | ||||||
|  |       :scheme,  | ||||||
|  |       :userinfo, :host, :port,  | ||||||
|  |       :path,  | ||||||
|  |       :query,  | ||||||
|  |       :fragment | ||||||
|  |     ].freeze | ||||||
|  | 
 | ||||||
|  | =begin | ||||||
|  | 
 | ||||||
|  | === Class Methods | ||||||
|  | 
 | ||||||
|  | --- URI::HTTP::build | ||||||
|  |     Create a new URI::HTTP object from components of URI::HTTP with | ||||||
|  |     check.  It is scheme, userinfo, host, port, path, query and | ||||||
|  |     fragment. It provided by an Array of a Hash. | ||||||
|  | 
 | ||||||
|  | --- URI::HTTP::new | ||||||
|  |     Create a new URI::HTTP object from ``generic'' components with no | ||||||
|  |     check. | ||||||
|  | 
 | ||||||
|  | =end | ||||||
|  | 
 | ||||||
|  |     def self.build(args) | ||||||
|  |       tmp = Util::make_components_hash(self, args) | ||||||
|  |       return super(tmp) | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     def initialize(*arg) | ||||||
|  |       super(*arg) | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  | =begin | ||||||
|  | 
 | ||||||
|  | === Instance Methods | ||||||
|  | 
 | ||||||
|  | --- URI::HTTP#request_uri | ||||||
|  | 
 | ||||||
|  | =end | ||||||
|  |     def request_uri | ||||||
|  |       r = path_query | ||||||
|  |       if r[0] != ?/ | ||||||
|  | 	r = '/' + r | ||||||
|  |       end | ||||||
|  | 
 | ||||||
|  |       r | ||||||
|  |     end | ||||||
|  |   end # HTTP | ||||||
|  | 
 | ||||||
|  |   @@schemes['HTTP'] = HTTP | ||||||
|  | end # URI | ||||||
							
								
								
									
										26
									
								
								lib/uri/https.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								lib/uri/https.rb
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,26 @@ | ||||||
|  | # | ||||||
|  | # $Id$ | ||||||
|  | # | ||||||
|  | # Copyright (c) 2001 akira yamada <akira@ruby-lang.org> | ||||||
|  | # You can redistribute it and/or modify it under the same term as Ruby. | ||||||
|  | # | ||||||
|  | 
 | ||||||
|  | require 'uri/http' | ||||||
|  | 
 | ||||||
|  | module URI | ||||||
|  | 
 | ||||||
|  | =begin | ||||||
|  | 
 | ||||||
|  | == URI::HTTPS | ||||||
|  | 
 | ||||||
|  | === Super Class | ||||||
|  | 
 | ||||||
|  | ((<URI::HTTP>)) | ||||||
|  | 
 | ||||||
|  | =end | ||||||
|  | 
 | ||||||
|  |   class HTTPS < HTTP | ||||||
|  |     DEFAULT_PORT = 443 | ||||||
|  |   end | ||||||
|  |   @@schemes['HTTPS'] = HTTPS | ||||||
|  | end # URI | ||||||
							
								
								
									
										238
									
								
								lib/uri/ldap.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										238
									
								
								lib/uri/ldap.rb
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,238 @@ | ||||||
|  | # | ||||||
|  | # $Id$ | ||||||
|  | # | ||||||
|  | 
 | ||||||
|  | require 'uri/generic' | ||||||
|  | 
 | ||||||
|  | module URI | ||||||
|  | 
 | ||||||
|  | =begin | ||||||
|  | 
 | ||||||
|  | == URI::LDAP | ||||||
|  | 
 | ||||||
|  | URI::LDAP is copyrighted free software by Takaaki Tateishi and akira yamada. | ||||||
|  | 
 | ||||||
|  |   Copyright (c) 2001 Takaaki Tateishi <ttate@jaist.ac.jp> and  | ||||||
|  |   akira yamada <akira@ruby-lang.org>. | ||||||
|  |   You can redistribute it and/or modify it under the same term as Ruby. | ||||||
|  | 
 | ||||||
|  | === Super Class | ||||||
|  | 
 | ||||||
|  | ((<URI::Generic>)) | ||||||
|  | 
 | ||||||
|  | =end | ||||||
|  | 
 | ||||||
|  |   # LDAP URI SCHEMA (described in RFC2255) | ||||||
|  |   # ldap://<host>/<dn>[?<attrs>[?<scope>[?<filter>[?<extensions>]]]] | ||||||
|  |   class LDAP < Generic | ||||||
|  | 
 | ||||||
|  |     DEFAULT_PORT = 389 | ||||||
|  |      | ||||||
|  |     COMPONENT = [ | ||||||
|  |       :scheme, | ||||||
|  |       :host, :port, | ||||||
|  |       :dn, | ||||||
|  |       :attributes, | ||||||
|  |       :scope, | ||||||
|  |       :filter, | ||||||
|  |       :extensions, | ||||||
|  |     ].freeze | ||||||
|  | 
 | ||||||
|  |     SCOPE = [ | ||||||
|  |       SCOPE_ONE = 'one', | ||||||
|  |       SCOPE_SUB = 'sub', | ||||||
|  |       SCOPE_BASE = 'base', | ||||||
|  |     ].freeze | ||||||
|  | 
 | ||||||
|  | =begin | ||||||
|  | 
 | ||||||
|  | === Class Methods | ||||||
|  | 
 | ||||||
|  | --- URI::LDAP::build | ||||||
|  | 
 | ||||||
|  | --- URI::LDAP::new | ||||||
|  | 
 | ||||||
|  | =end | ||||||
|  | 
 | ||||||
|  |     def self.build(args) | ||||||
|  |       tmp = Util::make_components_hash(self, args) | ||||||
|  | 
 | ||||||
|  |       if tmp[:dn] | ||||||
|  | 	tmp[:path] = tmp[:dn] | ||||||
|  |       end | ||||||
|  | 
 | ||||||
|  |       query = [] | ||||||
|  |       [:extensions, :filter, :scope, :attributes].collect do |x| | ||||||
|  | 	next if !tmp[x] && query.size == 0 | ||||||
|  | 	query.unshift(tmp[x]) | ||||||
|  |       end | ||||||
|  | 
 | ||||||
|  |       tmp[:query] = query.join('?') | ||||||
|  | 
 | ||||||
|  |       return super(tmp) | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     def initialize(*arg) | ||||||
|  |       super(*arg) | ||||||
|  | 
 | ||||||
|  |       if @fragment | ||||||
|  | 	raise InvalidURIError, 'bad LDAP URL' | ||||||
|  |       end | ||||||
|  | 
 | ||||||
|  |       parse_dn | ||||||
|  |       parse_query | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     def parse_dn | ||||||
|  |       @dn = @path[1..-1] | ||||||
|  |     end | ||||||
|  |     private :parse_dn | ||||||
|  | 
 | ||||||
|  |     def parse_query | ||||||
|  |       @attributes = nil | ||||||
|  |       @scope      = nil | ||||||
|  |       @filter     = nil | ||||||
|  |       @extensions = nil | ||||||
|  | 
 | ||||||
|  |       if @query | ||||||
|  | 	attrs, scope, filter, extensions = @query.split('?') | ||||||
|  | 
 | ||||||
|  | 	@attributes = attrs if attrs && attrs.size > 0 | ||||||
|  | 	@scope      = scope if scope && scope.size > 0 | ||||||
|  | 	@filter     = filter if filter && filter.size > 0 | ||||||
|  | 	@extensions = extensions if extensions && extensions.size > 0 | ||||||
|  |       end | ||||||
|  |     end | ||||||
|  |     private :parse_query | ||||||
|  | 
 | ||||||
|  |     def build_path_query | ||||||
|  |       @path = '/' + @dn | ||||||
|  | 
 | ||||||
|  |       query = [] | ||||||
|  |       [@extensions, @filter, @scope, @attributes].each do |x| | ||||||
|  | 	next if !x && query.size == 0 | ||||||
|  | 	query.unshift(x) | ||||||
|  |       end | ||||||
|  |       @query = query.join('?') | ||||||
|  |     end | ||||||
|  |     private :build_path_query | ||||||
|  | 
 | ||||||
|  | =begin | ||||||
|  | 
 | ||||||
|  | === Instance Methods | ||||||
|  | 
 | ||||||
|  | --- URI::LDAP#dn | ||||||
|  | 
 | ||||||
|  | --- URI::LDAP#dn=(v) | ||||||
|  | 
 | ||||||
|  | =end | ||||||
|  | 
 | ||||||
|  |     def dn | ||||||
|  |       @dn | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     def set_dn(val) | ||||||
|  |       @dn = val | ||||||
|  |       build_path_query | ||||||
|  |     end | ||||||
|  |     protected :set_dn | ||||||
|  | 
 | ||||||
|  |     def dn=(val) | ||||||
|  |       set_dn(val) | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  | =begin | ||||||
|  | 
 | ||||||
|  | --- URI::LDAP#attributes | ||||||
|  | 
 | ||||||
|  | --- URI::LDAP#attributes=(v) | ||||||
|  | 
 | ||||||
|  | =end | ||||||
|  | 
 | ||||||
|  |     def attributes | ||||||
|  |       @attributes | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     def set_attributes(val) | ||||||
|  |       @attributes = val | ||||||
|  |       build_path_query | ||||||
|  |     end | ||||||
|  |     protected :set_attributes | ||||||
|  | 
 | ||||||
|  |     def attributes=(val) | ||||||
|  |       set_attributes(val) | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  | =begin | ||||||
|  | 
 | ||||||
|  | --- URI::LDAP#scope | ||||||
|  | 
 | ||||||
|  | --- URI::LDAP#scope=(v) | ||||||
|  | 
 | ||||||
|  | =end | ||||||
|  | 
 | ||||||
|  |     def scope | ||||||
|  |       @scope | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     def set_scope(val) | ||||||
|  |       @scope = val | ||||||
|  |       build_path_query | ||||||
|  |     end | ||||||
|  |     protected :set_scope | ||||||
|  | 
 | ||||||
|  |     def scope=(val) | ||||||
|  |       set_scope(val) | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  | =begin | ||||||
|  | 
 | ||||||
|  | --- URI::LDAP#filter | ||||||
|  | 
 | ||||||
|  | --- URI::LDAP#filter=(v) | ||||||
|  | 
 | ||||||
|  | =end | ||||||
|  | 
 | ||||||
|  |     def filter | ||||||
|  |       @filter | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     def set_filter(val) | ||||||
|  |       @filter = val | ||||||
|  |       build_path_query | ||||||
|  |     end | ||||||
|  |     protected :set_filter | ||||||
|  | 
 | ||||||
|  |     def filter=(val) | ||||||
|  |       set_filter(val) | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  | =begin | ||||||
|  | 
 | ||||||
|  | --- URI::LDAP#extensions | ||||||
|  | 
 | ||||||
|  | --- URI::LDAP#extensions=(v) | ||||||
|  | 
 | ||||||
|  | =end | ||||||
|  | 
 | ||||||
|  |     def extensions | ||||||
|  |       @extensions | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     def set_extensions(val) | ||||||
|  |       @extensions = val | ||||||
|  |       build_path_query | ||||||
|  |     end | ||||||
|  |     protected :set_extensions | ||||||
|  | 
 | ||||||
|  |     def extensions=(val) | ||||||
|  |       set_extensions(val) | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def hierarchical? | ||||||
|  |     false | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   @@schemes['LDAP'] = LDAP | ||||||
|  | end | ||||||
							
								
								
									
										260
									
								
								lib/uri/mailto.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										260
									
								
								lib/uri/mailto.rb
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,260 @@ | ||||||
|  | # | ||||||
|  | # $Id$ | ||||||
|  | # | ||||||
|  | # Copyright (c) 2001 akira yamada <akira@ruby-lang.org> | ||||||
|  | # You can redistribute it and/or modify it under the same term as Ruby. | ||||||
|  | # | ||||||
|  | 
 | ||||||
|  | require 'uri/generic' | ||||||
|  | 
 | ||||||
|  | module URI | ||||||
|  | 
 | ||||||
|  | =begin | ||||||
|  | 
 | ||||||
|  | == URI::MailTo | ||||||
|  | 
 | ||||||
|  | === Super Class | ||||||
|  | 
 | ||||||
|  | ((<URI::Generic>)) | ||||||
|  | 
 | ||||||
|  | =end | ||||||
|  | 
 | ||||||
|  |   # RFC2368, The mailto URL scheme | ||||||
|  |   class MailTo < Generic | ||||||
|  |     include REGEXP | ||||||
|  | 
 | ||||||
|  |     DEFAULT_PORT = nil | ||||||
|  | 
 | ||||||
|  |     COMPONENT = [ | ||||||
|  |       :scheme, | ||||||
|  |       :to, :headers | ||||||
|  |     ].freeze | ||||||
|  | 
 | ||||||
|  |     #  "hname" and "hvalue" are encodings of an RFC 822 header name and | ||||||
|  |     #  value, respectively. As with "to", all URL reserved characters must | ||||||
|  |     #  be encoded. | ||||||
|  |     # | ||||||
|  |     #  "#mailbox" is as specified in RFC 822 [RFC822]. This means that it | ||||||
|  |     #  consists of zero or more comma-separated mail addresses, possibly | ||||||
|  |     #  including "phrase" and "comment" components. Note that all URL | ||||||
|  |     #  reserved characters in "to" must be encoded: in particular, | ||||||
|  |     #  parentheses, commas, and the percent sign ("%"), which commonly occur | ||||||
|  |     #  in the "mailbox" syntax. | ||||||
|  |     # | ||||||
|  |     #  Within mailto URLs, the characters "?", "=", "&" are reserved. | ||||||
|  | 
 | ||||||
|  |     # hname      =  *urlc | ||||||
|  |     # hvalue     =  *urlc | ||||||
|  |     # header     =  hname "=" hvalue | ||||||
|  |     HEADER_REGEXP = "(?:[^?=&]*=[^?=&]*)".freeze | ||||||
|  |     # headers    =  "?" header *( "&" header ) | ||||||
|  |     # to         =  #mailbox | ||||||
|  |     # mailtoURL  =  "mailto:" [ to ] [ headers ] | ||||||
|  |     MAILBOX_REGEXP = "(?:[^(),%?=&]|#{PATTERN::ESCAPED})".freeze | ||||||
|  |     MAILTO_REGEXP = Regexp.new(" | ||||||
|  |       \\A | ||||||
|  |       (#{MAILBOX_REGEXP}*?)                         (?# 1: to) | ||||||
|  |       (?: | ||||||
|  |         \\? | ||||||
|  |         (#{HEADER_REGEXP}(?:\\&#{HEADER_REGEXP})*)  (?# 2: headers) | ||||||
|  |       )? | ||||||
|  |       \\z | ||||||
|  |     ", Regexp::EXTENDED, 'N').freeze | ||||||
|  | 
 | ||||||
|  | =begin | ||||||
|  | 
 | ||||||
|  | === Class Methods | ||||||
|  | 
 | ||||||
|  | --- URI::MailTo::build | ||||||
|  |     Create a new URI::MailTo object from components of URI::MailTo | ||||||
|  |     with check.  It is to and headers. It provided by an Array of a | ||||||
|  |     Hash. You can provide headers as an String like | ||||||
|  |     "subject=subscribe&cc=addr" or an Array like [["subject", | ||||||
|  |     "subscribe"], ["cc", "addr"]] | ||||||
|  | 
 | ||||||
|  | --- URI::MailTo::new | ||||||
|  |     Create a new URI::MailTo object from ``generic'' components with | ||||||
|  |     no check. Because, this method is usually called from URI::parse | ||||||
|  |     and the method checks validity of each components. | ||||||
|  | 
 | ||||||
|  | =end | ||||||
|  | 
 | ||||||
|  |     def self.build(args) | ||||||
|  |       tmp = Util::make_components_hash(self, args) | ||||||
|  | 
 | ||||||
|  |       if tmp[:to] | ||||||
|  | 	tmp[:opaque] = tmp[:to] | ||||||
|  |       else | ||||||
|  | 	tmp[:opaque] = '' | ||||||
|  |       end | ||||||
|  | 
 | ||||||
|  |       if tmp[:headers] | ||||||
|  | 	tmp[:opaque] << '?' | ||||||
|  | 
 | ||||||
|  | 	if tmp[:headers].kind_of?(Array) | ||||||
|  | 	  tmp[:opaque] << tmp[:headers].collect { |x| | ||||||
|  | 	    if x.kind_of?(Array) | ||||||
|  | 	      x[0] + '=' + x[1..-1].to_s | ||||||
|  | 	    else | ||||||
|  | 	      x.to_s | ||||||
|  | 	    end | ||||||
|  | 	  }.join('&') | ||||||
|  | 
 | ||||||
|  | 	elsif tmp[:headers].kind_of?(Hash) | ||||||
|  | 	  tmp[:opaque] << tmp[:headers].collect { |h,v| | ||||||
|  | 	    h + '=' + v | ||||||
|  | 	  }.join('&') | ||||||
|  | 
 | ||||||
|  | 	else | ||||||
|  | 	  tmp[:opaque] << tmp[:headers].to_s | ||||||
|  | 	end | ||||||
|  |       end | ||||||
|  | 
 | ||||||
|  |       return super(tmp) | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     def initialize(*arg) | ||||||
|  |       super(*arg) | ||||||
|  | 
 | ||||||
|  |       @to = nil | ||||||
|  |       @headers = [] | ||||||
|  | 
 | ||||||
|  |       if MAILTO_REGEXP =~ @opaque | ||||||
|  |  	if arg[-1] | ||||||
|  | 	  self.to = $1 | ||||||
|  | 	  self.headers = $2 | ||||||
|  | 	else | ||||||
|  | 	  set_to($1) | ||||||
|  | 	  set_headers($2) | ||||||
|  | 	end | ||||||
|  |       elsif arg[-1] | ||||||
|  | 	raise InvalidComponentError, | ||||||
|  | 	  "unrecognised opaque part for mailtoURL: #{@opaque}" | ||||||
|  |       end | ||||||
|  |     end | ||||||
|  |     attr_reader :to | ||||||
|  |     attr_reader :headers | ||||||
|  | 
 | ||||||
|  | =begin | ||||||
|  | 
 | ||||||
|  | === Instance Methods | ||||||
|  | 
 | ||||||
|  | --- URI::MailTo#to | ||||||
|  | 
 | ||||||
|  | --- URI::MailTo#to=(v) | ||||||
|  | 
 | ||||||
|  | =end | ||||||
|  | 
 | ||||||
|  |     # | ||||||
|  |     # methods for to | ||||||
|  |     # | ||||||
|  | 
 | ||||||
|  |     def check_to(v) | ||||||
|  |       return true unless v | ||||||
|  |       return true if v.size == 0 | ||||||
|  | 
 | ||||||
|  |       if OPAQUE !~ v || /\A#{MAILBOX_REGEXP}*\z/o !~ v | ||||||
|  | 	raise InvalidComponentError, | ||||||
|  | 	  "bad component(expected opaque component): #{v}" | ||||||
|  |       end | ||||||
|  | 
 | ||||||
|  |       return true | ||||||
|  |     end | ||||||
|  |     private :check_to | ||||||
|  | 
 | ||||||
|  |     def set_to(v) | ||||||
|  |       @to = v | ||||||
|  |     end | ||||||
|  |     protected :set_to | ||||||
|  | 
 | ||||||
|  |     def to=(v) | ||||||
|  |       check_to(v) | ||||||
|  |       set_to(v) | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  | =begin | ||||||
|  | 
 | ||||||
|  | --- URI::MailTo#headers | ||||||
|  | 
 | ||||||
|  | --- URI::MailTo#headers=(v) | ||||||
|  | 
 | ||||||
|  | =end | ||||||
|  | 
 | ||||||
|  |     # | ||||||
|  |     # methods for headers | ||||||
|  |     # | ||||||
|  | 
 | ||||||
|  |     def check_headers(v) | ||||||
|  |       return true unless v | ||||||
|  |       return true if v.size == 0 | ||||||
|  | 
 | ||||||
|  |       if OPAQUE !~ v ||  | ||||||
|  | 	  /\A(#{HEADER_REGEXP}(?:\&#{HEADER_REGEXP})*)\z/o !~ v | ||||||
|  | 	raise InvalidComponentError, | ||||||
|  | 	  "bad component(expected opaque component): #{v}" | ||||||
|  |       end | ||||||
|  | 
 | ||||||
|  |       return true | ||||||
|  |     end | ||||||
|  |     private :check_headers | ||||||
|  | 
 | ||||||
|  |     def set_headers(v) | ||||||
|  |       @headers = [] | ||||||
|  |       if v | ||||||
|  | 	v.scan(HEADER_REGEXP) do |x| | ||||||
|  | 	  @headers << x.split(/=/o, 2) | ||||||
|  | 	end | ||||||
|  |       end | ||||||
|  |     end | ||||||
|  |     protected :set_headers | ||||||
|  | 
 | ||||||
|  |     def headers=(v) | ||||||
|  |       check_headers(v) | ||||||
|  |       set_headers(v) | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     def to_str | ||||||
|  |       @scheme + ':' +  | ||||||
|  | 	if @to  | ||||||
|  | 	  @to | ||||||
|  | 	else | ||||||
|  | 	  '' | ||||||
|  | 	end +  | ||||||
|  | 	if @headers.size > 0 | ||||||
|  | 	  '?' + @headers.collect{|x| x.join('=')}.join('&') | ||||||
|  | 	else | ||||||
|  | 	  '' | ||||||
|  | 	end | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  | =begin | ||||||
|  | 
 | ||||||
|  | --- URI::MailTo#to_mailtext | ||||||
|  | 
 | ||||||
|  | =end | ||||||
|  |     def to_mailtext | ||||||
|  |       to = URI::unescape(@to) | ||||||
|  |       head = '' | ||||||
|  |       body = '' | ||||||
|  |       @headers.each do |x| | ||||||
|  | 	case x[0] | ||||||
|  | 	when 'body' | ||||||
|  | 	  body = URI::unescape(x[1]) | ||||||
|  | 	when 'to' | ||||||
|  | 	  to << ', ' + URI::unescape(x[1]) | ||||||
|  | 	else | ||||||
|  | 	  head << URI::unescape(x[0]).capitalize + ': ' + | ||||||
|  | 	    URI::unescape(x[1])  + "\n" | ||||||
|  | 	end | ||||||
|  |       end | ||||||
|  | 
 | ||||||
|  |       return "To: #{to} | ||||||
|  | #{head} | ||||||
|  | #{body} | ||||||
|  | " | ||||||
|  |     end | ||||||
|  |     alias to_rfc822text to_mailtext | ||||||
|  |   end # MailTo | ||||||
|  | 
 | ||||||
|  |   @@schemes['MAILTO'] = MailTo | ||||||
|  | end # URI | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 (no author)
						(no author)