/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
|