webricknio 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,26 @@
1
+ Copyright (c) 2012, Pradeep Singh (pradeep ... pradeeplogs .. com)
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice, this
8
+ list of conditions and the following disclaimer.
9
+
10
+ * Redistributions in binary form must reproduce the above copyright notice,
11
+ this list of conditions and the following disclaimer in the documentation
12
+ and/or other materials provided with the distribution.
13
+
14
+ * The name Pradeep Singh may not be used to endorse or promote products
15
+ derived from this software without specific prior written permission.
16
+
17
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20
+ DISCLAIMED. IN NO EVENT SHALL PRADEEP SINGH BE LIABLE FOR ANY DIRECT,
21
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
24
+ OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.md ADDED
@@ -0,0 +1,58 @@
1
+ **Summary** -
2
+
3
+ Use WEBrickNIO as highly scalable server for JRuby apps. Taking advantage of JRuby, WEBrick’s code has been littered with Java NIO code and the result is WEBrickNIO. epoll and thread pool have been added to WEBrickNIO so that it uses the same technology that make eventmachine and nginx so scalable.
4
+
5
+ - - -
6
+
7
+ **Installation** -
8
+
9
+ In your Gemfile -
10
+
11
+ gem "webricknio", "~> 0.5.0"
12
+
13
+ then -
14
+
15
+ bundle install
16
+
17
+ This will install webricknio-{version}.gem
18
+
19
+ To run, at your rails root -
20
+
21
+ rails s wnio
22
+
23
+ To get the configuration file in your config directory -
24
+
25
+ rails g webricknio - this creates a file webricknio.rb in the 'config' directory (not in config/initialzers)
26
+
27
+ Some properties of inerest in the config file -
28
+
29
+ :LogLevel => ::WEBrick::Log::DEBUG
30
+
31
+ :NumThreads => 10,
32
+
33
+ These properties are all overriden by command line options.
34
+
35
+ Currently, it does not support file uploads and websockets. With the addition of these two it will be ready to move to version 1.0
36
+
37
+ Use it by itself,
38
+
39
+ or behind nginx -
40
+
41
+ upstream www.server.com {
42
+ server 127.0.0.1:3002;
43
+ keepalive 8;
44
+ }
45
+
46
+ server {
47
+ listen 80
48
+ server_name .server.com;
49
+
50
+ location / {
51
+ proxy_pass http://www.server.com;
52
+ proxy_http_version 1.1;
53
+ proxy_set_header Connection "";
54
+ }
55
+ }
56
+
57
+
58
+
@@ -0,0 +1,8 @@
1
+ Description:
2
+ Generates a configuration file for WebrickNIO
3
+
4
+ Example:
5
+ rails generate webricknio
6
+
7
+ This will create a file config/webricknio.rb
8
+
@@ -0,0 +1,57 @@
1
+ #--
2
+ # webricknio.rb
3
+ #
4
+ # Author: Pradeep Singh
5
+ # Copyright (c) 2012 Pradeep Singh
6
+ # All rights reserved.
7
+
8
+ General = {
9
+ :ServerName => ::WEBrick::Utils::getservername,
10
+ :BindAddress => nil, # "0.0.0.0" or "::" or nil
11
+ :Port => nil, # users MUST specify this!!
12
+ :MaxClients => 100, # maximum number of the concurrent connections
13
+ :ServerType => nil, # default: WEBrick::SimpleServer
14
+ :Logger => nil, # default: WEBrick::Log.new
15
+ #:ServerSoftware => "WEBrickNIO/#{WEBrickNIO::VERSION} " +
16
+ # "(Ruby/#{RUBY_VERSION}/#{RUBY_RELEASE_DATE})",
17
+ :ServerSoftware => "pks/#{WEBrickNIO::VERSION} ",
18
+ :TempDir => ENV['TMPDIR']||ENV['TMP']||ENV['TEMP']||'/tmp',
19
+ :DoNotListen => false,
20
+ :StartCallback => nil,
21
+ :StopCallback => nil,
22
+ :AcceptCallback => nil,
23
+ :DoNotReverseLookup => nil,
24
+ :ShutdownSocketWithoutClose => false,
25
+ }
26
+
27
+ HTTP = General.dup.update(
28
+ :Port => 80,
29
+ :RequestTimeout => 5,
30
+ :NumThreads => 20,
31
+ :HTTPVersion => ::WEBrick::HTTPVersion.new("1.1"),
32
+ :AccessLog => nil,
33
+ :LogLocation => nil, #"log/webrick.log"
34
+ :LogLevel => ::WEBrick::Log::INFO,
35
+ :MimeTypes => ::WEBrick::HTTPUtils::DefaultMimeTypes,
36
+ :DirectoryIndex => ["index.html","index.htm","index.cgi","index.rhtml"],
37
+ :DocumentRoot => nil,
38
+ :DocumentRootOptions => { :FancyIndexing => true },
39
+ :RequestCallback => nil,
40
+ :ServerAlias => nil,
41
+ :InputBufferSize => 65536, # input buffer size in reading request body
42
+ :OutputBufferSize => 65536, # output buffer size in sending File or IO
43
+
44
+ # for HTTPProxyServer
45
+ :ProxyAuthProc => nil,
46
+ :ProxyContentHandler => nil,
47
+ :ProxyVia => true,
48
+ :ProxyTimeout => true,
49
+ :ProxyURI => nil,
50
+
51
+ :CGIInterpreter => nil,
52
+ :CGIPathEnv => nil,
53
+
54
+ # workaround: if Request-URIs contain 8bit chars,
55
+ # they should be escaped before calling of URI::parse().
56
+ :Escape8bitURI => false
57
+ )
@@ -0,0 +1,15 @@
1
+ #--
2
+ # webricknio_generator.rb
3
+ #
4
+ # Author: Pradeep Singh
5
+ # Copyright (c) 2012 Pradeep Singh
6
+ # All rights reserved.
7
+
8
+ class WebricknioGenerator < Rails::Generators::Base
9
+ source_root File.expand_path('../', __FILE__)
10
+
11
+ def copy_initializer_file
12
+ copy_file "webricknio.rb", "config/webricknio.rb"
13
+ end
14
+
15
+ end
@@ -0,0 +1,88 @@
1
+ #--
2
+ # webricknio.rb
3
+ #
4
+ # Author: others and Pradeep Singh
5
+ # Copyright (c) 2012 Pradeep Singh
6
+ # All rights reserved.
7
+
8
+ require 'webricknio'
9
+ require 'stringio'
10
+ require 'rack/content_length'
11
+
12
+ module Rack
13
+ module Handler
14
+ class WEBrickNIO < ::WEBrick::HTTPServlet::AbstractServlet
15
+ def self.run(app, options={})
16
+ options[:BindAddress] = options.delete(:Host) if options[:Host]
17
+ @server = ::WEBrickNIO::HTTPServer.new(options)
18
+ @server.mount "/", ::Rack::Handler::WEBrickNIO, app
19
+ yield @server if block_given?
20
+ @server.start
21
+ end
22
+
23
+ def self.valid_options
24
+ {
25
+ "Host=HOST" => "Hostname to listen on (default: localhost)",
26
+ "Port=PORT" => "Port to listen on (default: 8080)",
27
+ }
28
+ end
29
+
30
+ def self.shutdown
31
+ @server.shutdown
32
+ @server = nil
33
+ end
34
+
35
+ def initialize(server, app)
36
+ #super server
37
+ @app = app
38
+ end
39
+
40
+ def service(req, res)
41
+ env = req.meta_vars
42
+ env.delete_if { |k, v| v.nil? }
43
+
44
+ rack_input = StringIO.new(req.body.to_s)
45
+ rack_input.set_encoding(Encoding::BINARY) if rack_input.respond_to?(:set_encoding)
46
+
47
+ env.update({"rack.version" => Rack::VERSION,
48
+ "rack.input" => rack_input,
49
+ "rack.errors" => $stderr,
50
+
51
+ "rack.multithread" => true,
52
+ "rack.multiprocess" => false,
53
+ "rack.run_once" => false,
54
+
55
+ "rack.url_scheme" => ["yes", "on", "1"].include?(ENV["HTTPS"]) ? "https" : "http"
56
+ })
57
+
58
+ env["HTTP_VERSION"] ||= env["SERVER_PROTOCOL"]
59
+ env["QUERY_STRING"] ||= ""
60
+ unless env["PATH_INFO"] == ""
61
+ path, n = req.request_uri.path, env["SCRIPT_NAME"].length
62
+ env["PATH_INFO"] = path[n, path.length-n]
63
+ end
64
+ env["REQUEST_PATH"] ||= [env["SCRIPT_NAME"], env["PATH_INFO"]].join
65
+
66
+ status, headers, body = @app.call(env)
67
+ begin
68
+ res.status = status.to_i
69
+ headers.each { |k, vs|
70
+ if k.downcase == "set-cookie"
71
+ res.cookies.concat vs.split("\n")
72
+ else
73
+ # Since WEBrick won't accept repeated headers,
74
+ # merge the values per RFC 1945 section 4.2.
75
+ res[k] = vs.split("\n").join(", ")
76
+ end
77
+ }
78
+ body.each { |part|
79
+ res.body << part
80
+ }
81
+ ensure
82
+ body.close if body.respond_to? :close
83
+ end
84
+ end
85
+
86
+ end
87
+ end
88
+ end
data/lib/webricknio.rb ADDED
@@ -0,0 +1,237 @@
1
+ ##
2
+ # = WEB server toolkit.
3
+ #
4
+ # WEBrick is an HTTP server toolkit that can be configured as an HTTPS server,
5
+ # a proxy server, and a virtual-host server. WEBrick features complete
6
+ # logging of both server operations and HTTP access. WEBrick supports both
7
+ # basic and digest authentication in addition to algorithms not in RFC 2617.
8
+ #
9
+ # A WEBrick servers can be composed of multiple WEBrick servers or servlets to
10
+ # provide differing behavior on a per-host or per-path basis. WEBrick
11
+ # includes servlets for handling CGI scripts, ERb pages, ruby blocks and
12
+ # directory listings.
13
+ #
14
+ # WEBrick also includes tools for daemonizing a process and starting a process
15
+ # at a higher privilege level and dropping permissions.
16
+ #
17
+ # == Starting an HTTP server
18
+ #
19
+ # To create a new WEBrick::HTTPServer that will listen to connections on port
20
+ # 8000 and serve documents from the current user's public_html folder:
21
+ #
22
+ # require 'webrick'
23
+ #
24
+ # root = File.expand_path '~/public_html'
25
+ # server = WEBrick::HTTPServer.new :Port => 8000, :DocumentRoot => root
26
+ #
27
+ # To run the server you will need to provide a suitable shutdown hook as
28
+ # starting the server blocks the current thread:
29
+ #
30
+ # trap 'INT' do server.shutdown end
31
+ #
32
+ # server.start
33
+ #
34
+ # == Custom Behavior
35
+ #
36
+ # The easiest way to have a server perform custom operations is through
37
+ # WEBrick::HTTPServer#mount_proc. The block given will be called with a
38
+ # WEBrick::HTTPRequest with request info and a WEBrick::HTTPResponse which
39
+ # must be filled in appropriately:
40
+ #
41
+ # server.mount_proc '/' do |req, res|
42
+ # res.body = 'Hello, world!'
43
+ # end
44
+ #
45
+ # Remember that <tt>server.mount_proc</tt> must <tt>server.start</tt>.
46
+ #
47
+ # == Servlets
48
+ #
49
+ # Advanced custom behavior can be obtained through mounting a subclass of
50
+ # WEBrick::HTTPServlet::AbstractServlet. Servlets provide more modularity
51
+ # when writing an HTTP server than mount_proc allows. Here is a simple
52
+ # servlet:
53
+ #
54
+ # class Simple < WEBrick::HTTPServlet::AbstractServlet
55
+ # def do_GET request, response
56
+ # status, content_type, body = do_stuff_with request
57
+ #
58
+ # response.status = 200
59
+ # response['Content-Type'] = 'text/plain'
60
+ # response.body = 'Hello, World!'
61
+ # end
62
+ # end
63
+ #
64
+ # To initialize the servlet you mount it on the server:
65
+ #
66
+ # server.mount '/simple', Simple
67
+ #
68
+ # See WEBrick::HTTPServlet::AbstractServlet for more details.
69
+ #
70
+ # == Virtual Hosts
71
+ #
72
+ # A server can act as a virtual host for multiple host names. After creating
73
+ # the listening host, additional hosts that do not listen can be created and
74
+ # attached as virtual hosts:
75
+ #
76
+ # server = WEBrick::HTTPServer.new # ...
77
+ #
78
+ # vhost = WEBrick::HTTPServer.new :ServerName => 'vhost.example',
79
+ # :DoNotListen => true, # ...
80
+ # vhost.mount '/', ...
81
+ #
82
+ # server.virtual_host vhost
83
+ #
84
+ # If no +:DocumentRoot+ is provided and no servlets or procs are mounted on the
85
+ # main server it will return 404 for all URLs.
86
+ #
87
+ # == HTTPS
88
+ #
89
+ # To create an HTTPS server you only need to enable SSL and provide an SSL
90
+ # certificate name:
91
+ #
92
+ # require 'webrick'
93
+ # require 'webrick/https'
94
+ #
95
+ # cert_name = [
96
+ # %w[CN localhost],
97
+ # ]
98
+ #
99
+ # server = WEBrick::HTTPServer.new(:Port => 8000,
100
+ # :SSLEnable => true,
101
+ # :SSLCertName => cert_name)
102
+ #
103
+ # This will start the server with a self-generated self-signed certificate.
104
+ # The certificate will be changed every time the server is restarted.
105
+ #
106
+ # To create a server with a pre-determined key and certificate you can provide
107
+ # them:
108
+ #
109
+ # require 'webrick'
110
+ # require 'webrick/https'
111
+ # require 'openssl'
112
+ #
113
+ # cert = OpenSSL::X509::Certificate.new File.read '/path/to/cert.pem'
114
+ # pkey = OpenSSL::PKey::RSA.new File.read '/path/to/pkey.pem'
115
+ #
116
+ # server = WEBrick::HTTPServer.new(:Port => 8000,
117
+ # :SSLEnable => true,
118
+ # :SSLCertificate => cert,
119
+ # :SSLPrivateKey => pkey)
120
+ #
121
+ # == Proxy Server
122
+ #
123
+ # WEBrick can act as a proxy server:
124
+ #
125
+ # require 'webrick'
126
+ # require 'webrick/httpproxy'
127
+ #
128
+ # proxy = WEBrick::HTTPProxyServer.new :Port => 8000
129
+ #
130
+ # trap 'INT' do proxy.shutdown end
131
+ #
132
+ # Proxies may modifier the content of the response through the
133
+ # +:ProxyContentHandler+ callback which will be invoked with the request and
134
+ # respone after the remote content has been fetched.
135
+ #
136
+ # == Basic and Digest authentication
137
+ #
138
+ # WEBrick provides both Basic and Digest authentication for regular and proxy
139
+ # servers. See WEBrick::HTTPAuth, WEBrick::HTTPAuth::BasicAuth and
140
+ # WEBrick::HTTPAuth::DigestAuth.
141
+ #
142
+ # == WEBrick as a Production Web Server
143
+ #
144
+ # WEBrick can be run as a production server for small loads.
145
+ #
146
+ # === Daemonizing
147
+ #
148
+ # To start a WEBrick server as a daemon simple run WEBrick::Daemon.start
149
+ # before starting the server.
150
+ #
151
+ # === Dropping Permissions
152
+ #
153
+ # WEBrick can be started as one user to gain permission to bind to port 80 or
154
+ # 443 for serving HTTP or HTTPS traffic then can drop these permissions for
155
+ # regular operation. To listen on all interfaces for HTTP traffic:
156
+ #
157
+ # sockets = WEBrick::Utils.create_listeners nil, 80
158
+ #
159
+ # Then drop privileges:
160
+ #
161
+ # WEBrick::Utils.su 'www'
162
+ #
163
+ # Then create a server that does not listen by default:
164
+ #
165
+ # server = WEBrick::HTTPServer.new :DoNotListen => true, # ...
166
+ #
167
+ # Then overwrite the listening sockets with the port 80 sockets:
168
+ #
169
+ # server.listeners.replace sockets
170
+ #
171
+ # === Logging
172
+ #
173
+ # WEBrick can separately log server operations and end-user access. For
174
+ # server operations:
175
+ #
176
+ # log_file = File.open '/var/log/webrick.log', 'a+'
177
+ # log = WEBrick::Log.new log_file
178
+ #
179
+ # For user access logging:
180
+ #
181
+ # access_log = [
182
+ # [log_file, WEBrick::AccessLog::COMBINED_LOG_FORMAT],
183
+ # ]
184
+ #
185
+ # server = WEBrick::HTTPServer.new :Logger => log, :AccessLog => access_log
186
+ #
187
+ # See WEBrick::AccessLog for further log formats.
188
+ #
189
+ # === Log Rotation
190
+ #
191
+ # To rotate logs in WEBrick on a HUP signal (like syslogd can send), open the
192
+ # log file in 'a+' mode (as above) and trap 'HUP' to reopen the log file:
193
+ #
194
+ # trap 'HUP' do log_file.reopen '/path/to/webrick.log', 'a+'
195
+ #
196
+ # == Copyright
197
+ #
198
+ # Author: IPR -- Internet Programming with Ruby -- writers, Pradeep Singh
199
+ #
200
+ # Copyright (c) 2000 TAKAHASHI Masayoshi, GOTOU YUUZOU
201
+ # Copyright (c) 2002 Internet Programming with Ruby writers
202
+ # Copyright (c) 2012 Pradeep Singh
203
+ # All rights reserved.
204
+ #--
205
+ # $IPR: webrick.rb,v 1.12 2002/10/01 17:16:31 gotoyuzo Exp $
206
+
207
+ module WEBrickNIO
208
+ end
209
+
210
+ require 'webrick/compat.rb'
211
+
212
+ require 'webricknio/version'
213
+ require 'webricknio/config'
214
+ require 'webrick/log.rb'
215
+ require 'webricknio/log'
216
+ require 'webrick/utils.rb'
217
+ require 'webricknio/accesslog'
218
+
219
+ require 'webrick/htmlutils.rb'
220
+ require 'webrick/httputils.rb'
221
+ require 'webrick/cookie.rb'
222
+ require 'webrick/httpversion.rb'
223
+ require 'webrick/httpstatus.rb'
224
+ require 'webricknio/httprequest'
225
+ require 'webricknio/httpresponse'
226
+ require 'webricknio/httpserver'
227
+ require 'webrick/httpservlet.rb'
228
+ require 'webrick/httpauth.rb'
229
+
230
+ require 'rack/handler'
231
+
232
+ if defined?(Rails) && defined?(Rails::Generators)
233
+ require 'generator/webricknio_generator'
234
+ end
235
+
236
+ Rack::Handler::autoload :WEBrickNIO, "rack/handler/webricknio"
237
+ Rack::Handler::register 'wnio', 'Rack::Handler::WEBrickNIO'