Class: Rex::Proto::Http::Packet::Header

Inherits:
Hash
  • Object
show all
Defined in:
lib/rex/proto/http/packet/header.rb

Overview

Represents the logical HTTP header portion of an HTTP packet (request or response).

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeHeader

Initializes an HTTP packet header class that inherits from a Hash base class.


20
21
22
23
24
# File 'lib/rex/proto/http/packet/header.rb', line 20

def initialize
  self.dcase_hash = {}

  reset
end

Instance Attribute Details

#cmd_stringObject

Returns the value of attribute cmd_string


170
171
172
# File 'lib/rex/proto/http/packet/header.rb', line 170

def cmd_string
  @cmd_string
end

#dcase_hashObject (protected)

:nodoc:


175
176
177
# File 'lib/rex/proto/http/packet/header.rb', line 175

def dcase_hash
  @dcase_hash
end

#foldObject

Returns the value of attribute fold


171
172
173
# File 'lib/rex/proto/http/packet/header.rb', line 171

def fold
  @fold
end

#junk_headersObject

The raw command string associated with the header which will vary between requests and responses.


169
170
171
# File 'lib/rex/proto/http/packet/header.rb', line 169

def junk_headers
  @junk_headers
end

Instance Method Details

#[](key) ⇒ Object

More advanced [] that does downcase comparison.


64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/rex/proto/http/packet/header.rb', line 64

def [](key)
  begin
    rv = self.fetch(key)
  rescue IndexError
    rv = nil
  end
  if (rv == nil)
    begin
      rv = self.dcase_hash[key.downcase]
    rescue IndexError
      rv = nil
    end
  end

  return rv
end

#[]=(key, value) ⇒ Object

More advanced []= that does downcase storage.


84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/rex/proto/http/packet/header.rb', line 84

def []=(key, value)
  stored = false

  self.each_key { |k|
    if (k.downcase == key.downcase)
      self.store(k, value)
      stored = true
    end
  }

  self.store(key, value) if (stored == false)
  self.dcase_hash[key.downcase] = value
end

#each(&block) ⇒ Object

Overrides the builtin 'each' operator to avoid the following exception on Ruby 1.9.2+

"can't add a new key into hash during iteration"

157
158
159
160
161
162
163
# File 'lib/rex/proto/http/packet/header.rb', line 157

def each(&block)
  list = []
  self.keys.sort.each do |sidx|
    list << [sidx, self[sidx]]
  end
  list.each(&block)
end

#from_a(ary) ⇒ Object

Brings in from an array like yo.


138
139
140
141
142
# File 'lib/rex/proto/http/packet/header.rb', line 138

def from_a(ary)
  ary.each { |e|
    self[e[0]] = e[1]
  }
end

#from_s(header) ⇒ Object

Parses a header from a string.

XXX - Putting : in a header value breaks this badly


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
# File 'lib/rex/proto/http/packet/header.rb', line 30

def from_s(header)
  reset

  # ghettoooooo!
  # If we don't have any newlines..., put one there.
  if (header.size > 0 && header !~ /\r\n/)
    header << "\r\n"
  end

  # put the non-standard line terminations back to normal
  # gah.  not having look behinds suck,
  header.gsub!(/([^\r])\n/n,'\1' + "\r\n")

  # undo folding, kinda ugly but works for now.
  header.gsub!(/:\s*\r\n\s+/smni,': ')

  # Extract the command string
  self.cmd_string = header.slice!(/.+\r\n/)

  # Extract each header value pair
  header.split(/\r\n/mn).each { |str|
    if (md = str.match(/^(.+?)\s*:\s*(.+?)\s*$/))
      if (self[md[1]])
        self[md[1]] << ", " + md[2]
      else
        self[md[1]] = md[2]
      end
    end
  }
end

#include?(key) ⇒ Boolean

More advanced include? that does downcase comparison

Returns:

  • (Boolean)

101
102
103
104
105
# File 'lib/rex/proto/http/packet/header.rb', line 101

def include?(key)
  self.each_key.any? { |k|
    k.casecmp?(key)
  }
end

#resetObject

Flushes all header pairs.


147
148
149
150
151
# File 'lib/rex/proto/http/packet/header.rb', line 147

def reset
  self.cmd_string = ''
  self.clear
  self.dcase_hash.clear
end

#to_s(prefix = '') ⇒ Object

Converts the header to a string.


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
# File 'lib/rex/proto/http/packet/header.rb', line 109

def to_s(prefix = '')
  str = prefix

  if self.junk_headers
    while str.length < 4096
      if self.fold
        str << "X-#{Rex::Text.rand_text_alphanumeric(rand(30) + 5)}:\r\n\t#{Rex::Text.rand_text_alphanumeric(rand(1024) + 1)}\r\n"
      else
        str << "X-#{Rex::Text.rand_text_alphanumeric(rand(30) + 5)}: #{Rex::Text.rand_text_alphanumeric(rand(1024) + 1)}\r\n"
      end
    end
  end

  each_pair { |var, val|
    if self.fold
      str << "#{var}:\r\n\t#{val}\r\n"
    else
      str << "#{var}: #{val}\r\n"
    end
  }

  str << "\r\n"

  return str
end