<commit_before>require 'mashape-analytics/capture'
require 'time'
require 'socket'
require 'rack/utils'

def status_code(status)
  Rack::Utils::HTTP_STATUS_CODES[status] || ''
end

def header_hash(headers)
  Rack::Utils::HeaderHash.new.merge(headers)
end

module MashapeAnalytics::Frameworks
  class Rack

    def initialize(app, options = {})
      @app = app
      @service_token = options[:service_token]
      @environment = options[:environment] || ''
      @send_body = options[:send_body] || false
      host = options[:host] || 'tcp://socket.analytics.mashape.com:5500'

      MashapeAnalytics::Capture.setOptions(host: host)
    end

    def call(env)
      startedDateTime = Time.now
      status, headers, body = @app.call(env)

      if body.respond_to? :to_str
        body = [body.to_str]
      elsif body.respond_to?(:body)
        body = [body.body]
      elsif body.respond_to?(:each)
        # do nothing
      else
        raise TypeError, "stringable or iterable required"
      end

      record_alf startedDateTime, env, {
        :status => status,
        :headers => header_hash(headers),
        :body => body
      }

      [status, headers, body]
    end

  protected
    def host(request)
      if forwarded = request['HTTP_X_FORWARDED_HOST']
        forwarded.split(/,\s?/).last
      elsif (request['rack.url_scheme'] == 'http' and request['SERVER_PORT'] == '80') or (request['rack.url_scheme'] == 'https' and request['SERVER_PORT'] == '443')
        request['HTTP_HOST'] || "#{request['SERVER_NAME'] || request['SERVER_ADDR']}"
      else
        request['HTTP_HOST'] || "#{request['SERVER_NAME'] || request['SERVER_ADDR']}:#{request['SERVER_PORT']}"
      end
    end

    def url(request)
      query_string = ''
      if request['QUERY_STRING'] != '' and request['QUERY_STRING'] != nil
        query_string = '?' + request['QUERY_STRING']
      end

      "#{request['PATH_INFO']}#{query_string}"
    end

    def absolute_url(request)
      "#{request['rack.url_scheme']}://#{host(request)}#{url(request)}"
    end

    def request_headers(request)
      request.select {|k,v| k.start_with? 'HTTP_'}
        .map { |k,v| {name: k.sub(/^HTTP_/, '').sub(/_/, '-'), value: v} }
    end

    def request_header_size(request)
      # {METHOD} {URL} HTTP/1.1\r\n = 12 extra characters for space between method and url, and ` HTTP/1.1\r\n`
      first_line = request['REQUEST_METHOD'].length + url(request).length + 12

      # {KEY}: {VALUE}\n\r = 4 extra characters for `: ` and `\n\r` minus `HTTP_` in the KEY is -1
      header_fields = request.select { |k,v| k.start_with? 'HTTP_' }
        .map { |k,v| k.length + v.bytesize - 1 }
        .inject(0) { |sum,v| sum + v }

      last_line = 2 # /r/n

      first_line + header_fields + last_line
    end

    def request_query_string(request)
      request['QUERY_STRING'].split('&')
        .map do |q|
          parts = q.split('=')
          {name: parts.first, value: parts.length > 1 ? parts.last : nil }
        end
    end

    def request_content_size(request)
      if request['HTTP_CONTENT_LENGTH']
        request['HTTP_CONTENT_LENGTH'].to_i
      else
        request['rack.input'].size
      end
    end

    def response_headers(response)
      response[:headers].map { |k,v| {name: k, value: v} }
    end

    def response_headers_size(response)
      # HTTP/1.1 {STATUS} {STATUS_TEXT} = 10 extra characters
      first_line = response[:status].to_s.length + status_code(response[:status]).length + 10
<commit_msg>[#1] Fix for "undefined method `size`" error<commit_after>require 'mashape-analytics/capture'
require 'time'
require 'socket'
require 'rack/utils'

def status_code(status)
  Rack::Utils::HTTP_STATUS_CODES[status] || ''
end

def header_hash(headers)
  Rack::Utils::HeaderHash.new.merge(headers)
end

module MashapeAnalytics::Frameworks
  class Rack

    def initialize(app, options = {})
      @app = app
      @service_token = options[:service_token]
      @environment = options[:environment] || ''
      @send_body = options[:send_body] || false
      host = options[:host] || 'tcp://socket.analytics.mashape.com:5500'

      MashapeAnalytics::Capture.setOptions(host: host)
    end

    def call(env)
      startedDateTime = Time.now
      status, headers, body = @app.call(env)

      if body.respond_to? :to_str
        body = [body.to_str]
      elsif body.respond_to?(:body)
        body = [body.body]
      elsif body.respond_to?(:each)
        # do nothing
      else
        raise TypeError, "stringable or iterable required"
      end

      record_alf startedDateTime, env, {
        :status => status,
        :headers => header_hash(headers),
        :body => body
      }

      [status, headers, body]
    end

  protected
    def host(request)
      if forwarded = request['HTTP_X_FORWARDED_HOST']
        forwarded.split(/,\s?/).last
      elsif (request['rack.url_scheme'] == 'http' and request['SERVER_PORT'] == '80') or (request['rack.url_scheme'] == 'https' and request['SERVER_PORT'] == '443')
        request['HTTP_HOST'] || "#{request['SERVER_NAME'] || request['SERVER_ADDR']}"
      else
        request['HTTP_HOST'] || "#{request['SERVER_NAME'] || request['SERVER_ADDR']}:#{request['SERVER_PORT']}"
      end
    end

    def url(request)
      query_string = ''
      if request['QUERY_STRING'] != '' and request['QUERY_STRING'] != nil
        query_string = '?' + request['QUERY_STRING']
      end

      "#{request['PATH_INFO']}#{query_string}"
    end

    def absolute_url(request)
      "#{request['rack.url_scheme']}://#{host(request)}#{url(request)}"
    end

    def request_headers(request)
      request.select {|k,v| k.start_with? 'HTTP_'}
        .map { |k,v| {name: k.sub(/^HTTP_/, '').sub(/_/, '-'), value: v} }
    end

    def request_header_size(request)
      # {METHOD} {URL} HTTP/1.1\r\n = 12 extra characters for space between method and url, and ` HTTP/1.1\r\n`
      first_line = request['REQUEST_METHOD'].length + url(request).length + 12

      # {KEY}: {VALUE}\n\r = 4 extra characters for `: ` and `\n\r` minus `HTTP_` in the KEY is -1
      header_fields = request.select { |k,v| k.start_with? 'HTTP_' }
        .map { |k,v| k.length + v.bytesize - 1 }
        .inject(0) { |sum,v| sum + v }

      last_line = 2 # /r/n

      first_line + header_fields + last_line
    end

    def request_query_string(request)
      request['QUERY_STRING'].split('&')
        .map do |q|
          parts = q.split('=')
          {name: parts.first, value: parts.length > 1 ? parts.last : nil }
        end
    end

    def request_content_size(request)
      if request['HTTP_CONTENT_LENGTH']
        request['HTTP_CONTENT_LENGTH'].to_i
      else
        if request['rack.input'].respond_to? :size
          request['rack.input'].size
        else
          -1 # Not available
        end
      end
    end

    def response_headers(response)
      response[:headers].map { |k,v| {name: k, value: v} }
    end

    def response_headers_size(response)
      # HTTP/1.1 {STATUS} {STATUS_TEXT} = 10 extra characters
      first_line = response[:status].to_s.length + status_code(response[:status]).length + 10

{'fraction_non_alphanumeric': 0.15037698966769059, 'fraction_numerical': 0.008377548170901982, 'mean_word_length': 2.8202666666666665, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 11, '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': '4643104', 'n_tokens_mistral': 2397, 'n_tokens_neox': 2324, 'n_words': 498}