extension.py 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. class Extension(object):
  2. name = ''
  3. rsv1 = False
  4. rsv2 = False
  5. rsv3 = False
  6. opcodes = ()
  7. defaults = {}
  8. def __init__(self, **kwargs):
  9. for param in kwargs.iterkeys():
  10. if param not in self.defaults:
  11. raise KeyError('unrecognized parameter "%s"' % param)
  12. # Copy dict first to avoid duplicate references to the same object
  13. self.defaults = dict(self.__class__.defaults)
  14. self.defaults.update(kwargs)
  15. def __str__(self):
  16. return '<Extension "%s" defaults=%s request=%s>' \
  17. % (self.name, self.defaults, self.request)
  18. @property
  19. def names(self):
  20. return (self.name,) if self.name else ()
  21. def conflicts(self, ext):
  22. """
  23. Check if the extension conflicts with an already accepted extension.
  24. This may be the case when the two extensions use the same reserved
  25. bits, or have the same name (when the same extension is negotiated
  26. multiple times with different parameters).
  27. """
  28. return ext.rsv1 and self.rsv1 \
  29. or ext.rsv2 and self.rsv2 \
  30. or ext.rsv3 and self.rsv3 \
  31. or set(ext.names) & set(self.names) \
  32. or set(ext.opcodes) & set(self.opcodes)
  33. def negotiate(self, name, params):
  34. """
  35. Same as `negotiate_safe`, but instead returns an iterator of (param,
  36. value) tuples and raises an exception on error.
  37. """
  38. raise NotImplementedError
  39. def negotiate_safe(self, name, params):
  40. """
  41. `name` and `params` are sent in the HTTP request by the client. Check
  42. if the extension name is supported by this extension, and validate the
  43. parameters. Returns a dict with accepted parameters, or None if not
  44. accepted.
  45. """
  46. for param in params.iterkeys():
  47. if param not in self.defaults:
  48. return
  49. try:
  50. return dict(self.negotiate(name, params))
  51. except (KeyError, ValueError, AssertionError):
  52. pass
  53. class Instance:
  54. def __init__(self, extension, name, params):
  55. self.extension = extension
  56. self.name = name
  57. self.params = params
  58. for param, value in extension.defaults.iteritems():
  59. setattr(self, param, value)
  60. for param, value in params.iteritems():
  61. setattr(self, param, value)
  62. self.init()
  63. def init(self):
  64. return NotImplemented
  65. def onsend_frame(self, frame):
  66. pass
  67. def onrecv_frame(self, frame):
  68. pass
  69. def onsend_message(self, message):
  70. pass
  71. def onrecv_message(self, message):
  72. pass