Class: K8::RackApplication

Inherits:
Object
  • Object
show all
Defined in:
lib/keight.rb

Constant Summary collapse

REQUEST_CLASS =
RackRequest
RESPONSE_CLASS =
RackResponse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(urlpath_mapping = [], urlpath_cache_size: 0, enable_urlpath_param_range: true) ⇒ RackApplication

Returns a new instance of RackApplication.



1651
1652
1653
1654
1655
1656
1657
# File 'lib/keight.rb', line 1651

def initialize(urlpath_mapping=[], urlpath_cache_size: 0,
                                   enable_urlpath_param_range: true)
  #; [!vkp65] mounts urlpath mappings.
  @mapping = ActionMapping.new(urlpath_mapping,
                               urlpath_cache_size: urlpath_cache_size,
                               enable_urlpath_param_range: enable_urlpath_param_range)
end

Class Method Details

.REQUEST_CLASS=(klass) ⇒ Object



1639
1640
1641
1642
1643
# File 'lib/keight.rb', line 1639

def self.REQUEST_CLASS=(klass)
  #; [!7uqb4] changes default request class.
  remove_const :REQUEST_CLASS
  const_set :REQUEST_CLASS, klass
end

.RESPONSE_CLASS=(klass) ⇒ Object



1645
1646
1647
1648
1649
# File 'lib/keight.rb', line 1645

def self.RESPONSE_CLASS=(klass)
  #; [!c1bd0] changes default response class.
  remove_const :RESPONSE_CLASS
  const_set :RESPONSE_CLASS, klass
end

Instance Method Details

#call(env) ⇒ Object



1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
# File 'lib/keight.rb', line 1699

def call(env)
  #; [!uvmxe] takes env object.
  #; [!gpe4g] returns status, headers and content.
  #; [!eb2ms] returns 301 when urlpath not found but found with tailing '/'.
  #; [!02dow] returns 301 when urlpath not found but found without tailing '/'.
  #; [!2a9c9] adds query string to 'Location' header.
  #; [!vz07j] redirects only when request method is GET or HEAD.
  #; [!l6kmc] uses 'GET' method to find action when request method is 'HEAD'.
  #; [!4vmd3] uses '_method' value of query string as request method when 'POST' method.
  #; [!rz13i] returns HTTP 404 when urlpath not found.
  #; [!rv3cf] returns HTTP 405 when urlpath found but request method not allowed.
  req  = REQUEST_CLASS.new(env)
  resp = RESPONSE_CLASS.new
  begin
    ret = handle_request(req, resp)
  rescue HttpException => ex
    ret = handle_http(ex, req, resp)
  rescue Exception => ex
    ret = handle_error(ex, req, resp)
  ensure
    #; [!vdllr] clears request and response if possible.
    req.clear()  if req.respond_to?(:clear)
    resp.clear() if resp.respond_to?(:clear)
  end
  return ret
end

#each_mapping(&block) ⇒ Object



1784
1785
1786
1787
1788
# File 'lib/keight.rb', line 1784

def each_mapping(&block)
  #; [!cgjyv] yields full urlpath pattern, action class and action methods.
  @mapping.each(&block)
  self
end

#find(req_path) ⇒ Object



1659
1660
1661
1662
# File 'lib/keight.rb', line 1659

def find(req_path)
  #; [!o0rnr] returns action class, action methods, urlpath names and values.
  return @mapping.find(req_path)
end

#lookup(req_meth, req_path, query_string = "") ⇒ Object



1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
# File 'lib/keight.rb', line 1664

def lookup(req_meth, req_path, query_string="")
  #; [!7476i] uses '_method' value of query string as request method when 'POST' method.
  if req_meth == :POST && query_string =~ /\A_method=(\w+)/
    req_meth = HTTP_REQUEST_METHODS[$1.upcase] || $1.upcase
  end
  #
  tuple = find(req_path)
  unless tuple
    #; [!c0job] redirects only when request method is GET or HEAD.
    if req_meth == :GET || req_meth == :HEAD
      #; [!u1qfv] raises 301 when urlpath not found but found with tailing '/'.
      #; [!kbff3] raises 301 when urlpath not found but found without tailing '/'.
      rpath  = req_path
      rpath2 = rpath.end_with?('/') ? rpath[0..-2] : rpath + '/'
      if find(rpath2)
        #; [!cgxx4] adds query string to 'Location' header when redirecting.
        qs = query_string
        location = ! qs || qs.empty? ? rpath2 : "#{rpath2}?#{qs}"
        status = 301              # 301 Moved Permanently
        raise HttpException.new(status, nil, {'Location'=>location})
      end
    end
    #; [!hdy1f] raises HTTP 404 when urlpath not found.
    raise HttpException.new(404)  # 404 Not Found
  end
  action_class, action_methods, urlpath_args = tuple
  #; [!0znwr] uses 'GET' method to find action when request method is 'HEAD'.
  d = action_methods
  action_name = d[req_meth] || (req_meth == :HEAD ? d[:GET] : nil) || d[:ANY]
  #; [!bfpav] raises HTTP 405 when urlpath found but request method not allowed.
  action_name  or
    raise HttpException.new(405)  # 405 Method Not Allowed
  return action_class, action_name, urlpath_args
end

#show_mappingsObject



1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
# File 'lib/keight.rb', line 1790

def show_mappings()
  #; [!u1g77] returns all mappings as YAML string.
  req_methods = HTTP_REQUEST_METHODS.values() + [:ANY]
  s = ""
  each_mapping do |full_urlpath_pat, action_class, action_methods|
    arr = req_methods.collect {|req_meth|
      action_name = action_methods[req_meth]
      action_name ? "#{req_meth}: #{action_name}" : nil
    }.compact()
    s << "- urlpath: #{full_urlpath_pat}\n"
    s << "  class:   #{action_class}\n"
    s << "  methods: {#{arr.join(', ')}}\n"
    s << "\n"
  end
  return s
end