Beispiel #1
0
def helloDataToHelloFrame(helloData):
	"""
	Convert arbitrary JSON-decoded blob of objects into a L{HelloFrame}.
	Raises L{InvalidHello} if there were errors in the blob of objects.
	"""
	if not isinstance(helloData, dict):
		raise InvalidHello("helloData not a dict")

	# simplejson without speedups will always give us unicode instead of str
	# objects.  (With speedups, it gives you a str when possible.)
	for k, v in helloData.iteritems():
		if isinstance(v, unicode):
			try:
				helloData[k] = v.encode('ascii')
			except UnicodeEncodeError:
				raise InvalidHello("could not encode value for key "
					"%r to ascii; was %r" % (k, v))

	obj = attrdict()

	# sack is always optional.
	if Hello_sack in helloData:
		try:
			sack = helloData[Hello_sack]
			if not isinstance(sack, str):
				raise TypeError
			obj.sack = sackStringToSack(sack)
		except (KeyError, TypeError, InvalidSackString):
			raise InvalidHello("bad sack")
	else:
		obj.sack = None

	try:
		lastSackSeen = helloData[Hello_lastSackSeenByClient]
		if not isinstance(lastSackSeen, str):
			raise TypeError
		obj.lastSackSeenByClient = sackStringToSack(lastSackSeen)
	except (KeyError, TypeError, InvalidSackString):
		raise InvalidHello("bad lastSackSeenByClient")

	try:
		# Any line here can raise KeyError; additional exceptions marked with 'e:'

		# requestNewStream is always optional.  If missing or False/0,
		# transport is intended to attach to an existing stream.
		obj.requestNewStream = ensureBool( # e: ValueError
			helloData[Hello_requestNewStream]) if \
			Hello_requestNewStream in helloData else False

		obj.transportNumber = ensureNonNegIntLimit( # e: ValueError, TypeError
			helloData[Hello_transportNumber], 2**53)

		obj.protocolVersion = helloData[Hello_protocolVersion]

		obj.streamingResponse = ensureBool( # e: ValueError
			helloData[Hello_streamingResponse])

		# Rules for streamId: must be 20-30 inclusive bytes, must not
		# contain codepoints > 127
		obj.streamId = helloData[Hello_streamId]
		if not isinstance(obj.streamId, str) or not 20 <= len(obj.streamId) <= 30:
			raise InvalidHello("bad streamId")
	except (KeyError, TypeError, ValueError):
		raise InvalidHello(
			"problem with requestNewStream, transportNumber, "
			"protocolVersion, streamingResponse, or streamId")

	if obj.protocolVersion != 2:
		raise InvalidHello("bad protocolVersion")

	# Hello_succeedsTransport is always optional.  If missing, the client does not
	# want to get S2C strings over this transport.  If None, the client does,
	# but the transport does not succeed an existing primary transport.  If a
	# number, the transport might succeed an existing primary transport.
	if Hello_succeedsTransport in helloData:
		obj.succeedsTransport = helloData[Hello_succeedsTransport]
		if obj.succeedsTransport is not None:
			try:
				obj.succeedsTransport = ensureNonNegIntLimit(
					obj.succeedsTransport, 2**53)
			except (TypeError, ValueError):
				raise InvalidHello("bad succeedsTransport")

	try:
		obj.httpFormat = helloData[Hello_httpFormat]
		if not obj.httpFormat in (FORMAT_XHR, FORMAT_HTMLFILE):
			raise InvalidHello("bad httpFormat")
	except KeyError:
		obj.httpFormat = None

	# needPaddingBytes is always optional.  If missing, 0.
	if Hello_needPaddingBytes in helloData:
		try:
			obj.needPaddingBytes = ensureNonNegIntLimit(
				helloData[Hello_needPaddingBytes], 16*1024) # e: ValueError, TypeError
		except (TypeError, ValueError):
			raise InvalidHello("bad needPaddingBytes")
	else:
		obj.needPaddingBytes = 0

	# maxReceiveBytes is optional.  If missing, no limit.
	try:
		obj.maxReceiveBytes = ensureNonNegIntLimit(
			helloData[Hello_maxReceiveBytes], 2**53) # e: ValueError, TypeError
	except KeyError:
		obj.maxReceiveBytes = 2**53
	except (TypeError, ValueError):
		raise InvalidHello("bad maxReceiveBytes")

	# maxOpenTime is optional.  If missing, no limit.
	# Time is in seconds.
	try:
		obj.maxOpenTime = ensureNonNegIntLimit(
			helloData[Hello_maxOpenTime], 2**53) # e: ValueError, TypeError
	except KeyError:
		obj.maxOpenTime = None
	except (TypeError, ValueError):
		raise InvalidHello("bad maxOpenTime")

	# maxInactivity is required.  If 0, no heartbeat.
	# Time is in seconds.
	try:
		obj.maxInactivity = ensureNonNegIntLimit(
			helloData[Hello_maxInactivity], 600) # e: ValueError, TypeError
	except (KeyError, TypeError, ValueError):
		raise InvalidHello("bad maxInactivity")

	return HelloFrame(obj)
Beispiel #2
0
	def test_False(self):
		for f in (0, 0.0, -0.0, False):
			self.assertIdentical(False, objcheck.ensureBool(f))
Beispiel #3
0
	def test_ValueError(self):
		for e in (-0.5, -1.00001, 1.0001, [], {}, set(), float('nan'), float('inf')):
			self.assertRaises(ValueError, lambda: objcheck.ensureBool(e))
Beispiel #4
0
	def test_True(self):
		for t in (1, 1.0, True):
			self.assertIdentical(True, objcheck.ensureBool(t))