class PacketGen::Header::HTTP::Request

An HTTP/1.1 Request packet consists of:

Create a HTTP Request header

# standalone
http_rqst = PacketGen::Header::HTTP::Request.new
# in a packet
pkt = PacketGen.gen("IP").add("TCP").add("HTTP::Request")
# access to HTTP Request header
pkt.http_request # => PacketGen::Header::HTTP::Request

Note: When creating a HTTP Request packet, sport and dport attributes of TCP header are not set.

HTTP Request attributes

http_rqst.version = "HTTP/1.1"
http_rqst.verb  = "GET"
http_rqst.path    = "/meow.html"
http_rqst.headers = "Host: tcpdump.org"     # string or
http_rqst.headers = { "Host": "tcpdump.org" } # even a hash

@author Kent 'picat' Gruber @author Sylvain Daubert @since 3.1.0 Rename #method into {#verb} to not mask +Object#method+.

Public Class Methods

new(options={}) click to toggle source

@param [Hash] options @option options [String] :verb @option options [String] :path @option options [String] :version @option options [Hash] :headers

Calls superclass method PacketGen::Header::Base::new
# File lib/packetgen/header/http/request.rb, line 62
def initialize(options={})
  super(options)
  self.headers ||= options[:headers]
end

Public Instance Methods

parse?() click to toggle source
# File lib/packetgen/header/http/request.rb, line 84
def parse?
  VERBS.include?(self.verb) && self.version.start_with?('HTTP/1.')
end
read(str) click to toggle source

Read in the HTTP portion of the packet, and parse it. @return [PacketGen::HTTP::Request]

# File lib/packetgen/header/http/request.rb, line 69
def read(str)
  lines = lines(str)
  first_line_words = lines.shift.split
  self[:verb].read first_line_words[0]
  self[:path].read first_line_words[1]
  self[:version].read first_line_words[2]

  # requests can sometimes have a payload
  headers, data = headers_and_payload_from_lines(lines)
  self[:headers].read(headers)
  self[:body].read(data)

  self
end
to_s() click to toggle source

String representation of data. @return [String]

# File lib/packetgen/header/http/request.rb, line 90
def to_s
  raise FormatError, 'Missing #verb.' if self.verb.empty?
  raise FormatError, 'Missing #path.'    if self.path.empty?
  raise FormatError, 'Missing #version.' if self.version.empty?

  "#{self.verb.dup} #{self.path} #{self.version}\r\n#{self[:headers]}#{self.body}"
end

Private Instance Methods

headers_and_payload_from_lines(lines) click to toggle source
# File lib/packetgen/header/http/request.rb, line 108
def headers_and_payload_from_lines(lines)
  if (data_index = lines.find_index(''))
    data    = lines[data_index + 1..-1].join("\n")
    headers = lines[0..data_index - 1].join("\n")
  else
    headers = lines.join("\n")
    data = nil
  end

  [headers, data]
end
lines(str) click to toggle source

@todo check verb is correct or raise a ParseError

# File lib/packetgen/header/http/request.rb, line 101
def lines(str)
  str = str.bytes.map!(&:chr).join unless str.valid_encoding?
  # vrb = HTTP::VERBS.detect { |verb| str.include?(verb) }

  str.split("\r\n").map(&:chomp)
end