Example #1
0
 def _parseHeaders(self, data):
     "Given a control frame data block, return a list of (name, value) tuples."
     # TODO: separate null-delimited into separate instances
     data = decompress(data, dictionary=dictionary) # FIXME: catch errors
     cursor = 2
     (num_hdrs,) = struct.unpack("!h", data[:cursor]) # FIXME: catch errors
     hdrs = []
     while cursor < len(data):
         try:
             (name_len,) = struct.unpack("!h", data[cursor:cursor+2]) # FIXME: catch errors
             cursor += 2
             name = data[cursor:cursor+name_len] # FIXME: catch errors
             cursor += name_len
         except IndexError:
             raise
         except struct.error:
             raise
         try:
             (val_len,) = struct.unpack("!h", data[cursor:cursor+2]) # FIXME: catch errors
             cursor += 2
             value = data[cursor:cursor+val_len] # FIXME: catch errors
             cursor += val_len
         except IndexError:
             raise
         except struct.error:
             print len(data), cursor, data # FIXME
             raise
         self.addRawHeader(name, value)
Example #2
0
	def _parse_header_chunk(self, compressed_data, version):
		#chunk = self.inflater.decompress(compressed_data)
		chunk = decompress(compressed_data, dictionary=HEADER_ZLIB_DICT_2)
		#print 'decompressed_headers', repr(chunk)
		
		length_size = 2 if version == 2 else 4
		length_fmt = '>H' if length_size == 2 else '>L'
		headers = {}

		#first two bytes: number of pairs
		#num_values = int.from_bytes(chunk[0:length_size], 'big')
		num_values = struct.unpack(length_fmt, chunk[0:length_size])[0]

		#after that...
		cursor = length_size
		for _ in range(num_values):
			#two/four bytes: length of name
			#name_length = int.from_bytes(chunk[cursor:cursor+length_size], 'big')
			name_length = struct.unpack(length_fmt, chunk[cursor:cursor+length_size])[0]
			cursor += length_size

			#next name_length bytes: name
			name = chunk[cursor:cursor+name_length].decode('UTF-8')
			cursor += name_length

			#two/four bytes: length of value
			#value_length = int.from_bytes(chunk[cursor:cursor+length_size], 'big')
			value_length = struct.unpack(length_fmt, chunk[cursor:cursor+length_size])[0]
			cursor += length_size

			#next value_length bytes: value
			value = chunk[cursor:cursor+value_length].decode('UTF-8')
			cursor += value_length

			if name_length == 0 or value_length == 0:
				raise SpdyProtocolError("zero-length name or value in n/v block")
			if name in headers:
				raise SpdyProtocolError("duplicate name in n/v block")
			headers[name] = value

		return headers