def read_request(self, reader, message): """ read and output one http request. """ if message.expect_header and not utils.is_request(reader.fetch_line()): req_header = message.expect_header message.expect_header = None else: req_header = self.read_http_req_header(reader) if req_header is None: # read header error, we skip all data. reader.skip_all() return if req_header.expect: # it is expect:continue-100 post request message.expect_header = req_header # deal with body if not req_header.chunked: content = reader.read(req_header.content_len) else: content = self.read_chunked_body(reader) _filter = config.get_filter() show = _filter.by_domain(req_header.host) and _filter.by_uri(req_header.uri) message.filtered = not show if show: self.processor.on_http_req(req_header, content, self.cur_numbers)
def on_packet(self, packet): """ :type packet: TcpPack """ if self.is_http is None and packet.body: self.is_http = is_request(packet.body) if self.is_http == False: return if packet.source_key() == self.client_key: send_stream = self.up_stream confirm_stream = self.down_stream pac_type = HttpType.RESPONSE else: send_stream = self.down_stream confirm_stream = self.up_stream pac_type = HttpType.REQUEST if len(packet.body) > 0: send_stream.append_packet(packet) if packet.syn: pass if packet.ack: packets = confirm_stream.retrieve_packet(packet.ack_seq) if packets: for packet in packets: self.http_parser.send(pac_type, packet.body, packet.number) if packet.fin: send_stream.status = 1
def read_http_req_header(self, reader): """read & parse http headers""" line = reader.read_line() if line is None: return None line = line.strip() if not utils.is_request(line): return None req_header = HttpRequestHeader() items = line.split(b' ') if len(items) == 3: req_header.method = items[0] req_header.uri = items[1] req_header.protocol = items[2] lines = [line] header_dict = self.read_headers(reader, lines) if b"content-length" in header_dict: req_header.content_len = int(header_dict[b"content-length"]) if b"transfer-encoding" in header_dict and b'chunked' in header_dict[b"transfer-encoding"]: req_header.chunked = True req_header.content_type = header_dict[b'content-type'] req_header.compress = utils.get_compress_type(header_dict[b"content-encoding"]) req_header.host = header_dict[b"host"] if b'expect' in header_dict: req_header.expect = header_dict[b'expect'] req_header.raw_data = b'\n'.join(lines) return req_header
def parse_pcap_file(infile): """ :type infile:file """ conn_dict = OrderedDict() storage = dict() import builtins old_ord = ord file_format, head = get_file_format(infile) if file_format == FileFormat.PCAP: pcap_file = pcap.PcapFile(infile, head).read_packet elif file_format == FileFormat.PCAP_NG: # fix bug with ord(option[4]) in line 86 of pcapng.py def new_ord(c): if isinstance(c, str): return old_ord(c) return c builtins.ord = new_ord pcap_file = pcapng.PcapngFile(infile, head).read_packet else: print("unknown file format.", file=sys.stderr) sys.exit(1) _filter = config.get_filter() for tcp_pac in packet_parser.read_tcp_packet(pcap_file): # filter if not (_filter.by_ip(tcp_pac.source) or _filter.by_ip(tcp_pac.dest)): continue if not (_filter.by_port(tcp_pac.source_port) or _filter.by_port(tcp_pac.dest_port)): continue key = tcp_pac.gen_key() # we already have this conn if key in conn_dict: conn_dict[key].on_packet(tcp_pac) # conn closed. if conn_dict[key].closed(): conn_dict[key].finish() del conn_dict[key] # begin tcp connection. elif tcp_pac.syn and not tcp_pac.ack: conn_dict[key] = TcpConnection(tcp_pac, storage) elif utils.is_request(tcp_pac.body): # tcp init before capture, we start from a possible http request header. conn_dict[key] = TcpConnection(tcp_pac, storage) # finish connection which not close yet for conn in conn_dict.values(): conn.finish() builtins.ord = old_ord return storage
def _init(self, http_type, data): if not utils.is_request(data) or http_type != HttpType.REQUEST: # not a http request self.is_http = False else: self.is_http = True