webrick 1.3.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of webrick might be problematic. Click here for more details.

Files changed (63) hide show
  1. data/README.txt +21 -0
  2. data/lib/webrick.rb +227 -0
  3. data/lib/webrick/accesslog.rb +151 -0
  4. data/lib/webrick/cgi.rb +260 -0
  5. data/lib/webrick/compat.rb +35 -0
  6. data/lib/webrick/config.rb +121 -0
  7. data/lib/webrick/cookie.rb +110 -0
  8. data/lib/webrick/htmlutils.rb +28 -0
  9. data/lib/webrick/httpauth.rb +95 -0
  10. data/lib/webrick/httpauth/authenticator.rb +112 -0
  11. data/lib/webrick/httpauth/basicauth.rb +108 -0
  12. data/lib/webrick/httpauth/digestauth.rb +392 -0
  13. data/lib/webrick/httpauth/htdigest.rb +128 -0
  14. data/lib/webrick/httpauth/htgroup.rb +93 -0
  15. data/lib/webrick/httpauth/htpasswd.rb +121 -0
  16. data/lib/webrick/httpauth/userdb.rb +52 -0
  17. data/lib/webrick/httpproxy.rb +305 -0
  18. data/lib/webrick/httprequest.rb +461 -0
  19. data/lib/webrick/httpresponse.rb +399 -0
  20. data/lib/webrick/https.rb +64 -0
  21. data/lib/webrick/httpserver.rb +264 -0
  22. data/lib/webrick/httpservlet.rb +22 -0
  23. data/lib/webrick/httpservlet/abstract.rb +153 -0
  24. data/lib/webrick/httpservlet/cgi_runner.rb +46 -0
  25. data/lib/webrick/httpservlet/cgihandler.rb +108 -0
  26. data/lib/webrick/httpservlet/erbhandler.rb +87 -0
  27. data/lib/webrick/httpservlet/filehandler.rb +470 -0
  28. data/lib/webrick/httpservlet/prochandler.rb +33 -0
  29. data/lib/webrick/httpstatus.rb +184 -0
  30. data/lib/webrick/httputils.rb +394 -0
  31. data/lib/webrick/httpversion.rb +49 -0
  32. data/lib/webrick/log.rb +136 -0
  33. data/lib/webrick/server.rb +218 -0
  34. data/lib/webrick/ssl.rb +127 -0
  35. data/lib/webrick/utils.rb +241 -0
  36. data/lib/webrick/version.rb +13 -0
  37. data/sample/webrick/demo-app.rb +66 -0
  38. data/sample/webrick/demo-multipart.cgi +12 -0
  39. data/sample/webrick/demo-servlet.rb +6 -0
  40. data/sample/webrick/demo-urlencoded.cgi +12 -0
  41. data/sample/webrick/hello.cgi +11 -0
  42. data/sample/webrick/hello.rb +8 -0
  43. data/sample/webrick/httpd.rb +23 -0
  44. data/sample/webrick/httpproxy.rb +25 -0
  45. data/sample/webrick/httpsd.rb +33 -0
  46. data/test/openssl/utils.rb +313 -0
  47. data/test/ruby/envutil.rb +208 -0
  48. data/test/webrick/test_cgi.rb +134 -0
  49. data/test/webrick/test_cookie.rb +131 -0
  50. data/test/webrick/test_filehandler.rb +285 -0
  51. data/test/webrick/test_httpauth.rb +167 -0
  52. data/test/webrick/test_httpproxy.rb +282 -0
  53. data/test/webrick/test_httprequest.rb +411 -0
  54. data/test/webrick/test_httpresponse.rb +49 -0
  55. data/test/webrick/test_httpserver.rb +305 -0
  56. data/test/webrick/test_httputils.rb +96 -0
  57. data/test/webrick/test_httpversion.rb +40 -0
  58. data/test/webrick/test_server.rb +67 -0
  59. data/test/webrick/test_utils.rb +64 -0
  60. data/test/webrick/utils.rb +58 -0
  61. data/test/webrick/webrick.cgi +36 -0
  62. data/test/webrick/webrick_long_filename.cgi +36 -0
  63. metadata +106 -0
@@ -0,0 +1,35 @@
1
+ #
2
+ # compat.rb -- cross platform compatibility
3
+ #
4
+ # Author: IPR -- Internet Programming with Ruby -- writers
5
+ # Copyright (c) 2002 GOTOU Yuuzou
6
+ # Copyright (c) 2002 Internet Programming with Ruby writers. All rights
7
+ # reserved.
8
+ #
9
+ # $IPR: compat.rb,v 1.6 2002/10/01 17:16:32 gotoyuzo Exp $
10
+
11
+ ##
12
+ # System call error module used by webrick for cross platform compatability.
13
+ #
14
+ # EPROTO:: protocol error
15
+ # ECONNRESET:: remote host reset the connection request
16
+ # ECONNABORTED:: Client sent TCP reset (RST) before server has accepted the
17
+ # connection requested by client.
18
+ #
19
+ module Errno
20
+ ##
21
+ # Protocol error.
22
+
23
+ class EPROTO < SystemCallError; end
24
+
25
+ ##
26
+ # Remote host reset the connection request.
27
+
28
+ class ECONNRESET < SystemCallError; end
29
+
30
+ ##
31
+ # Client sent TCP reset (RST) before server has accepted the connection
32
+ # requested by client.
33
+
34
+ class ECONNABORTED < SystemCallError; end
35
+ end
@@ -0,0 +1,121 @@
1
+ #
2
+ # config.rb -- Default configurations.
3
+ #
4
+ # Author: IPR -- Internet Programming with Ruby -- writers
5
+ # Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
6
+ # Copyright (c) 2003 Internet Programming with Ruby writers. All rights
7
+ # reserved.
8
+ #
9
+ # $IPR: config.rb,v 1.52 2003/07/22 19:20:42 gotoyuzo Exp $
10
+
11
+ require 'webrick/version'
12
+ require 'webrick/httpversion'
13
+ require 'webrick/httputils'
14
+ require 'webrick/utils'
15
+ require 'webrick/log'
16
+
17
+ module WEBrick
18
+ module Config
19
+ LIBDIR = File::dirname(__FILE__)
20
+
21
+ # for GenericServer
22
+ General = {
23
+ :ServerName => Utils::getservername,
24
+ :BindAddress => nil, # "0.0.0.0" or "::" or nil
25
+ :Port => nil, # users MUST specify this!!
26
+ :MaxClients => 100, # maximum number of the concurrent connections
27
+ :ServerType => nil, # default: WEBrick::SimpleServer
28
+ :Logger => nil, # default: WEBrick::Log.new
29
+ :ServerSoftware => "WEBrick/#{WEBrick::VERSION} " +
30
+ "(Ruby/#{RUBY_VERSION}/#{RUBY_RELEASE_DATE})",
31
+ :TempDir => ENV['TMPDIR']||ENV['TMP']||ENV['TEMP']||'/tmp',
32
+ :DoNotListen => false,
33
+ :StartCallback => nil,
34
+ :StopCallback => nil,
35
+ :AcceptCallback => nil,
36
+ :DoNotReverseLookup => nil,
37
+ :ShutdownSocketWithoutClose => false,
38
+ }
39
+
40
+ # for HTTPServer, HTTPRequest, HTTPResponse ...
41
+ HTTP = General.dup.update(
42
+ :Port => 80,
43
+ :RequestTimeout => 30,
44
+ :HTTPVersion => HTTPVersion.new("1.1"),
45
+ :AccessLog => nil,
46
+ :MimeTypes => HTTPUtils::DefaultMimeTypes,
47
+ :DirectoryIndex => ["index.html","index.htm","index.cgi","index.rhtml"],
48
+ :DocumentRoot => nil,
49
+ :DocumentRootOptions => { :FancyIndexing => true },
50
+ :RequestCallback => nil,
51
+ :ServerAlias => nil,
52
+ :InputBufferSize => 65536, # input buffer size in reading request body
53
+ :OutputBufferSize => 65536, # output buffer size in sending File or IO
54
+
55
+ # for HTTPProxyServer
56
+ :ProxyAuthProc => nil,
57
+ :ProxyContentHandler => nil,
58
+ :ProxyVia => true,
59
+ :ProxyTimeout => true,
60
+ :ProxyURI => nil,
61
+
62
+ :CGIInterpreter => nil,
63
+ :CGIPathEnv => nil,
64
+
65
+ # workaround: if Request-URIs contain 8bit chars,
66
+ # they should be escaped before calling of URI::parse().
67
+ :Escape8bitURI => false
68
+ )
69
+
70
+ FileHandler = {
71
+ :NondisclosureName => [".ht*", "*~"],
72
+ :FancyIndexing => false,
73
+ :HandlerTable => {},
74
+ :HandlerCallback => nil,
75
+ :DirectoryCallback => nil,
76
+ :FileCallback => nil,
77
+ :UserDir => nil, # e.g. "public_html"
78
+ :AcceptableLanguages => [] # ["en", "ja", ... ]
79
+ }
80
+
81
+ BasicAuth = {
82
+ :AutoReloadUserDB => true,
83
+ }
84
+
85
+ ##
86
+ # Default configuration for WEBrick::HTTPAuth::DigestAuth.
87
+ #
88
+ # :Algorithm:: MD5, MD5-sess (default), SHA1, SHA1-sess
89
+ # :Domain:: An Array of URIs that define the protected space
90
+ # :Qop:: 'auth' for authentication, 'auth-int' for integrity protection or
91
+ # both
92
+ # :UseOpaque:: Should the server send opaque values to the client? This
93
+ # helps prevent replay attacks.
94
+ # :CheckNc:: Should the server check the nonce count? This helps the
95
+ # server detect replay attacks.
96
+ # :UseAuthenticationInfoHeader:: Should the server send an
97
+ # AuthenticationInfo header?
98
+ # :AutoReloadUserDB:: Reload the user database provided by :UserDB
99
+ # automatically?
100
+ # :NonceExpirePeriod:: How long should we store used nonces? Default is
101
+ # 30 minutes.
102
+ # :NonceExpireDelta:: How long is a nonce valid? Default is 1 minute
103
+ # :InternetExplorerHack:: Hack which allows Internet Explorer to work.
104
+ # :OperaHack:: Hack which allows Opera to work.
105
+
106
+ DigestAuth = {
107
+ :Algorithm => 'MD5-sess', # or 'MD5'
108
+ :Domain => nil, # an array includes domain names.
109
+ :Qop => [ 'auth' ], # 'auth' or 'auth-int' or both.
110
+ :UseOpaque => true,
111
+ :UseNextNonce => false,
112
+ :CheckNc => false,
113
+ :UseAuthenticationInfoHeader => true,
114
+ :AutoReloadUserDB => true,
115
+ :NonceExpirePeriod => 30*60,
116
+ :NonceExpireDelta => 60,
117
+ :InternetExplorerHack => true,
118
+ :OperaHack => true,
119
+ }
120
+ end
121
+ end
@@ -0,0 +1,110 @@
1
+ #
2
+ # cookie.rb -- Cookie class
3
+ #
4
+ # Author: IPR -- Internet Programming with Ruby -- writers
5
+ # Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
6
+ # Copyright (c) 2002 Internet Programming with Ruby writers. All rights
7
+ # reserved.
8
+ #
9
+ # $IPR: cookie.rb,v 1.16 2002/09/21 12:23:35 gotoyuzo Exp $
10
+
11
+ require 'time'
12
+ require 'webrick/httputils'
13
+
14
+ module WEBrick
15
+ class Cookie
16
+
17
+ attr_reader :name
18
+ attr_accessor :value, :version
19
+ attr_accessor :domain, :path, :secure
20
+ attr_accessor :comment, :max_age
21
+ #attr_accessor :comment_url, :discard, :port
22
+
23
+ def initialize(name, value)
24
+ @name = name
25
+ @value = value
26
+ @version = 0 # Netscape Cookie
27
+
28
+ @domain = @path = @secure = @comment = @max_age =
29
+ @expires = @comment_url = @discard = @port = nil
30
+ end
31
+
32
+ def expires=(t)
33
+ @expires = t && (t.is_a?(Time) ? t.httpdate : t.to_s)
34
+ end
35
+
36
+ def expires
37
+ @expires && Time.parse(@expires)
38
+ end
39
+
40
+ def to_s
41
+ ret = ""
42
+ ret << @name << "=" << @value
43
+ ret << "; " << "Version=" << @version.to_s if @version > 0
44
+ ret << "; " << "Domain=" << @domain if @domain
45
+ ret << "; " << "Expires=" << @expires if @expires
46
+ ret << "; " << "Max-Age=" << @max_age.to_s if @max_age
47
+ ret << "; " << "Comment=" << @comment if @comment
48
+ ret << "; " << "Path=" << @path if @path
49
+ ret << "; " << "Secure" if @secure
50
+ ret
51
+ end
52
+
53
+ # Cookie::parse()
54
+ # It parses Cookie field sent from the user agent.
55
+ def self.parse(str)
56
+ if str
57
+ ret = []
58
+ cookie = nil
59
+ ver = 0
60
+ str.split(/[;,]\s+/).each{|x|
61
+ key, val = x.split(/=/,2)
62
+ val = val ? HTTPUtils::dequote(val) : ""
63
+ case key
64
+ when "$Version"; ver = val.to_i
65
+ when "$Path"; cookie.path = val
66
+ when "$Domain"; cookie.domain = val
67
+ when "$Port"; cookie.port = val
68
+ else
69
+ ret << cookie if cookie
70
+ cookie = self.new(key, val)
71
+ cookie.version = ver
72
+ end
73
+ }
74
+ ret << cookie if cookie
75
+ ret
76
+ end
77
+ end
78
+
79
+ def self.parse_set_cookie(str)
80
+ cookie_elem = str.split(/;/)
81
+ first_elem = cookie_elem.shift
82
+ first_elem.strip!
83
+ key, value = first_elem.split(/=/, 2)
84
+ cookie = new(key, HTTPUtils.dequote(value))
85
+ cookie_elem.each{|pair|
86
+ pair.strip!
87
+ key, value = pair.split(/=/, 2)
88
+ if value
89
+ value = HTTPUtils.dequote(value.strip)
90
+ end
91
+ case key.downcase
92
+ when "domain" then cookie.domain = value
93
+ when "path" then cookie.path = value
94
+ when "expires" then cookie.expires = value
95
+ when "max-age" then cookie.max_age = Integer(value)
96
+ when "comment" then cookie.comment = value
97
+ when "version" then cookie.version = Integer(value)
98
+ when "secure" then cookie.secure = true
99
+ end
100
+ }
101
+ return cookie
102
+ end
103
+
104
+ def self.parse_set_cookies(str)
105
+ return str.split(/,(?=[^;,]*=)|,$/).collect{|c|
106
+ parse_set_cookie(c)
107
+ }
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,28 @@
1
+ #--
2
+ # htmlutils.rb -- HTMLUtils Module
3
+ #
4
+ # Author: IPR -- Internet Programming with Ruby -- writers
5
+ # Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
6
+ # Copyright (c) 2002 Internet Programming with Ruby writers. All rights
7
+ # reserved.
8
+ #
9
+ # $IPR: htmlutils.rb,v 1.7 2002/09/21 12:23:35 gotoyuzo Exp $
10
+
11
+ module WEBrick
12
+ module HTMLUtils
13
+
14
+ ##
15
+ # Escapes &, ", > and < in +string+
16
+
17
+ def escape(string)
18
+ str = string ? string.dup : ""
19
+ str.gsub!(/&/n, '&amp;')
20
+ str.gsub!(/\"/n, '&quot;')
21
+ str.gsub!(/>/n, '&gt;')
22
+ str.gsub!(/</n, '&lt;')
23
+ str
24
+ end
25
+ module_function :escape
26
+
27
+ end
28
+ end
@@ -0,0 +1,95 @@
1
+ #
2
+ # httpauth.rb -- HTTP access authentication
3
+ #
4
+ # Author: IPR -- Internet Programming with Ruby -- writers
5
+ # Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
6
+ # Copyright (c) 2002 Internet Programming with Ruby writers. All rights
7
+ # reserved.
8
+ #
9
+ # $IPR: httpauth.rb,v 1.14 2003/07/22 19:20:42 gotoyuzo Exp $
10
+
11
+ require 'webrick/httpauth/basicauth'
12
+ require 'webrick/httpauth/digestauth'
13
+ require 'webrick/httpauth/htpasswd'
14
+ require 'webrick/httpauth/htdigest'
15
+ require 'webrick/httpauth/htgroup'
16
+
17
+ module WEBrick
18
+
19
+ ##
20
+ # HTTPAuth provides both basic and digest authentication.
21
+ #
22
+ # To enable authentication for requests in WEBrick you will need a user
23
+ # database and an authenticator. To start, here's an Htpasswd database for
24
+ # use with a DigestAuth authenticator:
25
+ #
26
+ # config = { :Realm => 'DigestAuth example realm' }
27
+ #
28
+ # htpasswd = WEBrick::HTTPAuth::Htpasswd.new 'my_password_file'
29
+ # htpasswd.auth_type = WEBrick::HTTPAuth::DigestAuth
30
+ # htpasswd.set_passwd config[:Realm], 'username', 'password'
31
+ # htpasswd.flush
32
+ #
33
+ # The +:Realm+ is used to provide different access to different groups
34
+ # across several resources on a server. Typically you'll need only one
35
+ # realm for a server.
36
+ #
37
+ # This database can be used to create an authenticator:
38
+ #
39
+ # config[:UserDB] = htpasswd
40
+ #
41
+ # digest_auth = WEBrick::HTTPAuth::DigestAuth.new config
42
+ #
43
+ # To authenticate a request call #authenticate with a request and response
44
+ # object in a servlet:
45
+ #
46
+ # def do_GET req, res
47
+ # @authenticator.authenticate req, res
48
+ # end
49
+ #
50
+ # For digest authentication the authenticator must not be created every
51
+ # request, it must be passed in as an option via WEBrick::HTTPServer#mount.
52
+
53
+ module HTTPAuth
54
+ module_function
55
+
56
+ def _basic_auth(req, res, realm, req_field, res_field, err_type,
57
+ block) # :nodoc:
58
+ user = pass = nil
59
+ if /^Basic\s+(.*)/o =~ req[req_field]
60
+ userpass = $1
61
+ user, pass = userpass.unpack("m*")[0].split(":", 2)
62
+ end
63
+ if block.call(user, pass)
64
+ req.user = user
65
+ return
66
+ end
67
+ res[res_field] = "Basic realm=\"#{realm}\""
68
+ raise err_type
69
+ end
70
+
71
+ ##
72
+ # Simple wrapper for providing basic authentication for a request. When
73
+ # called with a request +req+, response +res+, authentication +realm+ and
74
+ # +block+ the block will be called with a +username+ and +password+. If
75
+ # the block returns true the request is allowed to continue, otherwise an
76
+ # HTTPStatus::Unauthorized error is raised.
77
+
78
+ def basic_auth(req, res, realm, &block) # :yield: username, password
79
+ _basic_auth(req, res, realm, "Authorization", "WWW-Authenticate",
80
+ HTTPStatus::Unauthorized, block)
81
+ end
82
+
83
+ ##
84
+ # Simple wrapper for providing basic authentication for a proxied request.
85
+ # When called with a request +req+, response +res+, authentication +realm+
86
+ # and +block+ the block will be called with a +username+ and +password+.
87
+ # If the block returns true the request is allowed to continue, otherwise
88
+ # an HTTPStatus::ProxyAuthenticationRequired error is raised.
89
+
90
+ def proxy_basic_auth(req, res, realm, &block) # :yield: username, password
91
+ _basic_auth(req, res, realm, "Proxy-Authorization", "Proxy-Authenticate",
92
+ HTTPStatus::ProxyAuthenticationRequired, block)
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,112 @@
1
+ #--
2
+ # httpauth/authenticator.rb -- Authenticator mix-in module.
3
+ #
4
+ # Author: IPR -- Internet Programming with Ruby -- writers
5
+ # Copyright (c) 2003 Internet Programming with Ruby writers. All rights
6
+ # reserved.
7
+ #
8
+ # $IPR: authenticator.rb,v 1.3 2003/02/20 07:15:47 gotoyuzo Exp $
9
+
10
+ module WEBrick
11
+ module HTTPAuth
12
+
13
+ ##
14
+ # Module providing generic support for both Digest and Basic
15
+ # authentication schemes.
16
+
17
+ module Authenticator
18
+
19
+ RequestField = "Authorization"
20
+ ResponseField = "WWW-Authenticate"
21
+ ResponseInfoField = "Authentication-Info"
22
+ AuthException = HTTPStatus::Unauthorized
23
+
24
+ ##
25
+ # Method of authentication, must be overridden by the including class
26
+
27
+ AuthScheme = nil
28
+
29
+ ##
30
+ # The realm this authenticator covers
31
+
32
+ attr_reader :realm
33
+
34
+ ##
35
+ # The user database for this authenticator
36
+
37
+ attr_reader :userdb
38
+
39
+ ##
40
+ # The logger for this authenticator
41
+
42
+ attr_reader :logger
43
+
44
+ private
45
+
46
+ ##
47
+ # Initializes the authenticator from +config+
48
+
49
+ def check_init(config)
50
+ [:UserDB, :Realm].each{|sym|
51
+ unless config[sym]
52
+ raise ArgumentError, "Argument #{sym.inspect} missing."
53
+ end
54
+ }
55
+ @realm = config[:Realm]
56
+ @userdb = config[:UserDB]
57
+ @logger = config[:Logger] || Log::new($stderr)
58
+ @reload_db = config[:AutoReloadUserDB]
59
+ @request_field = self::class::RequestField
60
+ @response_field = self::class::ResponseField
61
+ @resp_info_field = self::class::ResponseInfoField
62
+ @auth_exception = self::class::AuthException
63
+ @auth_scheme = self::class::AuthScheme
64
+ end
65
+
66
+ ##
67
+ # Ensures +req+ has credentials that can be authenticated.
68
+
69
+ def check_scheme(req)
70
+ unless credentials = req[@request_field]
71
+ error("no credentials in the request.")
72
+ return nil
73
+ end
74
+ unless match = /^#{@auth_scheme}\s+/i.match(credentials)
75
+ error("invalid scheme in %s.", credentials)
76
+ info("%s: %s", @request_field, credentials) if $DEBUG
77
+ return nil
78
+ end
79
+ return match.post_match
80
+ end
81
+
82
+ def log(meth, fmt, *args)
83
+ msg = format("%s %s: ", @auth_scheme, @realm)
84
+ msg << fmt % args
85
+ @logger.send(meth, msg)
86
+ end
87
+
88
+ def error(fmt, *args)
89
+ if @logger.error?
90
+ log(:error, fmt, *args)
91
+ end
92
+ end
93
+
94
+ def info(fmt, *args)
95
+ if @logger.info?
96
+ log(:info, fmt, *args)
97
+ end
98
+ end
99
+ end
100
+
101
+ ##
102
+ # Module providing generic support for both Digest and Basic
103
+ # authentication schemes for proxies.
104
+
105
+ module ProxyAuthenticator
106
+ RequestField = "Proxy-Authorization"
107
+ ResponseField = "Proxy-Authenticate"
108
+ InfoField = "Proxy-Authentication-Info"
109
+ AuthException = HTTPStatus::ProxyAuthenticationRequired
110
+ end
111
+ end
112
+ end