github.com/grumpyhome/grumpy@v0.3.1-0.20201208125205-7b775405bdf1/grumpy-runtime-src/third_party/stdlib/socket.py (about) 1 # Wrapper module for _socket, providing some additional facilities 2 # implemented in Python. 3 4 """\ 5 This module provides socket operations and some related functions. 6 On Unix, it supports IP (Internet Protocol) and Unix domain sockets. 7 On other systems, it only supports IP. Functions specific for a 8 socket are available as methods of the socket object. 9 10 Functions: 11 12 socket() -- create a new socket object 13 socketpair() -- create a pair of new socket objects [*] 14 fromfd() -- create a socket object from an open file descriptor [*] 15 gethostname() -- return the current hostname 16 gethostbyname() -- map a hostname to its IP number 17 gethostbyaddr() -- map an IP number or hostname to DNS info 18 getservbyname() -- map a service name and a protocol name to a port number 19 getprotobyname() -- map a protocol name (e.g. 'tcp') to a number 20 ntohs(), ntohl() -- convert 16, 32 bit int from network to host byte order 21 htons(), htonl() -- convert 16, 32 bit int from host to network byte order 22 inet_aton() -- convert IP addr string (123.45.67.89) to 32-bit packed format 23 inet_ntoa() -- convert 32-bit packed format IP to string (123.45.67.89) 24 ssl() -- secure socket layer support (only available if configured) 25 socket.getdefaulttimeout() -- get the default timeout value 26 socket.setdefaulttimeout() -- set the default timeout value 27 create_connection() -- connects to an address, with an optional timeout and 28 optional source address. 29 30 [*] not available on all platforms! 31 32 Special objects: 33 34 SocketType -- type object for socket objects 35 error -- exception raised for I/O errors 36 has_ipv6 -- boolean value indicating if IPv6 is supported 37 38 Integer constants: 39 40 AF_INET, AF_UNIX -- socket domains (first argument to socket() call) 41 SOCK_STREAM, SOCK_DGRAM, SOCK_RAW -- socket types (second argument) 42 43 Many other constants may be defined; these may be used in calls to 44 the setsockopt() and getsockopt() methods. 45 """ 46 47 import _socket 48 #from _socket import * 49 for _k, _v in _socket.__dict__.iteritems(): 50 if not _k.startswith('_'): 51 globals()[_k] = _v 52 from functools import partial 53 from types import MethodType 54 55 #try: 56 # import _ssl 57 #except ImportError: 58 # # no SSL support 59 # pass 60 #else: 61 # def ssl(sock, keyfile=None, certfile=None): 62 # # we do an internal import here because the ssl 63 # # module imports the socket module 64 # import ssl as _realssl 65 # warnings.warn("socket.ssl() is deprecated. Use ssl.wrap_socket() instead.", 66 # DeprecationWarning, stacklevel=2) 67 # return _realssl.sslwrap_simple(sock, keyfile, certfile) 68 # 69 # # we need to import the same constants we used to... 70 # from _ssl import SSLError as sslerror 71 # from _ssl import \ 72 # RAND_add, \ 73 # RAND_status, \ 74 # SSL_ERROR_ZERO_RETURN, \ 75 # SSL_ERROR_WANT_READ, \ 76 # SSL_ERROR_WANT_WRITE, \ 77 # SSL_ERROR_WANT_X509_LOOKUP, \ 78 # SSL_ERROR_SYSCALL, \ 79 # SSL_ERROR_SSL, \ 80 # SSL_ERROR_WANT_CONNECT, \ 81 # SSL_ERROR_EOF, \ 82 # SSL_ERROR_INVALID_ERROR_CODE 83 # try: 84 # from _ssl import RAND_egd 85 # except ImportError: 86 # # LibreSSL does not provide RAND_egd 87 # pass 88 89 import os, sys, warnings 90 91 try: 92 from cStringIO import StringIO 93 except ImportError: 94 from StringIO import StringIO 95 96 try: 97 import errno 98 except ImportError: 99 errno = None 100 EBADF = getattr(errno, 'EBADF', 9) 101 EINTR = getattr(errno, 'EINTR', 4) 102 103 __all__ = ["getfqdn", "create_connection"] 104 __all__.extend(dir(_socket)) 105 #__all__.extend(os._get_exports_list(_socket)) 106 107 108 _realsocket = socket 109 110 # WSA error codes 111 #if sys.platform.lower().startswith("win"): 112 # errorTab = {} 113 # errorTab[10004] = "The operation was interrupted." 114 # errorTab[10009] = "A bad file handle was passed." 115 # errorTab[10013] = "Permission denied." 116 # errorTab[10014] = "A fault occurred on the network??" # WSAEFAULT 117 # errorTab[10022] = "An invalid operation was attempted." 118 # errorTab[10035] = "The socket operation would block" 119 # errorTab[10036] = "A blocking operation is already in progress." 120 # errorTab[10048] = "The network address is in use." 121 # errorTab[10054] = "The connection has been reset." 122 # errorTab[10058] = "The network has been shut down." 123 # errorTab[10060] = "The operation timed out." 124 # errorTab[10061] = "Connection refused." 125 # errorTab[10063] = "The name is too long." 126 # errorTab[10064] = "The host is down." 127 # errorTab[10065] = "The host is unreachable." 128 # __all__.append("errorTab") 129 130 131 132 def getfqdn(name=''): 133 """Get fully qualified domain name from name. 134 135 An empty argument is interpreted as meaning the local host. 136 137 First the hostname returned by gethostbyaddr() is checked, then 138 possibly existing aliases. In case no FQDN is available, hostname 139 from gethostname() is returned. 140 """ 141 name = name.strip() 142 if not name or name == '0.0.0.0': 143 name = gethostname() 144 try: 145 hostname, aliases, ipaddrs = gethostbyaddr(name) 146 except error: 147 pass 148 else: 149 aliases.insert(0, hostname) 150 for name in aliases: 151 if '.' in name: 152 break 153 else: 154 name = hostname 155 return name 156 157 158 _socketmethods = ( 159 'bind', 'connect', 'connect_ex', 'fileno', 'listen', 160 'getpeername', 'getsockname', 'getsockopt', 'setsockopt', 161 'sendall', 'setblocking', 162 'settimeout', 'gettimeout', 'shutdown') 163 164 #if os.name == "nt": 165 # _socketmethods = _socketmethods + ('ioctl',) 166 # 167 #if sys.platform == "riscos": 168 # _socketmethods = _socketmethods + ('sleeptaskw',) 169 170 # All the method names that must be delegated to either the real socket 171 # object or the _closedsocket object. 172 _delegate_methods = ("recv", "recvfrom", "recv_into", "recvfrom_into", 173 "send", "sendto") 174 175 class _closedsocket(object): 176 __slots__ = [] 177 def _dummy(*args): 178 raise error(EBADF, 'Bad file descriptor') 179 # All _delegate_methods must also be initialized here. 180 send = recv = recv_into = sendto = recvfrom = recvfrom_into = _dummy 181 __getattr__ = _dummy 182 183 # Wrapper around platform socket objects. This implements 184 # a platform-independent dup() functionality. The 185 # implementation currently relies on reference counting 186 # to close the underlying socket object. 187 class _socketobject(object): 188 189 #__doc__ = _realsocket.__doc__ 190 191 __slots__ = ["_sock", "__weakref__"] + list(_delegate_methods) 192 193 def __init__(self, family=AF_INET, type=SOCK_STREAM, proto=0, _sock=None): 194 if _sock is None: 195 _sock = _realsocket(family, type, proto) 196 self._sock = _sock 197 for method in _delegate_methods: 198 setattr(self, method, getattr(_sock, method)) 199 200 def close(self, _closedsocket=_closedsocket, 201 _delegate_methods=_delegate_methods, setattr=setattr): 202 # This function should not reference any globals. See issue #808164. 203 self._sock = _closedsocket() 204 dummy = self._sock._dummy 205 for method in _delegate_methods: 206 setattr(self, method, dummy) 207 #close.__doc__ = _realsocket.close.__doc__ 208 209 def accept(self): 210 sock, addr = self._sock.accept() 211 return _socketobject(_sock=sock), addr 212 #accept.__doc__ = _realsocket.accept.__doc__ 213 214 def dup(self): 215 """dup() -> socket object 216 217 Return a new socket object connected to the same system resource.""" 218 return _socketobject(_sock=self._sock) 219 220 def makefile(self, mode='r', bufsize=-1): 221 """makefile([mode[, bufsize]]) -> file object 222 223 Return a regular file object corresponding to the socket. The mode 224 and bufsize arguments are as for the built-in open() function.""" 225 return _fileobject(self._sock, mode, bufsize) 226 227 family = property(lambda self: self._sock.family, doc="the socket family") 228 type = property(lambda self: self._sock.type, doc="the socket type") 229 proto = property(lambda self: self._sock.proto, doc="the socket protocol") 230 231 def meth(name,self,*args): 232 return getattr(self._sock,name)(*args) 233 234 for _m in _socketmethods: 235 p = partial(meth,_m) 236 p.__name__ = _m 237 #p.__doc__ = getattr(_realsocket,_m).__doc__ 238 m = MethodType(p,None,_socketobject) 239 setattr(_socketobject,_m,m) 240 241 socket = SocketType = _socketobject 242 243 class _fileobject(object): 244 """Faux file object attached to a socket object.""" 245 246 default_bufsize = 8192 247 name = "<socket>" 248 249 __slots__ = ["mode", "bufsize", "softspace", 250 # "closed" is a property, see below 251 "_sock", "_rbufsize", "_wbufsize", "_rbuf", "_wbuf", "_wbuf_len", 252 "_close"] 253 254 def __init__(self, sock, mode='rb', bufsize=-1, close=False): 255 self._sock = sock 256 self.mode = mode # Not actually used in this version 257 if bufsize < 0: 258 bufsize = self.default_bufsize 259 self.bufsize = bufsize 260 self.softspace = False 261 # _rbufsize is the suggested recv buffer size. It is *strictly* 262 # obeyed within readline() for recv calls. If it is larger than 263 # default_bufsize it will be used for recv calls within read(). 264 if bufsize == 0: 265 self._rbufsize = 1 266 elif bufsize == 1: 267 self._rbufsize = self.default_bufsize 268 else: 269 self._rbufsize = bufsize 270 self._wbufsize = bufsize 271 # We use StringIO for the read buffer to avoid holding a list 272 # of variously sized string objects which have been known to 273 # fragment the heap due to how they are malloc()ed and often 274 # realloc()ed down much smaller than their original allocation. 275 self._rbuf = StringIO() 276 self._wbuf = [] # A list of strings 277 self._wbuf_len = 0 278 self._close = close 279 280 def _getclosed(self): 281 return self._sock is None 282 closed = property(_getclosed, doc="True if the file is closed") 283 284 def close(self): 285 try: 286 if self._sock: 287 self.flush() 288 finally: 289 if self._close: 290 self._sock.close() 291 self._sock = None 292 293 def __del__(self): 294 try: 295 self.close() 296 except: 297 # close() may fail if __init__ didn't complete 298 pass 299 300 def flush(self): 301 if self._wbuf: 302 data = "".join(self._wbuf) 303 self._wbuf = [] 304 self._wbuf_len = 0 305 buffer_size = max(self._rbufsize, self.default_bufsize) 306 data_size = len(data) 307 write_offset = 0 308 view = data #memoryview(data) 309 try: 310 while write_offset < data_size: 311 self._sock.sendall(view[write_offset:write_offset+buffer_size]) 312 write_offset += buffer_size 313 finally: 314 if write_offset < data_size: 315 remainder = data[write_offset:] 316 del view, data # explicit free 317 self._wbuf.append(remainder) 318 self._wbuf_len = len(remainder) 319 320 def fileno(self): 321 return self._sock.fileno() 322 323 def write(self, data): 324 data = str(data) # XXX Should really reject non-string non-buffers 325 if not data: 326 return 327 self._wbuf.append(data) 328 self._wbuf_len += len(data) 329 if (self._wbufsize == 0 or 330 (self._wbufsize == 1 and '\n' in data) or 331 (self._wbufsize > 1 and self._wbuf_len >= self._wbufsize)): 332 self.flush() 333 334 def writelines(self, list): 335 # XXX We could do better here for very long lists 336 # XXX Should really reject non-string non-buffers 337 lines = filter(None, map(str, list)) 338 self._wbuf_len += sum(map(len, lines)) 339 self._wbuf.extend(lines) 340 if (self._wbufsize <= 1 or 341 self._wbuf_len >= self._wbufsize): 342 self.flush() 343 344 def read(self, size=-1): 345 # Use max, disallow tiny reads in a loop as they are very inefficient. 346 # We never leave read() with any leftover data from a new recv() call 347 # in our internal buffer. 348 rbufsize = max(self._rbufsize, self.default_bufsize) 349 # Our use of StringIO rather than lists of string objects returned by 350 # recv() minimizes memory usage and fragmentation that occurs when 351 # rbufsize is large compared to the typical return value of recv(). 352 buf = self._rbuf 353 buf.seek(0, 2) # seek end 354 if size < 0: 355 # Read until EOF 356 self._rbuf = StringIO() # reset _rbuf. we consume it via buf. 357 while True: 358 try: 359 data = self._sock.recv(rbufsize) 360 except error, e: 361 if e.args[0] == EINTR: 362 continue 363 raise 364 if not data: 365 break 366 buf.write(data) 367 return buf.getvalue() 368 else: 369 # Read until size bytes or EOF seen, whichever comes first 370 buf_len = buf.tell() 371 if buf_len >= size: 372 # Already have size bytes in our buffer? Extract and return. 373 buf.seek(0) 374 rv = buf.read(size) 375 self._rbuf = StringIO() 376 self._rbuf.write(buf.read()) 377 return rv 378 379 self._rbuf = StringIO() # reset _rbuf. we consume it via buf. 380 while True: 381 left = size - buf_len 382 # recv() will malloc the amount of memory given as its 383 # parameter even though it often returns much less data 384 # than that. The returned data string is short lived 385 # as we copy it into a StringIO and free it. This avoids 386 # fragmentation issues on many platforms. 387 try: 388 data = self._sock.recv(left) 389 except error, e: 390 if e.args[0] == EINTR: 391 continue 392 raise 393 if not data: 394 break 395 n = len(data) 396 if n == size and not buf_len: 397 # Shortcut. Avoid buffer data copies when: 398 # - We have no data in our buffer. 399 # AND 400 # - Our call to recv returned exactly the 401 # number of bytes we were asked to read. 402 return data 403 if n == left: 404 buf.write(data) 405 del data # explicit free 406 break 407 assert n <= left, "recv(%d) returned %d bytes" % (left, n) 408 buf.write(data) 409 buf_len += n 410 del data # explicit free 411 #assert buf_len == buf.tell() 412 return buf.getvalue() 413 414 def readline(self, size=-1): 415 buf = self._rbuf 416 buf.seek(0, 2) # seek end 417 if buf.tell() > 0: 418 # check if we already have it in our buffer 419 buf.seek(0) 420 bline = buf.readline(size) 421 if bline.endswith('\n') or len(bline) == size: 422 self._rbuf = StringIO() 423 self._rbuf.write(buf.read()) 424 return bline 425 del bline 426 if size < 0: 427 # Read until \n or EOF, whichever comes first 428 if self._rbufsize <= 1: 429 # Speed up unbuffered case 430 buf.seek(0) 431 buffers = [buf.read()] 432 self._rbuf = StringIO() # reset _rbuf. we consume it via buf. 433 data = None 434 recv = self._sock.recv 435 while True: 436 try: 437 while data != "\n": 438 data = recv(1) 439 if not data: 440 break 441 buffers.append(data) 442 except error, e: 443 # The try..except to catch EINTR was moved outside the 444 # recv loop to avoid the per byte overhead. 445 if e.args[0] == EINTR: 446 continue 447 raise 448 break 449 return "".join(buffers) 450 451 buf.seek(0, 2) # seek end 452 self._rbuf = StringIO() # reset _rbuf. we consume it via buf. 453 while True: 454 try: 455 data = self._sock.recv(self._rbufsize) 456 except error, e: 457 if e.args[0] == EINTR: 458 continue 459 raise 460 if not data: 461 break 462 nl = data.find('\n') 463 if nl >= 0: 464 nl += 1 465 buf.write(data[:nl]) 466 self._rbuf.write(data[nl:]) 467 del data 468 break 469 buf.write(data) 470 return buf.getvalue() 471 else: 472 # Read until size bytes or \n or EOF seen, whichever comes first 473 buf.seek(0, 2) # seek end 474 buf_len = buf.tell() 475 if buf_len >= size: 476 buf.seek(0) 477 rv = buf.read(size) 478 self._rbuf = StringIO() 479 self._rbuf.write(buf.read()) 480 return rv 481 self._rbuf = StringIO() # reset _rbuf. we consume it via buf. 482 while True: 483 try: 484 data = self._sock.recv(self._rbufsize) 485 except error, e: 486 if e.args[0] == EINTR: 487 continue 488 raise 489 if not data: 490 break 491 left = size - buf_len 492 # did we just receive a newline? 493 nl = data.find('\n', 0, left) 494 if nl >= 0: 495 nl += 1 496 # save the excess data to _rbuf 497 self._rbuf.write(data[nl:]) 498 if buf_len: 499 buf.write(data[:nl]) 500 break 501 else: 502 # Shortcut. Avoid data copy through buf when returning 503 # a substring of our first recv(). 504 return data[:nl] 505 n = len(data) 506 if n == size and not buf_len: 507 # Shortcut. Avoid data copy through buf when 508 # returning exactly all of our first recv(). 509 return data 510 if n >= left: 511 buf.write(data[:left]) 512 self._rbuf.write(data[left:]) 513 break 514 buf.write(data) 515 buf_len += n 516 #assert buf_len == buf.tell() 517 return buf.getvalue() 518 519 def readlines(self, sizehint=0): 520 total = 0 521 list = [] 522 while True: 523 line = self.readline() 524 if not line: 525 break 526 list.append(line) 527 total += len(line) 528 if sizehint and total >= sizehint: 529 break 530 return list 531 532 # Iterator protocols 533 534 def __iter__(self): 535 return self 536 537 def next(self): 538 line = self.readline() 539 if not line: 540 raise StopIteration 541 return line 542 543 _GLOBAL_DEFAULT_TIMEOUT = object() 544 545 def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT, 546 source_address=None): 547 """Connect to *address* and return the socket object. 548 549 Convenience function. Connect to *address* (a 2-tuple ``(host, 550 port)``) and return the socket object. Passing the optional 551 *timeout* parameter will set the timeout on the socket instance 552 before attempting to connect. If no *timeout* is supplied, the 553 global default timeout setting returned by :func:`getdefaulttimeout` 554 is used. If *source_address* is set it must be a tuple of (host, port) 555 for the socket to bind as a source address before making the connection. 556 A host of '' or port 0 tells the OS to use the default. 557 """ 558 559 host, port = address 560 err = None 561 for res in getaddrinfo(host, port, 0, SOCK_STREAM): 562 af, socktype, proto, canonname, sa = res 563 sock = None 564 try: 565 sock = socket(af, socktype, proto) 566 if timeout is not _GLOBAL_DEFAULT_TIMEOUT: 567 sock.settimeout(timeout) 568 if source_address: 569 sock.bind(source_address) 570 sock.connect(sa) 571 return sock 572 573 except error as _: 574 err = _ 575 if sock is not None: 576 sock.close() 577 578 if err is not None: 579 raise err 580 else: 581 raise error("getaddrinfo returns an empty list")