PageRenderTime 53ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/google/appengine/api/remote_socket/_remote_socket.py

https://github.com/theosp/google_appengine
Python | 1180 lines | 1056 code | 75 blank | 49 comment | 28 complexity | 3aa1fdf46bbb303c7d643df481f7256f MD5 | raw file
  1. #!/usr/bin/env python
  2. #
  3. # Copyright 2007 Google Inc.
  4. #
  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
  8. #
  9. # http://www.apache.org/licenses/LICENSE-2.0
  10. #
  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.
  16. #
  17. """Socket Module.
  18. This file is intended to provide the equivalent of
  19. python/Modules/socketmodule.c rather than python/Lib/socket.py which amongst
  20. other things adds a buffered file-like interface.
  21. """
  22. import errno
  23. import os
  24. import re
  25. import struct
  26. import time
  27. import weakref
  28. from google.appengine.api import apiproxy_stub_map
  29. from google.appengine.api.remote_socket import remote_socket_service_pb
  30. from google.appengine.api.remote_socket._remote_socket_addr import *
  31. from google.appengine.api.remote_socket._remote_socket_error import *
  32. from google.appengine.runtime import apiproxy_errors
  33. has_ipv6 = True
  34. SOCK_STREAM = 1
  35. SOCK_DGRAM = 2
  36. SOMAXCONN = 128
  37. MSG_PEEK = 2
  38. MSG_WAITALL = 256
  39. IPPROTO_IP = 0
  40. IPPROTO_ICMP = 1
  41. IPPROTO_TCP = 6
  42. IPPROTO_UDP = 17
  43. IPPORT_RESERVED = 1024
  44. IPPORT_USERRESERVED = 5000
  45. INADDR_ANY = 0x00000000
  46. INADDR_BROADCAST = 0xffffffff
  47. INADDR_LOOPBACK = 0x7f000001
  48. INADDR_NONE = 0xffffffff
  49. (AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST, AI_NUMERICSERV, AI_V4MAPPED, AI_ALL,
  50. AI_ADDRCONFIG) = map(lambda x: 1 << x, range(7))
  51. RemoteSocketServiceError = remote_socket_service_pb.RemoteSocketServiceError
  52. def _ImportSymbols(protobuf, symbols, prefix='SOCKET_'):
  53. """Import symbols defined in a protobuf into the global namespace."""
  54. for sym in symbols:
  55. globals()[sym] = getattr(protobuf, prefix + sym)
  56. _ImportSymbols(remote_socket_service_pb.ResolveReply, (
  57. 'EAI_ADDRFAMILY', 'EAI_AGAIN', 'EAI_BADFLAGS', 'EAI_FAIL', 'EAI_FAMILY',
  58. 'EAI_MEMORY', 'EAI_NODATA', 'EAI_NONAME', 'EAI_SERVICE', 'EAI_SOCKTYPE',
  59. 'EAI_SYSTEM', 'EAI_BADHINTS', 'EAI_PROTOCOL', 'EAI_OVERFLOW', 'EAI_MAX'))
  60. _ImportSymbols(remote_socket_service_pb.ShutDownRequest, (
  61. 'SHUT_RD', 'SHUT_WR', 'SHUT_RDWR'))
  62. _ImportSymbols(remote_socket_service_pb.SocketOption, (
  63. 'SOL_SOCKET', 'SOL_IP', 'SOL_TCP', 'SOL_UDP',
  64. 'SO_DEBUG', 'SO_REUSEADDR', 'SO_TYPE', 'SO_ERROR', 'SO_DONTROUTE',
  65. 'SO_BROADCAST', 'SO_SNDBUF', 'SO_RCVBUF', 'SO_KEEPALIVE',
  66. 'IP_TOS', 'IP_TTL', 'IP_HDRINCL', 'IP_OPTIONS',
  67. 'TCP_NODELAY', 'TCP_MAXSEG', 'TCP_CORK', 'TCP_KEEPIDLE', 'TCP_KEEPINTVL',
  68. 'TCP_KEEPCNT', 'TCP_SYNCNT', 'TCP_LINGER2', 'TCP_DEFER_ACCEPT',
  69. 'TCP_WINDOW_CLAMP', 'TCP_INFO', 'TCP_QUICKACK'))
  70. _ImportSymbols(remote_socket_service_pb.PollEvent, (
  71. 'POLLNONE', 'POLLIN', 'POLLPRI', 'POLLOUT', 'POLLERR', 'POLLHUP',
  72. 'POLLNVAL', 'POLLRDNORM', 'POLLRDBAND', 'POLLWRNORM', 'POLLWRBAND',
  73. 'POLLMSG', 'POLLREMOVE', 'POLLRDHUP'))
  74. _GLOBAL_DEFAULT_TIMEOUT = object()
  75. _GLOBAL_TIMEOUT_VALUE = -1.0
  76. _GLOBAL_SOCKET_NEXT_FILENO = 2**32
  77. _GLOBAL_SOCKET_MAP = weakref.WeakValueDictionary()
  78. _SERVICES = {
  79. 'ftp': [('tcp', 21), ('udp', 21)],
  80. 'ftp-data': [('tcp', 20), ('udp', 20)],
  81. 'http': [('tcp', 80), ('udp', 80)],
  82. 'pop3': [('tcp', 110), ('udp', 110)],
  83. 'pop3s': [('tcp', 995), ('udp', 995)],
  84. 'smtp': [('tcp', 25), ('udp', 25)],
  85. 'telnet': [('tcp', 23), ('udp', 23)],
  86. 'www': [('tcp', 80), ('udp', 80)],
  87. 'www-http': [('tcp', 80), ('udp', 80)],
  88. }
  89. _ERROR_MAP = {
  90. RemoteSocketServiceError.PERMISSION_DENIED: errno.EACCES,
  91. RemoteSocketServiceError.INVALID_REQUEST: errno.EINVAL,
  92. RemoteSocketServiceError.SOCKET_CLOSED: errno.EPIPE,
  93. }
  94. _SOCK_PROTO_MAP = {
  95. (SOCK_STREAM, IPPROTO_TCP): 'tcp',
  96. (SOCK_DGRAM, IPPROTO_UDP): 'udp',
  97. }
  98. _ADDRESS_FAMILY_MAP = {
  99. AF_INET: remote_socket_service_pb.CreateSocketRequest.IPv4,
  100. AF_INET6: remote_socket_service_pb.CreateSocketRequest.IPv6,
  101. }
  102. _ADDRESS_FAMILY_LENGTH_MAP = {
  103. 4: AF_INET,
  104. 16: AF_INET6,
  105. }
  106. class SocketApiNotImplementedError(NotImplementedError, error):
  107. pass
  108. def _SystemExceptionFromAppError(e):
  109. app_error = e.application_error
  110. if app_error in (RemoteSocketServiceError.SYSTEM_ERROR,
  111. RemoteSocketServiceError.GAI_ERROR):
  112. error_detail = RemoteSocketServiceError()
  113. try:
  114. error_detail.ParseASCII(e.error_detail)
  115. except NotImplementedError:
  116. m = re.match(
  117. r'system_error:\s*(-?\d+)\s*,?\s*error_detail:\s*"([^"]*)"\s*',
  118. e.error_detail)
  119. if m:
  120. error_detail.set_system_error(int(m.group(1)))
  121. error_detail.set_error_detail(m.group(2))
  122. else:
  123. error_detail.set_system_error(-1)
  124. error_detail.set_error_detail(e.error_detail)
  125. if app_error == RemoteSocketServiceError.SYSTEM_ERROR:
  126. return error(error_detail.system_error(),
  127. (error_detail.error_detail() or
  128. os.strerror(error_detail.system_error())))
  129. elif app_error == RemoteSocketServiceError.GAI_ERROR:
  130. return gaierror(error_detail.system_error(),
  131. error_detail.error_detail())
  132. elif app_error in _ERROR_MAP:
  133. return error(_ERROR_MAP[app_error], os.strerror(_ERROR_MAP[app_error]))
  134. else:
  135. return e
  136. def _IsAddr(family, addr):
  137. try:
  138. inet_pton(family, addr)
  139. except Exception:
  140. return False
  141. return True
  142. def _Resolve(name, families, use_dns=True, canonical=False):
  143. for family in families:
  144. if _IsAddr(family, name):
  145. return (name, [], [name])
  146. if use_dns:
  147. canon, aliases, addresses = _ResolveName(name, families)
  148. if addresses:
  149. return (canon, aliases, addresses)
  150. raise gaierror(EAI_NONAME, 'nodename nor servname provided, or not known')
  151. def _ResolveName(name, address_families=(AF_INET6, AF_INET)):
  152. request = remote_socket_service_pb.ResolveRequest()
  153. request.set_name(name)
  154. for af in address_families:
  155. request.add_address_families(_ADDRESS_FAMILY_MAP[af])
  156. reply = remote_socket_service_pb.ResolveReply()
  157. try:
  158. apiproxy_stub_map.MakeSyncCall('remote_socket', 'Resolve', request, reply)
  159. except apiproxy_errors.ApplicationError, e:
  160. raise _SystemExceptionFromAppError(e)
  161. canonical_name = reply.canonical_name()
  162. aliases = reply.aliases_list()
  163. addresses = [inet_ntop(_ADDRESS_FAMILY_LENGTH_MAP[len(a)], a)
  164. for a in reply.packed_address_list()]
  165. return canonical_name, aliases, addresses
  166. def _ResolveService(servicename, protocolname, numeric_only=False):
  167. try:
  168. return (protocolname, int(servicename))
  169. except ValueError:
  170. pass
  171. if not numeric_only:
  172. for protocol, port in _SERVICES.get(servicename, []):
  173. if not protocolname or protocol == protocolname:
  174. return (protocol, port)
  175. raise gaierror(EAI_SERVICE, '')
  176. def gethostbyname(host):
  177. """gethostbyname(host) -> address
  178. Return the IP address (a string of the form '255.255.255.255') for a host.
  179. """
  180. return _Resolve(host, [AF_INET])[2][0]
  181. def gethostbyname_ex(host):
  182. """gethostbyname_ex(host) -> (name, aliaslist, addresslist)
  183. Return the true host name, a list of aliases, and a list of IP addresses,
  184. for a host. The host argument is a string giving a host name or IP number.
  185. """
  186. return _Resolve(host, [AF_INET])
  187. def gethostbyaddr(addr):
  188. raise SocketApiNotImplementedError()
  189. def gethostname():
  190. """gethostname() -> string
  191. Return the current host name.
  192. """
  193. return os.environ.get('HTTP_HOST', 'www.appspot.com')
  194. def getprotobyname(protocolname):
  195. raise SocketApiNotImplementedError()
  196. def getservbyname(servicename, protocolname=None):
  197. """getservbyname(servicename[, protocolname]) -> integer
  198. Return a port number from a service name and protocol name.
  199. The optional protocol name, if given, should be 'tcp' or 'udp',
  200. otherwise any protocol will match.
  201. """
  202. return _ResolveService(servicename, protocolname)[1]
  203. def getservbyport(portnumber, protocolname=0):
  204. raise SocketApiNotImplementedError()
  205. def getaddrinfo(host, service, family=AF_UNSPEC, socktype=0, proto=0, flags=0):
  206. """getaddrinfo(host, port [, family, socktype, proto, flags])
  207. -> list of (family, socktype, proto, canonname, sockaddr)
  208. Resolve host and port into addrinfo struct.
  209. """
  210. if isinstance(host, unicode):
  211. host = host.encode('idna')
  212. if host == '*':
  213. host = ''
  214. if service == '*':
  215. service = ''
  216. if not host and not service:
  217. raise gaierror(EAI_NONAME, 'nodename nor servname provided, or not known')
  218. families = [f for f in _ADDRESS_FAMILY_MAP.keys()
  219. if family in (AF_UNSPEC, f)]
  220. if not families:
  221. raise gaierror(EAI_FAMILY, 'ai_family not supported')
  222. sock_proto = [sp for sp in _SOCK_PROTO_MAP.keys()
  223. if socktype in (0, sp[0]) and proto in (0, sp[1])]
  224. if not sock_proto:
  225. raise gaierror(EAI_BADHINTS, 'Bad hints')
  226. canon = ''
  227. sock_proto_port = []
  228. family_addresses = []
  229. if host:
  230. canon, _, addresses = _Resolve(
  231. host, families,
  232. use_dns=~(flags & AI_NUMERICHOST),
  233. canonical=(flags & AI_CANONNAME))
  234. family_addresses = [(f, a)
  235. for f in families
  236. for a in addresses if _IsAddr(f, a)]
  237. else:
  238. if flags & AI_PASSIVE:
  239. canon = 'anyaddr'
  240. if AF_INET6 in families:
  241. family_addresses.append((AF_INET6, '::'))
  242. if AF_INET in families:
  243. family_addresses.append((AF_INET, '0.0.0.0'))
  244. else:
  245. canon = 'localhost'
  246. if AF_INET6 in families:
  247. family_addresses.append((AF_INET6, '::1'))
  248. if AF_INET in families:
  249. family_addresses.append((AF_INET, '127.0.0.1'))
  250. if service:
  251. sock_proto_port = [
  252. sp + (_ResolveService(service, _SOCK_PROTO_MAP[sp],
  253. flags & AI_NUMERICSERV)[1],)
  254. for sp in sock_proto]
  255. else:
  256. sock_proto_port = [sp + (0,) for sp in sock_proto]
  257. return [(fa[0], spp[0], spp[1], canon, (fa[1], spp[2]))
  258. for fa in family_addresses
  259. for spp in sock_proto_port]
  260. def getnameinfo():
  261. raise SocketApiNotImplementedError()
  262. def getdefaulttimeout():
  263. """getdefaulttimeout() -> timeout
  264. Returns the default timeout in floating seconds for new socket objects.
  265. A value of None indicates that new socket objects have no timeout.
  266. When the socket module is first imported, the default is None.
  267. """
  268. if _GLOBAL_TIMEOUT_VALUE < 0.0:
  269. return None
  270. return _GLOBAL_TIMEOUT_VALUE
  271. def setdefaulttimeout(timeout):
  272. """setdefaulttimeout(timeout)
  273. Set the default timeout in floating seconds for new socket objects.
  274. A value of None indicates that new socket objects have no timeout.
  275. When the socket module is first imported, the default is None.
  276. """
  277. if timeout is None:
  278. timeout = -1.0
  279. else:
  280. try:
  281. timeout = 0.0 + timeout
  282. except TypeError:
  283. raise TypeError('a float is required')
  284. if timeout < 0.0:
  285. raise ValueError('Timeout value out of range')
  286. global _GLOBAL_TIMEOUT_VALUE
  287. _GLOBAL_TIMEOUT_VALUE = timeout
  288. def _GetSocket(value):
  289. if isinstance(value, (int, long)):
  290. fileno = value
  291. else:
  292. try:
  293. fileno = value.fileno()
  294. except AttributeError:
  295. raise TypeError('argument must be an int, or have a fileno() method.')
  296. try:
  297. return _GLOBAL_SOCKET_MAP[fileno]
  298. except KeyError:
  299. raise ValueError('select only supported on socket objects.')
  300. def select(rlist, wlist, xlist, timeout=None):
  301. """select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)
  302. Wait until one or more file descriptors are ready for some kind of I/O.
  303. The first three arguments are sequences of file descriptors to be waited for:
  304. rlist -- wait until ready for reading
  305. wlist -- wait until ready for writing
  306. xlist -- wait for an ``exceptional condition''
  307. If only one kind of condition is required, pass [] for the other lists.
  308. A file descriptor is either a socket or file object, or a small integer
  309. gotten from a fileno() method call on one of those.
  310. The optional 4th argument specifies a timeout in seconds; it may be
  311. a floating point number to specify fractions of seconds. If it is absent
  312. or None, the call will never time out.
  313. The return value is a tuple of three lists corresponding to the first three
  314. arguments; each contains the subset of the corresponding file descriptors
  315. that are ready.
  316. """
  317. if not rlist and not wlist and not xlist:
  318. if timeout:
  319. time.sleep(timeout)
  320. return ([], [], [])
  321. state_map = {}
  322. rlist_out, wlist_out, xlist_out = [], [], []
  323. def _SetState(request, sock, event):
  324. socket_descriptor = sock._SocketDescriptor()
  325. state = state_map.setdefault(socket_descriptor, { 'observed_events': 0, })
  326. if ((event == POLLIN and sock._shutdown_read) or
  327. (event == POLLOUT and sock._shutdown_write)):
  328. state['observed_events'] |= event
  329. request.set_timeout_seconds(0.0)
  330. return
  331. poll_event = state.get('poll_event')
  332. if not poll_event:
  333. poll_event = request.add_events()
  334. poll_event.set_socket_descriptor(socket_descriptor)
  335. poll_event.set_observed_events(0)
  336. state['poll_event'] = poll_event
  337. poll_event.set_requested_events(poll_event.requested_events()|event)
  338. request = remote_socket_service_pb.PollRequest()
  339. if timeout is not None:
  340. request.set_timeout_seconds(timeout)
  341. for value in rlist:
  342. _SetState(request, _GetSocket(value), POLLIN)
  343. for value in wlist:
  344. _SetState(request, _GetSocket(value), POLLOUT)
  345. if request.events_size():
  346. reply = remote_socket_service_pb.PollReply()
  347. try:
  348. apiproxy_stub_map.MakeSyncCall('remote_socket', 'Poll', request, reply)
  349. except apiproxy_errors.ApplicationError, e:
  350. raise _SystemExceptionFromAppError(e)
  351. for event in reply.events_list():
  352. state_map[event.socket_descriptor()][
  353. 'observed_events'] |= event.observed_events()
  354. for value in rlist:
  355. state = state_map[_GetSocket(value)._SocketDescriptor()]
  356. if state['observed_events'] & POLLIN:
  357. rlist_out.append(value)
  358. for value in wlist:
  359. state = state_map[_GetSocket(value)._SocketDescriptor()]
  360. if state['observed_events'] & POLLOUT:
  361. wlist_out.append(value)
  362. return (rlist_out, wlist_out, xlist_out)
  363. class socket(object):
  364. """socket([family[, type[, proto]]]) -> socket object
  365. Open a socket of the given type. The family argument specifies the
  366. address family; it defaults to AF_INET. The type argument specifies
  367. whether this is a stream (SOCK_STREAM, this is the default)
  368. or datagram (SOCK_DGRAM) socket. The protocol argument defaults to 0,
  369. specifying the default protocol. Keyword arguments are accepted.
  370. A socket object represents one endpoint of a network connection.
  371. """
  372. def __del__(self):
  373. if not self._serialized:
  374. self.close()
  375. def __getstate__(self):
  376. self._serialized = True
  377. return self.__dict__
  378. def __init__(self, family=AF_INET, type=SOCK_STREAM, proto=0, _create=False):
  379. if family not in (AF_INET, AF_INET6):
  380. raise error(errno.EAFNOSUPPORT, os.strerror(errno.EAFNOSUPPORT))
  381. if type not in (SOCK_STREAM, SOCK_DGRAM):
  382. raise error(errno.EPROTONOSUPPORT, os.strerror(errno.EPROTONOSUPPORT))
  383. if proto:
  384. if ((proto not in (IPPROTO_TCP, IPPROTO_UDP)) or
  385. (proto == IPPROTO_TCP and type != SOCK_STREAM) or
  386. (proto == IPPROTO_UDP and type != SOCK_DGRAM)):
  387. raise error(errno.EPROTONOSUPPORT, os.strerror(errno.EPROTONOSUPPORT))
  388. self.family = family
  389. self.type = type
  390. self.proto = proto
  391. self._created = False
  392. self._fileno = None
  393. self._serialized = False
  394. self.settimeout(getdefaulttimeout())
  395. self._Clear()
  396. if _create:
  397. self._CreateSocket()
  398. def _Clear(self):
  399. self._socket_descriptor = None
  400. self._bound = False
  401. self._listen = False
  402. self._connected = False
  403. self._connect_in_progress = False
  404. self._shutdown_read = False
  405. self._shutdown_write = False
  406. self._setsockopt = []
  407. self._stream_offset = 0
  408. def _CreateSocket(self, address=None, bind_address=None,
  409. address_hostname_hint=None):
  410. assert not self._created
  411. self._created = True
  412. request = remote_socket_service_pb.CreateSocketRequest()
  413. if self.family == AF_INET:
  414. request.set_family(remote_socket_service_pb.CreateSocketRequest.IPv4)
  415. elif self.family == AF_INET6:
  416. request.set_family(remote_socket_service_pb.CreateSocketRequest.IPv6)
  417. if self.type == SOCK_STREAM:
  418. request.set_protocol(remote_socket_service_pb.CreateSocketRequest.TCP)
  419. elif self.type == SOCK_DGRAM:
  420. request.set_protocol(remote_socket_service_pb.CreateSocketRequest.UDP)
  421. if address:
  422. assert self.gettimeout() is None, (
  423. 'Non-blocking connect not supported by CreateSocket')
  424. self._SetProtoFromAddr(request.mutable_remote_ip(), address,
  425. address_hostname_hint)
  426. if bind_address:
  427. self._SetProtoFromAddr(request.mutable_proxy_external_ip(), bind_address)
  428. for level, option, value in self._setsockopt:
  429. o = request.add_socket_options()
  430. o.set_level(level)
  431. o.set_option(option)
  432. if isinstance(value, (int, long)):
  433. o.set_value(struct.pack('=L', value))
  434. else:
  435. o.set_value(value)
  436. self._setsockopt = []
  437. reply = remote_socket_service_pb.CreateSocketReply()
  438. try:
  439. apiproxy_stub_map.MakeSyncCall(
  440. 'remote_socket', 'CreateSocket', request, reply)
  441. except apiproxy_errors.ApplicationError, e:
  442. raise _SystemExceptionFromAppError(e)
  443. self._socket_descriptor = reply.socket_descriptor()
  444. if bind_address:
  445. self._bound = True
  446. if address:
  447. self._bound = True
  448. self._connected = True
  449. def _GetPackedAddr(self, addr):
  450. if addr == '<broadcast>':
  451. if self.family == AF_INET6:
  452. return '\xff' * 16
  453. else:
  454. return '\xff' * 4
  455. for res in getaddrinfo(addr, '0',
  456. self.family, self.type, self.proto,
  457. AI_NUMERICSERV|AI_PASSIVE):
  458. return inet_pton(self.family, res[4][0])
  459. def _SetProtoFromAddr(self, proto, address, hostname_hint=None):
  460. address, port = address
  461. proto.set_packed_address(self._GetPackedAddr(address))
  462. proto.set_port(port)
  463. proto.set_hostname_hint(hostname_hint or address)
  464. def fileno(self):
  465. """fileno() -> integer
  466. Return the integer file descriptor of the socket.
  467. """
  468. global _GLOBAL_SOCKET_MAP
  469. global _GLOBAL_SOCKET_NEXT_FILENO
  470. if self._fileno is None:
  471. self._fileno = _GLOBAL_SOCKET_NEXT_FILENO
  472. _GLOBAL_SOCKET_NEXT_FILENO += 1
  473. _GLOBAL_SOCKET_MAP[self._fileno] = self
  474. assert _GLOBAL_SOCKET_MAP.get(self._fileno) == self, (
  475. "fileno mismatch in _GLOBAL_SOCKET_MAP")
  476. return self._fileno
  477. def bind(self, address):
  478. """bind(address)
  479. Bind the socket to a local address. For IP sockets, the address is a
  480. pair (host, port); the host must refer to the local host. For raw packet
  481. sockets the address is a tuple (ifname, proto [,pkttype [,hatype]])
  482. """
  483. if not self._created:
  484. self._CreateSocket(bind_address=address)
  485. return
  486. if not self._socket_descriptor:
  487. raise error(errno.EBADF, os.strerror(errno.EBADF))
  488. if self._bound:
  489. raise error(errno.EINVAL, os.strerror(errno.EINVAL))
  490. request = remote_socket_service_pb.BindRequest()
  491. request.set_socket_descriptor(self._socket_descriptor)
  492. self._SetProtoFromAddr(request.mutable_proxy_external_ip(), address)
  493. reply = remote_socket_service_pb.BindReply()
  494. try:
  495. apiproxy_stub_map.MakeSyncCall('remote_socket', 'Bind', request, reply)
  496. except apiproxy_errors.ApplicationError, e:
  497. raise _SystemExceptionFromAppError(e)
  498. def listen(self, backlog):
  499. """listen(backlog)
  500. Enable a server to accept connections. The backlog argument must be at
  501. least 1; it specifies the number of unaccepted connection that the system
  502. will allow before refusing new connections.
  503. """
  504. if not self._created:
  505. self._CreateSocket(bind_address=('', 0))
  506. if not self._socket_descriptor:
  507. raise error(errno.EBADF, os.strerror(errno.EBADF))
  508. if self._connected:
  509. raise error(errno.EINVAL, os.strerror(errno.EINVAL))
  510. if self.type != SOCK_STREAM:
  511. raise error(errno.EOPNOTSUPP, os.strerror(errno.EOPNOTSUPP))
  512. self._bound = True
  513. self._listen = True
  514. request = remote_socket_service_pb.ListenRequest()
  515. request.set_socket_descriptor(self._socket_descriptor)
  516. request.set_backlog(backlog)
  517. reply = remote_socket_service_pb.ListenReply()
  518. try:
  519. apiproxy_stub_map.MakeSyncCall('remote_socket', 'Listen', request, reply)
  520. except apiproxy_errors.ApplicationError, e:
  521. raise _SystemExceptionFromAppError(e)
  522. def accept(self):
  523. """accept() -> (socket object, address info)
  524. Wait for an incoming connection. Return a new socket representing the
  525. connection, and the address of the client. For IP sockets, the address
  526. info is a pair (hostaddr, port).
  527. """
  528. if not self._created:
  529. self._CreateSocket()
  530. if not self._socket_descriptor:
  531. raise error(errno.EBADF, os.strerror(errno.EBADF))
  532. if not self._listen:
  533. raise error(errno.EINVAL, os.strerror(errno.EINVAL))
  534. request = remote_socket_service_pb.AcceptRequest()
  535. request.set_socket_descriptor(self._socket_descriptor)
  536. if self.gettimeout() is not None:
  537. request.set_timeout_seconds(self.gettimeout())
  538. reply = remote_socket_service_pb.AcceptReply()
  539. try:
  540. apiproxy_stub_map.MakeSyncCall('remote_socket', 'Accept', request, reply)
  541. except apiproxy_errors.ApplicationError, e:
  542. raise _SystemExceptionFromAppError(e)
  543. ret = socket(self.family, self.type, self.proto)
  544. ret._socket_descriptor = reply.new_socket_descriptor()
  545. ret._created = True
  546. ret._bound = True
  547. ret._connected = True
  548. return ret
  549. def connect(self, address, _hostname_hint=None):
  550. """connect(address)
  551. Connect the socket to a remote address. For IP sockets, the address
  552. is a pair (host, port).
  553. """
  554. if not self._created:
  555. if self.gettimeout() is None:
  556. self._CreateSocket(address=address,
  557. address_hostname_hint=_hostname_hint)
  558. return
  559. else:
  560. self._CreateSocket()
  561. if not self._socket_descriptor:
  562. raise error(errno.EBADF, os.strerror(errno.EBADF))
  563. if self._connected:
  564. raise error(errno.EISCONN, os.strerror(errno.EISCONN))
  565. request = remote_socket_service_pb.ConnectRequest()
  566. request.set_socket_descriptor(self._socket_descriptor)
  567. self._SetProtoFromAddr(request.mutable_remote_ip(), address, _hostname_hint)
  568. if self.gettimeout() is not None:
  569. request.set_timeout_seconds(self.gettimeout())
  570. reply = remote_socket_service_pb.ConnectReply()
  571. try:
  572. apiproxy_stub_map.MakeSyncCall('remote_socket', 'Connect', request, reply)
  573. except apiproxy_errors.ApplicationError, e:
  574. translated_e = _SystemExceptionFromAppError(e)
  575. if translated_e.errno == errno.EISCONN:
  576. self._bound = True
  577. self._connected = True
  578. elif translated_e.errno == errno.EINPROGRESS:
  579. self._connect_in_progress = True
  580. raise translated_e
  581. self._bound = True
  582. self._connected = True
  583. def connect_ex(self, address):
  584. """connect_ex(address) -> errno
  585. This is like connect(address), but returns an error code (the errno value)
  586. instead of raising an exception when an error occurs.
  587. """
  588. try:
  589. self.connect(address)
  590. except error, e:
  591. return e.errno
  592. return 0
  593. def getpeername(self):
  594. """getpeername() -> address info
  595. Return the address of the remote endpoint. For IP sockets, the address
  596. info is a pair (hostaddr, port).
  597. """
  598. if not self._created:
  599. self._CreateSocket()
  600. if not self._socket_descriptor:
  601. raise error(errno.EBADF, os.strerror(errno.EBADF))
  602. if not (self._connected or self._connect_in_progress):
  603. raise error(errno.ENOTCONN, os.strerror(errno.ENOTCONN))
  604. request = remote_socket_service_pb.GetPeerNameRequest()
  605. request.set_socket_descriptor(self._socket_descriptor)
  606. reply = remote_socket_service_pb.GetPeerNameReply()
  607. try:
  608. apiproxy_stub_map.MakeSyncCall(
  609. 'remote_socket', 'GetPeerName', request, reply)
  610. except apiproxy_errors.ApplicationError, e:
  611. raise _SystemExceptionFromAppError(e)
  612. if self._connect_in_progress:
  613. self._connect_in_progress = False
  614. self._connected = True
  615. return (
  616. inet_ntop(self.family, reply.peer_ip().packed_address()),
  617. reply.peer_ip().port())
  618. def getsockname(self):
  619. """getsockname() -> address info
  620. Return the address of the local endpoint. For IP sockets, the address
  621. info is a pair (hostaddr, port).
  622. """
  623. if not self._created:
  624. self._CreateSocket()
  625. if not self._socket_descriptor:
  626. raise error(errno.EBADF, os.strerror(errno.EBADF))
  627. request = remote_socket_service_pb.GetSocketNameRequest()
  628. request.set_socket_descriptor(self._socket_descriptor)
  629. reply = remote_socket_service_pb.GetSocketNameReply()
  630. try:
  631. apiproxy_stub_map.MakeSyncCall(
  632. 'remote_socket', 'GetSocketName', request, reply)
  633. except apiproxy_errors.ApplicationError, e:
  634. raise _SystemExceptionFromAppError(e)
  635. return (
  636. inet_ntop(self.family, reply.proxy_external_ip().packed_address()),
  637. reply.proxy_external_ip().port())
  638. def recv(self, buffersize, flags=0):
  639. """recv(buffersize[, flags]) -> data
  640. Receive up to buffersize bytes from the socket. For the optional flags
  641. argument, see the Unix manual. When no data is available, block until
  642. at least one byte is available or until the remote end is closed. When
  643. the remote end is closed and all data is read, return the empty string.
  644. """
  645. return self.recvfrom(buffersize, flags)[0]
  646. def recv_into(self, buf, nbytes=0, flags=0):
  647. """recv_into(buffer, [nbytes[, flags]]) -> nbytes_read
  648. A version of recv() that stores its data into a buffer rather than
  649. creating a new string. Receive up to buffersize bytes from the socket.
  650. If buffersize is not specified (or 0), receive up to the size available
  651. in the given buffer.
  652. See recv() for documentation about the flags.
  653. """
  654. raise SocketApiNotImplementedError()
  655. def recvfrom(self, buffersize, flags=0):
  656. """recvfrom(buffersize[, flags]) -> (data, address info)
  657. Like recv(buffersize, flags) but also return the sender's address info.
  658. """
  659. if not self._created:
  660. self._CreateSocket()
  661. if not self._socket_descriptor:
  662. raise error(errno.EBADF, os.strerror(errno.EBADF))
  663. request = remote_socket_service_pb.ReceiveRequest()
  664. request.set_socket_descriptor(self._socket_descriptor)
  665. request.set_data_size(buffersize)
  666. request.set_flags(flags)
  667. if self.type == SOCK_STREAM:
  668. if not (self._connected or self._connect_in_progress):
  669. raise error(errno.ENOTCONN, os.strerror(errno.ENOTCONN))
  670. if self._shutdown_read:
  671. request.set_timeout_seconds(0.0)
  672. elif self.gettimeout() is not None:
  673. request.set_timeout_seconds(self.gettimeout())
  674. reply = remote_socket_service_pb.ReceiveReply()
  675. try:
  676. apiproxy_stub_map.MakeSyncCall('remote_socket', 'Receive', request, reply)
  677. except apiproxy_errors.ApplicationError, e:
  678. e = _SystemExceptionFromAppError(e)
  679. if not self._shutdown_read or e.errno != errno.EAGAIN:
  680. raise e
  681. if self._connect_in_progress:
  682. self._connect_in_progress = False
  683. self._connected = True
  684. address = None
  685. if reply.has_received_from():
  686. address = (
  687. inet_ntop(self.family, reply.received_from().packed_address()),
  688. reply.received_from().port())
  689. return reply.data(), address
  690. def recvfrom_into(self, buffer, nbytes=0, flags=0):
  691. """recvfrom_into(buffer[, nbytes[, flags]]) -> (nbytes, address info)
  692. Like recv_into(buffer[, nbytes[, flags]]) but also return the
  693. sender's address info.
  694. """
  695. raise SocketApiNotImplementedError()
  696. def send(self, data, flags=0):
  697. """send(data[, flags]) -> count
  698. Send a data string to the socket. For the optional flags
  699. argument, see the Unix manual. Return the number of bytes
  700. sent; this may be less than len(data) if the network is busy.
  701. """
  702. return self.sendto(data, flags, None)
  703. def sendall(self, data, flags=0):
  704. """sendall(data[, flags])
  705. Send a data string to the socket. For the optional flags
  706. argument, see the Unix manual. This calls send() repeatedly
  707. until all data is sent. If an error occurs, it's impossible
  708. to tell how much data has been sent.
  709. """
  710. offset = 0
  711. while offset < len(data):
  712. offset += self.sendto(data[offset:], flags, None)
  713. def sendto(self, data, *args):
  714. """sendto(data[, flags], address) -> count
  715. Like send(data, flags) but allows specifying the destination address.
  716. For IP sockets, the address is a pair (hostaddr, port).
  717. """
  718. if len(args) == 1:
  719. flags, address = 0, args[0]
  720. elif len(args) == 2:
  721. flags, address = args
  722. if not self._created:
  723. self._CreateSocket()
  724. if not self._socket_descriptor:
  725. raise error(errno.EBADF, os.strerror(errno.EBADF))
  726. if self._shutdown_write:
  727. raise error(errno.EPIPE, os.strerror(errno.EPIPE))
  728. request = remote_socket_service_pb.SendRequest()
  729. request.set_socket_descriptor(self._socket_descriptor)
  730. if len(data) > 512*1024:
  731. request.set_data(data[:512*1024])
  732. else:
  733. request.set_data(data)
  734. request.set_flags(flags)
  735. request.set_stream_offset(self._stream_offset)
  736. if address:
  737. if self._connected:
  738. raise error(errno.EISCONN, os.strerror(errno.EISCONN))
  739. if self.type != SOCK_DGRAM:
  740. raise error(errno.ENOTCONN, os.strerror(errno.ENOTCONN))
  741. self._SetProtoFromAddr(request.mutable_send_to(), address)
  742. else:
  743. if not (self._connected or self._connect_in_progress):
  744. raise error(errno.ENOTCONN, os.strerror(errno.ENOTCONN))
  745. if self.gettimeout() is not None:
  746. request.set_timeout_seconds(self.gettimeout())
  747. reply = remote_socket_service_pb.SendReply()
  748. try:
  749. apiproxy_stub_map.MakeSyncCall('remote_socket', 'Send', request, reply)
  750. except apiproxy_errors.ApplicationError, e:
  751. raise _SystemExceptionFromAppError(e)
  752. if self._connect_in_progress:
  753. self._connect_in_progress = False
  754. self._connected = True
  755. nbytes = reply.data_sent()
  756. assert nbytes >= 0
  757. if self.type == SOCK_STREAM:
  758. self._stream_offset += nbytes
  759. return nbytes
  760. def setblocking(self, block):
  761. """setblocking(flag)
  762. Set the socket to blocking (flag is true) or non-blocking (false).
  763. setblocking(True) is equivalent to settimeout(None);
  764. setblocking(False) is equivalent to settimeout(0.0).
  765. """
  766. if block:
  767. self._timeout = -1.0
  768. else:
  769. self._timeout = 0.0
  770. def settimeout(self, timeout):
  771. """settimeout(timeout)
  772. Set a timeout on socket operations. 'timeout' can be a float,
  773. giving in seconds, or None. Setting a timeout of None disables
  774. the timeout feature and is equivalent to setblocking(1).
  775. Setting a timeout of zero is the same as setblocking(0).
  776. """
  777. if timeout is None:
  778. self._timeout = -1.0
  779. else:
  780. try:
  781. self._timeout = 0.0 + timeout
  782. except:
  783. raise TypeError('a float is required')
  784. if self._timeout < 0.0:
  785. raise ValueError('Timeout value out of range')
  786. def gettimeout(self):
  787. """gettimeout() -> timeout
  788. Returns the timeout in floating seconds associated with socket
  789. operations. A timeout of None indicates that timeouts on socket
  790. operations are disabled.
  791. """
  792. if self._timeout < 0.0:
  793. return None
  794. return self._timeout
  795. def setsockopt(self, level, option, value):
  796. """setsockopt(level, option, value)
  797. Set a socket option. See the Unix manual for level and option.
  798. The value argument can either be an integer or a string.
  799. """
  800. if not self._created:
  801. self._setsockopt.append((level, option, value))
  802. self._CreateSocket()
  803. return
  804. if not self._socket_descriptor:
  805. raise error(errno.EBADF, os.strerror(errno.EBADF))
  806. request = remote_socket_service_pb.SetSocketOptionsRequest()
  807. request.set_socket_descriptor(self._socket_descriptor)
  808. o = request.add_options()
  809. o.set_level(level)
  810. o.set_option(option)
  811. if isinstance(value, (int, long)):
  812. o.set_value(struct.pack('=L', value))
  813. else:
  814. o.set_value(value)
  815. reply = remote_socket_service_pb.SetSocketOptionsReply()
  816. try:
  817. apiproxy_stub_map.MakeSyncCall(
  818. 'remote_socket', 'SetSocketOptions', request, reply)
  819. except apiproxy_errors.ApplicationError, e:
  820. raise _SystemExceptionFromAppError(e)
  821. def getsockopt(self, level, option, buffersize=0):
  822. """getsockopt(level, option[, buffersize]) -> value
  823. Get a socket option. See the Unix manual for level and option.
  824. If a nonzero buffersize argument is given, the return value is a
  825. string of that length; otherwise it is an integer.
  826. """
  827. if not self._created:
  828. self._CreateSocket()
  829. if not self._socket_descriptor:
  830. raise error(errno.EBADF, os.strerror(errno.EBADF))
  831. request = remote_socket_service_pb.GetSocketOptionsRequest()
  832. request.set_socket_descriptor(self._socket_descriptor)
  833. o = request.add_options()
  834. o.set_level(level)
  835. o.set_option(option)
  836. o.set_value('')
  837. reply = remote_socket_service_pb.GetSocketOptionsReply()
  838. try:
  839. apiproxy_stub_map.MakeSyncCall(
  840. 'remote_socket', 'GetSocketOptions', request, reply)
  841. except apiproxy_errors.ApplicationError, e:
  842. raise _SystemExceptionFromAppError(e)
  843. if not buffersize:
  844. return struct.unpack('=L', reply.options(0).value())[0]
  845. else:
  846. return reply.options(0).value()[:buffersize]
  847. def shutdown(self, flag):
  848. """shutdown(flag)
  849. Shut down the reading side of the socket (flag == SHUT_RD), the writing side
  850. of the socket (flag == SHUT_WR), or both ends (flag == SHUT_RDWR).
  851. """
  852. if not flag in (SHUT_RD, SHUT_WR, SHUT_RDWR):
  853. raise error(errno.EINVAL, os.strerror(errno.EINVAL))
  854. if not self._created:
  855. self._CreateSocket()
  856. if not self._socket_descriptor:
  857. raise error(errno.EBADF, os.strerror(errno.EBADF))
  858. if (not self._connected or
  859. (self._shutdown_read and flag in (SHUT_RD, SHUT_RDWR)) or
  860. (self._shutdown_write and flag in (SHUT_RD, SHUT_RDWR))):
  861. raise error(errno.ENOTCONN, os.strerror(errno.ENOTCONN))
  862. request = remote_socket_service_pb.ShutDownRequest()
  863. request.set_socket_descriptor(self._socket_descriptor)
  864. request.set_how(flag)
  865. request.set_send_offset(self._stream_offset)
  866. reply = remote_socket_service_pb.ShutDownReply()
  867. try:
  868. apiproxy_stub_map.MakeSyncCall(
  869. 'remote_socket', 'ShutDown', request, reply)
  870. except apiproxy_errors.ApplicationError, e:
  871. raise _SystemExceptionFromAppError(e)
  872. if flag == SHUT_RD or flag == SHUT_RDWR:
  873. self._shutdown_read = True
  874. if flag == SHUT_WR or flag == SHUT_RDWR:
  875. self._shutdown_write = True
  876. def close(self):
  877. """close()
  878. Close the socket. It cannot be used after this call.
  879. """
  880. self._created = True
  881. if not self._socket_descriptor:
  882. return
  883. request = remote_socket_service_pb.CloseRequest()
  884. request.set_socket_descriptor(self._socket_descriptor)
  885. reply = remote_socket_service_pb.CloseReply()
  886. try:
  887. apiproxy_stub_map.MakeSyncCall('remote_socket', 'Close', request, reply)
  888. except apiproxy_errors.ApplicationError, e:
  889. raise _SystemExceptionFromAppError(e)
  890. self._Clear()
  891. def _SocketDescriptor(self):
  892. if not self._created:
  893. self._CreateSocket()
  894. if not self._socket_descriptor:
  895. raise error(errno.EBADF, os.strerror(errno.EBADF))
  896. return self._socket_descriptor