ry / ebb fork watch download tarball
public this repo is viewable by everyone
Description: web server
Homepage: http://ebb.rubyforge.org
Clone URL: git://github.com/ry/ebb.git
more small changes - ebb_rails working
Ryan Dahl (author)
2 months ago
commit  e371bdae561942f088985098dece7eed08e28e85
tree    6fbbea4761d38a1a69339089c99f93e15075882a
parent  85308837b343711aa4fbd9777bf7fb2bd8f5a033
...
30
31
32
 
33
34
35
...
30
31
32
33
34
35
36
0
@@ -30,6 +30,7 @@ spec = Gem::Specification.new do |s|
0
   s.homepage = 'http://repo.or.cz/w/ebb.git'
0
   s.version = File.read(dir("VERSION")).gsub(/\s/,'')
0
   s.requirements << 'none'
0
+ s.rubyforge_project = 'ebb'
0
   
0
   s.require_path = 'ruby_lib'
0
   s.extensions = 'src/extconf.rb'
...
1
2
3
4
 
 
 
 
 
 
 
 
5
6
7
...
13
14
15
 
16
17
18
...
52
53
54
55
 
56
57
58
...
1
2
 
3
4
5
6
7
8
9
10
11
12
13
14
...
20
21
22
23
24
25
26
...
60
61
62
 
63
64
65
66
0
@@ -1,7 +1,14 @@
0
 #!/usr/bin/env ruby
0
 require File.dirname(__FILE__) + '/../ruby_lib/ebb'
0
-require File.dirname(__FILE__) + '/../ruby_lib/rails_adapter'
0
 require 'optparse'
0
+require 'rubygems'
0
+require 'rack'
0
+
0
+module Rack
0
+ module Adapter
0
+ autoload :Rails, Ebb::LIBDIR + '/rack/adapter/rails'
0
+ end
0
+end
0
 
0
 options = {
0
   :root => Dir.pwd,
0
@@ -13,6 +20,7 @@ options = {
0
   :pid_file => 'tmp/pids/ebb.pid'
0
 }
0
 
0
+
0
 opts = OptionParser.new do |opts|
0
   opts.banner = "Usage: ebb_rails [options] start|stop"
0
 
0
@@ -52,7 +60,7 @@ end
0
 case ARGV[0]
0
   
0
 when 'start'
0
- app = RailsAdapter.new(options)
0
+ app = Rack::Adapter::Rails.new(options)
0
   server = Ebb::Server.new(app, options)
0
   
0
   server.pid_file = options[:pid_file]
...
76
77
78
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
80
81
...
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
...
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
...
132
133
134
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
135
136
137
0
@@ -76,6 +76,33 @@ module Ebb
0
       FFI::server_initialize(self)
0
     end
0
     
0
+ def start
0
+ trap('INT') { @running = false }
0
+
0
+ if @socket
0
+ raise NotImplemented
0
+ FFI::server_listen_on_socket(self, @socket) or raise "Problem listening on socket #{@socket}"
0
+ else
0
+ FFI::server_listen_on_port(self, @port) or raise "Problem listening on port #{@port}"
0
+ end
0
+ @waiting_clients = []
0
+
0
+ puts "Ebb listening at http://0.0.0.0:#{@port}/"
0
+
0
+ @running = true
0
+ while FFI::server_process_connections(self) and @running
0
+ unless @waiting_clients.empty?
0
+ if $DEBUG and @waiting_clients.length > 1
0
+ puts "#{@waiting_clients.length} waiting clients"
0
+ end
0
+ client = @waiting_clients.shift
0
+ process_client(client)
0
+ end
0
+ end
0
+ puts "Ebb unlistening"
0
+ FFI::server_unlisten(self)
0
+ end
0
+
0
     def process_client(client)
0
       begin
0
         status, headers, body = @app.call(client.env)
0
@@ -105,30 +132,6 @@ module Ebb
0
       end
0
       client.finished
0
     end
0
-
0
- def start
0
- trap('INT') { @running = false }
0
-
0
- if @socket
0
- raise NotImplemented
0
- FFI::server_listen_on_socket(self, @socket) or raise "Problem listening on socket #{@socket}"
0
- else
0
- FFI::server_listen_on_port(self, @port) or raise "Problem listening on port #{@port}"
0
- end
0
- @waiting_clients = []
0
-
0
- @running = true
0
- while FFI::server_process_connections(self) and @running
0
- unless @waiting_clients.empty?
0
- if $DEBUG and @waiting_clients.length > 1
0
- puts "#{@waiting_clients.length} waiting clients"
0
- end
0
- client = @waiting_clients.shift
0
- process_client(client)
0
- end
0
- end
0
- FFI::server_unlisten(self)
0
- end
0
   end
0
   
0
   HTTP_STATUS_CODES = {
...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
0
@@ -0,0 +1,152 @@
0
+require 'cgi'
0
+
0
+# Adapter to run a Rails app with any supported Rack handler.
0
+# By default it will try to load the Rails application in the
0
+# current directory in the development environment.
0
+# Options:
0
+# root: Root directory of the Rails app
0
+# env: Rails environment to run in (development, production or test)
0
+# Based on http://fuzed.rubyforge.org/ Rails adapter
0
+module Rack
0
+ module Adapter
0
+ class Rails
0
+ def initialize(options={})
0
+ @root = options[:root] || Dir.pwd
0
+ @env = options[:environment] || 'development'
0
+ @prefix = options[:prefix]
0
+
0
+ load_application
0
+
0
+ @file_server = Rack::File.new(::File.join(RAILS_ROOT, "public"))
0
+ end
0
+
0
+ def load_application
0
+ ENV['RAILS_ENV'] = @env
0
+
0
+ require "#{@root}/config/environment"
0
+ require 'dispatcher'
0
+
0
+ ActionController::AbstractRequest.relative_url_root = @prefix if @prefix
0
+ end
0
+
0
+ # TODO refactor this in File#can_serve?(path) ??
0
+ def file_exist?(path)
0
+ full_path = ::File.join(@file_server.root, Utils.unescape(path))
0
+ ::File.file?(full_path) && ::File.readable?(full_path)
0
+ end
0
+
0
+ def serve_file(env)
0
+ @file_server.call(env)
0
+ end
0
+
0
+ def serve_rails(env)
0
+ request = Request.new(env)
0
+ response = Response.new
0
+
0
+ session_options = ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS
0
+ cgi = CGIWrapper.new(request, response)
0
+
0
+ Dispatcher.dispatch(cgi, session_options, response)
0
+
0
+ response.finish
0
+ end
0
+
0
+ def call(env)
0
+ path = env['PATH_INFO'].chomp('/')
0
+ cached_path = (path.empty? ? 'index' : path) + ActionController::Base.page_cache_extension
0
+
0
+ if file_exist?(path) # Serve the file if it's there
0
+ serve_file(env)
0
+ elsif file_exist?(cached_path) # Serve the page cache if it's there
0
+ env['PATH_INFO'] = cached_path
0
+ serve_file(env)
0
+ else # No static file, let Rails handle it
0
+ serve_rails(env)
0
+ end
0
+ end
0
+
0
+ protected
0
+
0
+ class CGIWrapper < ::CGI
0
+ def initialize(request, response, *args)
0
+ @request = request
0
+ @response = response
0
+ @args = *args
0
+ @input = request.body
0
+
0
+ super *args
0
+ end
0
+
0
+ def header(options = "text/html")
0
+ if options.is_a?(String)
0
+ @response['Content-Type'] = options unless @response['Content-Type']
0
+ else
0
+ @response['Content-Length'] = options.delete('Content-Length').to_s if options['Content-Length']
0
+
0
+ @response['Content-Type'] = options.delete('type') || "text/html"
0
+ @response['Content-Type'] += "; charset=" + options.delete('charset') if options['charset']
0
+
0
+ @response['Content-Language'] = options.delete('language') if options['language']
0
+ @response['Expires'] = options.delete('expires') if options['expires']
0
+
0
+ @response.status = options.delete('Status') if options['Status']
0
+
0
+ # Convert 'cookie' header to 'Set-Cookie' headers.
0
+ # Because Set-Cookie header can appear more the once in the response body,
0
+ # we store it in a line break seperated string that will be translated to
0
+ # multiple Set-Cookie header by the handler.
0
+ if cookie = options.delete('cookie')
0
+ cookies = []
0
+
0
+ case cookie
0
+ when Array then cookie.each { |c| cookies << c.to_s }
0
+ when Hash then cookie.each { |_, c| cookies << c.to_s }
0
+ else cookies << cookie.to_s
0
+ end
0
+
0
+ @output_cookies.each { |c| cookies << c.to_s } if @output_cookies
0
+
0
+ @response['Set-Cookie'] = [@response['Set-Cookie'], cookies].compact.join("\n")
0
+ end
0
+
0
+ options.each { |k,v| @response[k] = v }
0
+ end
0
+
0
+ ""
0
+ end
0
+
0
+ def params
0
+ @params ||= @request.params
0
+ end
0
+
0
+ def cookies
0
+ @request.cookies
0
+ end
0
+
0
+ def query_string
0
+ @request.query_string
0
+ end
0
+
0
+ # Used to wrap the normal args variable used inside CGI.
0
+ def args
0
+ @args
0
+ end
0
+
0
+ # Used to wrap the normal env_table variable used inside CGI.
0
+ def env_table
0
+ @request.env
0
+ end
0
+
0
+ # Used to wrap the normal stdinput variable used inside CGI.
0
+ def stdinput
0
+ @input
0
+ end
0
+
0
+ def stdoutput
0
+ STDERR.puts "stdoutput should not be used."
0
+ @response.body
0
+ end
0
+ end
0
+ end
0
+ end
0
+end
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0
@@ -1,135 +0,0 @@
0
-# This as been submitted to Rack as a patch, tested and everything.
0
-# Bug Christian Neukirchen at chneukirchen@gmail.com to apply the patch!
0
-
0
-require 'cgi'
0
-require 'rubygems'
0
-require 'rack'
0
-
0
-# Adapter to run a Rails app with any supported Rack handler.
0
-# By default it will try to load the Rails application in the
0
-# current directory in the development environment.
0
-# Options:
0
-# root: Root directory of the Rails app
0
-# env: Rails environment to run in (development, production or test)
0
-# Based on http://fuzed.rubyforge.org/ Rails adapter
0
-class RailsAdapter
0
- def initialize(options={})
0
- @root = options[:root] || Dir.pwd
0
- @env = options[:env] || 'development'
0
-
0
- load_application
0
-
0
- @file_server = Rack::File.new(::File.join(RAILS_ROOT, "public"))
0
- end
0
-
0
- def load_application
0
- ENV['RAILS_ENV'] = @env
0
-
0
- require "#{@root}/config/environment"
0
- require 'dispatcher'
0
- end
0
-
0
- # TODO refactor this in File#can_serve?(path) ??
0
- def file?(path)
0
- full_path = ::File.join(@file_server.root, Utils.unescape(path))
0
- ::File.file?(full_path) && ::File.readable?(full_path)
0
- end
0
-
0
- def call(env)
0
- # Serve the file if it's there
0
- return @file_server.call(env) if file?(env['PATH_INFO'])
0
-
0
- request = Request.new(env)
0
- response = Response.new
0
-
0
- session_options = ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS
0
- cgi = CGIWrapper.new(request, response)
0
-
0
- Dispatcher.dispatch(cgi, session_options, response)
0
-
0
- response.finish
0
- end
0
-
0
- protected
0
-
0
- class CGIWrapper < ::CGI
0
- def initialize(request, response, *args)
0
- @request = request
0
- @response = response
0
- @args = *args
0
- @input = request.body
0
-
0
- super *args
0
- end
0
-
0
- def header(options = "text/html")
0
- if options.is_a?(String)
0
- @response['Content-Type'] = options unless @response['Content-Type']
0
- else
0
- @response['Content-Length'] = options.delete('Content-Length').to_s if options['Content-Length']
0
-
0
- @response['Content-Type'] = options.delete('type') || "text/html"
0
- @response['Content-Type'] += "; charset=" + options.delete('charset') if options['charset']
0
-
0
- @response['Content-Language'] = options.delete('language') if options['language']
0
- @response['Expires'] = options.delete('expires') if options['expires']
0
-
0
- @response.status = options.delete('Status') if options['Status']
0
-
0
- options.each { |k,v| @response[k] = v }
0
-
0
- # Convert 'cookie' header to 'Set-Cookie' headers.
0
- # According to http://www.faqs.org/rfcs/rfc2109.html:
0
- # the Set-Cookie response header comprises the token
0
- # Set-Cookie:, followed by a comma-separated list of
0
- # one or more cookies.
0
- if cookie = @response.header.delete('Cookie')
0
- cookies = case cookie
0
- when Array then cookie.collect { |c| c.to_s }.join(', ')
0
- when Hash then cookie.collect { |_, c| c.to_s }.join(', ')
0
- else cookie.to_s
0
- end
0
-
0
- cookies << ', ' + @output_cookies.each { |c| c.to_s }.join(', ') if @output_cookies
0
-
0
- @response['Set-Cookie'] = cookies
0
- end
0
- end
0
-
0
- ""
0
- end
0
-
0
- def params
0
- @params ||= @request.params
0
- end
0
-
0
- def cookies
0
- @request.cookies
0
- end
0
-
0
- def query_string
0
- @request.query_string
0
- end
0
-
0
- # Used to wrap the normal args variable used inside CGI.
0
- def args
0
- @args
0
- end
0
-
0
- # Used to wrap the normal env_table variable used inside CGI.
0
- def env_table
0
- @request.env
0
- end
0
-
0
- # Used to wrap the normal stdinput variable used inside CGI.
0
- def stdinput
0
- @input
0
- end
0
-
0
- def stdoutput
0
- STDERR.puts "stdoutput should not be used."
0
- @response.body
0
- end
0
- end
0
-end
0
-

Comments

    No one has commented yet.