__init__.py 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. # Copyright 2011, Google Inc.
  2. # All rights reserved.
  3. #
  4. # Redistribution and use in source and binary forms, with or without
  5. # modification, are permitted provided that the following conditions are
  6. # met:
  7. #
  8. # * Redistributions of source code must retain the above copyright
  9. # notice, this list of conditions and the following disclaimer.
  10. # * Redistributions in binary form must reproduce the above
  11. # copyright notice, this list of conditions and the following disclaimer
  12. # in the documentation and/or other materials provided with the
  13. # distribution.
  14. # * Neither the name of Google Inc. nor the names of its
  15. # contributors may be used to endorse or promote products derived from
  16. # this software without specific prior written permission.
  17. #
  18. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19. # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20. # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  21. # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  22. # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23. # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  24. # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25. # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  26. # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  28. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. """WebSocket extension for Apache HTTP Server.
  30. mod_pywebsocket is a WebSocket extension for Apache HTTP Server
  31. intended for testing or experimental purposes. mod_python is required.
  32. Installation
  33. ============
  34. 0. Prepare an Apache HTTP Server for which mod_python is enabled.
  35. 1. Specify the following Apache HTTP Server directives to suit your
  36. configuration.
  37. If mod_pywebsocket is not in the Python path, specify the following.
  38. <websock_lib> is the directory where mod_pywebsocket is installed.
  39. PythonPath "sys.path+['<websock_lib>']"
  40. Always specify the following. <websock_handlers> is the directory where
  41. user-written WebSocket handlers are placed.
  42. PythonOption mod_pywebsocket.handler_root <websock_handlers>
  43. PythonHeaderParserHandler mod_pywebsocket.headerparserhandler
  44. To limit the search for WebSocket handlers to a directory <scan_dir>
  45. under <websock_handlers>, configure as follows:
  46. PythonOption mod_pywebsocket.handler_scan <scan_dir>
  47. <scan_dir> is useful in saving scan time when <websock_handlers>
  48. contains many non-WebSocket handler files.
  49. If you want to allow handlers whose canonical path is not under the root
  50. directory (i.e. symbolic link is in root directory but its target is not),
  51. configure as follows:
  52. PythonOption mod_pywebsocket.allow_handlers_outside_root_dir On
  53. Example snippet of httpd.conf:
  54. (mod_pywebsocket is in /websock_lib, WebSocket handlers are in
  55. /websock_handlers, port is 80 for ws, 443 for wss.)
  56. <IfModule python_module>
  57. PythonPath "sys.path+['/websock_lib']"
  58. PythonOption mod_pywebsocket.handler_root /websock_handlers
  59. PythonHeaderParserHandler mod_pywebsocket.headerparserhandler
  60. </IfModule>
  61. 2. Tune Apache parameters for serving WebSocket. We'd like to note that at
  62. least TimeOut directive from core features and RequestReadTimeout
  63. directive from mod_reqtimeout should be modified not to kill connections
  64. in only a few seconds of idle time.
  65. 3. Verify installation. You can use example/console.html to poke the server.
  66. Writing WebSocket handlers
  67. ==========================
  68. When a WebSocket request comes in, the resource name
  69. specified in the handshake is considered as if it is a file path under
  70. <websock_handlers> and the handler defined in
  71. <websock_handlers>/<resource_name>_wsh.py is invoked.
  72. For example, if the resource name is /example/chat, the handler defined in
  73. <websock_handlers>/example/chat_wsh.py is invoked.
  74. A WebSocket handler is composed of the following three functions:
  75. web_socket_do_extra_handshake(request)
  76. web_socket_transfer_data(request)
  77. web_socket_passive_closing_handshake(request)
  78. where:
  79. request: mod_python request.
  80. web_socket_do_extra_handshake is called during the handshake after the
  81. headers are successfully parsed and WebSocket properties (ws_location,
  82. ws_origin, and ws_resource) are added to request. A handler
  83. can reject the request by raising an exception.
  84. A request object has the following properties that you can use during the
  85. extra handshake (web_socket_do_extra_handshake):
  86. - ws_resource
  87. - ws_origin
  88. - ws_version
  89. - ws_location (HyBi 00 only)
  90. - ws_extensions (HyBi 06 and later)
  91. - ws_deflate (HyBi 06 and later)
  92. - ws_protocol
  93. - ws_requested_protocols (HyBi 06 and later)
  94. The last two are a bit tricky. See the next subsection.
  95. Subprotocol Negotiation
  96. -----------------------
  97. For HyBi 06 and later, ws_protocol is always set to None when
  98. web_socket_do_extra_handshake is called. If ws_requested_protocols is not
  99. None, you must choose one subprotocol from this list and set it to
  100. ws_protocol.
  101. For HyBi 00, when web_socket_do_extra_handshake is called,
  102. ws_protocol is set to the value given by the client in
  103. Sec-WebSocket-Protocol header or None if
  104. such header was not found in the opening handshake request. Finish extra
  105. handshake with ws_protocol untouched to accept the request subprotocol.
  106. Then, Sec-WebSocket-Protocol header will be sent to
  107. the client in response with the same value as requested. Raise an exception
  108. in web_socket_do_extra_handshake to reject the requested subprotocol.
  109. Data Transfer
  110. -------------
  111. web_socket_transfer_data is called after the handshake completed
  112. successfully. A handler can receive/send messages from/to the client
  113. using request. mod_pywebsocket.msgutil module provides utilities
  114. for data transfer.
  115. You can receive a message by the following statement.
  116. message = request.ws_stream.receive_message()
  117. This call blocks until any complete text frame arrives, and the payload data
  118. of the incoming frame will be stored into message. When you're using IETF
  119. HyBi 00 or later protocol, receive_message() will return None on receiving
  120. client-initiated closing handshake. When any error occurs, receive_message()
  121. will raise some exception.
  122. You can send a message by the following statement.
  123. request.ws_stream.send_message(message)
  124. Closing Connection
  125. ------------------
  126. Executing the following statement or just return-ing from
  127. web_socket_transfer_data cause connection close.
  128. request.ws_stream.close_connection()
  129. close_connection will wait
  130. for closing handshake acknowledgement coming from the client. When it
  131. couldn't receive a valid acknowledgement, raises an exception.
  132. web_socket_passive_closing_handshake is called after the server receives
  133. incoming closing frame from the client peer immediately. You can specify
  134. code and reason by return values. They are sent as a outgoing closing frame
  135. from the server. A request object has the following properties that you can
  136. use in web_socket_passive_closing_handshake.
  137. - ws_close_code
  138. - ws_close_reason
  139. Threading
  140. ---------
  141. A WebSocket handler must be thread-safe if the server (Apache or
  142. standalone.py) is configured to use threads.
  143. """
  144. # vi:sts=4 sw=4 et tw=72