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.
- checksums.yaml +14 -6
- data/.travis.yml +5 -6
- data/lib/rubysl/webrick/version.rb +1 -1
- data/lib/rubysl/webrick/webrick.rb +199 -2
- data/lib/webrick/accesslog.rb +96 -5
- data/lib/webrick/cgi.rb +80 -29
- data/lib/webrick/compat.rb +20 -0
- data/lib/webrick/config.rb +59 -5
- data/lib/webrick/cookie.rb +66 -5
- data/lib/webrick/htmlutils.rb +4 -1
- data/lib/webrick/httpauth.rb +53 -3
- data/lib/webrick/httpauth/authenticator.rb +53 -16
- data/lib/webrick/httpauth/basicauth.rb +45 -2
- data/lib/webrick/httpauth/digestauth.rb +82 -17
- data/lib/webrick/httpauth/htdigest.rb +38 -1
- data/lib/webrick/httpauth/htgroup.rb +32 -0
- data/lib/webrick/httpauth/htpasswd.rb +40 -2
- data/lib/webrick/httpauth/userdb.rb +27 -4
- data/lib/webrick/httpproxy.rb +197 -112
- data/lib/webrick/httprequest.rb +268 -50
- data/lib/webrick/httpresponse.rb +170 -33
- data/lib/webrick/https.rb +26 -3
- data/lib/webrick/httpserver.rb +75 -7
- data/lib/webrick/httpservlet/abstract.rb +88 -6
- data/lib/webrick/httpservlet/cgi_runner.rb +5 -4
- data/lib/webrick/httpservlet/cgihandler.rb +37 -18
- data/lib/webrick/httpservlet/erbhandler.rb +40 -7
- data/lib/webrick/httpservlet/filehandler.rb +116 -28
- data/lib/webrick/httpservlet/prochandler.rb +17 -4
- data/lib/webrick/httpstatus.rb +86 -18
- data/lib/webrick/httputils.rb +131 -23
- data/lib/webrick/httpversion.rb +28 -2
- data/lib/webrick/log.rb +72 -5
- data/lib/webrick/server.rb +158 -33
- data/lib/webrick/ssl.rb +78 -9
- data/lib/webrick/utils.rb +151 -5
- data/lib/webrick/version.rb +5 -1
- data/rubysl-webrick.gemspec +0 -1
- metadata +12 -24
data/lib/webrick/compat.rb
CHANGED
@@ -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
|
data/lib/webrick/config.rb
CHANGED
@@ -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
|
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
|
-
:
|
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,
|
data/lib/webrick/cookie.rb
CHANGED
@@ -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
|
-
|
19
|
-
|
20
|
-
|
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
|
-
|
54
|
-
#
|
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)
|
data/lib/webrick/htmlutils.rb
CHANGED
@@ -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, '&')
|
data/lib/webrick/httpauth.rb
CHANGED
@@ -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,
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
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
|