App Engine Python SDK version 1.7.4 (2)
[gae.git] / python / google / appengine / dist / socket.py
blobeb76ca18c4539a30b9191683abe2badd20accc21
1 #!/usr/bin/env python
3 # Copyright 2007 Google Inc.
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
24 """\
25 This module provides socket operations and some related functions.
26 On Unix, it supports IP (Internet Protocol) and Unix domain sockets.
27 On other systems, it only supports IP. Functions specific for a
28 socket are available as methods of the socket object.
30 Functions:
32 socket() -- create a new socket object
33 socketpair() -- create a pair of new socket objects [*]
34 fromfd() -- create a socket object from an open file descriptor [*]
35 gethostname() -- return the current hostname
36 gethostbyname() -- map a hostname to its IP number
37 gethostbyaddr() -- map an IP number or hostname to DNS info
38 getservbyname() -- map a service name and a protocol name to a port number
39 getprotobyname() -- mape a protocol name (e.g. 'tcp') to a number
40 ntohs(), ntohl() -- convert 16, 32 bit int from network to host byte order
41 htons(), htonl() -- convert 16, 32 bit int from host to network byte order
42 inet_aton() -- convert IP addr string (123.45.67.89) to 32-bit packed format
43 inet_ntoa() -- convert 32-bit packed format IP to string (123.45.67.89)
44 ssl() -- secure socket layer support (only available if configured)
45 socket.getdefaulttimeout() -- get the default timeout value
46 socket.setdefaulttimeout() -- set the default timeout value
48 [*] not available on all platforms!
50 Special objects:
52 SocketType -- type object for socket objects
53 error -- exception raised for I/O errors
54 has_ipv6 -- boolean value indicating if IPv6 is supported
56 Integer constants:
58 AF_INET, AF_UNIX -- socket domains (first argument to socket() call)
59 SOCK_STREAM, SOCK_DGRAM, SOCK_RAW -- socket types (second argument)
61 Many other constants may be defined; these may be used in calls to
62 the setsockopt() and getsockopt() methods.
63 """
66 from google.appengine.api.remote_socket import _remote_socket as _socket
67 from google.appengine.api.remote_socket._remote_socket import *
69 import os, sys
71 try:
72 from errno import EBADF
73 except ImportError:
74 EBADF = 9
76 __all__ = ["getfqdn"]
77 __all__.extend(os._get_exports_list(_socket))
79 _realsocket = socket
82 if sys.platform.lower().startswith("win"):
83 errorTab = {}
84 errorTab[10004] = "The operation was interrupted."
85 errorTab[10009] = "A bad file handle was passed."
86 errorTab[10013] = "Permission denied."
87 errorTab[10014] = "A fault occurred on the network??"
88 errorTab[10022] = "An invalid operation was attempted."
89 errorTab[10035] = "The socket operation would block"
90 errorTab[10036] = "A blocking operation is already in progress."
91 errorTab[10048] = "The network address is in use."
92 errorTab[10054] = "The connection has been reset."
93 errorTab[10058] = "The network has been shut down."
94 errorTab[10060] = "The operation timed out."
95 errorTab[10061] = "Connection refused."
96 errorTab[10063] = "The name is too long."
97 errorTab[10064] = "The host is down."
98 errorTab[10065] = "The host is unreachable."
99 __all__.append("errorTab")
103 def getfqdn(name=''):
104 """Get fully qualified domain name from name.
106 An empty argument is interpreted as meaning the local host.
108 First the hostname returned by gethostbyaddr() is checked, then
109 possibly existing aliases. In case no FQDN is available, hostname
110 from gethostname() is returned.
112 name = name.strip()
113 if not name or name == '0.0.0.0':
114 name = gethostname()
115 try:
116 hostname, aliases, ipaddrs = gethostbyaddr(name)
117 except error:
118 pass
119 else:
120 aliases.insert(0, hostname)
121 for name in aliases:
122 if '.' in name:
123 break
124 else:
125 name = hostname
126 return name
129 _socketmethods = (
130 'bind', 'connect', 'connect_ex', 'fileno', 'listen',
131 'getpeername', 'getsockname', 'getsockopt', 'setsockopt',
132 'sendall', 'setblocking',
133 'settimeout', 'gettimeout', 'shutdown')
137 _delegate_methods = ("recv", "recvfrom", "recv_into", "recvfrom_into",
138 "send", "sendto")
140 class _closedsocket(object):
141 __slots__ = []
142 def _dummy(*args):
143 raise error(EBADF, 'Bad file descriptor')
145 send = recv = recv_into = sendto = recvfrom = recvfrom_into = _dummy
146 __getattr__ = _dummy
148 class _socketobject(object):
150 __doc__ = _realsocket.__doc__
152 __slots__ = ["_sock", "__weakref__"] + list(_delegate_methods)
155 def __getstate__(self):
156 if isinstance(self._sock, _closedsocket):
157 return None
158 return self._sock
161 def __setstate__(self, _sock):
162 if _sock is None:
163 _sock = _closedsocket()
164 self.__init__(_sock=_sock)
166 def __init__(self, family=AF_INET, type=SOCK_STREAM, proto=0, _sock=None):
167 if _sock is None:
168 _sock = _realsocket(family, type, proto)
169 self._sock = _sock
170 for method in _delegate_methods:
171 setattr(self, method, getattr(_sock, method))
173 def close(self):
178 if isinstance(self._sock, _realsocket):
179 self._sock.close()
180 self._sock = _closedsocket()
181 dummy = self._sock._dummy
182 for method in _delegate_methods:
183 setattr(self, method, dummy)
184 close.__doc__ = _realsocket.close.__doc__
186 def accept(self):
187 sock, addr = self._sock.accept()
188 return _socketobject(_sock=sock), addr
189 accept.__doc__ = _realsocket.accept.__doc__
191 def dup(self):
192 """dup() -> socket object
194 Return a new socket object connected to the same system resource."""
195 return _socketobject(_sock=self._sock)
197 def makefile(self, mode='r', bufsize=-1):
198 """makefile([mode[, bufsize]]) -> file object
200 Return a regular file object corresponding to the socket. The mode
201 and bufsize arguments are as for the built-in open() function."""
202 return _fileobject(self._sock, mode, bufsize)
204 family = property(lambda self: self._sock.family, doc="the socket family")
205 type = property(lambda self: self._sock.type, doc="the socket type")
206 proto = property(lambda self: self._sock.proto, doc="the socket protocol")
208 _s = ("def %s(self, *args): return self._sock.%s(*args)\n\n"
209 "%s.__doc__ = _realsocket.%s.__doc__\n")
210 for _m in _socketmethods:
211 exec _s % (_m, _m, _m, _m)
212 del _m, _s
214 socket = SocketType = _socketobject
216 class _fileobject(object):
217 """Faux file object attached to a socket object."""
219 default_bufsize = 8192
220 name = "<socket>"
222 __slots__ = ["mode", "bufsize", "softspace",
224 "_sock", "_rbufsize", "_wbufsize", "_rbuf", "_wbuf",
225 "_close"]
227 def __init__(self, sock, mode='rb', bufsize=-1, close=False):
228 self._sock = sock
229 self.mode = mode
230 if bufsize < 0:
231 bufsize = self.default_bufsize
232 self.bufsize = bufsize
233 self.softspace = False
234 if bufsize == 0:
235 self._rbufsize = 1
236 elif bufsize == 1:
237 self._rbufsize = self.default_bufsize
238 else:
239 self._rbufsize = bufsize
240 self._wbufsize = bufsize
241 self._rbuf = ""
242 self._wbuf = []
243 self._close = close
245 def _getclosed(self):
246 return self._sock is None
247 closed = property(_getclosed, doc="True if the file is closed")
249 def close(self):
250 try:
251 if self._sock:
252 self.flush()
253 finally:
254 if self._close:
255 self._sock.close()
256 self._sock = None
258 def __del__(self):
259 try:
260 self.close()
261 except:
263 pass
265 def flush(self):
266 if self._wbuf:
267 buffer = "".join(self._wbuf)
268 self._wbuf = []
269 self._sock.sendall(buffer)
271 def fileno(self):
272 return self._sock.fileno()
274 def write(self, data):
275 data = str(data)
276 if not data:
277 return
278 self._wbuf.append(data)
279 if (self._wbufsize == 0 or
280 self._wbufsize == 1 and '\n' in data or
281 self._get_wbuf_len() >= self._wbufsize):
282 self.flush()
284 def writelines(self, list):
287 self._wbuf.extend(filter(None, map(str, list)))
288 if (self._wbufsize <= 1 or
289 self._get_wbuf_len() >= self._wbufsize):
290 self.flush()
292 def _get_wbuf_len(self):
293 buf_len = 0
294 for x in self._wbuf:
295 buf_len += len(x)
296 return buf_len
298 def read(self, size=-1):
299 data = self._rbuf
300 if size < 0:
302 buffers = []
303 if data:
304 buffers.append(data)
305 self._rbuf = ""
306 if self._rbufsize <= 1:
307 recv_size = self.default_bufsize
308 else:
309 recv_size = self._rbufsize
310 while True:
311 data = self._sock.recv(recv_size)
312 if not data:
313 break
314 buffers.append(data)
315 return "".join(buffers)
316 else:
318 buf_len = len(data)
319 if buf_len >= size:
320 self._rbuf = data[size:]
321 return data[:size]
322 buffers = []
323 if data:
324 buffers.append(data)
325 self._rbuf = ""
326 while True:
327 left = size - buf_len
328 recv_size = max(self._rbufsize, left)
329 data = self._sock.recv(recv_size)
330 if not data:
331 break
332 buffers.append(data)
333 n = len(data)
334 if n >= left:
335 self._rbuf = data[left:]
336 buffers[-1] = data[:left]
337 break
338 buf_len += n
339 return "".join(buffers)
341 def readline(self, size=-1):
342 data = self._rbuf
343 if size < 0:
345 if self._rbufsize <= 1:
347 assert data == ""
348 buffers = []
349 recv = self._sock.recv
350 while data != "\n":
351 data = recv(1)
352 if not data:
353 break
354 buffers.append(data)
355 return "".join(buffers)
356 nl = data.find('\n')
357 if nl >= 0:
358 nl += 1
359 self._rbuf = data[nl:]
360 return data[:nl]
361 buffers = []
362 if data:
363 buffers.append(data)
364 self._rbuf = ""
365 while True:
366 data = self._sock.recv(self._rbufsize)
367 if not data:
368 break
369 buffers.append(data)
370 nl = data.find('\n')
371 if nl >= 0:
372 nl += 1
373 self._rbuf = data[nl:]
374 buffers[-1] = data[:nl]
375 break
376 return "".join(buffers)
377 else:
379 nl = data.find('\n', 0, size)
380 if nl >= 0:
381 nl += 1
382 self._rbuf = data[nl:]
383 return data[:nl]
384 buf_len = len(data)
385 if buf_len >= size:
386 self._rbuf = data[size:]
387 return data[:size]
388 buffers = []
389 if data:
390 buffers.append(data)
391 self._rbuf = ""
392 while True:
393 data = self._sock.recv(self._rbufsize)
394 if not data:
395 break
396 buffers.append(data)
397 left = size - buf_len
398 nl = data.find('\n', 0, left)
399 if nl >= 0:
400 nl += 1
401 self._rbuf = data[nl:]
402 buffers[-1] = data[:nl]
403 break
404 n = len(data)
405 if n >= left:
406 self._rbuf = data[left:]
407 buffers[-1] = data[:left]
408 break
409 buf_len += n
410 return "".join(buffers)
412 def readlines(self, sizehint=0):
413 total = 0
414 list = []
415 while True:
416 line = self.readline()
417 if not line:
418 break
419 list.append(line)
420 total += len(line)
421 if sizehint and total >= sizehint:
422 break
423 return list
427 def __iter__(self):
428 return self
430 def next(self):
431 line = self.readline()
432 if not line:
433 raise StopIteration
434 return line
437 _GLOBAL_DEFAULT_TIMEOUT = object()
440 def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT):
441 """Connect to *address* and return the socket object.
443 Convenience function. Connect to *address* (a 2-tuple ``(host,
444 port)``) and return the socket object. Passing the optional
445 *timeout* parameter will set the timeout on the socket instance
446 before attempting to connect. If no *timeout* is supplied, the
447 global default timeout setting returned by :func:`getdefaulttimeout`
448 is used.
451 msg = "getaddrinfo returns an empty list"
452 host, port = address
453 for res in getaddrinfo(host, port, 0, SOCK_STREAM):
454 af, socktype, proto, canonname, sa = res
455 sock = None
456 try:
457 sock = socket(af, socktype, proto)
458 if timeout is not _GLOBAL_DEFAULT_TIMEOUT:
459 sock.settimeout(timeout)
460 sock.connect(sa, host)
461 return sock
463 except error, msg:
464 if sock is not None:
465 sock.close()
467 raise error, msg
470 ssl = None