<commit_before>module Rackable
  attr_reader :rack

  def call(env)
    allowed_methods = [:get, :put, :post, :delete]

    @rack = Struct.new(:env, :request, :response, :header, :query, :data).new
    rack.env = env

    rack.request  = Rack::Request.new(env)
    rack.response = Rack::Response.new
    rack.header   = rack.response.header

    rack.query = rack.request.GET.inject({})  {|h, (k,v)| h[k.to_sym] = v; h }
    rack.data  = rack.request.POST.inject({}) {|h, (k,v)| h[k.to_sym] = v; h }

    method = rack.env['REQUEST_METHOD'].downcase.to_sym

    args = rack.env['PATH_INFO'][1..-1].split('/').collect { |arg|
      Rack::Utils.unescape(arg)
    }

    method, was_head = :get, true if method == :head

    rack.response.status, body = catch(:halt) do
      begin
        raise NoMethodError unless allowed_methods.include? method
        body = send(method, *args)
        [rack.response.status, body]

      rescue NoMethodError
        rack.header['Allow'] = allowed_methods.delete_if { |meth|
          !respond_to?(meth)
        }.tap {|a|
          a.unshift 'HEAD' if respond_to? :get
        }.map { |meth|
          meth.to_s.upcase
        }.join(', ')

        http_error 405

      rescue ArgumentError
        http_error 400

      end
    end

    rack.response.write(body) unless was_head
    rack.response.finish
  end

  private

  def http_error(code, message=nil)
    throw :halt, [code, message || Rack::Utils::HTTP_STATUS_CODES[code]]<commit_msg>be more tolerant with empty paths and don't randomly catch NoMethodErrors<commit_after>module Rackable
  attr_reader :rack

  class MethodNotAllowed < NoMethodError
  end

  def call(env)
    allowed_methods = [:get, :put, :post, :delete]

    @rack = Struct.new(:env, :request, :response, :header, :query, :data).new
    rack.env = env

    rack.request  = Rack::Request.new(env)
    rack.response = Rack::Response.new
    rack.header   = rack.response.header

    rack.query = rack.request.GET.inject({})  {|h, (k,v)| h[k.to_sym] = v; h }
    rack.data  = rack.request.POST.inject({}) {|h, (k,v)| h[k.to_sym] = v; h }

    method = rack.env['REQUEST_METHOD'].downcase.to_sym

    path = rack.env['PATH_INFO'][1..-1]
    args = path && path.any? ? path.split('/').collect { |arg|
      Rack::Utils.unescape(arg)
    } : []

    method, was_head = :get, true if method == :head

    rack.response.status, body = catch(:halt) do
      begin
        raise MethodNotAllowed unless allowed_methods.include? method
        body = send(method, *args)
        [rack.response.status, body]

      rescue MethodNotAllowed
        rack.header['Allow'] = allowed_methods.delete_if { |meth|
          !respond_to?(meth)
        }.tap {|a|
          a.unshift 'HEAD' if respond_to? :get
        }.map { |meth|
          meth.to_s.upcase
        }.join(', ')

        http_error 405

      rescue ArgumentError
        http_error 400

      end
    end

    rack.response.write(body) unless was_head
    rack.response.finish
  end

  private

  def http_error(code, message=nil)
    throw :halt, [code, message || Rack::Utils::HTTP_STATUS_CODES[code]]
{'fraction_non_alphanumeric': 0.1426739339531901, 'fraction_numerical': 0.005129849310676499, 'mean_word_length': 2.6576787807737396, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '854807', 'n_tokens_mistral': 1099, 'n_tokens_neox': 1046, 'n_words': 231}