Class: Mu::Pcap::Reader::HttpFamily

Inherits:
Mu::Pcap::Reader show all
Defined in:
lib/mu/pcap/reader/http_family.rb

Overview

Reader for HTTP family of protocols (HTTP/SIP/RTSP). Handles message boundaries and decompressing/dechunking payloads.

Constant Summary collapse

FAMILY =
:http
CRLF =
"\r\n"
RE_CONTENT_ENCODING =
/^content-encoding:\s*(gzip|deflate)/i
RE_CHUNKED =
/Transfer-Encoding:\s*chunked/i
RE_HEADERS_COMPLETE =
/.*?\r\n\r\n/m
RE_REQUEST_LINE =

Request line e.g. GET /index.html HTTP/1.1

/\A([^ \t\r\n]+)[ \t]+([^ \t\r\n]+)[ \t]+(HTTP|SIP|RTSP)\/[\d.]+.*\r\n/
RE_STATUS_LINE =

Status line e.g. SIP/2.0 404 Authorization required

/\A((HTTP|SIP|RTSP)\/[\d.]+[ \t]+(\d+))\b.*\r\n/
RE_CONTENT_LENGTH =
/^(Content-Length)(:\s*)(\d+)\r\n/i
RE_CONTENT_LENGTH_SIP =
/^(Content-Length|l)(:\s*)(\d+)\r\n/i
RE_CHUNK_SIZE_LINE =

Returns array containing raw and dechunked payload. Returns nil if payload cannot be completely read.

/\A([[:xdigit:]]+)\r\n?/

Constants inherited from Mu::Pcap::Reader

FAMILY_TO_READER

Instance Attribute Summary

Attributes inherited from Mu::Pcap::Reader

#pcap2scenario

Instance Method Summary collapse

Methods inherited from Mu::Pcap::Reader

#read_message, #read_message!, reader, #record_write

Instance Method Details

#familyObject



19
20
21
# File 'lib/mu/pcap/reader/http_family.rb', line 19

def family
    FAMILY
end

#get_chunks(bytes) ⇒ Object



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/mu/pcap/reader/http_family.rb', line 121

def get_chunks bytes
    raw = []
    dechunked = []
    io = StringIO.new bytes
    until io.eof?
        # Read size line
        size_line = io.readline 
        raw << size_line
        if size_line =~ RE_CHUNK_SIZE_LINE
            chunk_size = $1.to_i(16)
        else
            # Malformed chunk size line
            $stderr.puts "malformed size line : #{size_line.inspect}"
            return nil
        end

        # Read chunk data
        chunk = io.read(chunk_size)
        if chunk.size < chunk_size
            # malformed/incomplete
            $stderr.puts "malformed/incomplete #{chunk_size}"
            return nil
        end
        raw << chunk
        dechunked << chunk
        # Get end-of-chunk CRLF
        crlf = io.read(2)
        if crlf == CRLF
            raw << crlf
        else
            # CRLF has not arrived or, if this is the last chunk,
            # we might be looking at the first two bytes of a trailer
            # and we don't support trailers (see rfc 2616 sec3.6.1).
            return nil
        end

        if chunk_size == 0
            # Done. Return raw and dechunked payloads.
            return raw.join, dechunked.join
        end
    end

    # EOF w/out reaching last chunk.
    return nil
end