summaryrefslogtreecommitdiff
path: root/ruby_1_8_6/lib/webrick
diff options
context:
space:
mode:
Diffstat (limited to 'ruby_1_8_6/lib/webrick')
-rw-r--r--ruby_1_8_6/lib/webrick/accesslog.rb67
-rw-r--r--ruby_1_8_6/lib/webrick/cgi.rb257
-rw-r--r--ruby_1_8_6/lib/webrick/compat.rb15
-rw-r--r--ruby_1_8_6/lib/webrick/config.rb97
-rw-r--r--ruby_1_8_6/lib/webrick/cookie.rb110
-rw-r--r--ruby_1_8_6/lib/webrick/htmlutils.rb25
-rw-r--r--ruby_1_8_6/lib/webrick/httpauth.rb45
-rw-r--r--ruby_1_8_6/lib/webrick/httpauth/authenticator.rb79
-rw-r--r--ruby_1_8_6/lib/webrick/httpauth/basicauth.rb65
-rw-r--r--ruby_1_8_6/lib/webrick/httpauth/digestauth.rb343
-rw-r--r--ruby_1_8_6/lib/webrick/httpauth/htdigest.rb91
-rw-r--r--ruby_1_8_6/lib/webrick/httpauth/htgroup.rb61
-rw-r--r--ruby_1_8_6/lib/webrick/httpauth/htpasswd.rb83
-rw-r--r--ruby_1_8_6/lib/webrick/httpauth/userdb.rb29
-rw-r--r--ruby_1_8_6/lib/webrick/httpproxy.rb254
-rw-r--r--ruby_1_8_6/lib/webrick/httprequest.rb365
-rw-r--r--ruby_1_8_6/lib/webrick/httpresponse.rb327
-rw-r--r--ruby_1_8_6/lib/webrick/https.rb63
-rw-r--r--ruby_1_8_6/lib/webrick/httpserver.rb210
-rw-r--r--ruby_1_8_6/lib/webrick/httpservlet.rb22
-rw-r--r--ruby_1_8_6/lib/webrick/httpservlet/abstract.rb71
-rw-r--r--ruby_1_8_6/lib/webrick/httpservlet/cgi_runner.rb47
-rw-r--r--ruby_1_8_6/lib/webrick/httpservlet/cgihandler.rb104
-rw-r--r--ruby_1_8_6/lib/webrick/httpservlet/erbhandler.rb54
-rw-r--r--ruby_1_8_6/lib/webrick/httpservlet/filehandler.rb435
-rw-r--r--ruby_1_8_6/lib/webrick/httpservlet/prochandler.rb33
-rw-r--r--ruby_1_8_6/lib/webrick/httpstatus.rb126
-rw-r--r--ruby_1_8_6/lib/webrick/httputils.rb399
-rw-r--r--ruby_1_8_6/lib/webrick/httpversion.rb49
-rw-r--r--ruby_1_8_6/lib/webrick/log.rb88
-rw-r--r--ruby_1_8_6/lib/webrick/server.rb200
-rw-r--r--ruby_1_8_6/lib/webrick/ssl.rb126
-rw-r--r--ruby_1_8_6/lib/webrick/utils.rb100
-rw-r--r--ruby_1_8_6/lib/webrick/version.rb13
34 files changed, 0 insertions, 4453 deletions
diff --git a/ruby_1_8_6/lib/webrick/accesslog.rb b/ruby_1_8_6/lib/webrick/accesslog.rb
deleted file mode 100644
index f97769545e..0000000000
--- a/ruby_1_8_6/lib/webrick/accesslog.rb
+++ /dev/null
@@ -1,67 +0,0 @@
-#
-# accesslog.rb -- Access log handling utilities
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2002 keita yamaguchi
-# Copyright (c) 2002 Internet Programming with Ruby writers
-#
-# $IPR: accesslog.rb,v 1.1 2002/10/01 17:16:32 gotoyuzo Exp $
-
-module WEBrick
- module AccessLog
- class AccessLogError < StandardError; end
-
- CLF_TIME_FORMAT = "[%d/%b/%Y:%H:%M:%S %Z]"
- COMMON_LOG_FORMAT = "%h %l %u %t \"%r\" %s %b"
- CLF = COMMON_LOG_FORMAT
- REFERER_LOG_FORMAT = "%{Referer}i -> %U"
- AGENT_LOG_FORMAT = "%{User-Agent}i"
- COMBINED_LOG_FORMAT = "#{CLF} \"%{Referer}i\" \"%{User-agent}i\""
-
- module_function
-
- # This format specification is a subset of mod_log_config of Apache.
- # http://httpd.apache.org/docs/mod/mod_log_config.html#formats
- def setup_params(config, req, res)
- params = Hash.new("")
- params["a"] = req.peeraddr[3]
- params["b"] = res.sent_size
- params["e"] = ENV
- params["f"] = res.filename || ""
- params["h"] = req.peeraddr[2]
- params["i"] = req
- params["l"] = "-"
- params["m"] = req.request_method
- params["n"] = req.attributes
- params["o"] = res
- params["p"] = req.port
- params["q"] = req.query_string
- params["r"] = req.request_line.sub(/\x0d?\x0a\z/o, '')
- params["s"] = res.status # won't support "%>s"
- params["t"] = req.request_time
- params["T"] = Time.now - req.request_time
- params["u"] = req.user || "-"
- params["U"] = req.unparsed_uri
- params["v"] = config[:ServerName]
- params
- end
-
- def format(format_string, params)
- format_string.gsub(/\%(?:\{(.*?)\})?>?([a-zA-Z%])/){
- param, spec = $1, $2
- case spec[0]
- when ?e, ?i, ?n, ?o
- raise AccessLogError,
- "parameter is required for \"#{spec}\"" unless param
- params[spec][param] || "-"
- when ?t
- params[spec].strftime(param || CLF_TIME_FORMAT)
- when ?%
- "%"
- else
- params[spec]
- end
- }
- end
- end
-end
diff --git a/ruby_1_8_6/lib/webrick/cgi.rb b/ruby_1_8_6/lib/webrick/cgi.rb
deleted file mode 100644
index ff5f7a6102..0000000000
--- a/ruby_1_8_6/lib/webrick/cgi.rb
+++ /dev/null
@@ -1,257 +0,0 @@
-#
-# cgi.rb -- Yet another CGI library
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2003 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $Id$
-
-require "webrick/httprequest"
-require "webrick/httpresponse"
-require "webrick/config"
-require "stringio"
-
-module WEBrick
- class CGI
- CGIError = Class.new(StandardError)
-
- attr_reader :config, :logger
-
- def initialize(*args)
- if defined?(MOD_RUBY)
- unless ENV.has_key?("GATEWAY_INTERFACE")
- Apache.request.setup_cgi_env
- end
- end
- if %r{HTTP/(\d+\.\d+)} =~ ENV["SERVER_PROTOCOL"]
- httpv = $1
- end
- @config = WEBrick::Config::HTTP.dup.update(
- :ServerSoftware => ENV["SERVER_SOFTWARE"] || "null",
- :HTTPVersion => HTTPVersion.new(httpv || "1.0"),
- :RunOnCGI => true, # to detect if it runs on CGI.
- :NPH => false # set true to run as NPH script.
- )
- if config = args.shift
- @config.update(config)
- end
- @config[:Logger] ||= WEBrick::BasicLog.new($stderr)
- @logger = @config[:Logger]
- @options = args
- end
-
- def [](key)
- @config[key]
- end
-
- def start(env=ENV, stdin=$stdin, stdout=$stdout)
- sock = WEBrick::CGI::Socket.new(@config, env, stdin, stdout)
- req = HTTPRequest.new(@config)
- res = HTTPResponse.new(@config)
- unless @config[:NPH] or defined?(MOD_RUBY)
- def res.setup_header
- unless @header["status"]
- phrase = HTTPStatus::reason_phrase(@status)
- @header["status"] = "#{@status} #{phrase}"
- end
- super
- end
- def res.status_line
- ""
- end
- end
-
- begin
- req.parse(sock)
- req.script_name = (env["SCRIPT_NAME"] || File.expand_path($0)).dup
- req.path_info = (env["PATH_INFO"] || "").dup
- req.query_string = env["QUERY_STRING"]
- req.user = env["REMOTE_USER"]
- res.request_method = req.request_method
- res.request_uri = req.request_uri
- res.request_http_version = req.http_version
- res.keep_alive = req.keep_alive?
- self.service(req, res)
- rescue HTTPStatus::Error => ex
- res.set_error(ex)
- rescue HTTPStatus::Status => ex
- res.status = ex.code
- rescue Exception => ex
- @logger.error(ex)
- res.set_error(ex, true)
- ensure
- req.fixup
- if defined?(MOD_RUBY)
- res.setup_header
- Apache.request.status_line = "#{res.status} #{res.reason_phrase}"
- Apache.request.status = res.status
- table = Apache.request.headers_out
- res.header.each{|key, val|
- case key
- when /^content-encoding$/i
- Apache::request.content_encoding = val
- when /^content-type$/i
- Apache::request.content_type = val
- else
- table[key] = val.to_s
- end
- }
- res.cookies.each{|cookie|
- table.add("Set-Cookie", cookie.to_s)
- }
- Apache.request.send_http_header
- res.send_body(sock)
- else
- res.send_response(sock)
- end
- end
- end
-
- def service(req, res)
- method_name = "do_" + req.request_method.gsub(/-/, "_")
- if respond_to?(method_name)
- __send__(method_name, req, res)
- else
- raise HTTPStatus::MethodNotAllowed,
- "unsupported method `#{req.request_method}'."
- end
- end
-
- class Socket
- include Enumerable
-
- private
-
- def initialize(config, env, stdin, stdout)
- @config = config
- @env = env
- @header_part = StringIO.new
- @body_part = stdin
- @out_port = stdout
- @out_port.binmode
-
- @server_addr = @env["SERVER_ADDR"] || "0.0.0.0"
- @server_name = @env["SERVER_NAME"]
- @server_port = @env["SERVER_PORT"]
- @remote_addr = @env["REMOTE_ADDR"]
- @remote_host = @env["REMOTE_HOST"] || @remote_addr
- @remote_port = @env["REMOTE_PORT"] || 0
-
- begin
- @header_part << request_line << CRLF
- setup_header
- @header_part << CRLF
- @header_part.rewind
- rescue Exception => ex
- raise CGIError, "invalid CGI environment"
- end
- end
-
- def request_line
- meth = @env["REQUEST_METHOD"] || "GET"
- unless url = @env["REQUEST_URI"]
- url = (@env["SCRIPT_NAME"] || File.expand_path($0)).dup
- url << @env["PATH_INFO"].to_s
- url = WEBrick::HTTPUtils.escape_path(url)
- if query_string = @env["QUERY_STRING"]
- unless query_string.empty?
- url << "?" << query_string
- end
- end
- end
- # we cannot get real HTTP version of client ;)
- httpv = @config[:HTTPVersion]
- return "#{meth} #{url} HTTP/#{httpv}"
- end
-
- def setup_header
- add_header("CONTENT_TYPE", "Content-Type")
- add_header("CONTENT_LENGTH", "Content-length")
- @env.each_key{|name|
- if /^HTTP_(.*)/ =~ name
- add_header(name, $1.gsub(/_/, "-"))
- end
- }
- end
-
- def add_header(envname, hdrname)
- if value = @env[envname]
- unless value.empty?
- @header_part << hdrname << ": " << value << CRLF
- end
- end
- end
-
- def input
- @header_part.eof? ? @body_part : @header_part
- end
-
- public
-
- def peeraddr
- [nil, @remote_port, @remote_host, @remote_addr]
- end
-
- def addr
- [nil, @server_port, @server_name, @server_addr]
- end
-
- def gets(eol=LF)
- input.gets(eol)
- end
-
- def read(size=nil)
- input.read(size)
- end
-
- def each
- input.each{|line| yield(line) }
- end
-
- def <<(data)
- @out_port << data
- end
-
- def cert
- return nil unless defined?(OpenSSL)
- if pem = @env["SSL_SERVER_CERT"]
- OpenSSL::X509::Certificate.new(pem) unless pem.empty?
- end
- end
-
- def peer_cert
- return nil unless defined?(OpenSSL)
- if pem = @env["SSL_CLIENT_CERT"]
- OpenSSL::X509::Certificate.new(pem) unless pem.empty?
- end
- end
-
- def peer_cert_chain
- return nil unless defined?(OpenSSL)
- if @env["SSL_CLIENT_CERT_CHAIN_0"]
- keys = @env.keys
- certs = keys.sort.collect{|k|
- if /^SSL_CLIENT_CERT_CHAIN_\d+$/ =~ k
- if pem = @env[k]
- OpenSSL::X509::Certificate.new(pem) unless pem.empty?
- end
- end
- }
- certs.compact
- end
- end
-
- def cipher
- return nil unless defined?(OpenSSL)
- if cipher = @env["SSL_CIPHER"]
- ret = [ cipher ]
- ret << @env["SSL_PROTOCOL"]
- ret << @env["SSL_CIPHER_USEKEYSIZE"]
- ret << @env["SSL_CIPHER_ALGKEYSIZE"]
- ret
- end
- end
- end
- end
-end
diff --git a/ruby_1_8_6/lib/webrick/compat.rb b/ruby_1_8_6/lib/webrick/compat.rb
deleted file mode 100644
index ad7760b640..0000000000
--- a/ruby_1_8_6/lib/webrick/compat.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-#
-# compat.rb -- cross platform compatibility
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2002 GOTOU Yuuzou
-# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: compat.rb,v 1.6 2002/10/01 17:16:32 gotoyuzo Exp $
-
-module Errno
- class EPROTO < SystemCallError; end
- class ECONNRESET < SystemCallError; end
- class ECONNABORTED < SystemCallError; end
-end
diff --git a/ruby_1_8_6/lib/webrick/config.rb b/ruby_1_8_6/lib/webrick/config.rb
deleted file mode 100644
index 5897b977d8..0000000000
--- a/ruby_1_8_6/lib/webrick/config.rb
+++ /dev/null
@@ -1,97 +0,0 @@
-#
-# config.rb -- Default configurations.
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
-# Copyright (c) 2003 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: config.rb,v 1.52 2003/07/22 19:20:42 gotoyuzo Exp $
-
-require 'webrick/version'
-require 'webrick/httpversion'
-require 'webrick/httputils'
-require 'webrick/utils'
-require 'webrick/log'
-
-module WEBrick
- module Config
- LIBDIR = File::dirname(__FILE__)
-
- # for GenericServer
- General = {
- :ServerName => Utils::getservername,
- :BindAddress => nil, # "0.0.0.0" or "::" or nil
- :Port => nil, # users MUST specifiy this!!
- :MaxClients => 100, # maximum number of the concurrent connections
- :ServerType => nil, # default: WEBrick::SimpleServer
- :Logger => nil, # default: WEBrick::Log.new
- :ServerSoftware => "WEBrick/#{WEBrick::VERSION} " +
- "(Ruby/#{RUBY_VERSION}/#{RUBY_RELEASE_DATE})",
- :TempDir => ENV['TMPDIR']||ENV['TMP']||ENV['TEMP']||'/tmp',
- :DoNotListen => false,
- :StartCallback => nil,
- :StopCallback => nil,
- :AcceptCallback => nil,
- }
-
- # for HTTPServer, HTTPRequest, HTTPResponse ...
- HTTP = General.dup.update(
- :Port => 80,
- :RequestTimeout => 30,
- :HTTPVersion => HTTPVersion.new("1.1"),
- :AccessLog => nil,
- :MimeTypes => HTTPUtils::DefaultMimeTypes,
- :DirectoryIndex => ["index.html","index.htm","index.cgi","index.rhtml"],
- :DocumentRoot => nil,
- :DocumentRootOptions => { :FancyIndexing => true },
- :RequestHandler => nil,
- :RequestCallback => nil, # alias of :RequestHandler
- :ServerAlias => nil,
-
- # for HTTPProxyServer
- :ProxyAuthProc => nil,
- :ProxyContentHandler => nil,
- :ProxyVia => true,
- :ProxyTimeout => true,
- :ProxyURI => nil,
-
- :CGIInterpreter => nil,
- :CGIPathEnv => nil,
-
- # workaround: if Request-URIs contain 8bit chars,
- # they should be escaped before calling of URI::parse().
- :Escape8bitURI => false
- )
-
- FileHandler = {
- :NondisclosureName => [".ht*", "*~"],
- :FancyIndexing => false,
- :HandlerTable => {},
- :HandlerCallback => nil,
- :DirectoryCallback => nil,
- :FileCallback => nil,
- :UserDir => nil, # e.g. "public_html"
- :AcceptableLanguages => [] # ["en", "ja", ... ]
- }
-
- BasicAuth = {
- :AutoReloadUserDB => true,
- }
-
- DigestAuth = {
- :Algorithm => 'MD5-sess', # or 'MD5'
- :Domain => nil, # an array includes domain names.
- :Qop => [ 'auth' ], # 'auth' or 'auth-int' or both.
- :UseOpaque => true,
- :UseNextNonce => false,
- :CheckNc => false,
- :UseAuthenticationInfoHeader => true,
- :AutoReloadUserDB => true,
- :NonceExpirePeriod => 30*60,
- :NonceExpireDelta => 60,
- :InternetExplorerHack => true,
- :OperaHack => true,
- }
- end
-end
diff --git a/ruby_1_8_6/lib/webrick/cookie.rb b/ruby_1_8_6/lib/webrick/cookie.rb
deleted file mode 100644
index 814e6645a3..0000000000
--- a/ruby_1_8_6/lib/webrick/cookie.rb
+++ /dev/null
@@ -1,110 +0,0 @@
-#
-# cookie.rb -- Cookie class
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
-# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: cookie.rb,v 1.16 2002/09/21 12:23:35 gotoyuzo Exp $
-
-require 'time'
-require 'webrick/httputils'
-
-module WEBrick
- class Cookie
-
- attr_reader :name
- attr_accessor :value, :version
- attr_accessor :domain, :path, :secure
- attr_accessor :comment, :max_age
- #attr_accessor :comment_url, :discard, :port
-
- def initialize(name, value)
- @name = name
- @value = value
- @version = 0 # Netscape Cookie
-
- @domain = @path = @secure = @comment = @max_age =
- @expires = @comment_url = @discard = @port = nil
- end
-
- def expires=(t)
- @expires = t && (t.is_a?(Time) ? t.httpdate : t.to_s)
- end
-
- def expires
- @expires && Time.parse(@expires)
- end
-
- def to_s
- ret = ""
- ret << @name << "=" << @value
- ret << "; " << "Version=" << @version.to_s if @version > 0
- ret << "; " << "Domain=" << @domain if @domain
- ret << "; " << "Expires=" << @expires if @expires
- ret << "; " << "Max-Age=" << @max_age.to_s if @max_age
- ret << "; " << "Comment=" << @comment if @comment
- ret << "; " << "Path=" << @path if @path
- ret << "; " << "Secure" if @secure
- ret
- end
-
- # Cookie::parse()
- # It parses Cookie field sent from the user agent.
- def self.parse(str)
- if str
- ret = []
- cookie = nil
- ver = 0
- str.split(/[;,]\s+/).each{|x|
- key, val = x.split(/=/,2)
- val = val ? HTTPUtils::dequote(val) : ""
- case key
- when "$Version"; ver = val.to_i
- when "$Path"; cookie.path = val
- when "$Domain"; cookie.domain = val
- when "$Port"; cookie.port = val
- else
- ret << cookie if cookie
- cookie = self.new(key, val)
- cookie.version = ver
- end
- }
- ret << cookie if cookie
- ret
- end
- end
-
- def self.parse_set_cookie(str)
- cookie_elem = str.split(/;/)
- first_elem = cookie_elem.shift
- first_elem.strip!
- key, value = first_elem.split(/=/, 2)
- cookie = new(key, HTTPUtils.dequote(value))
- cookie_elem.each{|pair|
- pair.strip!
- key, value = pair.split(/=/, 2)
- if value
- value = HTTPUtils.dequote(value.strip)
- end
- case key.downcase
- when "domain" then cookie.domain = value
- when "path" then cookie.path = value
- when "expires" then cookie.expires = value
- when "max-age" then cookie.max_age = Integer(value)
- when "comment" then cookie.comment = value
- when "version" then cookie.version = Integer(value)
- when "secure" then cookie.secure = true
- end
- }
- return cookie
- end
-
- def self.parse_set_cookies(str)
- return str.split(/,(?=[^;,]*=)|,$/).collect{|c|
- parse_set_cookie(c)
- }
- end
- end
-end
diff --git a/ruby_1_8_6/lib/webrick/htmlutils.rb b/ruby_1_8_6/lib/webrick/htmlutils.rb
deleted file mode 100644
index cf8d542c09..0000000000
--- a/ruby_1_8_6/lib/webrick/htmlutils.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-#
-# htmlutils.rb -- HTMLUtils Module
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
-# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: htmlutils.rb,v 1.7 2002/09/21 12:23:35 gotoyuzo Exp $
-
-module WEBrick
- module HTMLUtils
-
- def escape(string)
- str = string ? string.dup : ""
- str.gsub!(/&/n, '&amp;')
- str.gsub!(/\"/n, '&quot;')
- str.gsub!(/>/n, '&gt;')
- str.gsub!(/</n, '&lt;')
- str
- end
- module_function :escape
-
- end
-end
diff --git a/ruby_1_8_6/lib/webrick/httpauth.rb b/ruby_1_8_6/lib/webrick/httpauth.rb
deleted file mode 100644
index 147c04021c..0000000000
--- a/ruby_1_8_6/lib/webrick/httpauth.rb
+++ /dev/null
@@ -1,45 +0,0 @@
-#
-# httpauth.rb -- HTTP access authentication
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
-# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: httpauth.rb,v 1.14 2003/07/22 19:20:42 gotoyuzo Exp $
-
-require 'webrick/httpauth/basicauth'
-require 'webrick/httpauth/digestauth'
-require 'webrick/httpauth/htpasswd'
-require 'webrick/httpauth/htdigest'
-require 'webrick/httpauth/htgroup'
-
-module WEBrick
- module HTTPAuth
- module_function
-
- def _basic_auth(req, res, realm, req_field, res_field, err_type, block)
- user = pass = nil
- if /^Basic\s+(.*)/o =~ req[req_field]
- userpass = $1
- user, pass = userpass.unpack("m*")[0].split(":", 2)
- end
- if block.call(user, pass)
- req.user = user
- return
- end
- res[res_field] = "Basic realm=\"#{realm}\""
- raise err_type
- end
-
- def basic_auth(req, res, realm, &block)
- _basic_auth(req, res, realm, "Authorization", "WWW-Authenticate",
- HTTPStatus::Unauthorized, block)
- end
-
- def proxy_basic_auth(req, res, realm, &block)
- _basic_auth(req, res, realm, "Proxy-Authorization", "Proxy-Authenticate",
- HTTPStatus::ProxyAuthenticationRequired, block)
- end
- end
-end
diff --git a/ruby_1_8_6/lib/webrick/httpauth/authenticator.rb b/ruby_1_8_6/lib/webrick/httpauth/authenticator.rb
deleted file mode 100644
index fe2dbf4e0c..0000000000
--- a/ruby_1_8_6/lib/webrick/httpauth/authenticator.rb
+++ /dev/null
@@ -1,79 +0,0 @@
-#
-# httpauth/authenticator.rb -- Authenticator mix-in module.
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2003 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: authenticator.rb,v 1.3 2003/02/20 07:15:47 gotoyuzo Exp $
-
-module WEBrick
- module HTTPAuth
- module Authenticator
- RequestField = "Authorization"
- ResponseField = "WWW-Authenticate"
- ResponseInfoField = "Authentication-Info"
- AuthException = HTTPStatus::Unauthorized
- AuthScheme = nil # must override by the derived class
-
- attr_reader :realm, :userdb, :logger
-
- private
-
- def check_init(config)
- [:UserDB, :Realm].each{|sym|
- unless config[sym]
- raise ArgumentError, "Argument #{sym.inspect} missing."
- end
- }
- @realm = config[:Realm]
- @userdb = config[:UserDB]
- @logger = config[:Logger] || Log::new($stderr)
- @reload_db = config[:AutoReloadUserDB]
- @request_field = self::class::RequestField
- @response_field = self::class::ResponseField
- @resp_info_field = self::class::ResponseInfoField
- @auth_exception = self::class::AuthException
- @auth_scheme = self::class::AuthScheme
- end
-
- def check_scheme(req)
- unless credentials = req[@request_field]
- error("no credentials in the request.")
- return nil
- end
- unless match = /^#{@auth_scheme}\s+/.match(credentials)
- error("invalid scheme in %s.", credentials)
- info("%s: %s", @request_field, credentials) if $DEBUG
- return nil
- end
- return match.post_match
- end
-
- def log(meth, fmt, *args)
- msg = format("%s %s: ", @auth_scheme, @realm)
- msg << fmt % args
- @logger.send(meth, msg)
- end
-
- def error(fmt, *args)
- if @logger.error?
- log(:error, fmt, *args)
- end
- end
-
- def info(fmt, *args)
- if @logger.info?
- log(:info, fmt, *args)
- end
- end
- end
-
- module ProxyAuthenticator
- RequestField = "Proxy-Authorization"
- ResponseField = "Proxy-Authenticate"
- InfoField = "Proxy-Authentication-Info"
- AuthException = HTTPStatus::ProxyAuthenticationRequired
- end
- end
-end
diff --git a/ruby_1_8_6/lib/webrick/httpauth/basicauth.rb b/ruby_1_8_6/lib/webrick/httpauth/basicauth.rb
deleted file mode 100644
index e835361dc2..0000000000
--- a/ruby_1_8_6/lib/webrick/httpauth/basicauth.rb
+++ /dev/null
@@ -1,65 +0,0 @@
-#
-# httpauth/basicauth.rb -- HTTP basic access authentication
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2003 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: basicauth.rb,v 1.5 2003/02/20 07:15:47 gotoyuzo Exp $
-
-require 'webrick/config'
-require 'webrick/httpstatus'
-require 'webrick/httpauth/authenticator'
-
-module WEBrick
- module HTTPAuth
- class BasicAuth
- include Authenticator
-
- AuthScheme = "Basic"
-
- def self.make_passwd(realm, user, pass)
- pass ||= ""
- pass.crypt(Utils::random_string(2))
- end
-
- attr_reader :realm, :userdb, :logger
-
- def initialize(config, default=Config::BasicAuth)
- check_init(config)
- @config = default.dup.update(config)
- end
-
- def authenticate(req, res)
- unless basic_credentials = check_scheme(req)
- challenge(req, res)
- end
- userid, password = basic_credentials.unpack("m*")[0].split(":", 2)
- password ||= ""
- if userid.empty?
- error("user id was not given.")
- challenge(req, res)
- end
- unless encpass = @userdb.get_passwd(@realm, userid, @reload_db)
- error("%s: the user is not allowed.", userid)
- challenge(req, res)
- end
- if password.crypt(encpass) != encpass
- error("%s: password unmatch.", userid)
- challenge(req, res)
- end
- info("%s: authentication succeeded.", userid)
- req.user = userid
- end
-
- def challenge(req, res)
- res[@response_field] = "#{@auth_scheme} realm=\"#{@realm}\""
- raise @auth_exception
- end
- end
-
- class ProxyBasicAuth < BasicAuth
- include ProxyAuthenticator
- end
- end
-end
diff --git a/ruby_1_8_6/lib/webrick/httpauth/digestauth.rb b/ruby_1_8_6/lib/webrick/httpauth/digestauth.rb
deleted file mode 100644
index 318e0bf17f..0000000000
--- a/ruby_1_8_6/lib/webrick/httpauth/digestauth.rb
+++ /dev/null
@@ -1,343 +0,0 @@
-#
-# httpauth/digestauth.rb -- HTTP digest access authentication
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2003 Internet Programming with Ruby writers.
-# Copyright (c) 2003 H.M.
-#
-# The original implementation is provided by H.M.
-# URL: http://rwiki.jin.gr.jp/cgi-bin/rw-cgi.rb?cmd=view;name=
-# %C7%A7%BE%DA%B5%A1%C7%BD%A4%F2%B2%FE%C2%A4%A4%B7%A4%C6%A4%DF%A4%EB
-#
-# $IPR: digestauth.rb,v 1.5 2003/02/20 07:15:47 gotoyuzo Exp $
-
-require 'webrick/config'
-require 'webrick/httpstatus'
-require 'webrick/httpauth/authenticator'
-require 'digest/md5'
-require 'digest/sha1'
-
-module WEBrick
- module HTTPAuth
- class DigestAuth
- include Authenticator
-
- AuthScheme = "Digest"
- OpaqueInfo = Struct.new(:time, :nonce, :nc)
- attr_reader :algorithm, :qop
-
- def self.make_passwd(realm, user, pass)
- pass ||= ""
- Digest::MD5::hexdigest([user, realm, pass].join(":"))
- end
-
- def initialize(config, default=Config::DigestAuth)
- check_init(config)
- @config = default.dup.update(config)
- @algorithm = @config[:Algorithm]
- @domain = @config[:Domain]
- @qop = @config[:Qop]
- @use_opaque = @config[:UseOpaque]
- @use_next_nonce = @config[:UseNextNonce]
- @check_nc = @config[:CheckNc]
- @use_auth_info_header = @config[:UseAuthenticationInfoHeader]
- @nonce_expire_period = @config[:NonceExpirePeriod]
- @nonce_expire_delta = @config[:NonceExpireDelta]
- @internet_explorer_hack = @config[:InternetExplorerHack]
- @opera_hack = @config[:OperaHack]
-
- case @algorithm
- when 'MD5','MD5-sess'
- @h = Digest::MD5
- when 'SHA1','SHA1-sess' # it is a bonus feature :-)
- @h = Digest::SHA1
- else
- msg = format('Alogrithm "%s" is not supported.', @algorithm)
- raise ArgumentError.new(msg)
- end
-
- @instance_key = hexdigest(self.__id__, Time.now.to_i, Process.pid)
- @opaques = {}
- @last_nonce_expire = Time.now
- @mutex = Mutex.new
- end
-
- def authenticate(req, res)
- unless result = @mutex.synchronize{ _authenticate(req, res) }
- challenge(req, res)
- end
- if result == :nonce_is_stale
- challenge(req, res, true)
- end
- return true
- end
-
- def challenge(req, res, stale=false)
- nonce = generate_next_nonce(req)
- if @use_opaque
- opaque = generate_opaque(req)
- @opaques[opaque].nonce = nonce
- end
-
- param = Hash.new
- param["realm"] = HTTPUtils::quote(@realm)
- param["domain"] = HTTPUtils::quote(@domain.to_a.join(" ")) if @domain
- param["nonce"] = HTTPUtils::quote(nonce)
- param["opaque"] = HTTPUtils::quote(opaque) if opaque
- param["stale"] = stale.to_s
- param["algorithm"] = @algorithm
- param["qop"] = HTTPUtils::quote(@qop.to_a.join(",")) if @qop
-
- res[@response_field] =
- "#{@auth_scheme} " + param.map{|k,v| "#{k}=#{v}" }.join(", ")
- info("%s: %s", @response_field, res[@response_field]) if $DEBUG
- raise @auth_exception
- end
-
- private
-
- MustParams = ['username','realm','nonce','uri','response']
- MustParamsAuth = ['cnonce','nc']
-
- def _authenticate(req, res)
- unless digest_credentials = check_scheme(req)
- return false
- end
-
- auth_req = split_param_value(digest_credentials)
- if auth_req['qop'] == "auth" || auth_req['qop'] == "auth-int"
- req_params = MustParams + MustParamsAuth
- else
- req_params = MustParams
- end
- req_params.each{|key|
- unless auth_req.has_key?(key)
- error('%s: parameter missing. "%s"', auth_req['username'], key)
- raise HTTPStatus::BadRequest
- end
- }
-
- if !check_uri(req, auth_req)
- raise HTTPStatus::BadRequest
- end
-
- if auth_req['realm'] != @realm
- error('%s: realm unmatch. "%s" for "%s"',
- auth_req['username'], auth_req['realm'], @realm)
- return false
- end
-
- auth_req['algorithm'] ||= 'MD5'
- if auth_req['algorithm'] != @algorithm &&
- (@opera_hack && auth_req['algorithm'] != @algorithm.upcase)
- error('%s: algorithm unmatch. "%s" for "%s"',
- auth_req['username'], auth_req['algorithm'], @algorithm)
- return false
- end
-
- if (@qop.nil? && auth_req.has_key?('qop')) ||
- (@qop && (! @qop.member?(auth_req['qop'])))
- error('%s: the qop is not allowed. "%s"',
- auth_req['username'], auth_req['qop'])
- return false
- end
-
- password = @userdb.get_passwd(@realm, auth_req['username'], @reload_db)
- unless password
- error('%s: the user is not allowd.', auth_req['username'])
- return false
- end
-
- nonce_is_invalid = false
- if @use_opaque
- info("@opaque = %s", @opaque.inspect) if $DEBUG
- if !(opaque = auth_req['opaque'])
- error('%s: opaque is not given.', auth_req['username'])
- nonce_is_invalid = true
- elsif !(opaque_struct = @opaques[opaque])
- error('%s: invalid opaque is given.', auth_req['username'])
- nonce_is_invalid = true
- elsif !check_opaque(opaque_struct, req, auth_req)
- @opaques.delete(auth_req['opaque'])
- nonce_is_invalid = true
- end
- elsif !check_nonce(req, auth_req)
- nonce_is_invalid = true
- end
-
- if /-sess$/ =~ auth_req['algorithm'] ||
- (@opera_hack && /-SESS$/ =~ auth_req['algorithm'])
- ha1 = hexdigest(password, auth_req['nonce'], auth_req['cnonce'])
- else
- ha1 = password
- end
-
- if auth_req['qop'] == "auth" || auth_req['qop'] == nil
- ha2 = hexdigest(req.request_method, auth_req['uri'])
- ha2_res = hexdigest("", auth_req['uri'])
- elsif auth_req['qop'] == "auth-int"
- ha2 = hexdigest(req.request_method, auth_req['uri'],
- hexdigest(req.body))
- ha2_res = hexdigest("", auth_req['uri'], hexdigest(res.body))
- end
-
- if auth_req['qop'] == "auth" || auth_req['qop'] == "auth-int"
- param2 = ['nonce', 'nc', 'cnonce', 'qop'].map{|key|
- auth_req[key]
- }.join(':')
- digest = hexdigest(ha1, param2, ha2)
- digest_res = hexdigest(ha1, param2, ha2_res)
- else
- digest = hexdigest(ha1, auth_req['nonce'], ha2)
- digest_res = hexdigest(ha1, auth_req['nonce'], ha2_res)
- end
-
- if digest != auth_req['response']
- error("%s: digest unmatch.", auth_req['username'])
- return false
- elsif nonce_is_invalid
- error('%s: digest is valid, but nonce is not valid.',
- auth_req['username'])
- return :nonce_is_stale
- elsif @use_auth_info_header
- auth_info = {
- 'nextnonce' => generate_next_nonce(req),
- 'rspauth' => digest_res
- }
- if @use_opaque
- opaque_struct.time = req.request_time
- opaque_struct.nonce = auth_info['nextnonce']
- opaque_struct.nc = "%08x" % (auth_req['nc'].hex + 1)
- end
- if auth_req['qop'] == "auth" || auth_req['qop'] == "auth-int"
- ['qop','cnonce','nc'].each{|key|
- auth_info[key] = auth_req[key]
- }
- end
- res[@resp_info_field] = auth_info.keys.map{|key|
- if key == 'nc'
- key + '=' + auth_info[key]
- else
- key + "=" + HTTPUtils::quote(auth_info[key])
- end
- }.join(', ')
- end
- info('%s: authentication scceeded.', auth_req['username'])
- req.user = auth_req['username']
- return true
- end
-
- def split_param_value(string)
- ret = {}
- while string.size != 0
- case string
- when /^\s*([\w\-\.\*\%\!]+)=\s*\"((\\.|[^\"])*)\"\s*,?/
- key = $1
- matched = $2
- string = $'
- ret[key] = matched.gsub(/\\(.)/, "\\1")
- when /^\s*([\w\-\.\*\%\!]+)=\s*([^,\"]*),?/
- key = $1
- matched = $2
- string = $'
- ret[key] = matched.clone
- when /^s*^,/
- string = $'
- else
- break
- end
- end
- ret
- end
-
- def generate_next_nonce(req)
- now = "%012d" % req.request_time.to_i
- pk = hexdigest(now, @instance_key)[0,32]
- nonce = [now + ":" + pk].pack("m*").chop # it has 60 length of chars.
- nonce
- end
-
- def check_nonce(req, auth_req)
- username = auth_req['username']
- nonce = auth_req['nonce']
-
- pub_time, pk = nonce.unpack("m*")[0].split(":", 2)
- if (!pub_time || !pk)
- error("%s: empty nonce is given", username)
- return false
- elsif (hexdigest(pub_time, @instance_key)[0,32] != pk)
- error("%s: invalid private-key: %s for %s",
- username, hexdigest(pub_time, @instance_key)[0,32], pk)
- return false
- end
-
- diff_time = req.request_time.to_i - pub_time.to_i
- if (diff_time < 0)
- error("%s: difference of time-stamp is negative.", username)
- return false
- elsif diff_time > @nonce_expire_period
- error("%s: nonce is expired.", username)
- return false
- end
-
- return true
- end
-
- def generate_opaque(req)
- @mutex.synchronize{
- now = req.request_time
- if now - @last_nonce_expire > @nonce_expire_delta
- @opaques.delete_if{|key,val|
- (now - val.time) > @nonce_expire_period
- }
- @last_nonce_expire = now
- end
- begin
- opaque = Utils::random_string(16)
- end while @opaques[opaque]
- @opaques[opaque] = OpaqueInfo.new(now, nil, '00000001')
- opaque
- }
- end
-
- def check_opaque(opaque_struct, req, auth_req)
- if (@use_next_nonce && auth_req['nonce'] != opaque_struct.nonce)
- error('%s: nonce unmatched. "%s" for "%s"',
- auth_req['username'], auth_req['nonce'], opaque_struct.nonce)
- return false
- elsif !check_nonce(req, auth_req)
- return false
- end
- if (@check_nc && auth_req['nc'] != opaque_struct.nc)
- error('%s: nc unmatched."%s" for "%s"',
- auth_req['username'], auth_req['nc'], opaque_struct.nc)
- return false
- end
- true
- end
-
- def check_uri(req, auth_req)
- uri = auth_req['uri']
- if uri != req.request_uri.to_s && uri != req.unparsed_uri &&
- (@internet_explorer_hack && uri != req.path)
- error('%s: uri unmatch. "%s" for "%s"', auth_req['username'],
- auth_req['uri'], req.request_uri.to_s)
- return false
- end
- true
- end
-
- def hexdigest(*args)
- @h.hexdigest(args.join(":"))
- end
- end
-
- class ProxyDigestAuth < DigestAuth
- include ProxyAuthenticator
-
- def check_uri(req, auth_req)
- return true
- end
- end
- end
-end
diff --git a/ruby_1_8_6/lib/webrick/httpauth/htdigest.rb b/ruby_1_8_6/lib/webrick/httpauth/htdigest.rb
deleted file mode 100644
index 3949756f2b..0000000000
--- a/ruby_1_8_6/lib/webrick/httpauth/htdigest.rb
+++ /dev/null
@@ -1,91 +0,0 @@
-#
-# httpauth/htdigest.rb -- Apache compatible htdigest file
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2003 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: htdigest.rb,v 1.4 2003/07/22 19:20:45 gotoyuzo Exp $
-
-require 'webrick/httpauth/userdb'
-require 'webrick/httpauth/digestauth'
-require 'tempfile'
-
-module WEBrick
- module HTTPAuth
- class Htdigest
- include UserDB
-
- def initialize(path)
- @path = path
- @mtime = Time.at(0)
- @digest = Hash.new
- @mutex = Mutex::new
- @auth_type = DigestAuth
- open(@path,"a").close unless File::exist?(@path)
- reload
- end
-
- def reload
- mtime = File::mtime(@path)
- if mtime > @mtime
- @digest.clear
- open(@path){|io|
- while line = io.gets
- line.chomp!
- user, realm, pass = line.split(/:/, 3)
- unless @digest[realm]
- @digest[realm] = Hash.new
- end
- @digest[realm][user] = pass
- end
- }
- @mtime = mtime
- end
- end
-
- def flush(output=nil)
- output ||= @path
- tmp = Tempfile.new("htpasswd", File::dirname(output))
- begin
- each{|item| tmp.puts(item.join(":")) }
- tmp.close
- File::rename(tmp.path, output)
- rescue
- tmp.close(true)
- end
- end
-
- def get_passwd(realm, user, reload_db)
- reload() if reload_db
- if hash = @digest[realm]
- hash[user]
- end
- end
-
- def set_passwd(realm, user, pass)
- @mutex.synchronize{
- unless @digest[realm]
- @digest[realm] = Hash.new
- end
- @digest[realm][user] = make_passwd(realm, user, pass)
- }
- end
-
- def delete_passwd(realm, user)
- if hash = @digest[realm]
- hash.delete(user)
- end
- end
-
- def each
- @digest.keys.sort.each{|realm|
- hash = @digest[realm]
- hash.keys.sort.each{|user|
- yield([user, realm, hash[user]])
- }
- }
- end
- end
- end
-end
diff --git a/ruby_1_8_6/lib/webrick/httpauth/htgroup.rb b/ruby_1_8_6/lib/webrick/httpauth/htgroup.rb
deleted file mode 100644
index c9270c61cc..0000000000
--- a/ruby_1_8_6/lib/webrick/httpauth/htgroup.rb
+++ /dev/null
@@ -1,61 +0,0 @@
-#
-# httpauth/htgroup.rb -- Apache compatible htgroup file
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2003 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: htgroup.rb,v 1.1 2003/02/16 22:22:56 gotoyuzo Exp $
-
-require 'tempfile'
-
-module WEBrick
- module HTTPAuth
- class Htgroup
- def initialize(path)
- @path = path
- @mtime = Time.at(0)
- @group = Hash.new
- open(@path,"a").close unless File::exist?(@path)
- reload
- end
-
- def reload
- if (mtime = File::mtime(@path)) > @mtime
- @group.clear
- open(@path){|io|
- while line = io.gets
- line.chomp!
- group, members = line.split(/:\s*/)
- @group[group] = members.split(/\s+/)
- end
- }
- @mtime = mtime
- end
- end
-
- def flush(output=nil)
- output ||= @path
- tmp = Tempfile.new("htgroup", File::dirname(output))
- begin
- @group.keys.sort.each{|group|
- tmp.puts(format("%s: %s", group, self.members(group).join(" ")))
- }
- tmp.close
- File::rename(tmp.path, output)
- rescue
- tmp.close(true)
- end
- end
-
- def members(group)
- reload
- @group[group] || []
- end
-
- def add(group, members)
- @group[group] = members(group) | members
- end
- end
- end
-end
diff --git a/ruby_1_8_6/lib/webrick/httpauth/htpasswd.rb b/ruby_1_8_6/lib/webrick/httpauth/htpasswd.rb
deleted file mode 100644
index 40f9297b05..0000000000
--- a/ruby_1_8_6/lib/webrick/httpauth/htpasswd.rb
+++ /dev/null
@@ -1,83 +0,0 @@
-#
-# httpauth/htpasswd -- Apache compatible htpasswd file
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2003 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: htpasswd.rb,v 1.4 2003/07/22 19:20:45 gotoyuzo Exp $
-
-require 'webrick/httpauth/userdb'
-require 'webrick/httpauth/basicauth'
-require 'tempfile'
-
-module WEBrick
- module HTTPAuth
- class Htpasswd
- include UserDB
-
- def initialize(path)
- @path = path
- @mtime = Time.at(0)
- @passwd = Hash.new
- @auth_type = BasicAuth
- open(@path,"a").close unless File::exist?(@path)
- reload
- end
-
- def reload
- mtime = File::mtime(@path)
- if mtime > @mtime
- @passwd.clear
- open(@path){|io|
- while line = io.gets
- line.chomp!
- case line
- when %r!\A[^:]+:[a-zA-Z0-9./]{13}\z!
- user, pass = line.split(":")
- when /:\$/, /:\{SHA\}/
- raise NotImplementedError,
- 'MD5, SHA1 .htpasswd file not supported'
- else
- raise StandardError, 'bad .htpasswd file'
- end
- @passwd[user] = pass
- end
- }
- @mtime = mtime
- end
- end
-
- def flush(output=nil)
- output ||= @path
- tmp = Tempfile.new("htpasswd", File::dirname(output))
- begin
- each{|item| tmp.puts(item.join(":")) }
- tmp.close
- File::rename(tmp.path, output)
- rescue
- tmp.close(true)
- end
- end
-
- def get_passwd(realm, user, reload_db)
- reload() if reload_db
- @passwd[user]
- end
-
- def set_passwd(realm, user, pass)
- @passwd[user] = make_passwd(realm, user, pass)
- end
-
- def delete_passwd(realm, user)
- @passwd.delete(user)
- end
-
- def each
- @passwd.keys.sort.each{|user|
- yield([user, @passwd[user]])
- }
- end
- end
- end
-end
diff --git a/ruby_1_8_6/lib/webrick/httpauth/userdb.rb b/ruby_1_8_6/lib/webrick/httpauth/userdb.rb
deleted file mode 100644
index 33e01405f4..0000000000
--- a/ruby_1_8_6/lib/webrick/httpauth/userdb.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-#
-# httpauth/userdb.rb -- UserDB mix-in module.
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2003 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: userdb.rb,v 1.2 2003/02/20 07:15:48 gotoyuzo Exp $
-
-module WEBrick
- module HTTPAuth
- module UserDB
- attr_accessor :auth_type # BasicAuth or DigestAuth
-
- def make_passwd(realm, user, pass)
- @auth_type::make_passwd(realm, user, pass)
- end
-
- def set_passwd(realm, user, pass)
- self[user] = pass
- end
-
- def get_passwd(realm, user, reload_db=false)
- # reload_db is dummy
- make_passwd(realm, user, self[user])
- end
- end
- end
-end
diff --git a/ruby_1_8_6/lib/webrick/httpproxy.rb b/ruby_1_8_6/lib/webrick/httpproxy.rb
deleted file mode 100644
index 14e3499775..0000000000
--- a/ruby_1_8_6/lib/webrick/httpproxy.rb
+++ /dev/null
@@ -1,254 +0,0 @@
-#
-# httpproxy.rb -- HTTPProxy Class
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2002 GOTO Kentaro
-# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: httpproxy.rb,v 1.18 2003/03/08 18:58:10 gotoyuzo Exp $
-# $kNotwork: straw.rb,v 1.3 2002/02/12 15:13:07 gotoken Exp $
-
-require "webrick/httpserver"
-require "net/http"
-
-Net::HTTP::version_1_2 if RUBY_VERSION < "1.7"
-
-module WEBrick
- NullReader = Object.new
- class << NullReader
- def read(*args)
- nil
- end
- alias gets read
- end
-
- class HTTPProxyServer < HTTPServer
- def initialize(config)
- super
- c = @config
- @via = "#{c[:HTTPVersion]} #{c[:ServerName]}:#{c[:Port]}"
- end
-
- def service(req, res)
- if req.request_method == "CONNECT"
- proxy_connect(req, res)
- elsif req.unparsed_uri =~ %r!^http://!
- proxy_service(req, res)
- else
- super(req, res)
- end
- end
-
- def proxy_auth(req, res)
- if proc = @config[:ProxyAuthProc]
- proc.call(req, res)
- end
- req.header.delete("proxy-authorization")
- end
-
- # Some header fields shuold not be transfered.
- HopByHop = %w( connection keep-alive proxy-authenticate upgrade
- proxy-authorization te trailers transfer-encoding )
- ShouldNotTransfer = %w( set-cookie proxy-connection )
- def split_field(f) f ? f.split(/,\s+/).collect{|i| i.downcase } : [] end
-
- def choose_header(src, dst)
- connections = split_field(src['connection'])
- src.each{|key, value|
- key = key.downcase
- if HopByHop.member?(key) || # RFC2616: 13.5.1
- connections.member?(key) || # RFC2616: 14.10
- ShouldNotTransfer.member?(key) # pragmatics
- @logger.debug("choose_header: `#{key}: #{value}'")
- next
- end
- dst[key] = value
- }
- end
-
- # Net::HTTP is stupid about the multiple header fields.
- # Here is workaround:
- def set_cookie(src, dst)
- if str = src['set-cookie']
- cookies = []
- str.split(/,\s*/).each{|token|
- if /^[^=]+;/o =~ token
- cookies[-1] << ", " << token
- elsif /=/o =~ token
- cookies << token
- else
- cookies[-1] << ", " << token
- end
- }
- dst.cookies.replace(cookies)
- end
- end
-
- def set_via(h)
- if @config[:ProxyVia]
- if h['via']
- h['via'] << ", " << @via
- else
- h['via'] = @via
- end
- end
- end
-
- def proxy_uri(req, res)
- @config[:ProxyURI]
- end
-
- def proxy_service(req, res)
- # Proxy Authentication
- proxy_auth(req, res)
-
- # Create Request-URI to send to the origin server
- uri = req.request_uri
- path = uri.path.dup
- path << "?" << uri.query if uri.query
-
- # Choose header fields to transfer
- header = Hash.new
- choose_header(req, header)
- set_via(header)
-
- # select upstream proxy server
- if proxy = proxy_uri(req, res)
- proxy_host = proxy.host
- proxy_port = proxy.port
- if proxy.userinfo
- credentials = "Basic " + [proxy.userinfo].pack("m*")
- credentials.chomp!
- header['proxy-authorization'] = credentials
- end
- end
-
- response = nil
- begin
- http = Net::HTTP.new(uri.host, uri.port, proxy_host, proxy_port)
- http.start{
- if @config[:ProxyTimeout]
- ################################## these issues are
- http.open_timeout = 30 # secs # necessary (maybe bacause
- http.read_timeout = 60 # secs # Ruby's bug, but why?)
- ##################################
- end
- case req.request_method
- when "GET" then response = http.get(path, header)
- when "POST" then response = http.post(path, req.body || "", header)
- when "HEAD" then response = http.head(path, header)
- else
- raise HTTPStatus::MethodNotAllowed,
- "unsupported method `#{req.request_method}'."
- end
- }
- rescue => err
- logger.debug("#{err.class}: #{err.message}")
- raise HTTPStatus::ServiceUnavailable, err.message
- end
-
- # Persistent connction requirements are mysterious for me.
- # So I will close the connection in every response.
- res['proxy-connection'] = "close"
- res['connection'] = "close"
-
- # Convert Net::HTTP::HTTPResponse to WEBrick::HTTPProxy
- res.status = response.code.to_i
- choose_header(response, res)
- set_cookie(response, res)
- set_via(res)
- res.body = response.body
-
- # Process contents
- if handler = @config[:ProxyContentHandler]
- handler.call(req, res)
- end
- end
-
- def proxy_connect(req, res)
- # Proxy Authentication
- proxy_auth(req, res)
-
- ua = Thread.current[:WEBrickSocket] # User-Agent
- raise HTTPStatus::InternalServerError,
- "[BUG] cannot get socket" unless ua
-
- host, port = req.unparsed_uri.split(":", 2)
- # Proxy authentication for upstream proxy server
- if proxy = proxy_uri(req, res)
- proxy_request_line = "CONNECT #{host}:#{port} HTTP/1.0"
- if proxy.userinfo
- credentials = "Basic " + [proxy.userinfo].pack("m*")
- credentials.chomp!
- end
- host, port = proxy.host, proxy.port
- end
-
- begin
- @logger.debug("CONNECT: upstream proxy is `#{host}:#{port}'.")
- os = TCPSocket.new(host, port) # origin server
-
- if proxy
- @logger.debug("CONNECT: sending a Request-Line")
- os << proxy_request_line << CRLF
- @logger.debug("CONNECT: > #{proxy_request_line}")
- if credentials
- @logger.debug("CONNECT: sending a credentials")
- os << "Proxy-Authorization: " << credentials << CRLF
- end
- os << CRLF
- proxy_status_line = os.gets(LF)
- @logger.debug("CONNECT: read a Status-Line form the upstream server")
- @logger.debug("CONNECT: < #{proxy_status_line}")
- if %r{^HTTP/\d+\.\d+\s+200\s*} =~ proxy_status_line
- while line = os.gets(LF)
- break if /\A(#{CRLF}|#{LF})\z/om =~ line
- end
- else
- raise HTTPStatus::BadGateway
- end
- end
- @logger.debug("CONNECT #{host}:#{port}: succeeded")
- res.status = HTTPStatus::RC_OK
- rescue => ex
- @logger.debug("CONNECT #{host}:#{port}: failed `#{ex.message}'")
- res.set_error(ex)
- raise HTTPStatus::EOFError
- ensure
- if handler = @config[:ProxyContentHandler]
- handler.call(req, res)
- end
- res.send_response(ua)
- access_log(@config, req, res)
-
- # Should clear request-line not to send the sesponse twice.
- # see: HTTPServer#run
- req.parse(NullReader) rescue nil
- end
-
- begin
- while fds = IO::select([ua, os])
- if fds[0].member?(ua)
- buf = ua.sysread(1024);
- @logger.debug("CONNECT: #{buf.size} byte from User-Agent")
- os.syswrite(buf)
- elsif fds[0].member?(os)
- buf = os.sysread(1024);
- @logger.debug("CONNECT: #{buf.size} byte from #{host}:#{port}")
- ua.syswrite(buf)
- end
- end
- rescue => ex
- os.close
- @logger.debug("CONNECT #{host}:#{port}: closed")
- end
-
- raise HTTPStatus::EOFError
- end
-
- def do_OPTIONS(req, res)
- res['allow'] = "GET,HEAD,POST,OPTIONS,CONNECT"
- end
- end
-end
diff --git a/ruby_1_8_6/lib/webrick/httprequest.rb b/ruby_1_8_6/lib/webrick/httprequest.rb
deleted file mode 100644
index 1d32293a27..0000000000
--- a/ruby_1_8_6/lib/webrick/httprequest.rb
+++ /dev/null
@@ -1,365 +0,0 @@
-#
-# httprequest.rb -- HTTPRequest Class
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
-# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: httprequest.rb,v 1.64 2003/07/13 17:18:22 gotoyuzo Exp $
-
-require 'timeout'
-require 'uri'
-
-require 'webrick/httpversion'
-require 'webrick/httpstatus'
-require 'webrick/httputils'
-require 'webrick/cookie'
-
-module WEBrick
-
- class HTTPRequest
- BODY_CONTAINABLE_METHODS = [ "POST", "PUT" ]
- BUFSIZE = 1024*4
-
- # Request line
- attr_reader :request_line
- attr_reader :request_method, :unparsed_uri, :http_version
-
- # Request-URI
- attr_reader :request_uri, :host, :port, :path
- attr_accessor :script_name, :path_info, :query_string
-
- # Header and entity body
- attr_reader :raw_header, :header, :cookies
- attr_reader :accept, :accept_charset
- attr_reader :accept_encoding, :accept_language
-
- # Misc
- attr_accessor :user
- attr_reader :addr, :peeraddr
- attr_reader :attributes
- attr_reader :keep_alive
- attr_reader :request_time
-
- def initialize(config)
- @config = config
- @logger = config[:Logger]
-
- @request_line = @request_method =
- @unparsed_uri = @http_version = nil
-
- @request_uri = @host = @port = @path = nil
- @script_name = @path_info = nil
- @query_string = nil
- @query = nil
- @form_data = nil
-
- @raw_header = Array.new
- @header = nil
- @cookies = []
- @accept = []
- @accept_charset = []
- @accept_encoding = []
- @accept_language = []
- @body = ""
-
- @addr = @peeraddr = nil
- @attributes = {}
- @user = nil
- @keep_alive = false
- @request_time = nil
-
- @remaining_size = nil
- @socket = nil
- end
-
- def parse(socket=nil)
- @socket = socket
- begin
- @peeraddr = socket.respond_to?(:peeraddr) ? socket.peeraddr : []
- @addr = socket.respond_to?(:addr) ? socket.addr : []
- rescue Errno::ENOTCONN
- raise HTTPStatus::EOFError
- end
-
- read_request_line(socket)
- if @http_version.major > 0
- read_header(socket)
- @header['cookie'].each{|cookie|
- @cookies += Cookie::parse(cookie)
- }
- @accept = HTTPUtils.parse_qvalues(self['accept'])
- @accept_charset = HTTPUtils.parse_qvalues(self['accept-charset'])
- @accept_encoding = HTTPUtils.parse_qvalues(self['accept-encoding'])
- @accept_language = HTTPUtils.parse_qvalues(self['accept-language'])
- end
- return if @request_method == "CONNECT"
- return if @unparsed_uri == "*"
-
- begin
- @request_uri = parse_uri(@unparsed_uri)
- @path = HTTPUtils::unescape(@request_uri.path)
- @path = HTTPUtils::normalize_path(@path)
- @host = @request_uri.host
- @port = @request_uri.port
- @query_string = @request_uri.query
- @script_name = ""
- @path_info = @path.dup
- rescue
- raise HTTPStatus::BadRequest, "bad URI `#{@unparsed_uri}'."
- end
-
- if /close/io =~ self["connection"]
- @keep_alive = false
- elsif /keep-alive/io =~ self["connection"]
- @keep_alive = true
- elsif @http_version < "1.1"
- @keep_alive = false
- else
- @keep_alive = true
- end
- end
-
- def body(&block)
- block ||= Proc.new{|chunk| @body << chunk }
- read_body(@socket, block)
- @body.empty? ? nil : @body
- end
-
- def query
- unless @query
- parse_query()
- end
- @query
- end
-
- def content_length
- return Integer(self['content-length'])
- end
-
- def content_type
- return self['content-type']
- end
-
- def [](header_name)
- if @header
- value = @header[header_name.downcase]
- value.empty? ? nil : value.join(", ")
- end
- end
-
- def each
- @header.each{|k, v|
- value = @header[k]
- yield(k, value.empty? ? nil : value.join(", "))
- }
- end
-
- def keep_alive?
- @keep_alive
- end
-
- def to_s
- ret = @request_line.dup
- @raw_header.each{|line| ret << line }
- ret << CRLF
- ret << body if body
- ret
- end
-
- def fixup()
- begin
- body{|chunk| } # read remaining body
- rescue HTTPStatus::Error => ex
- @logger.error("HTTPRequest#fixup: #{ex.class} occured.")
- @keep_alive = false
- rescue => ex
- @logger.error(ex)
- @keep_alive = false
- end
- end
-
- def meta_vars
- # This method provides the metavariables defined by the revision 3
- # of ``The WWW Common Gateway Interface Version 1.1''.
- # (http://Web.Golux.Com/coar/cgi/)
-
- meta = Hash.new
-
- cl = self["Content-Length"]
- ct = self["Content-Type"]
- meta["CONTENT_LENGTH"] = cl if cl.to_i > 0
- meta["CONTENT_TYPE"] = ct.dup if ct
- meta["GATEWAY_INTERFACE"] = "CGI/1.1"
- meta["PATH_INFO"] = @path_info ? @path_info.dup : ""
- #meta["PATH_TRANSLATED"] = nil # no plan to be provided
- meta["QUERY_STRING"] = @query_string ? @query_string.dup : ""
- meta["REMOTE_ADDR"] = @peeraddr[3]
- meta["REMOTE_HOST"] = @peeraddr[2]
- #meta["REMOTE_IDENT"] = nil # no plan to be provided
- meta["REMOTE_USER"] = @user
- meta["REQUEST_METHOD"] = @request_method.dup
- meta["REQUEST_URI"] = @request_uri.to_s
- meta["SCRIPT_NAME"] = @script_name.dup
- meta["SERVER_NAME"] = @host
- meta["SERVER_PORT"] = @port.to_s
- meta["SERVER_PROTOCOL"] = "HTTP/" + @config[:HTTPVersion].to_s
- meta["SERVER_SOFTWARE"] = @config[:ServerSoftware].dup
-
- self.each{|key, val|
- next if /^content-type$/i =~ key
- next if /^content-length$/i =~ key
- name = "HTTP_" + key
- name.gsub!(/-/o, "_")
- name.upcase!
- meta[name] = val
- }
-
- meta
- end
-
- private
-
- def read_request_line(socket)
- @request_line = read_line(socket) if socket
- @request_time = Time.now
- raise HTTPStatus::EOFError unless @request_line
- if /^(\S+)\s+(\S+)(?:\s+HTTP\/(\d+\.\d+))?\r?\n/mo =~ @request_line
- @request_method = $1
- @unparsed_uri = $2
- @http_version = HTTPVersion.new($3 ? $3 : "0.9")
- else
- rl = @request_line.sub(/\x0d?\x0a\z/o, '')
- raise HTTPStatus::BadRequest, "bad Request-Line `#{rl}'."
- end
- end
-
- def read_header(socket)
- if socket
- while line = read_line(socket)
- break if /\A(#{CRLF}|#{LF})\z/om =~ line
- @raw_header << line
- end
- end
- begin
- @header = HTTPUtils::parse_header(@raw_header)
- rescue => ex
- raise HTTPStatus::BadRequest, ex.message
- end
- end
-
- def parse_uri(str, scheme="http")
- if @config[:Escape8bitURI]
- str = HTTPUtils::escape8bit(str)
- end
- uri = URI::parse(str)
- return uri if uri.absolute?
- if self["host"]
- pattern = /\A(#{URI::REGEXP::PATTERN::HOST})(?::(\d+))?\z/n
- host, port = *self['host'].scan(pattern)[0]
- elsif @addr.size > 0
- host, port = @addr[2], @addr[1]
- else
- host, port = @config[:ServerName], @config[:Port]
- end
- uri.scheme = scheme
- uri.host = host
- uri.port = port ? port.to_i : nil
- return URI::parse(uri.to_s)
- end
-
- def read_body(socket, block)
- return unless socket
- if tc = self['transfer-encoding']
- case tc
- when /chunked/io then read_chunked(socket, block)
- else raise HTTPStatus::NotImplemented, "Transfer-Encoding: #{tc}."
- end
- elsif self['content-length'] || @remaining_size
- @remaining_size ||= self['content-length'].to_i
- while @remaining_size > 0
- sz = BUFSIZE < @remaining_size ? BUFSIZE : @remaining_size
- break unless buf = read_data(socket, sz)
- @remaining_size -= buf.size
- block.call(buf)
- end
- if @remaining_size > 0 && @socket.eof?
- raise HTTPStatus::BadRequest, "invalid body size."
- end
- elsif BODY_CONTAINABLE_METHODS.member?(@request_method)
- raise HTTPStatus::LengthRequired
- end
- return @body
- end
-
- def read_chunk_size(socket)
- line = read_line(socket)
- if /^([0-9a-fA-F]+)(?:;(\S+))?/ =~ line
- chunk_size = $1.hex
- chunk_ext = $2
- [ chunk_size, chunk_ext ]
- else
- raise HTTPStatus::BadRequest, "bad chunk `#{line}'."
- end
- end
-
- def read_chunked(socket, block)
- chunk_size, = read_chunk_size(socket)
- while chunk_size > 0
- data = ""
- while data.size < chunk_size
- tmp = read_data(socket, chunk_size-data.size) # read chunk-data
- break unless tmp
- data << tmp
- end
- if data.nil? || data.size != chunk_size
- raise BadRequest, "bad chunk data size."
- end
- read_line(socket) # skip CRLF
- block.call(data)
- chunk_size, = read_chunk_size(socket)
- end
- read_header(socket) # trailer + CRLF
- @header.delete("transfer-encoding")
- @remaining_size = 0
- end
-
- def _read_data(io, method, arg)
- begin
- timeout(@config[:RequestTimeout]){
- return io.__send__(method, arg)
- }
- rescue Errno::ECONNRESET
- return nil
- rescue TimeoutError
- raise HTTPStatus::RequestTimeout
- end
- end
-
- def read_line(io)
- _read_data(io, :gets, LF)
- end
-
- def read_data(io, size)
- _read_data(io, :read, size)
- end
-
- def parse_query()
- begin
- if @request_method == "GET" || @request_method == "HEAD"
- @query = HTTPUtils::parse_query(@query_string)
- elsif self['content-type'] =~ /^application\/x-www-form-urlencoded/
- @query = HTTPUtils::parse_query(body)
- elsif self['content-type'] =~ /^multipart\/form-data; boundary=(.+)/
- boundary = HTTPUtils::dequote($1)
- @query = HTTPUtils::parse_form_data(body, boundary)
- else
- @query = Hash.new
- end
- rescue => ex
- raise HTTPStatus::BadRequest, ex.message
- end
- end
- end
-end
diff --git a/ruby_1_8_6/lib/webrick/httpresponse.rb b/ruby_1_8_6/lib/webrick/httpresponse.rb
deleted file mode 100644
index d0f232d1e1..0000000000
--- a/ruby_1_8_6/lib/webrick/httpresponse.rb
+++ /dev/null
@@ -1,327 +0,0 @@
-#
-# httpresponse.rb -- HTTPResponse Class
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
-# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: httpresponse.rb,v 1.45 2003/07/11 11:02:25 gotoyuzo Exp $
-
-require 'time'
-require 'webrick/httpversion'
-require 'webrick/htmlutils'
-require 'webrick/httputils'
-require 'webrick/httpstatus'
-
-module WEBrick
- class HTTPResponse
- BUFSIZE = 1024*4
-
- attr_reader :http_version, :status, :header
- attr_reader :cookies
- attr_accessor :reason_phrase
- attr_accessor :body
-
- attr_accessor :request_method, :request_uri, :request_http_version
- attr_accessor :filename
- attr_accessor :keep_alive
- attr_reader :config, :sent_size
-
- def initialize(config)
- @config = config
- @logger = config[:Logger]
- @header = Hash.new
- @status = HTTPStatus::RC_OK
- @reason_phrase = nil
- @http_version = HTTPVersion::convert(@config[:HTTPVersion])
- @body = ''
- @keep_alive = true
- @cookies = []
- @request_method = nil
- @request_uri = nil
- @request_http_version = @http_version # temporary
- @chunked = false
- @filename = nil
- @sent_size = 0
- end
-
- def status_line
- "HTTP/#@http_version #@status #@reason_phrase #{CRLF}"
- end
-
- def status=(status)
- @status = status
- @reason_phrase = HTTPStatus::reason_phrase(status)
- end
-
- def [](field)
- @header[field.downcase]
- end
-
- def []=(field, value)
- @header[field.downcase] = value.to_s
- end
-
- def content_length
- if len = self['content-length']
- return Integer(len)
- end
- end
-
- def content_length=(len)
- self['content-length'] = len.to_s
- end
-
- def content_type
- self['content-type']
- end
-
- def content_type=(type)
- self['content-type'] = type
- end
-
- def each
- @header.each{|k, v| yield(k, v) }
- end
-
- def chunked?
- @chunked
- end
-
- def chunked=(val)
- @chunked = val ? true : false
- end
-
- def keep_alive?
- @keep_alive
- end
-
- def send_response(socket)
- begin
- setup_header()
- send_header(socket)
- send_body(socket)
- rescue Errno::EPIPE, Errno::ECONNRESET, Errno::ENOTCONN => ex
- @logger.debug(ex)
- @keep_alive = false
- rescue Exception => ex
- @logger.error(ex)
- @keep_alive = false
- end
- end
-
- def setup_header()
- @reason_phrase ||= HTTPStatus::reason_phrase(@status)
- @header['server'] ||= @config[:ServerSoftware]
- @header['date'] ||= Time.now.httpdate
-
- # HTTP/0.9 features
- if @request_http_version < "1.0"
- @http_version = HTTPVersion.new("0.9")
- @keep_alive = false
- end
-
- # HTTP/1.0 features
- if @request_http_version < "1.1"
- if chunked?
- @chunked = false
- ver = @request_http_version.to_s
- msg = "chunked is set for an HTTP/#{ver} request. (ignored)"
- @logger.warn(msg)
- end
- end
-
- # Determin the message length (RFC2616 -- 4.4 Message Length)
- if @status == 304 || @status == 204 || HTTPStatus::info?(@status)
- @header.delete('content-length')
- @body = ""
- elsif chunked?
- @header["transfer-encoding"] = "chunked"
- @header.delete('content-length')
- elsif %r{^multipart/byteranges} =~ @header['content-type']
- @header.delete('content-length')
- elsif @header['content-length'].nil?
- unless @body.is_a?(IO)
- @header['content-length'] = @body ? @body.size : 0
- end
- end
-
- # Keep-Alive connection.
- if @header['connection'] == "close"
- @keep_alive = false
- elsif keep_alive?
- if chunked? || @header['content-length']
- @header['connection'] = "Keep-Alive"
- end
- else
- @header['connection'] = "close"
- end
-
- # Location is a single absoluteURI.
- if location = @header['location']
- if @request_uri
- @header['location'] = @request_uri.merge(location)
- end
- end
- end
-
- def send_header(socket)
- if @http_version.major > 0
- data = status_line()
- @header.each{|key, value|
- tmp = key.gsub(/\bwww|^te$|\b\w/){|s| s.upcase }
- data << "#{tmp}: #{value}" << CRLF
- }
- @cookies.each{|cookie|
- data << "Set-Cookie: " << cookie.to_s << CRLF
- }
- data << CRLF
- _write_data(socket, data)
- end
- end
-
- def send_body(socket)
- case @body
- when IO then send_body_io(socket)
- else send_body_string(socket)
- end
- end
-
- def to_s
- ret = ""
- send_response(ret)
- ret
- end
-
- def set_redirect(status, url)
- @body = "<HTML><A HREF=\"#{url.to_s}\">#{url.to_s}</A>.</HTML>\n"
- @header['location'] = url.to_s
- raise status
- end
-
- def set_error(ex, backtrace=false)
- case ex
- when HTTPStatus::Status
- @keep_alive = false if HTTPStatus::error?(ex.code)
- self.status = ex.code
- else
- @keep_alive = false
- self.status = HTTPStatus::RC_INTERNAL_SERVER_ERROR
- end
- @header['content-type'] = "text/html"
-
- if respond_to?(:create_error_page)
- create_error_page()
- return
- end
-
- if @request_uri
- host, port = @request_uri.host, @request_uri.port
- else
- host, port = @config[:ServerName], @config[:Port]
- end
-
- @body = ''
- @body << <<-_end_of_html_
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
-<HTML>
- <HEAD><TITLE>#{HTMLUtils::escape(@reason_phrase)}</TITLE></HEAD>
- <BODY>
- <H1>#{HTMLUtils::escape(@reason_phrase)}</H1>
- #{HTMLUtils::escape(ex.message)}
- <HR>
- _end_of_html_
-
- if backtrace && $DEBUG
- @body << "backtrace of `#{HTMLUtils::escape(ex.class.to_s)}' "
- @body << "#{HTMLUtils::escape(ex.message)}"
- @body << "<PRE>"
- ex.backtrace.each{|line| @body << "\t#{line}\n"}
- @body << "</PRE><HR>"
- end
-
- @body << <<-_end_of_html_
- <ADDRESS>
- #{HTMLUtils::escape(@config[:ServerSoftware])} at
- #{host}:#{port}
- </ADDRESS>
- </BODY>
-</HTML>
- _end_of_html_
- end
-
- private
-
- def send_body_io(socket)
- begin
- if @request_method == "HEAD"
- # do nothing
- elsif chunked?
- while buf = @body.read(BUFSIZE)
- next if buf.empty?
- data = ""
- data << format("%x", buf.size) << CRLF
- data << buf << CRLF
- _write_data(socket, data)
- @sent_size += buf.size
- end
- _write_data(socket, "0#{CRLF}#{CRLF}")
- else
- size = @header['content-length'].to_i
- _send_file(socket, @body, 0, size)
- @sent_size = size
- end
- ensure
- @body.close
- end
- end
-
- def send_body_string(socket)
- if @request_method == "HEAD"
- # do nothing
- elsif chunked?
- remain = body ? @body.size : 0
- while buf = @body[@sent_size, BUFSIZE]
- break if buf.empty?
- data = ""
- data << format("%x", buf.size) << CRLF
- data << buf << CRLF
- _write_data(socket, data)
- @sent_size += buf.size
- end
- _write_data(socket, "0#{CRLF}#{CRLF}")
- else
- if @body && @body.size > 0
- _write_data(socket, @body)
- @sent_size = @body.size
- end
- end
- end
-
- def _send_file(output, input, offset, size)
- while offset > 0
- sz = BUFSIZE < offset ? BUFSIZE : offset
- buf = input.read(sz)
- offset -= buf.size
- end
-
- if size == 0
- while buf = input.read(BUFSIZE)
- _write_data(output, buf)
- end
- else
- while size > 0
- sz = BUFSIZE < size ? BUFSIZE : size
- buf = input.read(sz)
- _write_data(output, buf)
- size -= buf.size
- end
- end
- end
-
- def _write_data(socket, data)
- socket << data
- end
- end
-end
diff --git a/ruby_1_8_6/lib/webrick/https.rb b/ruby_1_8_6/lib/webrick/https.rb
deleted file mode 100644
index 81b65ce803..0000000000
--- a/ruby_1_8_6/lib/webrick/https.rb
+++ /dev/null
@@ -1,63 +0,0 @@
-#
-# https.rb -- SSL/TLS enhancement for HTTPServer
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2001 GOTOU Yuuzou
-# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: https.rb,v 1.15 2003/07/22 19:20:42 gotoyuzo Exp $
-
-require 'webrick/ssl'
-
-module WEBrick
- module Config
- HTTP.update(SSL)
- end
-
- class HTTPRequest
- attr_reader :cipher, :server_cert, :client_cert
-
- alias orig_parse parse
-
- def parse(socket=nil)
- if socket.respond_to?(:cert)
- @server_cert = socket.cert || @config[:SSLCertificate]
- @client_cert = socket.peer_cert
- @client_cert_chain = socket.peer_cert_chain
- @cipher = socket.cipher
- end
- orig_parse(socket)
- end
-
- alias orig_parse_uri parse_uri
-
- def parse_uri(str, scheme="https")
- if @server_cert
- return orig_parse_uri(str, scheme)
- end
- return orig_parse_uri(str)
- end
-
- alias orig_meta_vars meta_vars
-
- def meta_vars
- meta = orig_meta_vars
- if @server_cert
- meta["HTTPS"] = "on"
- meta["SSL_SERVER_CERT"] = @server_cert.to_pem
- meta["SSL_CLIENT_CERT"] = @client_cert ? @client_cert.to_pem : ""
- if @client_cert_chain
- @client_cert_chain.each_with_index{|cert, i|
- meta["SSL_CLIENT_CERT_CHAIN_#{i}"] = cert.to_pem
- }
- end
- meta["SSL_CIPHER"] = @cipher[0]
- meta["SSL_PROTOCOL"] = @cipher[1]
- meta["SSL_CIPHER_USEKEYSIZE"] = @cipher[2].to_s
- meta["SSL_CIPHER_ALGKEYSIZE"] = @cipher[3].to_s
- end
- meta
- end
- end
-end
diff --git a/ruby_1_8_6/lib/webrick/httpserver.rb b/ruby_1_8_6/lib/webrick/httpserver.rb
deleted file mode 100644
index 9edb0018f8..0000000000
--- a/ruby_1_8_6/lib/webrick/httpserver.rb
+++ /dev/null
@@ -1,210 +0,0 @@
-#
-# httpserver.rb -- HTTPServer Class
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
-# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: httpserver.rb,v 1.63 2002/10/01 17:16:32 gotoyuzo Exp $
-
-require 'webrick/server'
-require 'webrick/httputils'
-require 'webrick/httpstatus'
-require 'webrick/httprequest'
-require 'webrick/httpresponse'
-require 'webrick/httpservlet'
-require 'webrick/accesslog'
-
-module WEBrick
- class HTTPServerError < ServerError; end
-
- class HTTPServer < ::WEBrick::GenericServer
- def initialize(config={}, default=Config::HTTP)
- super
- @http_version = HTTPVersion::convert(@config[:HTTPVersion])
-
- @mount_tab = MountTable.new
- if @config[:DocumentRoot]
- mount("/", HTTPServlet::FileHandler, @config[:DocumentRoot],
- @config[:DocumentRootOptions])
- end
-
- unless @config[:AccessLog]
- @config[:AccessLog] = [
- [ $stderr, AccessLog::COMMON_LOG_FORMAT ],
- [ $stderr, AccessLog::REFERER_LOG_FORMAT ]
- ]
- end
-
- @virtual_hosts = Array.new
- end
-
- def run(sock)
- while true
- res = HTTPResponse.new(@config)
- req = HTTPRequest.new(@config)
- server = self
- begin
- timeout = @config[:RequestTimeout]
- while timeout > 0
- break if IO.select([sock], nil, nil, 0.5)
- timeout = 0 if @status != :Running
- timeout -= 0.5
- end
- raise HTTPStatus::EOFError if timeout <= 0 || sock.eof?
- req.parse(sock)
- res.request_method = req.request_method
- res.request_uri = req.request_uri
- res.request_http_version = req.http_version
- res.keep_alive = req.keep_alive?
- server = lookup_server(req) || self
- if callback = server[:RequestCallback] || server[:RequestHandler]
- callback.call(req, res)
- end
- server.service(req, res)
- rescue HTTPStatus::EOFError, HTTPStatus::RequestTimeout => ex
- res.set_error(ex)
- rescue HTTPStatus::Error => ex
- @logger.error(ex.message)
- res.set_error(ex)
- rescue HTTPStatus::Status => ex
- res.status = ex.code
- rescue StandardError => ex
- @logger.error(ex)
- res.set_error(ex, true)
- ensure
- if req.request_line
- req.fixup()
- res.send_response(sock)
- server.access_log(@config, req, res)
- end
- end
- break if @http_version < "1.1"
- break unless req.keep_alive?
- break unless res.keep_alive?
- end
- end
-
- def service(req, res)
- if req.unparsed_uri == "*"
- if req.request_method == "OPTIONS"
- do_OPTIONS(req, res)
- raise HTTPStatus::OK
- end
- raise HTTPStatus::NotFound, "`#{req.unparsed_uri}' not found."
- end
-
- servlet, options, script_name, path_info = search_servlet(req.path)
- raise HTTPStatus::NotFound, "`#{req.path}' not found." unless servlet
- req.script_name = script_name
- req.path_info = path_info
- si = servlet.get_instance(self, *options)
- @logger.debug(format("%s is invoked.", si.class.name))
- si.service(req, res)
- end
-
- def do_OPTIONS(req, res)
- res["allow"] = "GET,HEAD,POST,OPTIONS"
- end
-
- def mount(dir, servlet, *options)
- @logger.debug(sprintf("%s is mounted on %s.", servlet.inspect, dir))
- @mount_tab[dir] = [ servlet, options ]
- end
-
- def mount_proc(dir, proc=nil, &block)
- proc ||= block
- raise HTTPServerError, "must pass a proc or block" unless proc
- mount(dir, HTTPServlet::ProcHandler.new(proc))
- end
-
- def unmount(dir)
- @logger.debug(sprintf("unmount %s.", dir))
- @mount_tab.delete(dir)
- end
- alias umount unmount
-
- def search_servlet(path)
- script_name, path_info = @mount_tab.scan(path)
- servlet, options = @mount_tab[script_name]
- if servlet
- [ servlet, options, script_name, path_info ]
- end
- end
-
- def virtual_host(server)
- @virtual_hosts << server
- @virtual_hosts = @virtual_hosts.sort_by{|s|
- num = 0
- num -= 4 if s[:BindAddress]
- num -= 2 if s[:Port]
- num -= 1 if s[:ServerName]
- num
- }
- end
-
- def lookup_server(req)
- @virtual_hosts.find{|s|
- (s[:BindAddress].nil? || req.addr[3] == s[:BindAddress]) &&
- (s[:Port].nil? || req.port == s[:Port]) &&
- ((s[:ServerName].nil? || req.host == s[:ServerName]) ||
- (!s[:ServerAlias].nil? && s[:ServerAlias].find{|h| h === req.host}))
- }
- end
-
- def access_log(config, req, res)
- param = AccessLog::setup_params(config, req, res)
- @config[:AccessLog].each{|logger, fmt|
- logger << AccessLog::format(fmt+"\n", param)
- }
- end
-
- class MountTable
- def initialize
- @tab = Hash.new
- compile
- end
-
- def [](dir)
- dir = normalize(dir)
- @tab[dir]
- end
-
- def []=(dir, val)
- dir = normalize(dir)
- @tab[dir] = val
- compile
- val
- end
-
- def delete(dir)
- dir = normalize(dir)
- res = @tab.delete(dir)
- compile
- res
- end
-
- def scan(path)
- @scanner =~ path
- [ $&, $' ]
- end
-
- private
-
- def compile
- k = @tab.keys
- k.sort!
- k.reverse!
- k.collect!{|path| Regexp.escape(path) }
- @scanner = Regexp.new("^(" + k.join("|") +")(?=/|$)")
- end
-
- def normalize(dir)
- ret = dir ? dir.dup : ""
- ret.sub!(%r|/+$|, "")
- ret
- end
- end
- end
-end
diff --git a/ruby_1_8_6/lib/webrick/httpservlet.rb b/ruby_1_8_6/lib/webrick/httpservlet.rb
deleted file mode 100644
index ac7c022bd7..0000000000
--- a/ruby_1_8_6/lib/webrick/httpservlet.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# httpservlet.rb -- HTTPServlet Utility File
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
-# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: httpservlet.rb,v 1.21 2003/02/23 12:24:46 gotoyuzo Exp $
-
-require 'webrick/httpservlet/abstract'
-require 'webrick/httpservlet/filehandler'
-require 'webrick/httpservlet/cgihandler'
-require 'webrick/httpservlet/erbhandler'
-require 'webrick/httpservlet/prochandler'
-
-module WEBrick
- module HTTPServlet
- FileHandler.add_handler("cgi", CGIHandler)
- FileHandler.add_handler("rhtml", ERBHandler)
- end
-end
diff --git a/ruby_1_8_6/lib/webrick/httpservlet/abstract.rb b/ruby_1_8_6/lib/webrick/httpservlet/abstract.rb
deleted file mode 100644
index 5375c4622d..0000000000
--- a/ruby_1_8_6/lib/webrick/httpservlet/abstract.rb
+++ /dev/null
@@ -1,71 +0,0 @@
-#
-# httpservlet.rb -- HTTPServlet Module
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2000 TAKAHASHI Masayoshi, GOTOU Yuuzou
-# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: abstract.rb,v 1.24 2003/07/11 11:16:46 gotoyuzo Exp $
-
-require 'thread'
-
-require 'webrick/htmlutils'
-require 'webrick/httputils'
-require 'webrick/httpstatus'
-
-module WEBrick
- module HTTPServlet
- class HTTPServletError < StandardError; end
-
- class AbstractServlet
- def self.get_instance(config, *options)
- self.new(config, *options)
- end
-
- def initialize(server, *options)
- @server = @config = server
- @logger = @server[:Logger]
- @options = options
- end
-
- def service(req, res)
- method_name = "do_" + req.request_method.gsub(/-/, "_")
- if respond_to?(method_name)
- __send__(method_name, req, res)
- else
- raise HTTPStatus::MethodNotAllowed,
- "unsupported method `#{req.request_method}'."
- end
- end
-
- def do_GET(req, res)
- raise HTTPStatus::NotFound, "not found."
- end
-
- def do_HEAD(req, res)
- do_GET(req, res)
- end
-
- def do_OPTIONS(req, res)
- m = self.methods.grep(/^do_[A-Z]+$/)
- m.collect!{|i| i.sub(/do_/, "") }
- m.sort!
- res["allow"] = m.join(",")
- end
-
- private
-
- def redirect_to_directory_uri(req, res)
- if req.path[-1] != ?/
- location = WEBrick::HTTPUtils.escape_path(req.path + "/")
- if req.query_string && req.query_string.size > 0
- location << "?" << req.query_string
- end
- res.set_redirect(HTTPStatus::MovedPermanently, location)
- end
- end
- end
-
- end
-end
diff --git a/ruby_1_8_6/lib/webrick/httpservlet/cgi_runner.rb b/ruby_1_8_6/lib/webrick/httpservlet/cgi_runner.rb
deleted file mode 100644
index 006abd458e..0000000000
--- a/ruby_1_8_6/lib/webrick/httpservlet/cgi_runner.rb
+++ /dev/null
@@ -1,47 +0,0 @@
-#
-# cgi_runner.rb -- CGI launcher.
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2000 TAKAHASHI Masayoshi, GOTOU YUUZOU
-# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: cgi_runner.rb,v 1.9 2002/09/25 11:33:15 gotoyuzo Exp $
-
-def sysread(io, size)
- buf = ""
- while size > 0
- tmp = io.sysread(size)
- buf << tmp
- size -= tmp.size
- end
- return buf
-end
-
-STDIN.binmode
-
-buf = ""
-len = sysread(STDIN, 8).to_i
-out = sysread(STDIN, len)
-STDOUT.reopen(open(out, "w"))
-
-len = sysread(STDIN, 8).to_i
-err = sysread(STDIN, len)
-STDERR.reopen(open(err, "w"))
-
-len = sysread(STDIN, 8).to_i
-dump = sysread(STDIN, len)
-hash = Marshal.restore(dump)
-ENV.keys.each{|name| ENV.delete(name) }
-hash.each{|k, v| ENV[k] = v if v }
-
-dir = File::dirname(ENV["SCRIPT_FILENAME"])
-Dir::chdir dir
-
-if interpreter = ARGV[0]
- argv = ARGV.dup
- argv << ENV["SCRIPT_FILENAME"]
- exec(*argv)
- # NOTREACHED
-end
-exec ENV["SCRIPT_FILENAME"]
diff --git a/ruby_1_8_6/lib/webrick/httpservlet/cgihandler.rb b/ruby_1_8_6/lib/webrick/httpservlet/cgihandler.rb
deleted file mode 100644
index a35b59edb8..0000000000
--- a/ruby_1_8_6/lib/webrick/httpservlet/cgihandler.rb
+++ /dev/null
@@ -1,104 +0,0 @@
-#
-# cgihandler.rb -- CGIHandler Class
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
-# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: cgihandler.rb,v 1.27 2003/03/21 19:56:01 gotoyuzo Exp $
-
-require 'rbconfig'
-require 'tempfile'
-require 'webrick/config'
-require 'webrick/httpservlet/abstract'
-
-module WEBrick
- module HTTPServlet
-
- class CGIHandler < AbstractServlet
- Ruby = File::join(::Config::CONFIG['bindir'],
- ::Config::CONFIG['ruby_install_name'])
- Ruby << ::Config::CONFIG['EXEEXT']
- CGIRunner = "\"#{Ruby}\" \"#{Config::LIBDIR}/httpservlet/cgi_runner.rb\""
-
- def initialize(server, name)
- super
- @script_filename = name
- @tempdir = server[:TempDir]
- @cgicmd = "#{CGIRunner} #{server[:CGIInterpreter]}"
- end
-
- def do_GET(req, res)
- data = nil
- status = -1
-
- cgi_in = IO::popen(@cgicmd, "wb")
- cgi_out = Tempfile.new("webrick.cgiout.", @tempdir)
- cgi_err = Tempfile.new("webrick.cgierr.", @tempdir)
- begin
- cgi_in.sync = true
- meta = req.meta_vars
- meta["SCRIPT_FILENAME"] = @script_filename
- meta["PATH"] = @config[:CGIPathEnv]
- if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM
- meta["SystemRoot"] = ENV["SystemRoot"]
- end
- dump = Marshal.dump(meta)
-
- cgi_in.write("%8d" % cgi_out.path.size)
- cgi_in.write(cgi_out.path)
- cgi_in.write("%8d" % cgi_err.path.size)
- cgi_in.write(cgi_err.path)
- cgi_in.write("%8d" % dump.size)
- cgi_in.write(dump)
-
- if req.body and req.body.size > 0
- cgi_in.write(req.body)
- end
- ensure
- cgi_in.close
- status = $?.exitstatus
- sleep 0.1 if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM
- data = cgi_out.read
- cgi_out.close(true)
- if errmsg = cgi_err.read
- if errmsg.size > 0
- @logger.error("CGIHandler: #{@script_filename}:\n" + errmsg)
- end
- end
- cgi_err.close(true)
- end
-
- if status != 0
- @logger.error("CGIHandler: #{@script_filename} exit with #{status}")
- end
-
- data = "" unless data
- raw_header, body = data.split(/^[\xd\xa]+/on, 2)
- raise HTTPStatus::InternalServerError,
- "Premature end of script headers: #{@script_filename}" if body.nil?
-
- begin
- header = HTTPUtils::parse_header(raw_header)
- if /^(\d+)/ =~ header['status'][0]
- res.status = $1.to_i
- header.delete('status')
- end
- if header.has_key?('set-cookie')
- header['set-cookie'].each{|k|
- res.cookies << Cookie.parse_set_cookie(k)
- }
- header.delete('set-cookie')
- end
- header.each{|key, val| res[key] = val.join(", ") }
- rescue => ex
- raise HTTPStatus::InternalServerError, ex.message
- end
- res.body = body
- end
- alias do_POST do_GET
- end
-
- end
-end
diff --git a/ruby_1_8_6/lib/webrick/httpservlet/erbhandler.rb b/ruby_1_8_6/lib/webrick/httpservlet/erbhandler.rb
deleted file mode 100644
index b9d5e65b65..0000000000
--- a/ruby_1_8_6/lib/webrick/httpservlet/erbhandler.rb
+++ /dev/null
@@ -1,54 +0,0 @@
-#
-# erbhandler.rb -- ERBHandler Class
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
-# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: erbhandler.rb,v 1.25 2003/02/24 19:25:31 gotoyuzo Exp $
-
-require 'webrick/httpservlet/abstract.rb'
-
-require 'erb'
-
-module WEBrick
- module HTTPServlet
-
- class ERBHandler < AbstractServlet
- def initialize(server, name)
- super
- @script_filename = name
- end
-
- def do_GET(req, res)
- unless defined?(ERB)
- @logger.warn "#{self.class}: ERB not defined."
- raise HTTPStatus::Forbidden, "ERBHandler cannot work."
- end
- begin
- data = open(@script_filename){|io| io.read }
- res.body = evaluate(ERB.new(data), req, res)
- res['content-type'] =
- HTTPUtils::mime_type(@script_filename, @config[:MimeTypes])
- rescue StandardError => ex
- raise
- rescue Exception => ex
- @logger.error(ex)
- raise HTTPStatus::InternalServerError, ex.message
- end
- end
-
- alias do_POST do_GET
-
- private
- def evaluate(erb, servlet_request, servlet_response)
- Module.new.module_eval{
- meta_vars = servlet_request.meta_vars
- query = servlet_request.query
- erb.result(binding)
- }
- end
- end
- end
-end
diff --git a/ruby_1_8_6/lib/webrick/httpservlet/filehandler.rb b/ruby_1_8_6/lib/webrick/httpservlet/filehandler.rb
deleted file mode 100644
index 24f59d7142..0000000000
--- a/ruby_1_8_6/lib/webrick/httpservlet/filehandler.rb
+++ /dev/null
@@ -1,435 +0,0 @@
-#
-# filehandler.rb -- FileHandler Module
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
-# Copyright (c) 2003 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: filehandler.rb,v 1.44 2003/06/07 01:34:51 gotoyuzo Exp $
-
-require 'thread'
-require 'time'
-
-require 'webrick/htmlutils'
-require 'webrick/httputils'
-require 'webrick/httpstatus'
-
-module WEBrick
- module HTTPServlet
-
- class DefaultFileHandler < AbstractServlet
- def initialize(server, local_path)
- super
- @local_path = local_path
- end
-
- def do_GET(req, res)
- st = File::stat(@local_path)
- mtime = st.mtime
- res['etag'] = sprintf("%x-%x-%x", st.ino, st.size, st.mtime.to_i)
-
- if not_modified?(req, res, mtime, res['etag'])
- res.body = ''
- raise HTTPStatus::NotModified
- elsif req['range']
- make_partial_content(req, res, @local_path, st.size)
- raise HTTPStatus::PartialContent
- else
- mtype = HTTPUtils::mime_type(@local_path, @config[:MimeTypes])
- res['content-type'] = mtype
- res['content-length'] = st.size
- res['last-modified'] = mtime.httpdate
- res.body = open(@local_path, "rb")
- end
- end
-
- def not_modified?(req, res, mtime, etag)
- if ir = req['if-range']
- begin
- if Time.httpdate(ir) >= mtime
- return true
- end
- rescue
- if HTTPUtils::split_header_value(ir).member?(res['etag'])
- return true
- end
- end
- end
-
- if (ims = req['if-modified-since']) && Time.parse(ims) >= mtime
- return true
- end
-
- if (inm = req['if-none-match']) &&
- HTTPUtils::split_header_value(inm).member?(res['etag'])
- return true
- end
-
- return false
- end
-
- def make_partial_content(req, res, filename, filesize)
- mtype = HTTPUtils::mime_type(filename, @config[:MimeTypes])
- unless ranges = HTTPUtils::parse_range_header(req['range'])
- raise HTTPStatus::BadRequest,
- "Unrecognized range-spec: \"#{req['range']}\""
- end
- open(filename, "rb"){|io|
- if ranges.size > 1
- time = Time.now
- boundary = "#{time.sec}_#{time.usec}_#{Process::pid}"
- body = ''
- ranges.each{|range|
- first, last = prepare_range(range, filesize)
- next if first < 0
- io.pos = first
- content = io.read(last-first+1)
- body << "--" << boundary << CRLF
- body << "Content-Type: #{mtype}" << CRLF
- body << "Content-Range: #{first}-#{last}/#{filesize}" << CRLF
- body << CRLF
- body << content
- body << CRLF
- }
- raise HTTPStatus::RequestRangeNotSatisfiable if body.empty?
- body << "--" << boundary << "--" << CRLF
- res["content-type"] = "multipart/byteranges; boundary=#{boundary}"
- res.body = body
- elsif range = ranges[0]
- first, last = prepare_range(range, filesize)
- raise HTTPStatus::RequestRangeNotSatisfiable if first < 0
- if last == filesize - 1
- content = io.dup
- content.pos = first
- else
- io.pos = first
- content = io.read(last-first+1)
- end
- res['content-type'] = mtype
- res['content-range'] = "#{first}-#{last}/#{filesize}"
- res['content-length'] = last - first + 1
- res.body = content
- else
- raise HTTPStatus::BadRequest
- end
- }
- end
-
- def prepare_range(range, filesize)
- first = range.first < 0 ? filesize + range.first : range.first
- return -1, -1 if first < 0 || first >= filesize
- last = range.last < 0 ? filesize + range.last : range.last
- last = filesize - 1 if last >= filesize
- return first, last
- end
- end
-
- class FileHandler < AbstractServlet
- HandlerTable = Hash.new
-
- def self.add_handler(suffix, handler)
- HandlerTable[suffix] = handler
- end
-
- def self.remove_handler(suffix)
- HandlerTable.delete(suffix)
- end
-
- def initialize(server, root, options={}, default=Config::FileHandler)
- @config = server.config
- @logger = @config[:Logger]
- @root = File.expand_path(root)
- if options == true || options == false
- options = { :FancyIndexing => options }
- end
- @options = default.dup.update(options)
- end
-
- def service(req, res)
- # if this class is mounted on "/" and /~username is requested.
- # we're going to override path informations before invoking service.
- if defined?(Etc) && @options[:UserDir] && req.script_name.empty?
- if %r|^(/~([^/]+))| =~ req.path_info
- script_name, user = $1, $2
- path_info = $'
- begin
- passwd = Etc::getpwnam(user)
- @root = File::join(passwd.dir, @options[:UserDir])
- req.script_name = script_name
- req.path_info = path_info
- rescue
- @logger.debug "#{self.class}#do_GET: getpwnam(#{user}) failed"
- end
- end
- end
- prevent_directory_traversal(req, res)
- super(req, res)
- end
-
- def do_GET(req, res)
- unless exec_handler(req, res)
- set_dir_list(req, res)
- end
- end
-
- def do_POST(req, res)
- unless exec_handler(req, res)
- raise HTTPStatus::NotFound, "`#{req.path}' not found."
- end
- end
-
- def do_OPTIONS(req, res)
- unless exec_handler(req, res)
- super(req, res)
- end
- end
-
- # ToDo
- # RFC2518: HTTP Extensions for Distributed Authoring -- WEBDAV
- #
- # PROPFIND PROPPATCH MKCOL DELETE PUT COPY MOVE
- # LOCK UNLOCK
-
- # RFC3253: Versioning Extensions to WebDAV
- # (Web Distributed Authoring and Versioning)
- #
- # VERSION-CONTROL REPORT CHECKOUT CHECK_IN UNCHECKOUT
- # MKWORKSPACE UPDATE LABEL MERGE ACTIVITY
-
- private
-
- def trailing_pathsep?(path)
- # check for trailing path separator:
- # File.dirname("/aaaa/bbbb/") #=> "/aaaa")
- # File.dirname("/aaaa/bbbb/x") #=> "/aaaa/bbbb")
- # File.dirname("/aaaa/bbbb") #=> "/aaaa")
- # File.dirname("/aaaa/bbbbx") #=> "/aaaa")
- return File.dirname(path) != File.dirname(path+"x")
- end
-
- def prevent_directory_traversal(req, res)
- # Preventing directory traversal on Windows platforms;
- # Backslashes (0x5c) in path_info are not interpreted as special
- # character in URI notation. So the value of path_info should be
- # normalize before accessing to the filesystem.
-
- if trailing_pathsep?(req.path_info)
- # File.expand_path removes the trailing path separator.
- # Adding a character is a workaround to save it.
- # File.expand_path("/aaa/") #=> "/aaa"
- # File.expand_path("/aaa/" + "x") #=> "/aaa/x"
- expanded = File.expand_path(req.path_info + "x")
- expanded.chop! # remove trailing "x"
- else
- expanded = File.expand_path(req.path_info)
- end
- req.path_info = expanded
- end
-
- def exec_handler(req, res)
- raise HTTPStatus::NotFound, "`#{req.path}' not found" unless @root
- if set_filename(req, res)
- handler = get_handler(req, res)
- call_callback(:HandlerCallback, req, res)
- h = handler.get_instance(@config, res.filename)
- h.service(req, res)
- return true
- end
- call_callback(:HandlerCallback, req, res)
- return false
- end
-
- def get_handler(req, res)
- suffix1 = (/\.(\w+)\z/ =~ res.filename) && $1.downcase
- if /\.(\w+)\.([\w\-]+)\z/ =~ res.filename
- if @options[:AcceptableLanguages].include?($2.downcase)
- suffix2 = $1.downcase
- end
- end
- handler_table = @options[:HandlerTable]
- return handler_table[suffix1] || handler_table[suffix2] ||
- HandlerTable[suffix1] || HandlerTable[suffix2] ||
- DefaultFileHandler
- end
-
- def set_filename(req, res)
- res.filename = @root.dup
- path_info = req.path_info.scan(%r|/[^/]*|)
-
- path_info.unshift("") # dummy for checking @root dir
- while base = path_info.first
- break if base == "/"
- break unless File.directory?(File.expand_path(res.filename + base))
- shift_path_info(req, res, path_info)
- call_callback(:DirectoryCallback, req, res)
- end
-
- if base = path_info.first
- if base == "/"
- if file = search_index_file(req, res)
- shift_path_info(req, res, path_info, file)
- call_callback(:FileCallback, req, res)
- return true
- end
- shift_path_info(req, res, path_info)
- elsif file = search_file(req, res, base)
- shift_path_info(req, res, path_info, file)
- call_callback(:FileCallback, req, res)
- return true
- else
- raise HTTPStatus::NotFound, "`#{req.path}' not found."
- end
- end
-
- return false
- end
-
- def check_filename(req, res, name)
- if nondisclosure_name?(name) || windows_ambiguous_name?(name)
- @logger.warn("the request refers nondisclosure name `#{name}'.")
- raise HTTPStatus::NotFound, "`#{req.path}' not found."
- end
- end
-
- def shift_path_info(req, res, path_info, base=nil)
- tmp = path_info.shift
- base = base || tmp
- req.path_info = path_info.join
- req.script_name << base
- res.filename = File.expand_path(res.filename + base)
- check_filename(req, res, File.basename(res.filename))
- end
-
- def search_index_file(req, res)
- @config[:DirectoryIndex].each{|index|
- if file = search_file(req, res, "/"+index)
- return file
- end
- }
- return nil
- end
-
- def search_file(req, res, basename)
- langs = @options[:AcceptableLanguages]
- path = res.filename + basename
- if File.file?(path)
- return basename
- elsif langs.size > 0
- req.accept_language.each{|lang|
- path_with_lang = path + ".#{lang}"
- if langs.member?(lang) && File.file?(path_with_lang)
- return basename + ".#{lang}"
- end
- }
- (langs - req.accept_language).each{|lang|
- path_with_lang = path + ".#{lang}"
- if File.file?(path_with_lang)
- return basename + ".#{lang}"
- end
- }
- end
- return nil
- end
-
- def call_callback(callback_name, req, res)
- if cb = @options[callback_name]
- cb.call(req, res)
- end
- end
-
- def windows_ambiguous_name?(name)
- return true if /[. ]+\z/ =~ name
- return true if /::\$DATA\z/ =~ name
- return false
- end
-
- def nondisclosure_name?(name)
- @options[:NondisclosureName].each{|pattern|
- if File.fnmatch(pattern, name, File::FNM_CASEFOLD)
- return true
- end
- }
- return false
- end
-
- def set_dir_list(req, res)
- redirect_to_directory_uri(req, res)
- unless @options[:FancyIndexing]
- raise HTTPStatus::Forbidden, "no access permission to `#{req.path}'"
- end
- local_path = res.filename
- list = Dir::entries(local_path).collect{|name|
- next if name == "." || name == ".."
- next if nondisclosure_name?(name)
- next if windows_ambiguous_name?(name)
- st = (File::stat(File.join(local_path, name)) rescue nil)
- if st.nil?
- [ name, nil, -1 ]
- elsif st.directory?
- [ name + "/", st.mtime, -1 ]
- else
- [ name, st.mtime, st.size ]
- end
- }
- list.compact!
-
- if d0 = req.query["N"]; idx = 0
- elsif d0 = req.query["M"]; idx = 1
- elsif d0 = req.query["S"]; idx = 2
- else d0 = "A" ; idx = 0
- end
- d1 = (d0 == "A") ? "D" : "A"
-
- if d0 == "A"
- list.sort!{|a,b| a[idx] <=> b[idx] }
- else
- list.sort!{|a,b| b[idx] <=> a[idx] }
- end
-
- res['content-type'] = "text/html"
-
- res.body = <<-_end_of_html_
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
-<HTML>
- <HEAD><TITLE>Index of #{HTMLUtils::escape(req.path)}</TITLE></HEAD>
- <BODY>
- <H1>Index of #{HTMLUtils::escape(req.path)}</H1>
- _end_of_html_
-
- res.body << "<PRE>\n"
- res.body << " <A HREF=\"?N=#{d1}\">Name</A> "
- res.body << "<A HREF=\"?M=#{d1}\">Last modified</A> "
- res.body << "<A HREF=\"?S=#{d1}\">Size</A>\n"
- res.body << "<HR>\n"
-
- list.unshift [ "..", File::mtime(local_path+"/.."), -1 ]
- list.each{ |name, time, size|
- if name == ".."
- dname = "Parent Directory"
- elsif name.size > 25
- dname = name.sub(/^(.{23})(.*)/){ $1 + ".." }
- else
- dname = name
- end
- s = " <A HREF=\"#{HTTPUtils::escape(name)}\">#{dname}</A>"
- s << " " * (30 - dname.size)
- s << (time ? time.strftime("%Y/%m/%d %H:%M ") : " " * 22)
- s << (size >= 0 ? size.to_s : "-") << "\n"
- res.body << s
- }
- res.body << "</PRE><HR>"
-
- res.body << <<-_end_of_html_
- <ADDRESS>
- #{HTMLUtils::escape(@config[:ServerSoftware])}<BR>
- at #{req.host}:#{req.port}
- </ADDRESS>
- </BODY>
-</HTML>
- _end_of_html_
- end
-
- end
- end
-end
diff --git a/ruby_1_8_6/lib/webrick/httpservlet/prochandler.rb b/ruby_1_8_6/lib/webrick/httpservlet/prochandler.rb
deleted file mode 100644
index 783cb27896..0000000000
--- a/ruby_1_8_6/lib/webrick/httpservlet/prochandler.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-#
-# prochandler.rb -- ProcHandler Class
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
-# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: prochandler.rb,v 1.7 2002/09/21 12:23:42 gotoyuzo Exp $
-
-require 'webrick/httpservlet/abstract.rb'
-
-module WEBrick
- module HTTPServlet
-
- class ProcHandler < AbstractServlet
- def get_instance(server, *options)
- self
- end
-
- def initialize(proc)
- @proc = proc
- end
-
- def do_GET(request, response)
- @proc.call(request, response)
- end
-
- alias do_POST do_GET
- end
-
- end
-end
diff --git a/ruby_1_8_6/lib/webrick/httpstatus.rb b/ruby_1_8_6/lib/webrick/httpstatus.rb
deleted file mode 100644
index 0b22c992b3..0000000000
--- a/ruby_1_8_6/lib/webrick/httpstatus.rb
+++ /dev/null
@@ -1,126 +0,0 @@
-#
-# httpstatus.rb -- HTTPStatus Class
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
-# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: httpstatus.rb,v 1.11 2003/03/24 20:18:55 gotoyuzo Exp $
-
-module WEBrick
-
- module HTTPStatus
-
- class Status < StandardError; end
- class Info < Status; end
- class Success < Status; end
- class Redirect < Status; end
- class Error < Status; end
- class ClientError < Error; end
- class ServerError < Error; end
-
- class EOFError < StandardError; end
-
- StatusMessage = {
- 100, 'Continue',
- 101, 'Switching Protocols',
- 200, 'OK',
- 201, 'Created',
- 202, 'Accepted',
- 203, 'Non-Authoritative Information',
- 204, 'No Content',
- 205, 'Reset Content',
- 206, 'Partial Content',
- 300, 'Multiple Choices',
- 301, 'Moved Permanently',
- 302, 'Found',
- 303, 'See Other',
- 304, 'Not Modified',
- 305, 'Use Proxy',
- 307, 'Temporary Redirect',
- 400, 'Bad Request',
- 401, 'Unauthorized',
- 402, 'Payment Required',
- 403, 'Forbidden',
- 404, 'Not Found',
- 405, 'Method Not Allowed',
- 406, 'Not Acceptable',
- 407, 'Proxy Authentication Required',
- 408, 'Request Timeout',
- 409, 'Conflict',
- 410, 'Gone',
- 411, 'Length Required',
- 412, 'Precondition Failed',
- 413, 'Request Entity Too Large',
- 414, 'Request-URI Too Large',
- 415, 'Unsupported Media Type',
- 416, 'Request Range Not Satisfiable',
- 417, 'Expectation Failed',
- 500, 'Internal Server Error',
- 501, 'Not Implemented',
- 502, 'Bad Gateway',
- 503, 'Service Unavailable',
- 504, 'Gateway Timeout',
- 505, 'HTTP Version Not Supported'
- }
-
- CodeToError = {}
-
- StatusMessage.each{|code, message|
- var_name = message.gsub(/[ \-]/,'_').upcase
- err_name = message.gsub(/[ \-]/,'')
-
- case code
- when 100...200; parent = Info
- when 200...300; parent = Success
- when 300...400; parent = Redirect
- when 400...500; parent = ClientError
- when 500...600; parent = ServerError
- end
-
- eval %-
- RC_#{var_name} = #{code}
- class #{err_name} < #{parent}
- def self.code() RC_#{var_name} end
- def self.reason_phrase() StatusMessage[code] end
- def code() self::class::code end
- def reason_phrase() self::class::reason_phrase end
- alias to_i code
- end
- -
-
- CodeToError[code] = const_get(err_name)
- }
-
- def reason_phrase(code)
- StatusMessage[code.to_i]
- end
- def info?(code)
- code.to_i >= 100 and code.to_i < 200
- end
- def success?(code)
- code.to_i >= 200 and code.to_i < 300
- end
- def redirect?(code)
- code.to_i >= 300 and code.to_i < 400
- end
- def error?(code)
- code.to_i >= 400 and code.to_i < 600
- end
- def client_error?(code)
- code.to_i >= 400 and code.to_i < 500
- end
- def server_error?(code)
- code.to_i >= 500 and code.to_i < 600
- end
-
- def self.[](code)
- CodeToError[code]
- end
-
- module_function :reason_phrase
- module_function :info?, :success?, :redirect?, :error?
- module_function :client_error?, :server_error?
- end
-end
diff --git a/ruby_1_8_6/lib/webrick/httputils.rb b/ruby_1_8_6/lib/webrick/httputils.rb
deleted file mode 100644
index c57af2c860..0000000000
--- a/ruby_1_8_6/lib/webrick/httputils.rb
+++ /dev/null
@@ -1,399 +0,0 @@
-#
-# httputils.rb -- HTTPUtils Module
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
-# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: httputils.rb,v 1.34 2003/06/05 21:34:08 gotoyuzo Exp $
-
-require 'socket'
-require 'tempfile'
-
-module WEBrick
- CR = "\x0d"
- LF = "\x0a"
- CRLF = "\x0d\x0a"
-
- module HTTPUtils
-
- def normalize_path(path)
- raise "abnormal path `#{path}'" if path[0] != ?/
- ret = path.dup
-
- ret.gsub!(%r{/+}o, '/') # // => /
- while ret.sub!(%r{/\.(/|\Z)}o, '/'); end # /. => /
- begin # /foo/.. => /foo
- match = ret.sub!(%r{/([^/]+)/\.\.(/|\Z)}o){
- if $1 == ".."
- raise "abnormal path `#{path}'"
- else
- "/"
- end
- }
- end while match
-
- raise "abnormal path `#{path}'" if %r{/\.\.(/|\Z)} =~ ret
- ret
- end
- module_function :normalize_path
-
- #####
-
- DefaultMimeTypes = {
- "ai" => "application/postscript",
- "asc" => "text/plain",
- "avi" => "video/x-msvideo",
- "bin" => "application/octet-stream",
- "bmp" => "image/bmp",
- "class" => "application/octet-stream",
- "cer" => "application/pkix-cert",
- "crl" => "application/pkix-crl",
- "crt" => "application/x-x509-ca-cert",
- #"crl" => "application/x-pkcs7-crl",
- "css" => "text/css",
- "dms" => "application/octet-stream",
- "doc" => "application/msword",
- "dvi" => "application/x-dvi",
- "eps" => "application/postscript",
- "etx" => "text/x-setext",
- "exe" => "application/octet-stream",
- "gif" => "image/gif",
- "htm" => "text/html",
- "html" => "text/html",
- "jpe" => "image/jpeg",
- "jpeg" => "image/jpeg",
- "jpg" => "image/jpeg",
- "lha" => "application/octet-stream",
- "lzh" => "application/octet-stream",
- "mov" => "video/quicktime",
- "mpe" => "video/mpeg",
- "mpeg" => "video/mpeg",
- "mpg" => "video/mpeg",
- "pbm" => "image/x-portable-bitmap",
- "pdf" => "application/pdf",
- "pgm" => "image/x-portable-graymap",
- "png" => "image/png",
- "pnm" => "image/x-portable-anymap",
- "ppm" => "image/x-portable-pixmap",
- "ppt" => "application/vnd.ms-powerpoint",
- "ps" => "application/postscript",
- "qt" => "video/quicktime",
- "ras" => "image/x-cmu-raster",
- "rb" => "text/plain",
- "rd" => "text/plain",
- "rtf" => "application/rtf",
- "sgm" => "text/sgml",
- "sgml" => "text/sgml",
- "tif" => "image/tiff",
- "tiff" => "image/tiff",
- "txt" => "text/plain",
- "xbm" => "image/x-xbitmap",
- "xls" => "application/vnd.ms-excel",
- "xml" => "text/xml",
- "xpm" => "image/x-xpixmap",
- "xwd" => "image/x-xwindowdump",
- "zip" => "application/zip",
- }
-
- # Load Apache compatible mime.types file.
- def load_mime_types(file)
- open(file){ |io|
- hash = Hash.new
- io.each{ |line|
- next if /^#/ =~ line
- line.chomp!
- mimetype, ext0 = line.split(/\s+/, 2)
- next unless ext0
- next if ext0.empty?
- ext0.split(/\s+/).each{ |ext| hash[ext] = mimetype }
- }
- hash
- }
- end
- module_function :load_mime_types
-
- def mime_type(filename, mime_tab)
- suffix1 = (/\.(\w+)$/ =~ filename && $1.downcase)
- suffix2 = (/\.(\w+)\.[\w\-]+$/ =~ filename && $1.downcase)
- mime_tab[suffix1] || mime_tab[suffix2] || "application/octet-stream"
- end
- module_function :mime_type
-
- #####
-
- def parse_header(raw)
- header = Hash.new([].freeze)
- field = nil
- raw.each{|line|
- case line
- when /^([A-Za-z0-9!\#$%&'*+\-.^_`|~]+):\s*(.*?)\s*\z/om
- field, value = $1, $2
- field.downcase!
- header[field] = [] unless header.has_key?(field)
- header[field] << value
- when /^\s+(.*?)\s*\z/om
- value = $1
- unless field
- raise "bad header '#{line.inspect}'."
- end
- header[field][-1] << " " << value
- else
- raise "bad header '#{line.inspect}'."
- end
- }
- header.each{|key, values|
- values.each{|value|
- value.strip!
- value.gsub!(/\s+/, " ")
- }
- }
- header
- end
- module_function :parse_header
-
- def split_header_value(str)
- str.scan(/((?:"(?:\\.|[^"])+?"|[^",]+)+)
- (?:,\s*|\Z)/xn).collect{|v| v[0] }
- end
- module_function :split_header_value
-
- def parse_range_header(ranges_specifier)
- if /^bytes=(.*)/ =~ ranges_specifier
- byte_range_set = split_header_value($1)
- byte_range_set.collect{|range_spec|
- case range_spec
- when /^(\d+)-(\d+)/ then $1.to_i .. $2.to_i
- when /^(\d+)-/ then $1.to_i .. -1
- when /^-(\d+)/ then -($1.to_i) .. -1
- else return nil
- end
- }
- end
- end
- module_function :parse_range_header
-
- def parse_qvalues(value)
- tmp = []
- if value
- parts = value.split(/,\s*/)
- parts.each {|part|
- if m = %r{^([^\s,]+?)(?:;\s*q=(\d+(?:\.\d+)?))?$}.match(part)
- val = m[1]
- q = (m[2] or 1).to_f
- tmp.push([val, q])
- end
- }
- tmp = tmp.sort_by{|val, q| -q}
- tmp.collect!{|val, q| val}
- end
- return tmp
- end
- module_function :parse_qvalues
-
- #####
-
- def dequote(str)
- ret = (/\A"(.*)"\Z/ =~ str) ? $1 : str.dup
- ret.gsub!(/\\(.)/, "\\1")
- ret
- end
- module_function :dequote
-
- def quote(str)
- '"' << str.gsub(/[\\\"]/o, "\\\1") << '"'
- end
- module_function :quote
-
- #####
-
- class FormData < String
- EmptyRawHeader = [].freeze
- EmptyHeader = {}.freeze
-
- attr_accessor :name, :filename, :next_data
- protected :next_data
-
- def initialize(*args)
- @name = @filename = @next_data = nil
- if args.empty?
- @raw_header = []
- @header = nil
- super("")
- else
- @raw_header = EmptyRawHeader
- @header = EmptyHeader
- super(args.shift)
- unless args.empty?
- @next_data = self.class.new(*args)
- end
- end
- end
-
- def [](*key)
- begin
- @header[key[0].downcase].join(", ")
- rescue StandardError, NameError
- super
- end
- end
-
- def <<(str)
- if @header
- super
- elsif str == CRLF
- @header = HTTPUtils::parse_header(@raw_header)
- if cd = self['content-disposition']
- if /\s+name="(.*?)"/ =~ cd then @name = $1 end
- if /\s+filename="(.*?)"/ =~ cd then @filename = $1 end
- end
- else
- @raw_header << str
- end
- self
- end
-
- def append_data(data)
- tmp = self
- while tmp
- unless tmp.next_data
- tmp.next_data = data
- break
- end
- tmp = tmp.next_data
- end
- self
- end
-
- def each_data
- tmp = self
- while tmp
- next_data = tmp.next_data
- yield(tmp)
- tmp = next_data
- end
- end
-
- def list
- ret = []
- each_data{|data|
- ret << data.to_s
- }
- ret
- end
-
- alias :to_ary :list
-
- def to_s
- String.new(self)
- end
- end
-
- def parse_query(str)
- query = Hash.new
- if str
- str.split(/[&;]/).each{|x|
- next if x.empty?
- key, val = x.split(/=/,2)
- key = unescape_form(key)
- val = unescape_form(val.to_s)
- val = FormData.new(val)
- val.name = key
- if query.has_key?(key)
- query[key].append_data(val)
- next
- end
- query[key] = val
- }
- end
- query
- end
- module_function :parse_query
-
- def parse_form_data(io, boundary)
- boundary_regexp = /\A--#{boundary}(--)?#{CRLF}\z/
- form_data = Hash.new
- return form_data unless io
- data = nil
- io.each{|line|
- if boundary_regexp =~ line
- if data
- data.chop!
- key = data.name
- if form_data.has_key?(key)
- form_data[key].append_data(data)
- else
- form_data[key] = data
- end
- end
- data = FormData.new
- next
- else
- if data
- data << line
- end
- end
- }
- return form_data
- end
- module_function :parse_form_data
-
- #####
-
- reserved = ';/?:@&=+$,'
- num = '0123456789'
- lowalpha = 'abcdefghijklmnopqrstuvwxyz'
- upalpha = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
- mark = '-_.!~*\'()'
- unreserved = num + lowalpha + upalpha + mark
- control = (0x0..0x1f).collect{|c| c.chr }.join + "\x7f"
- space = " "
- delims = '<>#%"'
- unwise = '{}|\\^[]`'
- nonascii = (0x80..0xff).collect{|c| c.chr }.join
-
- module_function
-
- def _make_regex(str) /([#{Regexp.escape(str)}])/n end
- def _make_regex!(str) /([^#{Regexp.escape(str)}])/n end
- def _escape(str, regex) str.gsub(regex){ "%%%02X" % $1[0] } end
- def _unescape(str, regex) str.gsub(regex){ $1.hex.chr } end
-
- UNESCAPED = _make_regex(control+space+delims+unwise+nonascii)
- UNESCAPED_FORM = _make_regex(reserved+control+delims+unwise+nonascii)
- NONASCII = _make_regex(nonascii)
- ESCAPED = /%([0-9a-fA-F]{2})/
- UNESCAPED_PCHAR = _make_regex!(unreserved+":@&=+$,")
-
- def escape(str)
- _escape(str, UNESCAPED)
- end
-
- def unescape(str)
- _unescape(str, ESCAPED)
- end
-
- def escape_form(str)
- ret = _escape(str, UNESCAPED_FORM)
- ret.gsub!(/ /, "+")
- ret
- end
-
- def unescape_form(str)
- _unescape(str.gsub(/\+/, " "), ESCAPED)
- end
-
- def escape_path(str)
- result = ""
- str.scan(%r{/([^/]*)}).each{|i|
- result << "/" << _escape(i[0], UNESCAPED_PCHAR)
- }
- return result
- end
-
- def escape8bit(str)
- _escape(str, NONASCII)
- end
- end
-end
diff --git a/ruby_1_8_6/lib/webrick/httpversion.rb b/ruby_1_8_6/lib/webrick/httpversion.rb
deleted file mode 100644
index 86907a26bd..0000000000
--- a/ruby_1_8_6/lib/webrick/httpversion.rb
+++ /dev/null
@@ -1,49 +0,0 @@
-#
-# HTTPVersion.rb -- presentation of HTTP version
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: httpversion.rb,v 1.5 2002/09/21 12:23:37 gotoyuzo Exp $
-
-module WEBrick
- class HTTPVersion
- include Comparable
-
- attr_accessor :major, :minor
-
- def self.convert(version)
- version.is_a?(self) ? version : new(version)
- end
-
- def initialize(version)
- case version
- when HTTPVersion
- @major, @minor = version.major, version.minor
- when String
- if /^(\d+)\.(\d+)$/ =~ version
- @major, @minor = $1.to_i, $2.to_i
- end
- end
- if @major.nil? || @minor.nil?
- raise ArgumentError,
- format("cannot convert %s into %s", version.class, self.class)
- end
- end
-
- def <=>(other)
- unless other.is_a?(self.class)
- other = self.class.new(other)
- end
- if (ret = @major <=> other.major) == 0
- return @minor <=> other.minor
- end
- return ret
- end
-
- def to_s
- format("%d.%d", @major, @minor)
- end
- end
-end
diff --git a/ruby_1_8_6/lib/webrick/log.rb b/ruby_1_8_6/lib/webrick/log.rb
deleted file mode 100644
index 5d4fd0a174..0000000000
--- a/ruby_1_8_6/lib/webrick/log.rb
+++ /dev/null
@@ -1,88 +0,0 @@
-#
-# log.rb -- Log Class
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
-# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: log.rb,v 1.26 2002/10/06 17:06:10 gotoyuzo Exp $
-
-module WEBrick
- class BasicLog
- # log-level constant
- FATAL, ERROR, WARN, INFO, DEBUG = 1, 2, 3, 4, 5
-
- attr_accessor :level
-
- def initialize(log_file=nil, level=nil)
- @level = level || INFO
- case log_file
- when String
- @log = open(log_file, "a+")
- @log.sync = true
- @opened = true
- when NilClass
- @log = $stderr
- else
- @log = log_file # requires "<<". (see BasicLog#log)
- end
- end
-
- def close
- @log.close if @opened
- @log = nil
- end
-
- def log(level, data)
- if @log && level <= @level
- data += "\n" if /\n\Z/ !~ data
- @log << data
- end
- end
-
- def <<(obj)
- log(INFO, obj.to_s)
- end
-
- def fatal(msg) log(FATAL, "FATAL " << format(msg)); end
- def error(msg) log(ERROR, "ERROR " << format(msg)); end
- def warn(msg) log(WARN, "WARN " << format(msg)); end
- def info(msg) log(INFO, "INFO " << format(msg)); end
- def debug(msg) log(DEBUG, "DEBUG " << format(msg)); end
-
- def fatal?; @level >= FATAL; end
- def error?; @level >= ERROR; end
- def warn?; @level >= WARN; end
- def info?; @level >= INFO; end
- def debug?; @level >= DEBUG; end
-
- private
-
- def format(arg)
- str = if arg.is_a?(Exception)
- "#{arg.class}: #{arg.message}\n\t" <<
- arg.backtrace.join("\n\t") << "\n"
- elsif arg.respond_to?(:to_str)
- arg.to_str
- else
- arg.inspect
- end
- end
- end
-
- class Log < BasicLog
- attr_accessor :time_format
-
- def initialize(log_file=nil, level=nil)
- super(log_file, level)
- @time_format = "[%Y-%m-%d %H:%M:%S]"
- end
-
- def log(level, data)
- tmp = Time.now.strftime(@time_format)
- tmp << " " << data
- super(level, tmp)
- end
- end
-end
diff --git a/ruby_1_8_6/lib/webrick/server.rb b/ruby_1_8_6/lib/webrick/server.rb
deleted file mode 100644
index 16dbd46f98..0000000000
--- a/ruby_1_8_6/lib/webrick/server.rb
+++ /dev/null
@@ -1,200 +0,0 @@
-#
-# server.rb -- GenericServer Class
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
-# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: server.rb,v 1.62 2003/07/22 19:20:43 gotoyuzo Exp $
-
-require 'thread'
-require 'socket'
-require 'timeout'
-require 'webrick/config'
-require 'webrick/log'
-
-module WEBrick
-
- class ServerError < StandardError; end
-
- class SimpleServer
- def SimpleServer.start
- yield
- end
- end
-
- class Daemon
- def Daemon.start
- exit!(0) if fork
- Process::setsid
- exit!(0) if fork
- Dir::chdir("/")
- File::umask(0)
- STDIN.reopen("/dev/null")
- STDOUT.reopen("/dev/null", "w")
- STDERR.reopen("/dev/null", "w")
- yield if block_given?
- end
- end
-
- class GenericServer
- attr_reader :status, :config, :logger, :tokens, :listeners
-
- def initialize(config={}, default=Config::General)
- @config = default.dup.update(config)
- @status = :Stop
- @config[:Logger] ||= Log::new
- @logger = @config[:Logger]
-
- @tokens = SizedQueue.new(@config[:MaxClients])
- @config[:MaxClients].times{ @tokens.push(nil) }
-
- webrickv = WEBrick::VERSION
- rubyv = "#{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]"
- @logger.info("WEBrick #{webrickv}")
- @logger.info("ruby #{rubyv}")
-
- @listeners = []
- unless @config[:DoNotListen]
- if @config[:Listen]
- warn(":Listen option is deprecated; use GenericServer#listen")
- end
- listen(@config[:BindAddress], @config[:Port])
- if @config[:Port] == 0
- @config[:Port] = @listeners[0].addr[1]
- end
- end
- end
-
- def [](key)
- @config[key]
- end
-
- def listen(address, port)
- @listeners += Utils::create_listeners(address, port, @logger)
- end
-
- def start(&block)
- raise ServerError, "already started." if @status != :Stop
- server_type = @config[:ServerType] || SimpleServer
-
- server_type.start{
- @logger.info \
- "#{self.class}#start: pid=#{$$} port=#{@config[:Port]}"
- call_callback(:StartCallback)
-
- thgroup = ThreadGroup.new
- @status = :Running
- while @status == :Running
- begin
- if svrs = IO.select(@listeners, nil, nil, 2.0)
- svrs[0].each{|svr|
- @tokens.pop # blocks while no token is there.
- if sock = accept_client(svr)
- th = start_thread(sock, &block)
- th[:WEBrickThread] = true
- thgroup.add(th)
- else
- @tokens.push(nil)
- end
- }
- end
- rescue Errno::EBADF, IOError => ex
- # if the listening socket was closed in GenericServer#shutdown,
- # IO::select raise it.
- rescue Exception => ex
- msg = "#{ex.class}: #{ex.message}\n\t#{ex.backtrace[0]}"
- @logger.error msg
- end
- end
-
- @logger.info "going to shutdown ..."
- thgroup.list.each{|th| th.join if th[:WEBrickThread] }
- call_callback(:StopCallback)
- @logger.info "#{self.class}#start done."
- @status = :Stop
- }
- end
-
- def stop
- if @status == :Running
- @status = :Shutdown
- end
- end
-
- def shutdown
- stop
- @listeners.each{|s|
- if @logger.debug?
- addr = s.addr
- @logger.debug("close TCPSocket(#{addr[2]}, #{addr[1]})")
- end
- s.close
- }
- @listeners.clear
- end
-
- def run(sock)
- @logger.fatal "run() must be provided by user."
- end
-
- private
-
- def accept_client(svr)
- sock = nil
- begin
- sock = svr.accept
- sock.sync = true
- Utils::set_non_blocking(sock)
- Utils::set_close_on_exec(sock)
- rescue Errno::ECONNRESET, Errno::ECONNABORTED, Errno::EPROTO => ex
- # TCP connection was established but RST segment was sent
- # from peer before calling TCPServer#accept.
- rescue Exception => ex
- msg = "#{ex.class}: #{ex.message}\n\t#{ex.backtrace[0]}"
- @logger.error msg
- end
- return sock
- end
-
- def start_thread(sock, &block)
- Thread.start{
- begin
- Thread.current[:WEBrickSocket] = sock
- begin
- addr = sock.peeraddr
- @logger.debug "accept: #{addr[3]}:#{addr[1]}"
- rescue SocketError
- @logger.debug "accept: <address unknown>"
- raise
- end
- call_callback(:AcceptCallback, sock)
- block ? block.call(sock) : run(sock)
- rescue Errno::ENOTCONN
- @logger.debug "Errno::ENOTCONN raised"
- rescue ServerError => ex
- msg = "#{ex.class}: #{ex.message}\n\t#{ex.backtrace[0]}"
- @logger.error msg
- rescue Exception => ex
- @logger.error ex
- ensure
- @tokens.push(nil)
- Thread.current[:WEBrickSocket] = nil
- if addr
- @logger.debug "close: #{addr[3]}:#{addr[1]}"
- else
- @logger.debug "close: <address unknown>"
- end
- sock.close
- end
- }
- end
-
- def call_callback(callback_name, *args)
- if cb = @config[callback_name]
- cb.call(*args)
- end
- end
- end # end of GenericServer
-end
diff --git a/ruby_1_8_6/lib/webrick/ssl.rb b/ruby_1_8_6/lib/webrick/ssl.rb
deleted file mode 100644
index 03bfdf4aa0..0000000000
--- a/ruby_1_8_6/lib/webrick/ssl.rb
+++ /dev/null
@@ -1,126 +0,0 @@
-#
-# ssl.rb -- SSL/TLS enhancement for GenericServer
-#
-# Copyright (c) 2003 GOTOU Yuuzou All rights reserved.
-#
-# $Id$
-
-require 'webrick'
-require 'openssl'
-
-module WEBrick
- module Config
- svrsoft = General[:ServerSoftware]
- osslv = ::OpenSSL::OPENSSL_VERSION.split[1]
- SSL = {
- :ServerSoftware => "#{svrsoft} OpenSSL/#{osslv}",
- :SSLEnable => false,
- :SSLCertificate => nil,
- :SSLPrivateKey => nil,
- :SSLClientCA => nil,
- :SSLExtraChainCert => nil,
- :SSLCACertificateFile => nil,
- :SSLCACertificatePath => nil,
- :SSLCertificateStore => nil,
- :SSLVerifyClient => ::OpenSSL::SSL::VERIFY_NONE,
- :SSLVerifyDepth => nil,
- :SSLVerifyCallback => nil, # custom verification
- :SSLTimeout => nil,
- :SSLOptions => nil,
- :SSLStartImmediately => true,
- # Must specify if you use auto generated certificate.
- :SSLCertName => nil,
- :SSLCertComment => "Generated by Ruby/OpenSSL"
- }
- General.update(SSL)
- end
-
- module Utils
- def create_self_signed_cert(bits, cn, comment)
- rsa = OpenSSL::PKey::RSA.new(bits){|p, n|
- case p
- when 0; $stderr.putc "." # BN_generate_prime
- when 1; $stderr.putc "+" # BN_generate_prime
- when 2; $stderr.putc "*" # searching good prime,
- # n = #of try,
- # but also data from BN_generate_prime
- when 3; $stderr.putc "\n" # found good prime, n==0 - p, n==1 - q,
- # but also data from BN_generate_prime
- else; $stderr.putc "*" # BN_generate_prime
- end
- }
- cert = OpenSSL::X509::Certificate.new
- cert.version = 3
- cert.serial = 0
- name = OpenSSL::X509::Name.new(cn)
- cert.subject = name
- cert.issuer = name
- cert.not_before = Time.now
- cert.not_after = Time.now + (365*24*60*60)
- cert.public_key = rsa.public_key
-
- ef = OpenSSL::X509::ExtensionFactory.new(nil,cert)
- ef.issuer_certificate = cert
- cert.extensions = [
- ef.create_extension("basicConstraints","CA:FALSE"),
- ef.create_extension("keyUsage", "keyEncipherment"),
- ef.create_extension("subjectKeyIdentifier", "hash"),
- ef.create_extension("extendedKeyUsage", "serverAuth"),
- ef.create_extension("nsComment", comment),
- ]
- aki = ef.create_extension("authorityKeyIdentifier",
- "keyid:always,issuer:always")
- cert.add_extension(aki)
- cert.sign(rsa, OpenSSL::Digest::SHA1.new)
-
- return [ cert, rsa ]
- end
- module_function :create_self_signed_cert
- end
-
- class GenericServer
- def ssl_context
- @ssl_context ||= nil
- end
-
- def listen(address, port)
- listeners = Utils::create_listeners(address, port, @logger)
- if @config[:SSLEnable]
- unless ssl_context
- @ssl_context = setup_ssl_context(@config)
- @logger.info("\n" + @config[:SSLCertificate].to_text)
- end
- listeners.collect!{|svr|
- ssvr = ::OpenSSL::SSL::SSLServer.new(svr, ssl_context)
- ssvr.start_immediately = @config[:SSLStartImmediately]
- ssvr
- }
- end
- @listeners += listeners
- end
-
- def setup_ssl_context(config)
- unless config[:SSLCertificate]
- cn = config[:SSLCertName]
- comment = config[:SSLCertComment]
- cert, key = Utils::create_self_signed_cert(1024, cn, comment)
- config[:SSLCertificate] = cert
- config[:SSLPrivateKey] = key
- end
- ctx = OpenSSL::SSL::SSLContext.new
- ctx.key = config[:SSLPrivateKey]
- ctx.cert = config[:SSLCertificate]
- ctx.client_ca = config[:SSLClientCA]
- ctx.extra_chain_cert = config[:SSLExtraChainCert]
- ctx.ca_file = config[:SSLCACertificateFile]
- ctx.ca_path = config[:SSLCACertificatePath]
- ctx.cert_store = config[:SSLCertificateStore]
- ctx.verify_mode = config[:SSLVerifyClient]
- ctx.verify_depth = config[:SSLVerifyDepth]
- ctx.verify_callback = config[:SSLVerifyCallback]
- ctx.timeout = config[:SSLTimeout]
- ctx.options = config[:SSLOptions]
- ctx
- end
- end
-end
diff --git a/ruby_1_8_6/lib/webrick/utils.rb b/ruby_1_8_6/lib/webrick/utils.rb
deleted file mode 100644
index cf9da6f2ce..0000000000
--- a/ruby_1_8_6/lib/webrick/utils.rb
+++ /dev/null
@@ -1,100 +0,0 @@
-#
-# utils.rb -- Miscellaneous utilities
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
-# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: utils.rb,v 1.10 2003/02/16 22:22:54 gotoyuzo Exp $
-
-require 'socket'
-require 'fcntl'
-begin
- require 'etc'
-rescue LoadError
- nil
-end
-
-module WEBrick
- module Utils
- def set_non_blocking(io)
- flag = File::NONBLOCK
- if defined?(Fcntl::F_GETFL)
- flag |= io.fcntl(Fcntl::F_GETFL)
- end
- io.fcntl(Fcntl::F_SETFL, flag)
- end
- module_function :set_non_blocking
-
- def set_close_on_exec(io)
- if defined?(Fcntl::FD_CLOEXEC)
- io.fcntl(Fcntl::FD_CLOEXEC, 1)
- end
- end
- module_function :set_close_on_exec
-
- def su(user)
- if defined?(Etc)
- pw = Etc.getpwnam(user)
- Process::initgroups(user, pw.gid)
- Process::Sys::setgid(pw.gid)
- Process::Sys::setuid(pw.uid)
- else
- warn("WEBrick::Utils::su doesn't work on this platform")
- end
- end
- module_function :su
-
- def getservername
- host = Socket::gethostname
- begin
- Socket::gethostbyname(host)[0]
- rescue
- host
- end
- end
- module_function :getservername
-
- def create_listeners(address, port, logger=nil)
- unless port
- raise ArgumentError, "must specify port"
- end
- res = Socket::getaddrinfo(address, port,
- Socket::AF_UNSPEC, # address family
- Socket::SOCK_STREAM, # socket type
- 0, # protocol
- Socket::AI_PASSIVE) # flag
- last_error = nil
- sockets = []
- res.each{|ai|
- begin
- logger.debug("TCPServer.new(#{ai[3]}, #{port})") if logger
- sock = TCPServer.new(ai[3], port)
- port = sock.addr[1] if port == 0
- Utils::set_close_on_exec(sock)
- sockets << sock
- rescue => ex
- logger.warn("TCPServer Error: #{ex}") if logger
- last_error = ex
- end
- }
- raise last_error if sockets.empty?
- return sockets
- end
- module_function :create_listeners
-
- RAND_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
- "0123456789" +
- "abcdefghijklmnopqrstuvwxyz"
-
- def random_string(len)
- rand_max = RAND_CHARS.size
- ret = ""
- len.times{ ret << RAND_CHARS[rand(rand_max)] }
- ret
- end
- module_function :random_string
-
- end
-end
diff --git a/ruby_1_8_6/lib/webrick/version.rb b/ruby_1_8_6/lib/webrick/version.rb
deleted file mode 100644
index b2b9fd3b78..0000000000
--- a/ruby_1_8_6/lib/webrick/version.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-#
-# version.rb -- version and release date
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2000 TAKAHASHI Masayoshi, GOTOU YUUZOU
-# Copyright (c) 2003 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: version.rb,v 1.74 2003/07/22 19:20:43 gotoyuzo Exp $
-
-module WEBrick
- VERSION = "1.3.1"
-end