This file is indexed.

/usr/lib/ruby/vendor_ruby/em/protocols/header_and_content.rb is in ruby-eventmachine 1.0.3-4.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#--
#
# Author:: Francis Cianfrocca (gmail: blackhedd)
# Homepage::  http://rubyeventmachine.com
# Date:: 15 Nov 2006
# 
# See EventMachine and EventMachine::Connection for documentation and
# usage examples.
#
#----------------------------------------------------------------------------
#
# Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
# Gmail: blackhedd
# 
# This program is free software; you can redistribute it and/or modify
# it under the terms of either: 1) the GNU General Public License
# as published by the Free Software Foundation; either version 2 of the
# License, or (at your option) any later version; or 2) Ruby's License.
# 
# See the file COPYING for complete licensing information.
#
#---------------------------------------------------------------------------
#
#

module EventMachine
  module Protocols

    # === Usage
    #
    #  class RequestHandler < EM::P::HeaderAndContentProtocol
    #    def receive_request headers, content
    #      p [:request, headers, content]
    #    end
    #  end
    #
    #  EM.run{
    #    EM.start_server 'localhost', 80, RequestHandler
    #  }
    #
    #--
    # Originally, this subclassed LineAndTextProtocol, which in
    # turn relies on BufferedTokenizer, which doesn't gracefully
    # handle the transitions between lines and binary text.
    # Changed 13Sep08 by FCianfrocca.
    class HeaderAndContentProtocol < Connection
      include LineText2

      ContentLengthPattern = /Content-length:\s*(\d+)/i

      def initialize *args
        super
        init_for_request
      end

      def receive_line line
        case @hc_mode
        when :discard_blanks
          unless line == ""
            @hc_mode = :headers
            receive_line line
          end
        when :headers
          if line == ""
            raise "unrecognized state" unless @hc_headers.length > 0
            if respond_to?(:receive_headers)
              receive_headers @hc_headers
            end
            # @hc_content_length will be nil, not 0, if there was no content-length header.
            if @hc_content_length.to_i > 0
              set_binary_mode @hc_content_length
            else
              dispatch_request
            end
          else
            @hc_headers << line
            if ContentLengthPattern =~ line
              # There are some attacks that rely on sending multiple content-length
              # headers. This is a crude protection, but needs to become tunable.
              raise "extraneous content-length header" if @hc_content_length
              @hc_content_length = $1.to_i
            end
            if @hc_headers.length == 1 and respond_to?(:receive_first_header_line)
              receive_first_header_line line
            end
          end
        else
          raise "internal error, unsupported mode"
        end
      end

      def receive_binary_data text
        @hc_content = text
        dispatch_request
      end

      def dispatch_request
        if respond_to?(:receive_request)
          receive_request @hc_headers, @hc_content
        end
        init_for_request
      end
      private :dispatch_request

      def init_for_request
        @hc_mode = :discard_blanks
        @hc_headers = []
        # originally was @hc_headers ||= []; @hc_headers.clear to get a performance
        # boost, but it's counterproductive because a subclassed handler will have to
        # call dup to use the header array we pass in receive_headers.

        @hc_content_length = nil
        @hc_content = ""
      end
      private :init_for_request

      # Basically a convenience method. We might create a subclass that does this
      # automatically. But it's such a performance killer.
      def headers_2_hash hdrs
        self.class.headers_2_hash hdrs
      end

      class << self
        def headers_2_hash hdrs
          hash = {}
          hdrs.each {|h|
            if /\A([^\s:]+)\s*:\s*/ =~ h
              tail = $'.dup
              hash[ $1.downcase.gsub(/-/,"_").intern ] = tail
            end
          }
          hash
        end
      end

    end
  end
end