rubysl-webrick 1.0.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. checksums.yaml +14 -6
  2. data/.travis.yml +5 -6
  3. data/lib/rubysl/webrick/version.rb +1 -1
  4. data/lib/rubysl/webrick/webrick.rb +199 -2
  5. data/lib/webrick/accesslog.rb +96 -5
  6. data/lib/webrick/cgi.rb +80 -29
  7. data/lib/webrick/compat.rb +20 -0
  8. data/lib/webrick/config.rb +59 -5
  9. data/lib/webrick/cookie.rb +66 -5
  10. data/lib/webrick/htmlutils.rb +4 -1
  11. data/lib/webrick/httpauth.rb +53 -3
  12. data/lib/webrick/httpauth/authenticator.rb +53 -16
  13. data/lib/webrick/httpauth/basicauth.rb +45 -2
  14. data/lib/webrick/httpauth/digestauth.rb +82 -17
  15. data/lib/webrick/httpauth/htdigest.rb +38 -1
  16. data/lib/webrick/httpauth/htgroup.rb +32 -0
  17. data/lib/webrick/httpauth/htpasswd.rb +40 -2
  18. data/lib/webrick/httpauth/userdb.rb +27 -4
  19. data/lib/webrick/httpproxy.rb +197 -112
  20. data/lib/webrick/httprequest.rb +268 -50
  21. data/lib/webrick/httpresponse.rb +170 -33
  22. data/lib/webrick/https.rb +26 -3
  23. data/lib/webrick/httpserver.rb +75 -7
  24. data/lib/webrick/httpservlet/abstract.rb +88 -6
  25. data/lib/webrick/httpservlet/cgi_runner.rb +5 -4
  26. data/lib/webrick/httpservlet/cgihandler.rb +37 -18
  27. data/lib/webrick/httpservlet/erbhandler.rb +40 -7
  28. data/lib/webrick/httpservlet/filehandler.rb +116 -28
  29. data/lib/webrick/httpservlet/prochandler.rb +17 -4
  30. data/lib/webrick/httpstatus.rb +86 -18
  31. data/lib/webrick/httputils.rb +131 -23
  32. data/lib/webrick/httpversion.rb +28 -2
  33. data/lib/webrick/log.rb +72 -5
  34. data/lib/webrick/server.rb +158 -33
  35. data/lib/webrick/ssl.rb +78 -9
  36. data/lib/webrick/utils.rb +151 -5
  37. data/lib/webrick/version.rb +5 -1
  38. data/rubysl-webrick.gemspec +0 -1
  39. metadata +12 -24
@@ -8,8 +8,28 @@
8
8
  #
9
9
  # $IPR: compat.rb,v 1.6 2002/10/01 17:16:32 gotoyuzo Exp $
10
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
+ #
11
19
  module Errno
20
+ ##
21
+ # Protocol error.
22
+
12
23
  class EPROTO < SystemCallError; end
24
+
25
+ ##
26
+ # Remote host reset the connection request.
27
+
13
28
  class ECONNRESET < SystemCallError; end
29
+
30
+ ##
31
+ # Client sent TCP reset (RST) before server has accepted the connection
32
+ # requested by client.
33
+
14
34
  class ECONNABORTED < SystemCallError; end
15
35
  end
@@ -16,13 +16,13 @@ require 'webrick/log'
16
16
 
17
17
  module WEBrick
18
18
  module Config
19
- LIBDIR = File::dirname(__FILE__)
19
+ LIBDIR = File::dirname(__FILE__) # :nodoc:
20
20
 
21
21
  # for GenericServer
22
22
  General = {
23
23
  :ServerName => Utils::getservername,
24
24
  :BindAddress => nil, # "0.0.0.0" or "::" or nil
25
- :Port => nil, # users MUST specifiy this!!
25
+ :Port => nil, # users MUST specify this!!
26
26
  :MaxClients => 100, # maximum number of the concurrent connections
27
27
  :ServerType => nil, # default: WEBrick::SimpleServer
28
28
  :Logger => nil, # default: WEBrick::Log.new
@@ -33,6 +33,8 @@ module WEBrick
33
33
  :StartCallback => nil,
34
34
  :StopCallback => nil,
35
35
  :AcceptCallback => nil,
36
+ :DoNotReverseLookup => nil,
37
+ :ShutdownSocketWithoutClose => false,
36
38
  }
37
39
 
38
40
  # for HTTPServer, HTTPRequest, HTTPResponse ...
@@ -45,9 +47,10 @@ module WEBrick
45
47
  :DirectoryIndex => ["index.html","index.htm","index.cgi","index.rhtml"],
46
48
  :DocumentRoot => nil,
47
49
  :DocumentRootOptions => { :FancyIndexing => true },
48
- :RequestHandler => nil,
49
- :RequestCallback => nil, # alias of :RequestHandler
50
+ :RequestCallback => nil,
50
51
  :ServerAlias => nil,
52
+ :InputBufferSize => 65536, # input buffer size in reading request body
53
+ :OutputBufferSize => 65536, # output buffer size in sending File or IO
51
54
 
52
55
  # for HTTPProxyServer
53
56
  :ProxyAuthProc => nil,
@@ -64,6 +67,30 @@ module WEBrick
64
67
  :Escape8bitURI => false
65
68
  )
66
69
 
70
+ ##
71
+ # Default configuration for WEBrick::HTTPServlet::FileHandler
72
+ #
73
+ # :AcceptableLanguages::
74
+ # Array of languages allowed for accept-language. There is no default
75
+ # :DirectoryCallback::
76
+ # Allows preprocessing of directory requests. There is no default
77
+ # callback.
78
+ # :FancyIndexing::
79
+ # If true, show an index for directories. The default is true.
80
+ # :FileCallback::
81
+ # Allows preprocessing of file requests. There is no default callback.
82
+ # :HandlerCallback::
83
+ # Allows preprocessing of requests. There is no default callback.
84
+ # :HandlerTable::
85
+ # Maps file suffixes to file handlers. DefaultFileHandler is used by
86
+ # default but any servlet can be used.
87
+ # :NondisclosureName::
88
+ # Do not show files matching this array of globs. .ht* and *~ are
89
+ # excluded by default.
90
+ # :UserDir::
91
+ # Directory inside ~user to serve content from for /~user requests.
92
+ # Only works if mounted on /. Disabled by default.
93
+
67
94
  FileHandler = {
68
95
  :NondisclosureName => [".ht*", "*~"],
69
96
  :FancyIndexing => false,
@@ -75,12 +102,39 @@ module WEBrick
75
102
  :AcceptableLanguages => [] # ["en", "ja", ... ]
76
103
  }
77
104
 
105
+ ##
106
+ # Default configuration for WEBrick::HTTPAuth::BasicAuth
107
+ #
108
+ # :AutoReloadUserDB:: Reload the user database provided by :UserDB
109
+ # automatically?
110
+
78
111
  BasicAuth = {
79
112
  :AutoReloadUserDB => true,
80
113
  }
81
114
 
115
+ ##
116
+ # Default configuration for WEBrick::HTTPAuth::DigestAuth.
117
+ #
118
+ # :Algorithm:: MD5, MD5-sess (default), SHA1, SHA1-sess
119
+ # :Domain:: An Array of URIs that define the protected space
120
+ # :Qop:: 'auth' for authentication, 'auth-int' for integrity protection or
121
+ # both
122
+ # :UseOpaque:: Should the server send opaque values to the client? This
123
+ # helps prevent replay attacks.
124
+ # :CheckNc:: Should the server check the nonce count? This helps the
125
+ # server detect replay attacks.
126
+ # :UseAuthenticationInfoHeader:: Should the server send an
127
+ # AuthenticationInfo header?
128
+ # :AutoReloadUserDB:: Reload the user database provided by :UserDB
129
+ # automatically?
130
+ # :NonceExpirePeriod:: How long should we store used nonces? Default is
131
+ # 30 minutes.
132
+ # :NonceExpireDelta:: How long is a nonce valid? Default is 1 minute
133
+ # :InternetExplorerHack:: Hack which allows Internet Explorer to work.
134
+ # :OperaHack:: Hack which allows Opera to work.
135
+
82
136
  DigestAuth = {
83
- :Algorithm => 'MD5-sess', # or 'MD5'
137
+ :Algorithm => 'MD5-sess', # or 'MD5'
84
138
  :Domain => nil, # an array includes domain names.
85
139
  :Qop => [ 'auth' ], # 'auth' or 'auth-int' or both.
86
140
  :UseOpaque => true,
@@ -12,14 +12,56 @@ require 'time'
12
12
  require 'webrick/httputils'
13
13
 
14
14
  module WEBrick
15
+
16
+ ##
17
+ # Processes HTTP cookies
18
+
15
19
  class Cookie
16
20
 
21
+ ##
22
+ # The cookie name
23
+
17
24
  attr_reader :name
18
- attr_accessor :value, :version
19
- attr_accessor :domain, :path, :secure
20
- attr_accessor :comment, :max_age
25
+
26
+ ##
27
+ # The cookie value
28
+
29
+ attr_accessor :value
30
+
31
+ ##
32
+ # The cookie version
33
+
34
+ attr_accessor :version
35
+
36
+ ##
37
+ # The cookie domain
38
+ attr_accessor :domain
39
+
40
+ ##
41
+ # The cookie path
42
+
43
+ attr_accessor :path
44
+
45
+ ##
46
+ # Is this a secure cookie?
47
+
48
+ attr_accessor :secure
49
+
50
+ ##
51
+ # The cookie comment
52
+
53
+ attr_accessor :comment
54
+
55
+ ##
56
+ # The maximum age of the cookie
57
+
58
+ attr_accessor :max_age
59
+
21
60
  #attr_accessor :comment_url, :discard, :port
22
61
 
62
+ ##
63
+ # Creates a new cookie with the given +name+ and +value+
64
+
23
65
  def initialize(name, value)
24
66
  @name = name
25
67
  @value = value
@@ -29,14 +71,25 @@ module WEBrick
29
71
  @expires = @comment_url = @discard = @port = nil
30
72
  end
31
73
 
74
+ ##
75
+ # Sets the cookie expiration to the time +t+. The expiration time may be
76
+ # a false value to disable expiration or a Time or HTTP format time string
77
+ # to set the expiration date.
78
+
32
79
  def expires=(t)
33
80
  @expires = t && (t.is_a?(Time) ? t.httpdate : t.to_s)
34
81
  end
35
82
 
83
+ ##
84
+ # Retrieves the expiration time as a Time
85
+
36
86
  def expires
37
87
  @expires && Time.parse(@expires)
38
88
  end
39
89
 
90
+ ##
91
+ # The cookie string suitable for use in an HTTP header
92
+
40
93
  def to_s
41
94
  ret = ""
42
95
  ret << @name << "=" << @value
@@ -50,8 +103,10 @@ module WEBrick
50
103
  ret
51
104
  end
52
105
 
53
- # Cookie::parse()
54
- # It parses Cookie field sent from the user agent.
106
+ ##
107
+ # Parses a Cookie field sent from the user-agent. Returns an array of
108
+ # cookies.
109
+
55
110
  def self.parse(str)
56
111
  if str
57
112
  ret = []
@@ -76,6 +131,9 @@ module WEBrick
76
131
  end
77
132
  end
78
133
 
134
+ ##
135
+ # Parses the cookie in +str+
136
+
79
137
  def self.parse_set_cookie(str)
80
138
  cookie_elem = str.split(/;/)
81
139
  first_elem = cookie_elem.shift
@@ -101,6 +159,9 @@ module WEBrick
101
159
  return cookie
102
160
  end
103
161
 
162
+ ##
163
+ # Parses the cookies in +str+
164
+
104
165
  def self.parse_set_cookies(str)
105
166
  return str.split(/,(?=[^;,]*=)|,$/).collect{|c|
106
167
  parse_set_cookie(c)
@@ -1,4 +1,4 @@
1
- #
1
+ #--
2
2
  # htmlutils.rb -- HTMLUtils Module
3
3
  #
4
4
  # Author: IPR -- Internet Programming with Ruby -- writers
@@ -11,6 +11,9 @@
11
11
  module WEBrick
12
12
  module HTMLUtils
13
13
 
14
+ ##
15
+ # Escapes &, ", > and < in +string+
16
+
14
17
  def escape(string)
15
18
  str = string ? string.dup : ""
16
19
  str.gsub!(/&/n, '&amp;')
@@ -15,10 +15,46 @@ require 'webrick/httpauth/htdigest'
15
15
  require 'webrick/httpauth/htgroup'
16
16
 
17
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
+
18
53
  module HTTPAuth
19
54
  module_function
20
55
 
21
- def _basic_auth(req, res, realm, req_field, res_field, err_type, block)
56
+ def _basic_auth(req, res, realm, req_field, res_field, err_type,
57
+ block) # :nodoc:
22
58
  user = pass = nil
23
59
  if /^Basic\s+(.*)/o =~ req[req_field]
24
60
  userpass = $1
@@ -32,12 +68,26 @@ module WEBrick
32
68
  raise err_type
33
69
  end
34
70
 
35
- def basic_auth(req, res, realm, &block)
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
36
79
  _basic_auth(req, res, realm, "Authorization", "WWW-Authenticate",
37
80
  HTTPStatus::Unauthorized, block)
38
81
  end
39
82
 
40
- def proxy_basic_auth(req, res, realm, &block)
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
41
91
  _basic_auth(req, res, realm, "Proxy-Authorization", "Proxy-Authenticate",
42
92
  HTTPStatus::ProxyAuthenticationRequired, block)
43
93
  end
@@ -1,4 +1,4 @@
1
- #
1
+ #--
2
2
  # httpauth/authenticator.rb -- Authenticator mix-in module.
3
3
  #
4
4
  # Author: IPR -- Internet Programming with Ruby -- writers
@@ -9,23 +9,51 @@
9
9
 
10
10
  module WEBrick
11
11
  module HTTPAuth
12
+
13
+ ##
14
+ # Module providing generic support for both Digest and Basic
15
+ # authentication schemes.
16
+
12
17
  module Authenticator
13
- RequestField = "Authorization"
14
- ResponseField = "WWW-Authenticate"
15
- ResponseInfoField = "Authentication-Info"
16
- AuthException = HTTPStatus::Unauthorized
17
- AuthScheme = nil # must override by the derived class
18
18
 
19
- attr_reader :realm, :userdb, :logger
19
+ RequestField = "Authorization" # :nodoc:
20
+ ResponseField = "WWW-Authenticate" # :nodoc:
21
+ ResponseInfoField = "Authentication-Info" # :nodoc:
22
+ AuthException = HTTPStatus::Unauthorized # :nodoc:
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
20
43
 
21
44
  private
22
45
 
46
+ # :stopdoc:
47
+
48
+ ##
49
+ # Initializes the authenticator from +config+
50
+
23
51
  def check_init(config)
24
52
  [:UserDB, :Realm].each{|sym|
25
53
  unless config[sym]
26
54
  raise ArgumentError, "Argument #{sym.inspect} missing."
27
55
  end
28
- }
56
+ }
29
57
  @realm = config[:Realm]
30
58
  @userdb = config[:UserDB]
31
59
  @logger = config[:Logger] || Log::new($stderr)
@@ -37,12 +65,15 @@ module WEBrick
37
65
  @auth_scheme = self::class::AuthScheme
38
66
  end
39
67
 
68
+ ##
69
+ # Ensures +req+ has credentials that can be authenticated.
70
+
40
71
  def check_scheme(req)
41
72
  unless credentials = req[@request_field]
42
73
  error("no credentials in the request.")
43
- return nil
44
- end
45
- unless match = /^#{@auth_scheme}\s+/.match(credentials)
74
+ return nil
75
+ end
76
+ unless match = /^#{@auth_scheme}\s+/i.match(credentials)
46
77
  error("invalid scheme in %s.", credentials)
47
78
  info("%s: %s", @request_field, credentials) if $DEBUG
48
79
  return nil
@@ -60,20 +91,26 @@ module WEBrick
60
91
  if @logger.error?
61
92
  log(:error, fmt, *args)
62
93
  end
63
- end
94
+ end
64
95
 
65
96
  def info(fmt, *args)
66
97
  if @logger.info?
67
98
  log(:info, fmt, *args)
68
99
  end
69
100
  end
101
+
102
+ # :startdoc:
70
103
  end
71
104
 
105
+ ##
106
+ # Module providing generic support for both Digest and Basic
107
+ # authentication schemes for proxies.
108
+
72
109
  module ProxyAuthenticator
73
- RequestField = "Proxy-Authorization"
74
- ResponseField = "Proxy-Authenticate"
75
- InfoField = "Proxy-Authentication-Info"
76
- AuthException = HTTPStatus::ProxyAuthenticationRequired
110
+ RequestField = "Proxy-Authorization" # :nodoc:
111
+ ResponseField = "Proxy-Authenticate" # :nodoc:
112
+ InfoField = "Proxy-Authentication-Info" # :nodoc:
113
+ AuthException = HTTPStatus::ProxyAuthenticationRequired # :nodoc:
77
114
  end
78
115
  end
79
116
  end