Changeset 83

Show
Ignore:
Timestamp:
11/13/06 13:49:01 (2 years ago)
Author:
e.@brainspl.at
Message:

add start of mongrel upload prpgress integration

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • Rakefile

    r73 r83  
    77require 'code_statistics'  
    88require 'fileutils' 
     9require File.dirname(__FILE__)+'/tools/rakehelp' 
    910include FileUtils 
    1011 
    1112NAME = "merb" 
    12 VERS = "0.0.6
     13VERS = "0.0.7
    1314CLEAN.include ['**/.*.sw?', '*.gem', '.config'] 
    1415RDOC_OPTS = ['--quiet', '--title', "Merb Documentation", 
     
    1819  "--inline-source"] 
    1920 
     21setup_clean ["ext/optimized_locking/*.{bundle,so,obj,pdb,lib,def,exp}", 
     22            "ext/optimized_locking/Makefile" "pkg", "lib/*.bundle", "*.gem",  
     23            "doc/rdoc/**/*", ".config"] 
     24 
     25 
    2026desc "Packages up Merb." 
    2127task :default => [:package] 
    22 task :package => [:clean
     28task :package => [:clean,:compile, :rdoc
    2329 
    2430task :doc => [:rdoc] 
     31 
     32desc "Compiles all extensions" 
     33task :compile => [:optimized_locking] do 
     34  if Dir.glob(File.join("lib","optimized_locking.*")).length == 0 
     35    STDERR.puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" 
     36    STDERR.puts "Gem actually failed to build.  Your system is" 
     37    STDERR.puts "NOT configured properly to build OptimizedMutex." 
     38    STDERR.puts "Merb will fall back to hot patched ruby mutex" 
     39    STDERR.puts "You still have a fully functional Merb install" 
     40    STDERR.puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" 
     41    exit(1) 
     42  end 
     43end 
     44 
     45setup_extension("optimized_locking", "optimized_locking") 
    2546 
    2647Rake::RDocTask.new do |rdoc| 
     
    5172  s.required_ruby_version = '>= 1.8.4' 
    5273 
    53   s.files = %w(LICENSE README Rakefile TODO) + Dir.glob("{app,bin,doc,test,lib,examples}/**/*")  
     74  s.files = %w(LICENSE README Rakefile TODO) + Dir.glob("{app,bin,doc,ext,test,lib,examples}/**/*")  
    5475       
    5576  s.require_path = "lib" 
  • TODO

    r72 r83  
    55* config file **DONE** 
    66* session 
    7   ** AR 
     7  ** AR ** DONE ** 
    88  ** DRb 
    99* Rails integration 
    10 * Mongoose ? 
    1110* Text backend? 
    1211* plugins support(rails plugins too?) 
    1312* Layouts **DONE** 
    1413* auto template_dir **DONE** 
    15 * before/after filters 
     14* before/after filters **DONE** 
    1615* merbjs **DONE** 
    1716* testing 
  • bin/merb

    r73 r83  
    55require 'fileutils' 
    66require 'yaml' 
     7require 'erubis' 
     8 
    79module Merb 
    810end 
     
    1618      :merb_root => Dir.pwd 
    1719    } 
    18  
    1920    begin 
    20       options = defaults.merge(YAML.load(ERB.new(IO.read("#{defaults[:merb_root]}/dist/conf/merb.yml")).result)) 
     21      options = defaults.merge(YAML.load(Erubis::Eruby.new(IO.read("#{defaults[:merb_root]}/dist/conf/merb.yml")).result)) 
    2122    rescue 
    2223      options = defaults 
     
    8081  end 
    8182 
     83  def self.initialize_merb 
     84    require 'merb' 
     85    require @@merb_opts[:merb_root]+'/dist/conf/router.rb' 
     86    require @@merb_opts[:merb_root]+'/dist/conf/merb_init.rb' 
     87  end   
     88 
    8289  def self.run 
    8390    @@merb_raw_opts = ARGV 
     
    8592     
    8693    @@merb_opts[:dist_root] = @@merb_opts[:merb_root]+'/dist'  
     94    $LOAD_PATH.unshift( File.join(@@merb_opts[:dist_root] , '/app/controllers') ) 
     95    $LOAD_PATH.unshift( File.join(@@merb_opts[:dist_root] , '/app/models') ) 
     96    $LOAD_PATH.unshift( File.join(@@merb_opts[:dist_root] , '/lib') ) 
    8797     
    88     $LOAD_PATH.unshift( File.join(@@merb_opts[:merb_root] , '/dist/app/controllers') ) 
    89     $LOAD_PATH.unshift( File.join(@@merb_opts[:merb_root] , '/dist/lib') ) 
    90     require 'merb' 
    91     require @@merb_opts[:merb_root]+'/dist/conf/router.rb' 
    92     require @@merb_opts[:merb_root]+'/dist/conf/merb_init.rb' 
    93  
    9498    if @@merb_opts[:console] 
     99      initialize_merb 
    95100      ARGV.clear # Avoid passing args to IRB  
    96101      require 'irb'  
     
    116121      start(@@merb_opts[:port]) 
    117122    else 
     123      initialize_merb 
    118124      trap('INT') {exit} 
    119125      mongrel_start(@@merb_opts[:port]) 
     
    153159 
    154160  def self.mongrel_start(port) 
    155     h = Mongrel::HttpServer.new((@@merb_opts[:host]||"0.0.0.0"), (port ||4000), (@@merb_opts[:numprocs]||100)) 
    156     h.register("/", MerbHandler.new(@@merb_opts[:dist_root]+'/public')) 
    157     h.register("/favicon.ico", Mongrel::Error404Handler.new("")) 
    158     h.run.join 
     161    initialize_merb 
     162 
     163    config = Mongrel::Configurator.new :host => (@@merb_opts[:host]||"0.0.0.0"), :port => (port ||4000) do 
     164      load_plugins :includes => ["mongrel"], :excludes => ["rails"] 
     165      listener do 
     166        run_config(@@merb_opts[:config]) if @@merb_opts[:config] 
     167        uri "/", :handler => MerbHandler.new(@@merb_opts[:dist_root]+'/public') 
     168        uri "/favicon.ico", :handler => Mongrel::Error404Handler.new("") 
     169      end 
     170 
     171      trap("INT") { stop } 
     172      run 
     173    end 
     174    config.join 
    159175  end   
    160176 
  • examples/sample_app/dist/conf/merb_init.rb

    r81 r83  
    1010  :adapter => 'mysql', 
    1111  :username => 'root', 
    12   :password => 'xxxxx', 
     12  :password => 'reversal', 
    1313  :database => 'merb' 
    1414) 
  • lib/merb.rb

    r78 r83  
    66 
    77module Merb 
    8   VERSION='0.0.6' unless defined?VERSION 
     8  VERSION='0.0.7' unless defined?VERSION 
    99  class Server 
    1010    def self.config 
     
    1717 
    1818MERB_FRAMEWORK_ROOT = File.dirname(__FILE__) 
     19 
     20begin 
     21  old_verbose = $VERBOSE 
     22  $VERBOSE = nil 
     23  require 'optimized_locking' 
     24  Mutex = OptimizedMutex 
     25  puts 'Using OptimizedMutex' 
     26rescue LoadError 
     27  Mutex = nil 
     28  require 'mutex_hotfix' 
     29ensure 
     30  $VERBOSE = old_verbose   
     31end   
    1932MERB_ROOT = Merb::Server.config[:merb_root] || Dir.pwd 
    2033DIST_ROOT = Merb::Server.config[:dist_root] || Dir.pwd+'/dist' 
  • lib/merb/merb_class_extensions.rb

    r78 r83  
    11class Class # :nodoc: 
    2   def inheritable_reader(*syms) 
     2  def meta_reader(*syms) 
    33    syms.each do |sym| 
    44      class_eval <<-EOS 
    55        def self.#{sym} 
    6           read_inheritable_attribute(:#{sym}) 
     6          read_meta_attribute(:#{sym}) 
    77        end 
    88 
     
    1414  end 
    1515 
    16   def inheritable_writer(*syms) 
     16  def meta_writer(*syms) 
    1717    syms.each do |sym| 
    1818      class_eval <<-EOS 
    1919        def self.#{sym}=(obj) 
    20           write_inheritable_attribute(:#{sym}, obj) 
     20          write_meta_attribute(:#{sym}, obj) 
    2121        end 
    2222 
     
    2828  end 
    2929 
    30  
    31   def inheritable_accessor(*syms) 
    32     inheritable_reader(*syms) 
    33     inheritable_writer(*syms) 
     30  def meta_accessor(*syms) 
     31    meta_reader(*syms) 
     32    meta_writer(*syms) 
    3433  end 
    3534 
    36   def inheritable_attributes 
    37     @inheritable_attributes ||= {} 
     35  def meta_attributes 
     36    @meta_attributes ||= {} 
    3837  end 
    3938   
    40   def write_inheritable_attribute(key, value) 
    41     inheritable_attributes[key] = value 
     39  def write_meta_attribute(key, value) 
     40    meta_attributes[key] = value 
    4241  end 
    4342 
    44   def read_inheritable_attribute(key) 
    45     inheritable_attributes[key] 
     43  def read_meta_attribute(key) 
     44    meta_attributes[key] 
    4645  end 
    4746   
    48   def reset_inheritable_attributes 
    49     inheritable_attributes.clear 
     47  def reset_meta_attributes 
     48    meta_attributes.clear 
    5049  end 
    5150 
    5251  private  
    53     def inherited_with_inheritable_attributes(child) 
    54       inherited_without_inheritable_attributes(child) if respond_to?(:inherited_without_inheritable_attributes) 
     52    def inherited_with_meta_attributes(child) 
     53      inherited_without_meta_attributes(child) if respond_to?(:inherited_without_meta_attributes) 
    5554       
    56       new_inheritable_attributes = inheritable_attributes.inject({}) do |memo, (key, value)| 
     55      new_meta_attributes = meta_attributes.inject({}) do |memo, (key, value)| 
    5756        memo.update(key => (value.dup rescue value)) 
    5857      end 
    5958       
    60       child.instance_variable_set('@inheritable_attributes', new_inheritable_attributes) 
     59      child.instance_variable_set('@meta_attributes', new_meta_attributes) 
    6160    end 
    6261 
    63     alias inherited_without_inheritable_attributes inherited 
    64     alias inherited inherited_with_inheritable_attributes 
     62    alias inherited_without_meta_attributes inherited 
     63    alias inherited inherited_with_meta_attributes 
    6564end 
  • lib/merb/merb_controller.rb

    r79 r83  
    2626    # file uploads by writing a tempfile and passing a reference  
    2727    # in params. 
    28     def initialize(req, env, args, method=(env['REQUEST_METHOD']||"GET")) #:nodoc: 
     28    def initialize(req, env, args, method=(env[Mongrel::Const::REQUEST_METHOD]||Mongrel::Const::GET)) 
    2929      env = MerbHash[env.to_hash] 
    30       @layout = 'application' 
    31       @status, @method, @env, @headers, @root = 200, method.downcase, env,  
    32           {'Content-Type'=>'text/html'}, env['SCRIPT_NAME'].sub(/\/$/,'') 
     30      @layout = :application 
     31      @status, @method, @env, @headers, @root = 200, method.downcase.to_sym, env,  
     32          {Mongrel::Const::CONTENT_TYPE =>'text/html'}, env[Mongrel::Const::SCRIPT_NAME].sub(/\/$/,'') 
    3333      @k = query_parse(env['HTTP_COOKIE'], ';,') 
    3434      qs = query_parse(env['QUERY_STRING']) 
    3535      @in = req 
    36       if %r|\Amultipart/form-data.*boundary=\"?([^\";,]+)|n.match(env['CONTENT_TYPE']) 
     36      if %r|\Amultipart/form-data.*boundary=\"?([^\";,]+)|n =~ (env[Mongrel::Const::CONTENT_TYPE]) 
    3737        b = /(?:\r?\n|\A)#{Regexp::quote("--#$1")}(?:--)?\r$/ 
    3838        until @in.eof? 
     
    6666          fh[:tempfile].rewind if fh.is_a?MerbHash 
    6767        end 
    68       elsif @method == "post" 
     68      elsif @method == :post 
    6969        qs.merge!(query_parse(@in.read)) 
    7070      end 
     
    7474     
    7575    def dispatch(action=nil) 
     76      puts self.class.name.to_s + "#{action}" 
    7677      setup_session if respond_to?:setup_session 
    7778      call_filters(before_filters) 
     
    99100    end 
    100101 
    101     inheritable_accessor :before_filters 
     102    # meta_accessor sets up a class instance variable that can 
     103    # be unique for each class but also inherits the meta attrs 
     104    # from its superclasses. Since @@class variables are almost 
     105    # global vars within an inheritance tree 
     106    meta_accessor :before_filters 
    102107     
    103108    def call_filters(filter_set) 
    104109      (filter_set || []).each do |filter| 
    105110        case filter 
    106           when Symbol 
     111          when Symbol, String 
    107112            send(filter) 
    108113          when Proc 
    109114            filter.call(self) 
    110           else 
    111             raise( 
    112               MerbControllerError,  
    113               'filters needs to be either a Symbol or a Proc' 
    114             ) 
    115115        end 
    116116      end   
     
    118118 
    119119    def self.before(filter) 
    120       (self.before_filters ||= []) << filter 
     120      case filter 
     121      when Symbol, String, Proc 
     122        (self.before_filters ||= []) << filter 
     123      else 
     124        raise( 
     125          MerbControllerError,  
     126          'filters need to be either a Symbol, String or a Proc' 
     127        )         
     128      end   
    121129    end 
    122130 
  • lib/merb/merb_handler.rb

    r74 r83  
    4242      # File exists as-is so serve it up 
    4343      MERB_LOGGER.info("Serving static file: #{path_info}") 
    44        
    4544      @files.process(request,response) 
    4645    elsif get_or_head and @files.can_serve(page_cached) 
    4746      # Possible cached page, serve it up 
    48       MERB_LOGGER.info("Serving static file: #{path_info}") 
     47      MERB_LOGGER.info("Serving static file: #{page_cached}") 
    4948      request.params[Mongrel::Const::PATH_INFO] = page_cached 
    5049      @files.process(request,response) 
     
    8988       
    9089      controller = nil 
    91        
    9290      if sendfile 
    9391        MERB_LOGGER.info("X-SENDFILE: #{sendfile}") 
    94         # send X-SENDFILE header to mongrel 
    95         response.send_status(File.size(sendfile)) 
    96         response.send_header 
    97         response.send_file(sendfile) 
     92        request.params[Mongrel::Const::PATH_INFO] = sendfile 
     93        @files.process(request, response) 
    9894      else 
    9995        MERB_LOGGER.info("Response status: #{response.status}\n\n") 
    10096        # render response from successful controller 
    101         response.send_status((output||'').length) 
     97        response.send_status((output||='').length) 
    10298        response.send_header 
    10399        response.write(output) 
     
    115111    path = path[0..-2] if (path[-1] == ?/) 
    116112    route = Merb::RouteMatcher.new.route_request(path) 
    117     if route 
    118       MERB_LOGGER.info("No Matching Route!") if route[:controller] == 'Noroutefound' 
    119       [ instantiate_controller(route[:controller], request.body, request.params, route),  
    120         route[:action] ] 
    121     else   
    122       MERB_LOGGER.info("No Matching Route!") 
    123       ["<html><body>Error: no route matches!</body></html>", nil] 
    124     end 
     113    MERB_LOGGER.info("No Matching Route!") if route[:controller] == 'Noroutefound' 
     114    [ instantiate_controller(route[:controller], request.body, request.params, route),  
     115      route[:action] ] 
    125116  end 
    126117   
  • lib/merb/merb_utils.rb

    r78 r83  
    6767  alias_method :regular_writer, :[]= unless method_defined?(:regular_writer) 
    6868  alias_method :regular_update, :update unless method_defined?(:regular_update) 
     69  alias_method :u, :regular_update 
    6970   
    7071  def []=(key, value) 
     
    120121end   
    121122 
    122 require 'thread' 
    123  
    124 # monkey patch Mutex so it does not leak memory. 
    125 class Mutex 
    126  
    127   def lock 
    128     while (Thread.critical = true; @locked) 
    129       @waiting.unshift Thread.current 
    130       Thread.stop 
    131     end 
    132     @locked = true 
    133     Thread.critical = false 
    134     self 
    135   end 
    136    
    137   def unlock 
    138     return unless @locked 
    139     Thread.critical = true 
    140     @locked = false 
    141     begin 
    142       t = @waiting.pop 
    143       t.wakeup if t 
    144     rescue ThreadError 
    145       retry 
    146     end 
    147     Thread.critical = false 
    148     begin 
    149       t.run if t 
    150     rescue ThreadError 
    151     end 
    152     self 
    153   end 
    154    
    155 end 
  • lib/merb/mixins/controller_mixin.rb

    r78 r83  
    77    MERB_LOGGER.info("Redirecting to: #{url}") 
    88    @status = 302 
    9     @headers.merge!({'Location'=> url}) 
     9    headers.merge!({'Location'=> url}) 
    1010    return '' 
    1111  end 
     
    3333  # {:bar => 'nik', :post => {:title => 'heya', :body => 'whatever}} 
    3434  def query_parse(qs, d = '&;') 
    35     m = proc {|_,o,n|o.update(n,&m)rescue([*o]<<n)} 
     35    puts qs 
     36    m = proc {|_,o,n|o.u(n,&m)rescue([*o]<<n)} 
    3637    (qs||'').split(/[#{d}] */n).inject(MerbHash[]) { |h,p|  
    3738            k, v=unescape(p).split('=',2) 
    38             h.update(k.split(/[\]\[]+/).reverse. 
     39            h.u(k.split(/[\]\[]+/).reverse. 
    3940              inject(v) { |x,i| MerbHash[i,x] },&m) 
    4041        } 
    4142  end 
     43 
     44  def make_token 
     45    require 'digest/md5' 
     46    Digest::MD5.hexdigest("#{inspect}#{Time.now}#{rand}") 
     47  end   
    4248 
    4349  # does url escaping 
     
    5763  alias js :escape_js 
    5864 
     65  # returns true if the request is an ajax request. 
    5966  def xml_http_request? 
    6067    not /XMLHttpRequest/i.match(@headers['HTTP_X_REQUESTED_WITH']).nil? 
     
    6370  alias ajax? :xml_http_request? 
    6471 
     72  # returns the remote IP address if it can find it. 
    6573  def remote_ip 
    6674    return @headers['HTTP_CLIENT_IP'] if @headers.include?('HTTP_CLIENT_IP') 
    6775 
    68     if @headers.include?('HTTP_X_FORWARDED_FOR') then 
    69       remote_ips = @headers['HTTP_X_FORWARDED_FOR'].split(',').reject do |ip| 
     76    if @headers.include?(Mongrel::Const::HTTP_X_FORWARDED_FOR) then 
     77      remote_ips = @headers[Mongrel::Const::HTTP_X_FORWARDED_FOR].split(',').reject do |ip| 
    7078        ip =~ /^unknown$|^(127|10|172\.16|192\.168)\./i 
    7179      end 
     
    7482    end 
    7583 
    76     return @headers['REMOTE_ADDR'
     84    return @headers[Mongrel::Const::REMOTE_ADDR
    7785  end 
    7886   
     87  # returns either 'https://' or 'http://' depending on 
     88  # the HTTPS header 
    7989  def protocol 
    8090    @headers['HTTPS'] == 'on' ? 'https://' : 'http://' 
    8191  end 
    8292   
     93  # returns true if the request is an SSL request 
    8394  def ssl? 
    8495    @headers['HTTPS'] == 'on' 
     
    8697   
    8798  # The request uri. 
    88    
    8999  def uri 
    90     @headers['REQUEST_URI'
     100    @headers[Mongrel::Const::REQUEST_URI
    91101  end 
    92102   
    93103  # The path is the uri without the query string. 
    94    
    95104  def path 
    96105    uri ? uri.split('?').first : '' 
    97106  end 
    98    
     107 
    99108  def path_info 
    100     @headers['PATH_INFO'
     109    @headers[Mongrel::Const::PATH_INFO
    101110  end 
    102111   
     
    119128   
    120129  def method 
    121     @headers['REQUEST_METHOD'].downcase.to_sym 
     130    @method ||= @headers[Mongrel::Const::REQUEST_METHOD].downcase.to_sym 
    122131  end 
    123132   
  • lib/merb/mixins/render_mixin.rb

    r72 r83  
    1414   
    1515  # does a render with no layout. Also sets the 
    16   # content type header to text/javascript and 
    17   # escapes the template for javascript eval on 
    18   # the client 
     16  # content type header to text/javascript 
    1917  def render_js(template=current_method_name(1), b=binding) 
    2018    headers['Content-Type'] = "text/javascript" 
     
    6967    MERB_LOGGER.info("With Layout: #{template_dir('layout')}/#{layout}.rhtml") 
    7068    @layout_content = layout_content 
    71     layout_tmpl = Erubis::Eruby.new( IO.read( template_dir('layout') + "/#{layout}.rhtml" ) )       
     69    layout_tmpl = Erubis::Eruby.new( IO.read( "#{template_dir('layout')}/#{layout}.rhtml" ) )       
    7270    layout_tmpl.result(b) 
    7371  end