<commit_before>require 'sinatra'
require 'travis/support/logging'
require 'sidekiq'
require 'travis/sidekiq/build_request'
require 'newrelic_rpm'
require 'multi_json'
require 'ipaddr'
require 'metriks'

module Travis
  module Listener
    class App < Sinatra::Base
      include Logging

      # use Rack::CommonLogger for request logging
      enable :logging, :dump_errors

      # see https://github.com/github/github-services/blob/master/services/travis.rb#L1-2
      set :events, %w[push pull_request]

      before do
        logger.level = 1
      end

      get '/' do
        redirect "http://about.travis-ci.org"
      end

      # Used for new relic uptime monitoring
      get '/uptime' do
        200
      end

      # the main endpoint for scm services
      post '/' do
        report_ip_validity
        if !ip_validation? || valid_ip?
          if valid_request?
            handle_event

            204
          else
            Metriks.meter('listener.request.no_payload').mark
            422
          end
        else
          403
        end
      end

      protected

      def valid_request?
        payload
      end

      def ip_validation?
        (Travis.config.listener && Travis.config.listener.ip_validation)
      end

      def report_ip_validity
        if valid_ip?
          Metriks.meter('listener.ip.valid').mark
        else
          Metriks.meter('listener.ip.invalid').mark
          logger.info "Payload to travis-listener sent from an invalid IP(#{request.ip})"
        end
      end

      def valid_ip?
        return true if valid_ips.empty?

        valid_ips.any? { |ip| IPAddr.new(ip).include? request.ip }
      end

      def valid_ips
        (Travis.config.listener && Travis.config.listener.valid_ips) || []
      end

      def handle_event
        return unless handle_event?
        debug "Request created: #{payload.inspect}"
        info "uuid=#{uuid} delivery_guid=#{delivery_guid} type=#{event_type} repository=#{slug} #{event_details}"
        Travis::Sidekiq::BuildRequest.perform_async(data)
      end

      def handle_event?
        settings.events.include?(event_type)
      end

      def data
        {
          :type => event_type,
          :credentials => credentials,
          :payload => payload,
          :uuid => uuid,
          :github_guid => delivery_guid,
          :github_event => event_type
        }
      end

      def uuid
        @uuid ||= Travis.uuid
      end

      def event_type
        env['HTTP_X_GITHUB_EVENT'] || 'push'
      end

      def event_details
        if event_type == 'pull_request'
          "number=#{decoded_payload['number']} action=#{decoded_payload['action']} source=#{decoded_payload['pull_request']['head']['repo']['full_name']} head=#{decoded_payload['pull_request']['head']['sha'][0..6]} ref=#{decoded_payload['pull_request']['head']['ref']} user=#{decoded_payload['pull_request']['user']['login']}"
        else
          "ref=#{decoded_payload['ref']} " +
            "head=#{decoded_payload['head_commit']['id'][0..6]} " +
            "commits=#{decoded_payload["commits"].map {|c| c['id'][0..6]}.join(",")}"
        end
      end

      def delivery_guid
        env['HTTP_X_GITHUB_GUID']
      end

      def credentials
        login, token = Rack::Auth::Basic::Request.new(env).credentials
        { :login => login, :token => token }
      end

      def payload
        params[:payload]<commit_msg>Handle missing head_commit, only handle push/pull_request events.<commit_after>require 'sinatra'
require 'travis/support/logging'
require 'sidekiq'
require 'travis/sidekiq/build_request'
require 'newrelic_rpm'
require 'multi_json'
require 'ipaddr'
require 'metriks'

module Travis
  module Listener
    class App < Sinatra::Base
      include Logging

      # use Rack::CommonLogger for request logging
      enable :logging, :dump_errors

      # see https://github.com/github/github-services/blob/master/services/travis.rb#L1-2
      set :events, %w[push pull_request]

      before do
        logger.level = 1
      end

      get '/' do
        redirect "http://about.travis-ci.org"
      end

      # Used for new relic uptime monitoring
      get '/uptime' do
        200
      end

      # the main endpoint for scm services
      post '/' do
        report_ip_validity
        if !ip_validation? || valid_ip?
          if valid_request?
            handle_event

            204
          else
            Metriks.meter('listener.request.no_payload').mark
            422
          end
        else
          403
        end
      end

      protected

      def valid_request?
        payload
      end

      def ip_validation?
        (Travis.config.listener && Travis.config.listener.ip_validation)
      end

      def report_ip_validity
        if valid_ip?
          Metriks.meter('listener.ip.valid').mark
        else
          Metriks.meter('listener.ip.invalid').mark
          logger.info "Payload to travis-listener sent from an invalid IP(#{request.ip})"
        end
      end

      def valid_ip?
        return true if valid_ips.empty?

        valid_ips.any? { |ip| IPAddr.new(ip).include? request.ip }
      end

      def valid_ips
        (Travis.config.listener && Travis.config.listener.valid_ips) || []
      end

      def handle_event
        return unless handle_event?
        debug "Request created: #{payload.inspect}"
        info "uuid=#{uuid} delivery_guid=#{delivery_guid} type=#{event_type} repository=#{slug} #{event_details}"
        Travis::Sidekiq::BuildRequest.perform_async(data)
      end

      def handle_event?
        settings.events.include?(event_type)
      end

      def data
        {
          :type => event_type,
          :credentials => credentials,
          :payload => payload,
          :uuid => uuid,
          :github_guid => delivery_guid,
          :github_event => event_type
        }
      end

      def uuid
        @uuid ||= Travis.uuid
      end

      def event_type
        env['HTTP_X_GITHUB_EVENT'] || 'push'
      end

      def event_details
        if event_type == 'pull_request'
          "number=#{decoded_payload['number']} action=#{decoded_payload['action']} source=#{decoded_payload['pull_request']['head']['repo']['full_name']} head=#{decoded_payload['pull_request']['head']['sha'][0..6]} ref=#{decoded_payload['pull_request']['head']['ref']} user=#{decoded_payload['pull_request']['user']['login']}"
        elsif event_type == 'push'
          "ref=#{decoded_payload['ref']} " +
            "head=#{push_head_commit} " +
            "commits=#{(decoded_payload["commits"] || []).map {|c| c['id'][0..6]}.join(",")}"
        end
      end

      def push_head_commit
        decoded_payload['head_commit'] && decoded_payload['head_commit']['id'] && decoded_payload['head_commit']['id'][0..6]
      end

      def delivery_guid
        env['HTTP_X_GITHUB_GUID']
      end

      def credentials
        login, token = Rack::Auth::Basic::Request.new(env).credentials
        { :login => login, :token => token }
      end

      def payload
        params[:payload]
{'fraction_non_alphanumeric': 0.12082334696179332, 'fraction_numerical': 0.0059213308896094745, 'mean_word_length': 2.2437128486511204, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 19, 'https://': 2, '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': '893409', 'n_tokens_mistral': 2159, 'n_tokens_neox': 2102, 'n_words': 434}