25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 
 
 

146 satır
4.4 KiB

  1. @cython.no_gc_clear
  2. cdef class UVStreamServer(UVSocketHandle):
  3. def __cinit__(self):
  4. self.opened = 0
  5. self._server = None
  6. self.ssl = None
  7. self.ssl_handshake_timeout = None
  8. self.ssl_shutdown_timeout = None
  9. self.protocol_factory = None
  10. cdef inline _init(self, Loop loop, object protocol_factory,
  11. Server server,
  12. object backlog,
  13. object ssl,
  14. object ssl_handshake_timeout,
  15. object ssl_shutdown_timeout):
  16. if not isinstance(backlog, int):
  17. # Don't allow floats
  18. raise TypeError('integer argument expected, got {}'.format(
  19. type(backlog).__name__))
  20. if ssl is not None:
  21. if not isinstance(ssl, ssl_SSLContext):
  22. raise TypeError(
  23. 'ssl is expected to be None or an instance of '
  24. 'ssl.SSLContext, got {!r}'.format(ssl))
  25. else:
  26. if ssl_handshake_timeout is not None:
  27. raise ValueError(
  28. 'ssl_handshake_timeout is only meaningful with ssl')
  29. if ssl_shutdown_timeout is not None:
  30. raise ValueError(
  31. 'ssl_shutdown_timeout is only meaningful with ssl')
  32. self.backlog = backlog
  33. self.ssl = ssl
  34. self.ssl_handshake_timeout = ssl_handshake_timeout
  35. self.ssl_shutdown_timeout = ssl_shutdown_timeout
  36. self._start_init(loop)
  37. self.protocol_factory = protocol_factory
  38. self._server = server
  39. cdef inline listen(self):
  40. cdef int err
  41. self._ensure_alive()
  42. if self.protocol_factory is None:
  43. raise RuntimeError('unable to listen(); no protocol_factory')
  44. if self.opened != 1:
  45. raise RuntimeError('unopened TCPServer')
  46. err = uv.uv_listen(<uv.uv_stream_t*> self._handle,
  47. self.backlog,
  48. __uv_streamserver_on_listen)
  49. if err < 0:
  50. exc = convert_error(err)
  51. self._fatal_error(exc, True)
  52. return
  53. cdef inline _on_listen(self):
  54. cdef UVStream client
  55. protocol = self.protocol_factory()
  56. if self.ssl is None:
  57. client = self._make_new_transport(protocol, None)
  58. else:
  59. waiter = self._loop._new_future()
  60. ssl_protocol = SSLProtocol(
  61. self._loop, protocol, self.ssl,
  62. waiter,
  63. server_side=True,
  64. server_hostname=None,
  65. ssl_handshake_timeout=self.ssl_handshake_timeout,
  66. ssl_shutdown_timeout=self.ssl_shutdown_timeout)
  67. client = self._make_new_transport(ssl_protocol, None)
  68. waiter.add_done_callback(
  69. ft_partial(self.__on_ssl_connected, client))
  70. client._accept(<UVStream>self)
  71. cdef _fatal_error(self, exc, throw, reason=None):
  72. # Overload UVHandle._fatal_error
  73. self._close()
  74. if not isinstance(exc, OSError):
  75. if throw or self._loop is None:
  76. raise exc
  77. msg = f'Fatal error on server {self.__class__.__name__}'
  78. if reason is not None:
  79. msg = f'{msg} ({reason})'
  80. self._loop.call_exception_handler({
  81. 'message': msg,
  82. 'exception': exc,
  83. })
  84. cdef inline _mark_as_open(self):
  85. self.opened = 1
  86. cdef UVStream _make_new_transport(self, object protocol, object waiter):
  87. raise NotImplementedError
  88. def __on_ssl_connected(self, transport, fut):
  89. exc = fut.exception()
  90. if exc is not None:
  91. transport._force_close(exc)
  92. cdef void __uv_streamserver_on_listen(uv.uv_stream_t* handle,
  93. int status) with gil:
  94. # callback for uv_listen
  95. if __ensure_handle_data(<uv.uv_handle_t*>handle,
  96. "UVStream listen callback") == 0:
  97. return
  98. cdef:
  99. UVStreamServer stream = <UVStreamServer> handle.data
  100. if status < 0:
  101. if UVLOOP_DEBUG:
  102. stream._loop._debug_stream_listen_errors_total += 1
  103. exc = convert_error(status)
  104. stream._fatal_error(
  105. exc, False, "error status in uv_stream_t.listen callback")
  106. return
  107. try:
  108. stream._on_listen()
  109. except BaseException as exc:
  110. stream._error(exc, False)