Skip to content

Instantly share code, notes, and snippets.

@yuja
Created October 13, 2012 17:34
Show Gist options
  • Save yuja/3885479 to your computer and use it in GitHub Desktop.
Save yuja/3885479 to your computer and use it in GitHub Desktop.
Run Kagemai 0.8.8 as a Rack application
# -*- mode: ruby -*-
=begin
config.ru - Run KAGEMAI 0.8.8 as a Rack application (under Ruby 1.8.7)
Initialization codes are borrowed from html/guest.cgi, which is
copyright (c) 2002-2008 FUKUOKA Tomoyuki, DAIFUKUYA.
=end
$KCODE = 'e'
$SAFE = 1
$SHOW_ENV_VARS = false # debug
$KAGEMAI_DEBUG = false # debug
kagemai_root = File.dirname(File.expand_path(__FILE__)).untaint
config_file = "#{kagemai_root}/kagemai.conf"
$:.unshift "#{kagemai_root}/lib"
require 'kagemai/config'
Kagemai::Config.initialize(kagemai_root, config_file)
require 'kagemai/kagemai'
require 'kagemai/mode'
require 'kagemai/kcgi'
require 'kagemai/kconv'
require 'kagemai/util'
module Kagemai
module RackActionResultHelper
def parse_http_header(str)
headers = {}
str.each_line do |l|
k, v = l.strip.split(/\s*:\s*/, 2)
next unless k
if headers.include? k # e.g. Set-Cookie may appear more than once
headers[k] << "\n" << v
else
headers[k] = v
end
end
status = pop_status_from_headers headers
[status, headers]
end
module_function :parse_http_header
def pop_status_from_headers(headers)
if headers.include? 'Status'
headers.delete('Status').to_i
elsif headers.include? 'Location'
302
else
200
end
end
module_function :pop_status_from_headers
end
class RawActionResult
include RackActionResultHelper
def rack_response(cgi, flush_log, show_env)
status, headers = parse_http_header(@header)
[status, headers, [@body]]
end
end
class ActionResult
include RackActionResultHelper
def rack_response(cgi, flush_log, show_env)
body = http_body(cgi, flush_log, show_env)
status, headers = parse_http_header(http_header(cgi, body.size))
[status, headers, [body]]
end
end
class RedirectActionResult
include RackActionResultHelper
def rack_response(cgi, flush_log, show_env)
status, headers = parse_http_header(http_header(cgi))
[status, headers, []]
end
end
class Download < Action
class DownloadActionResult
include RackActionResultHelper
def rack_response(cgi, flush_log, show_env)
status, headers = parse_http_header(http_header(cgi, @file.stat.size))
[status, headers, @file]
end
end
end
class RackCGI < CGI
attr_reader :env_table, :stdinput
def initialize(tag_maker, env)
@env_table = env.reject { |k, v| k =~ /^rack\./ }
@stdinput = env.fetch('rack.input')
super tag_maker
end
def stdoutput
raise 'oops! #stdoutput called'
end
end
class RackApplication
def initialize(mode, debug = false, show_env = false)
@mode = mode
@debug = debug
@show_env = show_env
end
def call(env)
cgi = RackCGI.new('html4Tr', env)
kcgi = KCGI.new(cgi)
begin
capp = CGIApplication.new(kcgi, @mode)
result = capp.action()
result.rack_response(kcgi, @debug, @show_env)
rescue Kagemai::Error => e
make_error_response(e)
ensure
kcgi.close
end
end
def make_error_response(error)
body = []
body << '<HTML><HEAD>'
body << '<LINK href="kagemai.css" rel="stylesheet" type="text/css">'
body << "<TITLE>#{error.class.to_s}</TITLE>"
body << '</HEAD><BODY>'
body << '<p class="error">Following errors occurred.</p>'
body << "<pre>#{error.class}: "
body << "#{KKconv.conv(error.to_s, KKconv::EUC).escape_h}</pre>"
body << %Q!<pre>#{error.backtrace.join("\r\n")}</pre>! if @debug
body << '</BODY></HTML>'
headers = {
'Content-Type' => 'text/html; charset=EUC-JP',
'Content-Language' => Config[:language],
}
[200, headers, body]
end
private :make_error_response
end
end
use Rack::Static, :urls => %w|/kagemai.css /wallpaper.gif|, :root => 'html'
%w|admin guest user|.each do |name|
map "/#{name}.cgi" do
mode = Kagemai::Mode.const_get(name.upcase)
run Kagemai::RackApplication.new(mode, $KAGEMAI_DEBUG, $SHOW_ENV_VARS)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment