您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

151 行
4.5 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. self.context = Context_CopyCurrent()
  47. err = uv.uv_listen(<uv.uv_stream_t*> self._handle,
  48. self.backlog,
  49. __uv_streamserver_on_listen)
  50. if err < 0:
  51. exc = convert_error(err)
  52. self._fatal_error(exc, True)
  53. return
  54. cdef inline _on_listen(self):
  55. cdef UVStream client
  56. protocol = run_in_context(self.context, self.protocol_factory)
  57. if self.ssl is None:
  58. client = self._make_new_transport(protocol, None, self.context)
  59. else:
  60. waiter = self._loop._new_future()
  61. ssl_protocol = SSLProtocol(
  62. self._loop, protocol, self.ssl,
  63. waiter,
  64. server_side=True,
  65. server_hostname=None,
  66. ssl_handshake_timeout=self.ssl_handshake_timeout,
  67. ssl_shutdown_timeout=self.ssl_shutdown_timeout)
  68. client = self._make_new_transport(ssl_protocol, None, self.context)
  69. waiter.add_done_callback(
  70. ft_partial(self.__on_ssl_connected, client))
  71. client._accept(<UVStream>self)
  72. cdef _fatal_error(self, exc, throw, reason=None):
  73. # Overload UVHandle._fatal_error
  74. self._close()
  75. if not isinstance(exc, OSError):
  76. if throw or self._loop is None:
  77. raise exc
  78. msg = f'Fatal error on server {self.__class__.__name__}'
  79. if reason is not None:
  80. msg = f'{msg} ({reason})'
  81. self._loop.call_exception_handler({
  82. 'message': msg,
  83. 'exception': exc,
  84. })
  85. cdef inline _mark_as_open(self):
  86. self.opened = 1
  87. cdef UVStream _make_new_transport(self, object protocol, object waiter,
  88. object context):
  89. raise NotImplementedError
  90. def __on_ssl_connected(self, transport, fut):
  91. exc = fut.exception()
  92. if exc is not None:
  93. transport._force_close(exc)
  94. cdef void __uv_streamserver_on_listen(
  95. uv.uv_stream_t* handle,
  96. int status,
  97. ) noexcept with gil:
  98. # callback for uv_listen
  99. if __ensure_handle_data(<uv.uv_handle_t*>handle,
  100. "UVStream listen callback") == 0:
  101. return
  102. cdef:
  103. UVStreamServer stream = <UVStreamServer> handle.data
  104. if status < 0:
  105. if UVLOOP_DEBUG:
  106. stream._loop._debug_stream_listen_errors_total += 1
  107. exc = convert_error(status)
  108. stream._fatal_error(
  109. exc, False, "error status in uv_stream_t.listen callback")
  110. return
  111. try:
  112. stream._on_listen()
  113. except BaseException as exc:
  114. stream._error(exc, False)