Class: Alone
- Inherits:
-
Object
- Object
- Alone
- Defined in:
- lib/al_main.rb
Overview
Aloneのベースとなる機能を、まとめている。
Aloneメインクラス
Defined Under Namespace
Classes: OutputTrap
Constant Summary
- CHAR_ENT_REF =
escape_html用定数テーブル
{'<'=>'<', '>'=>'>', '&'=>'&', '"'=>'"', '\''=>''', "\r\n"=>'<br>', "\r"=>'<br>', "\n"=>'<br>' }
- @@headers =
Httpヘッダ
[ "Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0" ]
nil
- @@flag_redirect =
リダイレクトするかのフラグ
false
- @@flag_send_http_headers =
Httpヘッダを送ったかのフラグ
false
- @@ctrl =
コントローラ名
$2.to_s
- @@action =
アクション名
$2.to_s
Class Method Summary (collapse)
-
+ (String) action
Getter アクション名.
-
+ (Object) add_http_header(header)
httpヘッダの追加.
-
+ (String) ctrl
Getter コントローラ名.
-
+ (String) decode_uri_component(s)
URIデコード.
-
+ (Object) delete_cookie(name, path = nil)
クッキーの消去.
-
+ (String) encode_uri_component(s)
URIエンコード.
-
+ (String) escape_html(str)
html特殊文字のエスケープ.
-
+ (String) escape_html_br(str)
html特殊文字のエスケープ with 改行文字.
-
+ (String, NilClass) get_cookie(name)
クッキーの取得.
-
+ (Object) handle_error(ex)
エラーハンドラ.
-
+ (Object) handle_error_display(ex)
エラーハンドラ:エラー詳細表示.
-
+ (Object) handle_error_static_page(ex)
エラーハンドラ:静的ページを表示.
-
+ (Object) main
メイン.
-
+ (String) make_uri(arg = {})
リンク用のURIを生成する.
-
+ (Object) redirect_to(uri)
リダイレクト設定.
-
+ (String) request_uri
リクエストされたURIを返す.
-
+ (Object) send_http_headers
httpヘッダの送信.
-
+ (Object) set_cookie(name, value, expire = nil, path = nil)
クッキーの設定.
Class Method Details
+ (String) action
Getter アクション名
54 55 56 |
# File 'lib/al_main.rb', line 54 def self.action() return @@action end |
+ (Object) add_http_header(header)
実際にhttpヘッダが送られる前に、使用する必要がある。 httpヘッダは、send_http_headers() メソッドで送られる。 典型的には、最初にユーザコードで文字列などが表示される直前に、 ヘッダが出力されるので、それまでに使用する。
httpヘッダの追加
165 166 167 |
# File 'lib/al_main.rb', line 165 def self.add_http_header( header ) @@headers << header.chomp.gsub( /\r?\n[^ \t]|\r[^\n \t]/, ' ' ) end |
+ (String) ctrl
Getter コントローラ名
45 46 47 |
# File 'lib/al_main.rb', line 45 def self.ctrl() return @@ctrl end |
+ (String) decode_uri_component(s)
URIデコード
290 291 292 293 294 |
# File 'lib/al_main.rb', line 290 def self.decode_uri_component( s ) a = s.gsub( /%([0-9a-fA-F]{2})/ ) { $1.hex.chr } a.force_encoding( AL_CHARSET ) # TODO: ruby1.9 only # TODO: UTF-8(あるいはその他の漢字コード)として無効なコードが来たらどうする? end |
+ (Object) delete_cookie(name, path = nil)
httpヘッダに出力する関係上、ヘッダ出力前にコールする必要がある。
クッキーの消去
243 244 245 246 247 248 249 250 251 |
# File 'lib/al_main.rb', line 243 def self.( name, path = nil ) # 既にヘッダへ出力予約されているものがあれば削除 target = "Set-Cookie: #{name}=" @@headers.delete_if { |h| h.start_with?( target ) } = "Set-Cookie: #{name}=; expires=Thu, 08-Jun-1944 00:00:00 GMT" << "; path=#{path}" if path @@headers << end |
+ (String) encode_uri_component(s)
URIエンコード
277 278 279 280 281 |
# File 'lib/al_main.rb', line 277 def self.encode_uri_component( s ) a = s.to_s.dup a.force_encoding( 'ASCII-8BIT' ) # TODO: ruby1.9 only a.gsub( /([^a-zA-Z0-9!'\(\)*\-._~])/ ) { "%#{$1.unpack('H2')[0]}" } end |
+ (String) escape_html(str)
html特殊文字のエスケープ
348 349 350 |
# File 'lib/al_main.rb', line 348 def self.escape_html( str ) return str.to_s.gsub( /([<>&"'])/ ) { CHAR_ENT_REF[$1] } end |
+ (String) escape_html_br(str)
html特殊文字のエスケープに加え、改行文字を
タグへ変更する。
html特殊文字のエスケープ with 改行文字
361 362 363 |
# File 'lib/al_main.rb', line 361 def self.escape_html_br( str ) return str.to_s.gsub( /([<>&"']|\r\n|\r|\n)/ ) { CHAR_ENT_REF[$1] } end |
+ (String, NilClass) get_cookie(name)
クッキーの取得
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 |
# File 'lib/al_main.rb', line 199 def self.( name ) if ! @@cookies @@cookies = {} = ENV['HTTP_COOKIE'] return nil if ! = .split( ';' ) .each do |c| (k,v) = c.split( '=', 2 ) next if ! v @@cookies[k.strip.to_sym] = decode_uri_component( v ) end end return @@cookies[name.to_sym] end |
+ (Object) handle_error(ex)
エラーハンドラ
88 89 90 91 |
# File 'lib/al_main.rb', line 88 def self.handle_error( ex ) __send__( AL_ERROR_HANDLER, ex ) if ex.class != SystemExit exit end |
+ (Object) handle_error_display(ex)
エラーハンドラ:エラー詳細表示
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 |
# File 'lib/al_main.rb', line 127 def self.handle_error_display( ex ) send_http_headers() puts AL_TEMPLATE_HEADER puts AL_TEMPLATE_BODY puts '<h1 class="al-error-display">Alone: Error detected.</h1>' puts "<h2 class=\"al-error-display\">#{ex.class} occurred.</h2>" puts '<pre class="al-error-display">' puts ' ' + escape_html( ex. ) puts '</pre>' puts '<h2 class="al-error-display">Backtrace</h2>' puts '<pre class="al-error-display">' ex.backtrace.each do |bt| puts ' ' + escape_html( bt ) end puts '</pre>' puts '<h2 class="al-error-display">Environment</h2>' puts '<pre class="al-error-display">' `env`.split("\n").each do |e| puts ' ' + escape_html( e ) end puts '</pre>' puts AL_TEMPLATE_FOOTER end |
+ (Object) handle_error_static_page(ex)
エラーハンドラ:静的ページを表示
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 |
# File 'lib/al_main.rb', line 97 def self.handle_error_static_page( ex ) status_code = nil = nil # check status code in @@headers. @@headers.each do |h| if /^Status: (\d+)(.*)$/ =~ h status_code = $1 = $1 + $2 end end if ! status_code status_code = "500" # default 500 Internal Server Error = "Internal Server Error" Alone::add_http_header( "Status: 500 Internal Server Error" ) end # display error page. send_http_headers() begin print File.read( "#{AL_BASEDIR}/templates/#{status_code}.html" ) rescue print end end |
+ (Object) main
ユーザコードがブロックで渡されるので、それを実行する。 例外はすべてキャッチして、正当なhtmlで表示する。
メイン
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/al_main.rb', line 66 def self.main() # # リダイレクトするなら、ヘッダ出力のみで終了(htmlコンテンツは必要ない) # if @@flag_redirect send_http_headers() exit end begin yield() send_http_headers() rescue Exception => ex handle_error( ex ) end end |
+ (String) make_uri(arg = {})
このメソッドは、escape_html()した値を返さない。 生成した値は、アトリビュート値にもテンプレートにも使われる。 少々危険な気もするが、エスケープはテンプレートエンジンの仕事にしなければ アプリケーションが破綻する。
リンク用のURIを生成する
329 330 331 332 333 334 335 336 337 338 339 |
# File 'lib/al_main.rb', line 329 def self.make_uri( arg = {} ) uri = "#{ENV['SCRIPT_NAME']}?ctrl=#{arg[:ctrl] || @@ctrl}" uri << "&action=#{arg[:action]}" if arg[:action] arg.each do |k,v| next if k == :ctrl || k == :action uri << "&#{k}=#{v}" end return uri end |
+ (Object) redirect_to(uri)
リダイレクト設定
259 260 261 262 263 264 265 266 267 268 |
# File 'lib/al_main.rb', line 259 def self.redirect_to( uri ) if @@flag_send_http_headers raise "HTTP header was already sent." end raise "Invalid URI" if /[\r\n]/ =~ uri @@headers << "Location: #{uri}" @@headers << "Status: 302 Found" @@flag_redirect = true end |
+ (String) request_uri
リクエストされたURIを返す
302 303 304 305 306 307 308 309 310 311 312 |
# File 'lib/al_main.rb', line 302 def self.request_uri() if ENV['REQUEST_URI'] return ENV['REQUEST_URI'] end if ENV['QUERY_STRING'] return "#{ENV['SCRIPT_NAME']}?#{ENV['QUERY_STRING']}" end return ENV['SCRIPT_NAME'] end |
+ (Object) send_http_headers
送信済みなら何もしないので、何度よんでも問題ない。
httpヘッダの送信
176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
# File 'lib/al_main.rb', line 176 def self.send_http_headers() return if @@flag_send_http_headers @@flag_send_http_headers = true flag_content_type = false @@headers.each do |h| puts h flag_content_type = true if h.start_with?( "Content-Type:" ) end if ! flag_content_type print "Content-Type: text/html; charset=#{AL_CHARSET}\n" end print "\n" end |
+ (Object) set_cookie(name, value, expire = nil, path = nil)
httpヘッダに出力する関係上、ヘッダ出力前にコールする必要がある。
クッキーの設定
227 228 229 230 231 232 |
# File 'lib/al_main.rb', line 227 def self.( name, value, expire = nil, path = nil ) = "Set-Cookie: #{name}=#{encode_uri_component( value )}" << "; expires=#{expire.to_s}" if expire << "; path=#{path}" if path @@headers << end |