Class: Camping::FastCGI
- Inherits:
-
Object
- Object
- Camping::FastCGI
- Defined in:
- lib/camping/fastcgi.rb
Overview
fast.start
Constant Summary collapse
- CHUNK_SIZE =
(4 * 1024)
Class Method Summary collapse
-
.serve(path, index = nil) ⇒ Object
Serve an entire directory of Camping apps.
-
.start(app) ⇒ Object
A simple single-app starter mechanism.
Instance Method Summary collapse
-
#initialize ⇒ FastCGI
constructor
Creates a Camping::FastCGI class with empty mounts.
-
#mount(dir, app) ⇒ Object
Mounts a Camping application.
-
#start ⇒ Object
Starts the FastCGI main loop.
Constructor Details
#initialize ⇒ FastCGI
Creates a Camping::FastCGI class with empty mounts.
62 63 64 |
# File 'lib/camping/fastcgi.rb', line 62 def initialize @mounts = {} end |
Class Method Details
.serve(path, index = nil) ⇒ Object
Serve an entire directory of Camping apps. (See code.whytheluckystiff.net/camping/wiki/TheCampingServer.)
Use this method inside your FastCGI dispatcher:
#!/usr/local/bin/ruby
require 'rubygems'
require 'camping/fastcgi'
Camping::Models::Base.establish_connection :adapter => 'sqlite3', :database => "/path/to/db"
Camping::FastCGI.serve("/home/why/cvs/camping/examples")
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/camping/fastcgi.rb', line 161 def self.serve(path, index=nil) require 'camping/reloader' if File.directory? path fast = Camping::FastCGI.new script_load = proc do |script| app = Camping::Reloader.new(script) fast.mount("/#{app.mount}", app) app end Dir[File.join(path, '*.rb')].each &script_load fast.mount("/", index) if index fast.start do |dir, app| Dir[File.join(path, dir, '*.rb')].each do |script| smount = "/" + File.basename(script, '.rb') script_load[script] unless @mounts.has_key? smount end end else start(Camping::Reloader.new(path)) end end |
Instance Method Details
#mount(dir, app) ⇒ Object
Mounts a Camping application. The dir
being the name of the directory to serve as the application’s root. The app
is a Camping class.
67 68 69 70 71 |
# File 'lib/camping/fastcgi.rb', line 67 def mount(dir, app) dir.gsub!(/\/{2,}/, '/') dir.gsub!(/\/+$/, '') @mounts[dir] = app end |
#start ⇒ Object
Starts the FastCGI main loop.
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 |
# File 'lib/camping/fastcgi.rb', line 74 def start FCGI.each do |req| dir, app = nil begin root, path = "/" if ENV['FORCE_ROOT'] and ENV['FORCE_ROOT'].to_i == 1 path = req.env['REQUEST_URI'] else root = req.env['SCRIPT_NAME'] path = req.env['PATH_INFO'] end dir, app = @mounts.max { |a,b| match(path, a[0]) <=> match(path, b[0]) } unless dir and app dir, app = '/', Camping end yield dir, app if block_given? req.env['SERVER_SCRIPT_NAME'] = req.env['SCRIPT_NAME'] req.env['SERVER_PATH_INFO'] = req.env['PATH_INFO'] req.env['SCRIPT_NAME'] = File.join(root, dir) req.env['PATH_INFO'] = path.gsub(/^#{dir}/, '') controller = app.run(req.in, req.env) sendfile = nil headers = {} controller.headers.each do |k, v| if k =~ /^X-SENDFILE$/i and !ENV['SERVER_X_SENDFILE'] sendfile = v else headers[k] = v end end body = controller.body controller.body = "" controller.headers = headers req.out << controller.to_s if sendfile File.open(sendfile, "rb") do |f| while chunk = f.read(CHUNK_SIZE) and chunk.length > 0 req.out << chunk end end elsif body.respond_to? :read while chunk = body.read(CHUNK_SIZE) and chunk.length > 0 req.out << chunk end body.close if body.respond_to? :close else req.out << body.to_s end rescue Exception => e req.out << "Content-Type: text/html\r\n\r\n" + "<h1>Camping Problem!</h1>" + "<h2><strong>#{root}</strong>#{path}</h2>" + "<h3>#{e.class} #{esc e.}</h3>" + "<ul>" + e.backtrace.map { |bt| "<li>#{esc bt}</li>" }.join + "</ul>" + "<hr /><p>#{req.env.inspect}</p>" ensure req.finish end end end |