arika (owner)

Revisions

gist: 28033 Download_button fork
public
Description:
rackup gonzui
Public Clone URL: git://gist.github.com/28033.git
Embed All Files: show embed
gonzui-rack.rb #
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
153
154
155
156
# 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
 
gonzui.cgi #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/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
 
gonzui.ru #
1
2
3
4
# rackup gonzui
require 'gonzui-rack'
run build_gonzui_app