From 26d550bc3512b5f9ac96109bded8e9b9a3e04bd3 Mon Sep 17 00:00:00 2001 From: makoto kuwata Date: Fri, 25 Feb 2011 06:55:03 +0900 Subject: [change] rewrite 'contrib/index.cgi' entirely --- contrib/index.cgi | 166 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 109 insertions(+), 57 deletions(-) mode change 100644 => 100755 contrib/index.cgi diff --git a/contrib/index.cgi b/contrib/index.cgi old mode 100644 new mode 100755 index 6a7b67c..f38f7fd --- a/contrib/index.cgi +++ b/contrib/index.cgi @@ -9,6 +9,10 @@ ## add directory path where Erubis installed #$LOAD_PATH << "/home/yourname/lib/ruby" +## configuration +$ENCODING = nil +$LAYOUT = '_layout.rhtml' + ## load Erubis begin require 'erubis' @@ -20,16 +24,11 @@ rescue LoadError => ex print "Status: 500 Internal Server Error\r\n" print "Content-Type: text/plain\r\n" print "\r\n" - print "ERROR: #{ex.message}" + print "LoadError: #{ex.message}" exit end end -include Erubis::XmlHelper -## configuration -ERUBY = Erubis::Eruby # or Erubis::EscapeEruby -@encoding = nil -@layout = '_layout.rhtml' ## helper class to represent http error class HttpError < Exception @@ -41,59 +40,112 @@ class HttpError < Exception end -## main -begin +class ErubisHandler + include Erubis::XmlHelper + + ERUBY = Erubis::Eruby # or Erubis::EscapeEruby + + def initialize + @encoding = $ENCODING + @layout = $LAYOUT + end + + attr_accessor :encoding, :layout - ## check environment variables - document_root = ENV['DOCUMENT_ROOT'] or raise "ENV['DOCUMENT_ROOT'] is not set." - request_uri = ENV['REQUEST_URI'] or raise "ENV['REQUEST_URI'] is not set." - ## get filepath - basepath = request_uri.split(/\?/, 2).first - filepath = basepath =~ /\A\/(~[-.\w]+)/ \ - ? File.join(File.expand_path($1), "public_html", $') \ - : File.join(document_root, basepath) - filepath.gsub!(/\.html\z/, '.rhtml') or # expected '*.html' - raise HttpError.new('500 Internal Error', 'invalid .htaccess configuration.') - File.file?(filepath) or # file not found - raise HttpError.new('404 Not Found', "#{basepath}: not found.") - basepath != ENV['SCRIPT_NAME'] or # can't access to index.cgi - raise HttpError.new('403 Forbidden', "#{basepath}: not accessable.") - ## process as eRuby file - #eruby = ERUBY.new(File.read(filepath)) # not create cache file (slower) - eruby = ERUBY.load_file(filepath) # create cache file (faster) - html = eruby.result() - ## use layout template - if @layout && File.file?(@layout) - @content = html - html = ERUBY.load_file(@layout).result() + def handle(env) + ## check environment variables + document_root = env['DOCUMENT_ROOT'] or raise "ENV['DOCUMENT_ROOT'] is not set." + request_uri = env['REQUEST_URI'] or raise "ENV['REQUEST_URI'] is not set." + ## get filepath + basepath = request_uri.split(/\?/, 2).first + filepath = basepath =~ /\A\/(~[-.\w]+)/ \ + ? File.join(File.expand_path($1), "public_html", $') \ + : File.join(document_root, basepath) + filepath.gsub!(/\.html\z/, '.rhtml') or # expected '*.html' + raise HttpError.new(500, 'invalid .htaccess configuration.') + File.file?(filepath) or # file not found + raise HttpError.new(404, "#{basepath}: not found.") + basepath != env['SCRIPT_NAME'] or # can't access to index.cgi + raise HttpError.new(403, "#{basepath}: not accessable.") + ## process as eRuby file + #eruby = ERUBY.new(File.read(filepath)) # not create cache file (slower) + eruby = ERUBY.load_file(filepath) # create cache file (faster) + html = eruby.evaluate(self) + ## use layout template + if @layout && File.file?(@layout) + @content = html + html = ERUBY.load_file(@layout).evaluate(self) + end + return html end - ## send response - print @encoding \ - ? "Content-Type: text/html; charset=#{@encoding}\r\n" \ - : "Content-Type: text/html\r\n" - print "Content-Length: #{html.length}\r\n" - print "\r\n" - print html - -rescue HttpError => ex - ## handle http error (such as 404 Not Found) - print "Status: #{ex.status}\r\n" - print "Content-Type: text/html\r\n" - print "\r\n" - print "

#{h(ex.status)}

\n" - print "

#{h(ex.message)}

" - -rescue Exception => ex - ## print exception backtrace - print "Status: 500 Internal Server Error\r\n" - print "Content-Type: text/html\r\n" - print "\r\n" - arr = ex.backtrace - print "
\n"
-  print   "#{h(arr[0])}: #{h(ex.message)} (#{h(ex.class.name)})\n"
-  arr[1..-1].each do |item|
-    print "        from #{h(item)}\n"
+
+end
+
+
+class ErubisApplication
+  include Erubis::XmlHelper
+
+  RESPONSE_STATUS = {
+    200 => "200 OK",
+    403 => "Forbidden",
+    404 => "404 Not Found",
+    500 => "500 Internal Server Error",
+  }
+
+  protected
+
+  def get_handler
+    return ErubisHandler.new()
   end
-  print   "
\n" + def handle_request(env) + handler = get_handler() + output = handler.handle(env) + cont_type = "text/html" + cont_type << ";charset=#{handler.encoding}" if handler.encoding + return [200, [["Content-Type", cont_type]], [output]] + end + + def handle_http_error(ex) + output = "

#{h(RESPONSE_STATUS[ex.status])}

\n

#{h(ex.message)}

\n" + return [ex.status, [["Content-Type", "text/html"]], [output]] + end + + def handle_error(ex) + arr = ex.backtrace + output = "" + output << "
\n"
+    output <<   "#{h(arr[0])}:
#{h(ex.message)} (#{h(ex.class.name)})
\n" + arr[1..-1].each do |item| + output << " from #{h(item)}\n" + end + output << "
\n" + return [500, [["Content-Type", "text/html"]], [output]] + end + + public + + def call(env) + begin + return handle_request(env) + rescue HttpError => ex + return handle_http_error(ex) + rescue => ex + return handle_error(ex) + end + end + + def run(env=ENV, stdout=$stdout) + status, headers, output_arr = call(env) + stdout << "Status: #{RESPONSE_STATUS[status]}\r\n" unless status == 200 + headers.each {|k, v| stdout << "#{k}: #{v}\r\n" } + stdout << "\r\n" + output_arr.each {|str| stdout << str } + end + +end + + +if __FILE__ == $0 + ErubisApplication.new.run() end -- cgit v1.2.1