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)
def test_False(self): for f in (0, 0.0, -0.0, False): self.assertIdentical(False, objcheck.ensureBool(f))
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))
def test_True(self): for t in (1, 1.0, True): self.assertIdentical(True, objcheck.ensureBool(t))