Module: PcapTools::HttpParser
- Defined in:
- lib/pcap_tools.rb
Class Method Summary collapse
- .add_headers(o, headers) ⇒ Object
- .parse_request(stream) ⇒ Object
- .parse_response(stream) ⇒ Object
- .read_chunked(str) ⇒ Object
- .split_headers(str) ⇒ Object
Class Method Details
.add_headers(o, headers) ⇒ Object
169 170 171 172 173 174 |
# File 'lib/pcap_tools.rb', line 169 def self.add_headers o, headers headers.each do |line| m = /\A([^:]+):\s*/.match(line) or raise "Unable to parse line #{line}" o[m[1]] = m.post_match end end |
.parse_request(stream) ⇒ Object
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/pcap_tools.rb', line 129 def parse_request stream headers, body = split_headers(stream[:data]) line0 = headers.shift m = /(\S+)\s+(\S+)\s+(\S+)/.match(line0) or raise "Unable to parse first line of http request #{line0}" clazz = {'POST' => Net::HTTP::Post, 'GET' => Net::HTTP::Get, 'PUT' => Net::HTTP::Put}[m[1]] or raise "Unknown http request type #{m[1]}" req = clazz.new m[2] req['Pcap-Src'] = stream[:from] req['Pcap-Src-Port'] = stream[:from_port] req['Pcap-Dst'] = stream[:to] req['Pcap-Dst-Port'] = stream[:to_port] req.time = stream[:time] req.body = body add_headers req, headers req.body.size == req['Content-Length'].to_i or raise "Wrong content-length for http request, header say #{req['Content-Length'].chomp}, found #{req.body.size}" req end |
.parse_response(stream) ⇒ Object
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/pcap_tools.rb', line 148 def parse_response stream headers, body = split_headers(stream[:data]) line0 = headers.shift m = /^(\S+)\s+(\S+)\s+(.*)$/.match(line0) or raise "Unable to parse first line of http response #{line0}" resp = Net::HTTPResponse.send(:response_class, m[2]).new(m[1], m[2], m[3]) resp.time = stream[:time] add_headers resp, headers if resp.chunked? resp.body = read_chunked("\r\n" + body) else resp.body = body resp.body.size == resp['Content-Length'].to_i or raise "Wrong content-length for http response, header say #{resp['Content-Length'].chomp}, found #{resp.body.size}" end resp.body = Zlib::GzipReader.new(StringIO.new(resp.body)).read if resp['Content-Encoding'] == 'gzip' resp end |
.read_chunked(str) ⇒ Object
181 182 183 184 185 186 187 |
# File 'lib/pcap_tools.rb', line 181 def self.read_chunked str return "" if str == "\r\n" m = /\r\n([0-9a-fA-F]+)\r\n/.match(str) or raise "Unable to read chunked body in #{str.split("\r\n")[0]}" len = m[1].hex return "" if len == 0 m.post_match[0..len - 1] + read_chunked(m.post_match[len .. -1]) end |
.split_headers(str) ⇒ Object
176 177 178 179 |
# File 'lib/pcap_tools.rb', line 176 def self.split_headers str index = str.index("\r\n\r\n") return str[0 .. index].split("\r\n"), str[index + 4 .. -1] end |