2012/05/09

Recent entries from same category

  1. Ruby の Array#<< は Array#push よりも速いか
  2. Ruby の a = a + 1 はなぜ undefined method '+' for nil:NilClass なのか
  3. Re: Ruby 製バッチ処理を省メモリ化した
  4. Crystal と CRuby でHTTPサーバのベンチマーク
  5. pure mruby な JSON パーサ書いた。

しなちく 「お前それ、シナチクって言いたかっただけやろ」

...
...
...
...

「そうですが、何か」

mruby で mruby-httpmruby-uv を使い、sinatra ライクなのが動くまでに到った。
ショボいアプリケーションなら書ける様になったけど、mrubyはまだファイルIOが出来ないのでアプリと呼べる様な物が動くにはまだまだ先。
require 'HTTP'
require 'UV'

# {{{
module Sinatic
  @routes = { 'GET' => [], 'POST' => [] }
  def self.route(method, path, opts, &block)
    @routes[method] << [path, opts, block]
  end
  def self.do(r)
    @routes[r.method].each {|path|
      if path[0] == r.path
        param = {}
        r.body.split('&').each {|x|
          tokens = x.split('=')
          param[tokens[0]] = HTTP::URL::decode(tokens[1])
        }
        body = path[2].call(r, param)
        return [
          "HTTP/1.0 200 OK",
          "Content-Type: text/html; charset=utf-8",
          "Content-Length: #{body.size}",
          """"].join("\r\n") + body
      end
    }
    return "HTTP/1.0 404 Not Found\r\nContent-Length: 10\r\n\r\nNot Found\n"
  end
  def self.run()
    s = UV::TCP.new()
    s.bind(UV::ip4_addr('127.0.0.1'8888))
    s.data = []
    s.listen(50) {|x|
      return if x != 0
      c = s.accept()
      c.read_start {|b|
        h = HTTP::Parser.new()
        h.parse_request(b) {|r|
          i = b.index("\r\n\r\n") + 4
          r.body = b.slice(i, b.size - i)
          c.write(::Sinatic.do(r)) {|x| c.close }
        }
      }
      s.data << c
    }
    while 1 do
      NOTE: must be call run_once to run GC.
      UV::run_once()
    end
  end
end

module Kernel
  def get(path, opts={}, &block)
    ::Sinatic.route 'GET', path, opts, &block
  end
  def post(path, opts={}, &block)
    ::Sinatic.route 'POST', path, opts, &block
  end
end
# }}}

get "/foo.js" do
'$(function() {
  $("#foo").text("hello world");
})'
end

get "/" do
'
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script src="/foo.js"></script>
<div id="foo"></div>
<form action="/add" method="post">
<label for="name"/>お名前</label>
<input type="text" id="name" name="name" value="">
<input type="submit">
</form>
'
end

post "/add" do |rparam|
"
<meta http-equiv=refresh content='2; URL=/'>
通報しますた「#{param['name']}
"
end


Sinatic.run

# vim: set fdm=marker:
Posted at by