Skip to content

Instantly share code, notes, and snippets.

@arika
Created November 23, 2008 04:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arika/28033 to your computer and use it in GitHub Desktop.
Save arika/28033 to your computer and use it in GitHub Desktop.
rackup gonzui
# gonzui <http://gonzui.sf.net> wrapper for Rack
unless defined?(GONZUIRC)
GONZUIRC = File.expand_path('~/.gonzuirc')
end
require 'gonzui'
require 'gonzui/webapp'
class GonzuiWEBrickServletApp
class Request
def initialize(rack_req)
@req = rack_req
end
def self.map(sym, key)
define_method(sym) do
@req.env[key]
end
end
def self.map_var(sym)
map(sym, sym.to_s.upcase)
end
map_var :request_method
map_var :path_info
map :peeraddr, 'REMOTE_ADDR'
def query
@req.params
end
def accept_language
WEBrick::HTTPUtils.parse_qvalues(@req.env['HTTP_ACCEPT_LANGUAGE'])
end
def gzip_encoding_supported?
/\bgzip\b/.match(@req.env['HTTP_ACCEPT_ENCODING'])
end
end
class Response
def initialize(rack_resp, env)
@resp = rack_resp
@env = env
end
def body
@resp.body
end
def body=(body)
@resp.body = body
end
def [](key, value)
@resp[key]
end
def []=(key, value)
@resp[key] = value
end
def set_redirect(status, url)
@resp.status = status.code
self['Location'] = url.to_s
self.body = "<HTML><A HREF=\"#{url.to_s}\">#{url.to_s}</A>.</HTML>\n"
raise status
end
end
def initialize(servlet, *options)
@servlet = servlet
@config = options.first
@options = options
@bmp_patt = %r,(?:(?!\A)/)?#{Regexp.quote(@servlet.mount_point)}\z,
end
def call(env)
# gonzuiはgonzuircの:base_mount_pointの値を使って
# リンクを常にフルパスで生成する。
# Rackではスクリプトを/とする仮想的なパスを扱うため
# CGIやFastCGIでは一般にミスマッチが起きる
# (gonzui.{,f}cgiが/にマップされている場合は除く)。
# このため、SCRIPT_NAMEと:base_mount_pointが
# マッチしない場合に調整を行う。
# $stderr.puts [[[@config.base_mount_point,env['SCRIPT_NAME'],env['SCRIPT_NAME'].sub(@bmp_patt, '')]]].inspect
if !env['SCRIPT_NAME'].empty? &&
(bmp = env['SCRIPT_NAME'].sub(@bmp_patt, '')) != @config.base_mount_point
@config.base_mount_point = bmp
end
req = Rack::Request.new(env)
wreq = Request.new(req)
res = Rack::Response.new
wres = Response.new(res, env)
# WEBrickのHTTPサーバ機能は使わないため
# サーブレットにはデフォルト設定を与えておく。
si = @servlet.get_instance(WEBrick::Config::HTTP, *@options)
begin
si.service(wreq, wres)
rescue WEBrick::HTTPStatus::Redirect
# noop
rescue WEBrick::HTTPStatus::ClientError, WEBrick::HTTPStatus::ServerError
res.status = $!.code
res.body << $!.reason_phrase
# rescue WEBrick::HTTPStatus::Status
end
res.finish
end
end
class NullLogger
def log(*arg)
end
end
def build_gonzui_app
config = Gonzui::Config.new
config.load(GONZUIRC) if GONZUIRC
yield(config) if block_given?
catalog_repository = Gonzui::CatalogRepository.new(config.catalog_directory)
dbm = Gonzui::DBM.open(config, true)
null_logger = NullLogger.new
Rack::Builder.new do
# f = open(config.access_log_file + '.ru', 'a')
# use Rack::CommonLogger, f
use Rack::Recursive # URLMapを使う場合、これがないとCommonLogger上でパスが空になったりする。
# 本来はリクエストの内部回送をするときに使う。
Gonzui::GonzuiServlet.servlets.each do |klass|
# Rackがリクエストパスの調整をしてくれる。
# たとえばMongrelなら/の下に、CGIならSCRIPT_NAMEの下に、
# WEBrickでいうところのmountが行われる。
# このためgonzuircの:base_mount_pointに/fooを指定したとすると
# Mongrelなら/foo/statで統計情報に
# CGIなら/path/to/gonzui.cgi/statで統計情報にアクセスできる。
abs_mount_point = URI.path_join(config.base_mount_point, klass.mount_point)
map abs_mount_point do
if klass == Gonzui::FileHandler
run Rack::File.new(config.doc_directory)
else
run GonzuiWEBrickServletApp.new(klass, config, null_logger, dbm, catalog_repository)
end
end
end
end.to_app
end
#!/usr/bin/ruby
# this script executes gonzui as a cgi program.
ENV['HOME'] = '/path/to/home/of/gonzui/user'
#ENV['GEM_HOME'] = '/tmp/GEM'
require 'rubygems'
require 'rack'
require 'gonzui-rack'
gonzui_app = build_gonzui_app do |config|
# config.base_mount_point = ENV['SCRIPT_NAME']
end
handler = if /\.fcgi/ =~ __FILE__
Rack::Handler::FastCGI
else
Rack::Handler::CGI
end
handler.run gonzui_app
# rackup gonzui
require 'gonzui-rack'
run build_gonzui_app
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment