Home | History | Annotate | Download | only in websocket
      1 """
      2 websocket - WebSocket client library for Python
      3 
      4 Copyright (C) 2010 Hiroki Ohtani(liris)
      5 
      6     This library is free software; you can redistribute it and/or
      7     modify it under the terms of the GNU Lesser General Public
      8     License as published by the Free Software Foundation; either
      9     version 2.1 of the License, or (at your option) any later version.
     10 
     11     This library is distributed in the hope that it will be useful,
     12     but WITHOUT ANY WARRANTY; without even the implied warranty of
     13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14     Lesser General Public License for more details.
     15 
     16     You should have received a copy of the GNU Lesser General Public
     17     License along with this library; if not, write to the Free Software
     18     Foundation, Inc., 51 Franklin Street, Fifth Floor,
     19     Boston, MA 02110-1335  USA
     20 
     21 """
     22 import socket
     23 
     24 import six
     25 
     26 from ._exceptions import *
     27 from ._ssl_compat import *
     28 from ._utils import *
     29 
     30 DEFAULT_SOCKET_OPTION = [(socket.SOL_TCP, socket.TCP_NODELAY, 1)]
     31 if hasattr(socket, "SO_KEEPALIVE"):
     32     DEFAULT_SOCKET_OPTION.append((socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1))
     33 if hasattr(socket, "TCP_KEEPIDLE"):
     34     DEFAULT_SOCKET_OPTION.append((socket.SOL_TCP, socket.TCP_KEEPIDLE, 30))
     35 if hasattr(socket, "TCP_KEEPINTVL"):
     36     DEFAULT_SOCKET_OPTION.append((socket.SOL_TCP, socket.TCP_KEEPINTVL, 10))
     37 if hasattr(socket, "TCP_KEEPCNT"):
     38     DEFAULT_SOCKET_OPTION.append((socket.SOL_TCP, socket.TCP_KEEPCNT, 3))
     39 
     40 _default_timeout = None
     41 
     42 __all__ = ["DEFAULT_SOCKET_OPTION", "sock_opt", "setdefaulttimeout", "getdefaulttimeout",
     43            "recv", "recv_line", "send"]
     44 
     45 
     46 class sock_opt(object):
     47 
     48     def __init__(self, sockopt, sslopt):
     49         if sockopt is None:
     50             sockopt = []
     51         if sslopt is None:
     52             sslopt = {}
     53         self.sockopt = sockopt
     54         self.sslopt = sslopt
     55         self.timeout = None
     56 
     57 
     58 def setdefaulttimeout(timeout):
     59     """
     60     Set the global timeout setting to connect.
     61 
     62     timeout: default socket timeout time. This value is second.
     63     """
     64     global _default_timeout
     65     _default_timeout = timeout
     66 
     67 
     68 def getdefaulttimeout():
     69     """
     70     Return the global timeout setting(second) to connect.
     71     """
     72     return _default_timeout
     73 
     74 
     75 def recv(sock, bufsize):
     76     if not sock:
     77         raise WebSocketConnectionClosedException("socket is already closed.")
     78 
     79     try:
     80         bytes_ = sock.recv(bufsize)
     81     except socket.timeout as e:
     82         message = extract_err_message(e)
     83         raise WebSocketTimeoutException(message)
     84     except SSLError as e:
     85         message = extract_err_message(e)
     86         if message == "The read operation timed out":
     87             raise WebSocketTimeoutException(message)
     88         else:
     89             raise
     90 
     91     if not bytes_:
     92         raise WebSocketConnectionClosedException(
     93             "Connection is already closed.")
     94 
     95     return bytes_
     96 
     97 
     98 def recv_line(sock):
     99     line = []
    100     while True:
    101         c = recv(sock, 1)
    102         line.append(c)
    103         if c == six.b("\n"):
    104             break
    105     return six.b("").join(line)
    106 
    107 
    108 def send(sock, data):
    109     if isinstance(data, six.text_type):
    110         data = data.encode('utf-8')
    111 
    112     if not sock:
    113         raise WebSocketConnectionClosedException("socket is already closed.")
    114 
    115     try:
    116         return sock.send(data)
    117     except socket.timeout as e:
    118         message = extract_err_message(e)
    119         raise WebSocketTimeoutException(message)
    120     except Exception as e:
    121         message = extract_err_message(e)
    122         if isinstance(message, str) and "timed out" in message:
    123             raise WebSocketTimeoutException(message)
    124         else:
    125             raise
    126