"""
This is an updated socket module for use on JVMs > 1.5; it is derived from the old jython socket module.
It is documented, along with known issues and workarounds, on the jython wiki.
http://wiki.python.org/jython/NewSocketModule
"""

_defaulttimeout = None

import errno
import jarray
import string
import struct
import sys
import threading
import time
import types

# Java.io classes
import java.io.BufferedInputStream
import java.io.BufferedOutputStream
# Java.io exceptions
import java.io.InterruptedIOException
import java.io.IOException

# Java.lang classes
import java.lang.String
# Java.lang exceptions
import java.lang.Exception

# Java.net classes
import java.net.DatagramPacket
import java.net.InetAddress
import java.net.InetSocketAddress
import java.net.Socket
# Java.net exceptions
import java.net.BindException
import java.net.ConnectException
import java.net.NoRouteToHostException
import java.net.PortUnreachableException
import java.net.ProtocolException
import java.net.SocketException
import java.net.SocketTimeoutException
import java.net.UnknownHostException

# Java.nio classes
import java.nio.ByteBuffer
import java.nio.channels.DatagramChannel
import java.nio.channels.ServerSocketChannel
import java.nio.channels.SocketChannel
# Java.nio exceptions
import java.nio.channels.AlreadyConnectedException
import java.nio.channels.AsynchronousCloseException
import java.nio.channels.CancelledKeyException
import java.nio.channels.ClosedByInterruptException
import java.nio.channels.ClosedChannelException
import java.nio.channels.ClosedSelectorException
import java.nio.channels.ConnectionPendingException
import java.nio.channels.IllegalBlockingModeException
import java.nio.channels.IllegalSelectorException
import java.nio.channels.NoConnectionPendingException
import java.nio.channels.NonReadableChannelException
import java.nio.channels.NonWritableChannelException
import java.nio.channels.NotYetBoundException
import java.nio.channels.NotYetConnectedException
import java.nio.channels.UnresolvedAddressException
import java.nio.channels.UnsupportedAddressTypeException

# Javax.net.ssl classes
import javax.net.ssl.SSLSocketFactory
# Javax.net.ssl exceptions
javax.net.ssl.SSLException
javax.net.ssl.SSLHandshakeException
javax.net.ssl.SSLKeyException
javax.net.ssl.SSLPeerUnverifiedException
javax.net.ssl.SSLProtocolException

import org.python.core.io.DatagramSocketIO
import org.python.core.io.ServerSocketIO
import org.python.core.io.SocketIO
from org.python.core.Py import newString as asPyString

class error(Exception): pass
class herror(error): pass
class gaierror(error): pass
class timeout(error): pass
class sslerror(error): pass

def _unmapped_exception(exc):
    return error(-1, 'Unmapped exception: %s' % exc)

def java_net_socketexception_handler(exc):
    if exc.message.startswith("Address family not supported by protocol family"):
        return error(errno.EAFNOSUPPORT, 'Address family not supported by protocol family: See http://wiki.python.org/jython/NewSocketModule#IPV6addresssupport')
    return _unmapped_exception(exc)

def would_block_error(exc=None):
    return error(errno.EWOULDBLOCK, 'The socket operation could not complete without blocking')

ALL = None

_exception_map = {

# (<javaexception>, <circumstance>) : callable that raises the python equivalent exception, or None to stub out as unmapped

(java.io.IOException, ALL)            : lambda x: error(errno.ECONNRESET, 'Software caused connection abort'),
(java.io.InterruptedIOException, ALL) : lambda x: timeout('timed out'),

(java.net.BindException, ALL)            : lambda x: error(errno.EADDRINUSE, 'Address already in use'),
(java.net.ConnectException, ALL)         : lambda x: error(errno.ECONNREFUSED, 'Connection refused'),
(java.net.NoRouteToHostException, ALL)   : None,
(java.net.PortUnreachableException, ALL) : None,
(java.net.ProtocolException, ALL)        : None,
(java.net.SocketException, ALL)          : java_net_socketexception_handler,
(java.net.SocketTimeoutException, ALL)   : lambda x: timeout('timed out'),
(java.net.UnknownHostException, ALL)     : lambda x: gaierror(errno.EGETADDRINFOFAILED, 'getaddrinfo failed'),

(java.nio.channels.AlreadyConnectedException, ALL)       : lambda x: error(errno.EISCONN, 'Socket is already connected'),
(java.nio.channels.AsynchronousCloseException, ALL)      : None,
(java.nio.channels.CancelledKeyException, ALL)           : None,
(java.nio.channels.ClosedByInterruptException, ALL)      : None,
(java.nio.channels.ClosedChannelException, ALL)          : lambda x: error(errno.EPIPE, 'Socket closed'),
(java.nio.channels.ClosedSelectorException, ALL)         : None,
(java.nio.channels.ConnectionPendingException, ALL)      : None,
(java.nio.channels.IllegalBlockingModeException, ALL)    : None,
(java.nio.channels.IllegalSelectorException, ALL)        : None,
(java.nio.channels.NoConnectionPendingException, ALL)    : None,
(java.nio.channels.NonReadableChannelException, ALL)     : None,
(java.nio.channels.NonWritableChannelException, ALL)     : None,
(java.nio.channels.NotYetBoundException, ALL)            : None,
(java.nio.channels.NotYetConnectedException, ALL)        : None,
(java.nio.channels.UnresolvedAddressException, ALL)      : lambda x: gaierror(errno.EGETADDRINFOFAILED, 'getaddrinfo failed'),
(java.nio.channels.UnsupportedAddressTypeException, ALL) : None,

# These error codes are currently wrong: getting them correct is going to require
# some investigation. Cpython 2.6 introduced extensive SSL support.

(javax.net.ssl.SSLException, ALL)                        : lambda x: sslerror(-1, 'SSL exception'),
(javax.net.ssl.SSLHandshakeException, ALL)               : lambda x: sslerror(-1, 'SSL handshake exception'),
(javax.net.ssl.SSLKeyException, ALL)                     : lambda x: sslerror(-1, 'SSL key exception'),
(javax.net.ssl.SSLPeerUnverifiedException, ALL)          : lambda x: sslerror(-1, 'SSL peer unverified exception'),
(javax.net.ssl.SSLProtocolException, ALL)                : lambda x: sslerror(-1, 'SSL protocol exception'),

}

def _map_exception(exc, circumstance=ALL):
#    print "Mapping exception: %s" % exc
    mapped_exception = _exception_map.get((exc.__class__, circumstance))
    if mapped_exception:
        exception = mapped_exception(exc)
    else:
        exception = error(-1, 'Unmapped exception: %s' % exc)
    exception.java_exception = exc
    return exception

_feature_support_map = {
    'ipv6': True,
    'idna': False,
    'tipc': False,
}

def supports(feature, *args):
    if len(args) == 1:
        _feature_support_map[feature] = args[0]
    return _feature_support_map.get(feature, False)

MODE_BLOCKING    = 'block'
MODE_NONBLOCKING = 'nonblock'
MODE_TIMEOUT     = 'timeout'

_permitted_modes = (MODE_BLOCKING, MODE_NONBLOCKING, MODE_TIMEOUT)

SHUT_RD   = 0
SHUT_WR   = 1
SHUT_RDWR = 2

AF_UNSPEC = 0
AF_INET = 2
AF_INET6 = 23

AI_PASSIVE=1
AI_CANONNAME=2

# For some reason, probably historical, SOCK_DGRAM and SOCK_STREAM are opposite values of what they are on cpython.
# I.E. The following is the way they are on cpython
# SOCK_STREAM    = 1
# SOCK_DGRAM     = 2
# At some point, we should probably switch them around, which *should* not affect anybody

SOCK_DGRAM     = 1
SOCK_STREAM    = 2
SOCK_RAW       = 3 # not supported
SOCK_RDM       = 4 # not supported
SOCK_SEQPACKET = 5 # not supported

SOL_SOCKET = 0xFFFF
IPPROTO_TCP = 6
IPPROTO_UDP = 17

SO_BROADCAST   = 1
SO_KEEPALIVE   = 2
SO_LINGER      = 4
SO_OOBINLINE   = 8
SO_RCVBUF      = 16
SO_REUSEADDR   = 32
SO_SNDBUF      = 64
SO_TIMEOUT     = 128

TCP_NODELAY    = 256

INADDR_ANY = "0.0.0.0"
INADDR_BROADCAST = "255.255.255.255"

# Options with negative constants are not supported
# They are being added here so that code that refers to them
# will not break with an AttributeError

SO_ACCEPTCONN       = -1
SO_DEBUG            = -2
SO_DONTROUTE        = -4
SO_ERROR            = -8
SO_EXCLUSIVEADDRUSE = -16
SO_RCVLOWAT         = -32
SO_RCVTIMEO         = -64
SO_REUSEPORT        = -128
SO_SNDLOWAT         = -256
SO_SNDTIMEO         = -512
SO_TYPE             = -1024
SO_USELOOPBACK      = -2048

__all__ = ['AF_UNSPEC', 'AF_INET', 'AF_INET6', 'AI_PASSIVE', 'SOCK_DGRAM',
        'SOCK_RAW', 'SOCK_RDM', 'SOCK_SEQPACKET', 'SOCK_STREAM', 'SOL_SOCKET',
        'SO_BROADCAST', 'SO_ERROR', 'SO_KEEPALIVE', 'SO_LINGER', 'SO_OOBINLINE',
        'SO_RCVBUF', 'SO_REUSEADDR', 'SO_SNDBUF', 'SO_TIMEOUT', 'TCP_NODELAY',
        'INADDR_ANY', 'INADDR_BROADCAST', 'IPPROTO_TCP', 'IPPROTO_UDP',
        'SocketType', 'error', 'herror', 'gaierror', 'timeout',
        'getfqdn', 'gethostbyaddr', 'gethostbyname', 'gethostname',
        'socket', 'getaddrinfo', 'getdefaulttimeout', 'setdefaulttimeout',
        'has_ipv6', 'htons', 'htonl', 'ntohs', 'ntohl',
        'SHUT_RD', 'SHUT_WR', 'SHUT_RDWR',
        ]

def _constant_to_name(const_value):
    sock_module = sys.modules['socket']
    try:
        for name in dir(sock_module):
            if getattr(sock_module, name) is const_value:
                return name
        return "Unknown"
    finally:
        sock_module = None

class _nio_impl:

    timeout = None
    mode = MODE_BLOCKING

    def getpeername(self):
        return (self.jsocket.getInetAddress().getHostAddress(), self.jsocket.getPort() )

    def config(self, mode, timeout):
        self.mode = mode
        if self.mode == MODE_BLOCKING:
            self.jchannel.configureBlocking(1)
        if self.mode == MODE_NONBLOCKING:
            self.jchannel.configureBlocking(0)
        if self.mode == MODE_TIMEOUT:
            self.jchannel.configureBlocking(1)
            self._timeout_millis = int(timeout*1000)
            self.jsocket.setSoTimeout(self._timeout_millis)

    def getsockopt(self, level, option):
        if (level, option) in self.options:
            result = getattr(self.jsocket, "get%s" % self.options[ (level, option) ])()
            if option == SO_LINGER:
                if result == -1:
                    enabled, linger_time = 0, 0
                else:
                    enabled, linger_time = 1, result
                return struct.pack('ii', enabled, linger_time)
            return result
        else:
            raise error(errno.ENOPROTOOPT, "Socket option '%s' (level '%s') not supported on socket(%s)" % (_constant_to_name(option), _constant_to_name(level), str(self.jsocket)))

    def setsockopt(self, level, option, value):
        if (level, option) in self.options:
            if option == SO_LINGER:
                values = struct.unpack('ii', value)
                self.jsocket.setSoLinger(*values)
            else:
                getattr(self.jsocket, "set%s" % self.options[ (level, option) ])(value)
        else:
            raise error(errno.ENOPROTOOPT, "Socket option '%s' (level '%s') not supported on socket(%s)" % (_constant_to_name(option), _constant_to_name(level), str(self.jsocket)))

    def close(self):
        self.jsocket.close()

    def getchannel(self):
        return self.jchannel

    def fileno(self):
        return self.socketio

class _client_socket_impl(_nio_impl):

    options = {
        (SOL_SOCKET,  SO_KEEPALIVE):   'KeepAlive',
        (SOL_SOCKET,  SO_LINGER):      'SoLinger',
        (SOL_SOCKET,  SO_OOBINLINE):   'OOBInline',
        (SOL_SOCKET,  SO_RCVBUF):      'ReceiveBufferSize',
        (SOL_SOCKET,  SO_REUSEADDR):   'ReuseAddress',
        (SOL_SOCKET,  SO_SNDBUF):      'SendBufferSize',
        (SOL_SOCKET,  SO_TIMEOUT):     'SoTimeout',
        (IPPROTO_TCP, TCP_NODELAY):    'TcpNoDelay',
    }

    def __init__(self, socket=None):
        if socket:
            self.jchannel = socket.getChannel()
        else:
            self.jchannel = java.nio.channels.SocketChannel.open()
        self.jsocket = self.jchannel.socket()
        self.socketio = org.python.core.io.SocketIO(self.jchannel, 'rw')

    def bind(self, jsockaddr, reuse_addr):
        self.jsocket.setReuseAddress(reuse_addr)
        self.jsocket.bind(jsockaddr)

    def connect(self, jsockaddr):
        if self.mode == MODE_TIMEOUT:
            self.jsocket.connect (jsockaddr, self._timeout_millis)
        else:
            self.jchannel.connect(jsockaddr)

    def finish_connect(self):
        return self.jchannel.finishConnect()

    def _do_read_net(self, buf):
        # Need two separate implementations because the java.nio APIs do not support timeouts
        return self.jsocket.getInputStream().read(buf)

    def _do_read_nio(self, buf):
        bytebuf = java.nio.ByteBuffer.wrap(buf)
        count = self.jchannel.read(bytebuf)
        return count

    def _do_write_net(self, buf):
        self.jsocket.getOutputStream().write(buf)
        return len(buf)

    def _do_write_nio(self, buf):
        bytebuf = java.nio.ByteBuffer.wrap(buf)
        count = self.jchannel.write(bytebuf)
        return count

    def read(self, buf):
        if self.mode == MODE_TIMEOUT:
            return self._do_read_net(buf)
        else:
            return self._do_read_nio(buf)

    def write(self, buf):
        if self.mode == MODE_TIMEOUT:
            return self._do_write_net(buf)
        else:
            return self._do_write_nio(buf)

    def shutdown(self, how):
        if how in (SHUT_RD, SHUT_RDWR):
            self.jsocket.shutdownInput()
        if how in (SHUT_WR, SHUT_RDWR):
            self.jsocket.shutdownOutput()

class _server_socket_impl(_nio_impl):

    options = {
        (SOL_SOCKET, SO_RCVBUF):      'ReceiveBufferSize',
        (SOL_SOCKET, SO_REUSEADDR):   'ReuseAddress',
        (SOL_SOCKET, SO_TIMEOUT):     'SoTimeout',
    }

    def __init__(self, jsockaddr, backlog, reuse_addr):
        self.jchannel = java.nio.channels.ServerSocketChannel.open()
        self.jsocket = self.jchannel.socket()
        self.jsocket.setReuseAddress(reuse_addr)
        self.jsocket.bind(jsockaddr, backlog)
        self.socketio = org.python.core.io.ServerSocketIO(self.jchannel, 'rw')

    def accept(self):
        if self.mode in (MODE_BLOCKING, MODE_NONBLOCKING):
            new_cli_chan = self.jchannel.accept()
            if new_cli_chan is not None:
                return _client_socket_impl(new_cli_chan.socket())
            else:
                return None
        else:
            # In timeout mode now
            new_cli_sock = self.jsocket.accept()
            return _client_socket_impl(new_cli_sock)

    def shutdown(self, how):
        # This is no-op on java, for server sockets.
        # What the user wants to achieve is achieved by calling close() on
        # java/jython. But we can't call that here because that would then
        # later cause the user explicit close() call to fail
        pass

class _datagram_socket_impl(_nio_impl):

    options = {
        (SOL_SOCKET, SO_BROADCAST):   'Broadcast',
        (SOL_SOCKET, SO_RCVBUF):      'ReceiveBufferSize',
        (SOL_SOCKET, SO_REUSEADDR):   'ReuseAddress',
        (SOL_SOCKET, SO_SNDBUF):      'SendBufferSize',
        (SOL_SOCKET, SO_TIMEOUT):     'SoTimeout',
    }

    def __init__(self, jsockaddr=None, reuse_addr=0):
        self.jchannel = java.nio.channels.DatagramChannel.open()
        self.jsocket = self.jchannel.socket()
        if jsockaddr is not None:
            self.jsocket.setReuseAddress(reuse_addr)
            self.jsocket.bind(jsockaddr)
        self.socketio = org.python.core.io.DatagramSocketIO(self.jchannel, 'rw')

    def connect(self, jsockaddr):
        self.jchannel.connect(jsockaddr)

    def disconnect(self):
        """
            Disconnect the datagram socket.
            cpython appears not to have this operation
        """
        self.jchannel.disconnect()

    def shutdown(self, how):
        # This is no-op on java, for datagram sockets.
        # What the user wants to achieve is achieved by calling close() on
        # java/jython. But we can't call that here because that would then
        # later cause the user explicit close() call to fail
        pass

    def _do_send_net(self, byte_array, socket_address, flags):
        # Need two separate implementations because the java.nio APIs do not support timeouts
        num_bytes = len(byte_array)
        if self.jsocket.isConnected() and socket_address is None:
            packet = java.net.DatagramPacket(byte_array, num_bytes)
        else:
            packet = java.net.DatagramPacket(byte_array, num_bytes, socket_address)
        self.jsocket.send(packet)
        return num_bytes

    def _do_send_nio(self, byte_array, socket_address, flags):
        byte_buf = java.nio.ByteBuffer.wrap(byte_array)
        if self.jchannel.isConnected() and socket_address is None:
            bytes_sent = self.jchannel.write(byte_buf)
        else:
            bytes_sent = self.jchannel.send(byte_buf, socket_address)
        return bytes_sent

    def sendto(self, byte_array, jsockaddr, flags):
        if self.mode == MODE_TIMEOUT:
            return self._do_send_net(byte_array, jsockaddr, flags)
        else:
            return self._do_send_nio(byte_array, jsockaddr, flags)

    def send(self, byte_array, flags):
        if self.mode == MODE_TIMEOUT:
            return self._do_send_net(byte_array, None, flags)
        else:
            return self._do_send_nio(byte_array, None, flags)

    def _do_receive_net(self, return_source_address, num_bytes, flags):
        byte_array = jarray.zeros(num_bytes, 'b')
        packet = java.net.DatagramPacket(byte_array, num_bytes)
        self.jsocket.receive(packet)
        bytes_rcvd = packet.getLength()
        if bytes_rcvd < num_bytes:
            byte_array = byte_array[:bytes_rcvd]
        return_data = byte_array.tostring()
        if return_source_address:
            host = None
            if packet.getAddress():
                host = packet.getAddress().getHostAddress()
            port = packet.getPort()
            return return_data, (host, port)
        else:
            return return_data

    def _do_receive_nio(self, return_source_address, num_bytes, flags):
        byte_array = jarray.zeros(num_bytes, 'b')
        byte_buf = java.nio.ByteBuffer.wrap(byte_array)
        source_address = self.jchannel.receive(byte_buf)
        if source_address is None and not self.jchannel.isBlocking():
            raise would_block_error()
        byte_buf.flip() ; bytes_read = byte_buf.remaining()
        if bytes_read < num_bytes:
            byte_array = byte_array[:bytes_read]
        return_data = byte_array.tostring()
        if return_source_address:
            return return_data, (source_address.getAddress().getHostAddress(), source_address.getPort())
        else:
            return return_data

    def recvfrom(self, num_bytes, flags):
        if self.mode == MODE_TIMEOUT:
            return self._do_receive_net(1, num_bytes, flags)
        else:
            return self._do_receive_nio(1, num_bytes, flags)

    def recv(self, num_bytes, flags):
        if self.mode == MODE_TIMEOUT:
            return self._do_receive_net(0, num_bytes, flags)
        else:
            return self._do_receive_nio(0, num_bytes, flags)

has_ipv6 = True # IPV6 FTW!

# Name and address functions

def _gethostbyaddr(name):
    # This is as close as I can get; at least the types are correct...
    addresses = java.net.InetAddress.getAllByName(gethostbyname(name))
    names = []
    addrs = []
    for addr in addresses:
        names.append(asPyString(addr.getHostName()))
        addrs.append(asPyString(addr.getHostAddress()))
    return (names, addrs)

def getfqdn(name=None):
    """
    Return a fully qualified domain name for name. If name is omitted or empty
    it is interpreted as the local host.  To find the fully qualified name,
    the hostname returned by gethostbyaddr() is checked, then aliases for the
    host, if available. The first name which includes a period is selected.
    In case no fully qualified domain name is available, the hostname is retur
    New in version 2.0.
    """
    if not name:
        name = gethostname()
    names, addrs = _gethostbyaddr(name)
    for a in names:
        if a.find(".") >= 0:
            return a
    return name

def gethostname():
    try:
        return asPyString(java.net.InetAddress.getLocalHost().getHostName())
    except java.lang.Exception, jlx:
        raise _map_exception(jlx)

def gethostbyname(name):
    try:
        return asPyString(java.net.InetAddress.getByName(name).getHostAddress())
    except java.lang.Exception, jlx:
        raise _map_exception(jlx)

def gethostbyaddr(name):
    names, addrs = _gethostbyaddr(name)
    return (names[0], names, addrs)

def getservbyname(service_name, protocol_name=None):
    try:
        from jnr.netdb import Service
    except ImportError:
        return None
    return Service.getServiceByName(service_name, protocol_name).getPort()

def getservbyport(port, protocol_name=None):
    try:
        from jnr.netdb import Service
    except ImportError:
        return None
    return Service.getServiceByPort(port, protocol_name).getName()

def getprotobyname(protocol_name=None):
    try:
        from jnr.netdb import Protocol
    except ImportError:
        return None
    return Protocol.getProtocolByName(protocol_name).getProto()

def _realsocket(family = AF_INET, type = SOCK_STREAM, protocol=0):
    assert family in (AF_INET, AF_INET6), "Only AF_INET and AF_INET6 sockets are currently supported on jython"
    assert type in (SOCK_DGRAM, SOCK_STREAM), "Only SOCK_STREAM and SOCK_DGRAM sockets are currently supported on jython"
    if type == SOCK_STREAM:
        if protocol != 0:
            assert protocol == IPPROTO_TCP, "Only IPPROTO_TCP supported on SOCK_STREAM sockets"
        return _tcpsocket()
    else:
        if protocol != 0:
            assert protocol == IPPROTO_UDP, "Only IPPROTO_UDP supported on SOCK_DGRAM sockets"
        return _udpsocket()

#
# Attempt to provide IDNA (RFC 3490) support.
#
# Try java.net.IDN, built into java 6
#

idna_libraries = [
    ('java.net.IDN', 'toASCII', java.lang.IllegalArgumentException)
]

for idna_lib, idna_fn_name, exc in idna_libraries:
    try:
        m = __import__(idna_lib, globals(), locals(), [idna_fn_name])
        idna_fn = getattr(m, idna_fn_name)
        def _encode_idna(name):
            try:
                return idna_fn(name)
            except exc:
                raise UnicodeEncodeError(name)
        supports('idna', True)
        break
    except (AttributeError, ImportError), e:
        pass
else:
    _encode_idna = lambda x: x.encode("ascii")

#
# Define data structures to support IPV4 and IPV6.
#

class _ip_address_t: pass

class _ipv4_address_t(_ip_address_t):

    def __init__(self, sockaddr, port, jaddress):
        self.sockaddr = sockaddr
        self.port     = port
        self.jaddress = jaddress

    def __getitem__(self, index):
        if   0 == index:
            return self.sockaddr
        elif 1 == index:
            return self.port
        else:
            raise IndexError()

    def __len__(self):
        return 2

    def __str__(self):
        return "('%s', %d)" % (self.sockaddr, self.port)

    __repr__ = __str__

class _ipv6_address_t(_ip_address_t):

    def __init__(self, sockaddr, port, jaddress):
        self.sockaddr = sockaddr
        self.port     = port
        self.jaddress = jaddress

    def __getitem__(self, index):
        if   0 == index:
            return self.sockaddr
        elif 1 == index:
            return self.port
        elif 2 == index:
            return 0
        elif 3 == index:
            return self.jaddress.scopeId
        else:
            raise IndexError()

    def __len__(self):
        return 4

    def __str__(self):
        return "('%s', %d, 0, %d)" % (self.sockaddr, self.port, self.jaddress.scopeId)

    __repr__ = __str__

def _get_jsockaddr(address_object, for_udp=False):
    if address_object is None:
        return java.net.InetSocketAddress(0) # Let the system pick an ephemeral port
    if isinstance(address_object, _ip_address_t):
        return java.net.InetSocketAddress(address_object.jaddress, address_object[1]) 
    error_message = "Address must be a 2-tuple (ipv4: (host, port)) or a 4-tuple (ipv6: (host, port, flow, scope))"
    if not isinstance(address_object, tuple) or \
            len(address_object) not in [2,4] or \
            not isinstance(address_object[0], basestring) or \
            not isinstance(address_object[1], (int, long)):
        raise TypeError(error_message)
    if len(address_object) == 4 and not isinstance(address_object[3], (int, long)):
        raise TypeError(error_message)
    hostname, port = address_object[0].strip(), address_object[1]
    if for_udp:
        if hostname == "":
            hostname = INADDR_ANY
        elif hostname == "<broadcast>":
            hostname = INADDR_BROADCAST
    else:
        if hostname == "":
            hostname = None
    if hostname is None:
        return java.net.InetSocketAddress(port)
    if isinstance(hostname, unicode):
        hostname = _encode_idna(hostname)
    if len(address_object) == 4:
        # There is no way to get a Inet6Address: Inet6Address.getByName() simply calls
        # InetAddress.getByName,() which also returns Inet4Address objects
        # If users want to use IPv6 address, scoped or not, 
        # they should use getaddrinfo(family=AF_INET6)
        pass
    return java.net.InetSocketAddress(java.net.InetAddress.getByName(hostname), port)

_ipv4_addresses_only = False

def _use_ipv4_addresses_only(value):
    global _ipv4_addresses_only
    _ipv4_addresses_only = value

def getaddrinfo(host, port, family=AF_INET, socktype=None, proto=0, flags=None):
    try:
        if not family in [AF_INET, AF_INET6, AF_UNSPEC]:
            raise gaierror(errno.EIO, 'ai_family not supported')
        filter_fns = []
        if _ipv4_addresses_only:
            filter_fns.append( lambda x: isinstance(x, java.net.Inet4Address) )
        else:
            filter_fns.append({
                AF_INET:   lambda x: isinstance(x, java.net.Inet4Address),
                AF_INET6:  lambda x: isinstance(x, java.net.Inet6Address),
                AF_UNSPEC: lambda x: isinstance(x, java.net.InetAddress),
            }[family])
        if host == "":
            host = java.net.InetAddress.getLocalHost().getHostName()
        if isinstance(host, unicode):
            host = _encode_idna(host)
        passive_mode = flags is not None and flags & AI_PASSIVE
        canonname_mode = flags is not None and flags & AI_CANONNAME
        results = []
        for a in java.net.InetAddress.getAllByName(host):
            if len([f for f in filter_fns if f(a)]):
                family = {java.net.Inet4Address: AF_INET, java.net.Inet6Address: AF_INET6}[a.getClass()]
                if passive_mode and not canonname_mode:
                    canonname = ""
                else:
                    canonname = asPyString(a.getCanonicalHostName())
                if host is None and passive_mode and not canonname_mode:
                    sockaddr = INADDR_ANY
                else:
                    sockaddr = asPyString(a.getHostAddress())
                # TODO: Include flowinfo and scopeid in a 4-tuple for IPv6 addresses
                sock_tuple = {AF_INET : _ipv4_address_t, AF_INET6 : _ipv6_address_t}[family](sockaddr, port, a)
                results.append((family, socktype, proto, canonname, sock_tuple))
        return results
    except java.lang.Exception, jlx:
        raise _map_exception(jlx)

def getnameinfo(sock_addr, flags):
    raise NotImplementedError("getnameinfo not yet supported on jython.")

def getdefaulttimeout():
    return _defaulttimeout

def _calctimeoutvalue(value):
    if value is None:
        return None
    try:
        floatvalue = float(value)
    except:
        raise TypeError('Socket timeout value must be a number or None')
    if floatvalue < 0.0:
        raise ValueError("Socket timeout value cannot be negative")
    if floatvalue < 0.000001:
        return 0.0
    return floatvalue

def setdefaulttimeout(timeout):
    global _defaulttimeout
    try:
        _defaulttimeout = _calctimeoutvalue(timeout)
    finally:
        _nonblocking_api_mixin.timeout = _defaulttimeout

def htons(x): return x
def htonl(x): return x
def ntohs(x): return x
def ntohl(x): return x

def inet_pton(family, ip_string):
    try:
        ia = java.net.InetAddress.getByName(ip_string)
        bytes = []
        for byte in ia.getAddress():
            if byte < 0:
                bytes.append(byte+256)
            else:
                bytes.append(byte)
        return "".join([chr(byte) for byte in bytes])
    except java.lang.Exception, jlx:
        raise _map_exception(jlx)

def inet_ntop(family, packed_ip):
    try:
        jByteArray = jarray.array(packed_ip, 'b')
        ia = java.net.InetAddress.getByAddress(jByteArray)
        return ia.getHostAddress()
    except java.lang.Exception, jlx:
        raise _map_exception(jlx)

def inet_aton(ip_string):
    return inet_pton(AF_INET, ip_string)

def inet_ntoa(packed_ip):
    return inet_ntop(AF_INET, packed_ip)

class _nonblocking_api_mixin:

    mode = MODE_BLOCKING
    reference_count = 0
    close_lock = threading.Lock()

    def __init__(self):
        self.timeout = _defaulttimeout
        if self.timeout is not None:
            self.mode = MODE_TIMEOUT
        self.pending_options = {
            (SOL_SOCKET, SO_REUSEADDR):  0,
        }

    def gettimeout(self):
        return self.timeout

    def settimeout(self, timeout):
        self.timeout = _calctimeoutvalue(timeout)
        if self.timeout is None:
            self.mode = MODE_BLOCKING
        elif self.timeout < 0.000001:
            self.mode = MODE_NONBLOCKING
        else:
            self.mode = MODE_TIMEOUT
        self._config()

    def setblocking(self, flag):
        if flag:
            self.mode = MODE_BLOCKING
            self.timeout = None
        else:
            self.mode = MODE_NONBLOCKING
            self.timeout = 0.0
        self._config()

    def getblocking(self):
        return self.mode == MODE_BLOCKING

    def setsockopt(self, level, optname, value):
        try:
            if self.sock_impl:
                self.sock_impl.setsockopt(level, optname, value)
            else:
                self.pending_options[ (level, optname) ] = value
        except java.lang.Exception, jlx:
            raise _map_exception(jlx)

    def getsockopt(self, level, optname):
        try:
            if self.sock_impl:
                return self.sock_impl.getsockopt(level, optname)
            else:
                return self.pending_options.get( (level, optname), None)
        except java.lang.Exception, jlx:
            raise _map_exception(jlx)

    def shutdown(self, how):
        assert how in (SHUT_RD, SHUT_WR, SHUT_RDWR)
        if not self.sock_impl:
            raise error(errno.ENOTCONN, "Transport endpoint is not connected")
        try:
            self.sock_impl.shutdown(how)
        except java.lang.Exception, jlx:
            raise _map_exception(jlx)

    def close(self):
        try:
            if self.sock_impl:
                self.sock_impl.close()
        except java.lang.Exception, jlx:
            raise _map_exception(jlx)

    def _config(self):
        assert self.mode in _permitted_modes
        if self.sock_impl:
            self.sock_impl.config(self.mode, self.timeout)
            for level, optname in self.pending_options.keys():
                if optname != SO_REUSEADDR:
                    self.sock_impl.setsockopt(level, optname, self.pending_options[ (level, optname) ])

    def getchannel(self):
        if not self.sock_impl:
            return None
        return self.sock_impl.getchannel()

    def fileno(self):
        if not self.sock_impl:
            return None
        return self.sock_impl.fileno()

    def _get_jsocket(self):
        return self.sock_impl.jsocket

class _tcpsocket(_nonblocking_api_mixin):

    sock_impl = None
    istream = None
    ostream = None
    local_addr = None
    server = 0

    def __init__(self):
        _nonblocking_api_mixin.__init__(self)

    def bind(self, addr):
        assert not self.sock_impl
        assert not self.local_addr
        # Do the address format check
        _get_jsockaddr(addr)
        self.local_addr = addr

    def listen(self, backlog):
        "This signifies a server socket"
        try:
            assert not self.sock_impl
            self.server = 1
            self.sock_impl = _server_socket_impl(_get_jsockaddr(self.local_addr), backlog, self.pending_options[ (SOL_SOCKET, SO_REUSEADDR) ])
            self._config()
        except java.lang.Exception, jlx:
            raise _map_exception(jlx)

    def accept(self):
        "This signifies a server socket"
        try:
            if not self.sock_impl:
                self.listen()
            assert self.server
            new_sock = self.sock_impl.accept()
            if not new_sock:
                raise would_block_error()
            cliconn = _tcpsocket()
            cliconn.pending_options[ (SOL_SOCKET, SO_REUSEADDR) ] = new_sock.jsocket.getReuseAddress()
            cliconn.sock_impl = new_sock
            cliconn._setup()
            return cliconn, new_sock.getpeername()
        except java.lang.Exception, jlx:
            raise _map_exception(jlx)

    def _do_connect(self, addr):
        try:
            assert not self.sock_impl
            self.sock_impl = _client_socket_impl()
            if self.local_addr: # Has the socket been bound to a local address?
                self.sock_impl.bind(_get_jsockaddr(self.local_addr), self.pending_options[ (SOL_SOCKET, SO_REUSEADDR) ])
            self._config() # Configure timeouts, etc, now that the socket exists
            self.sock_impl.connect(_get_jsockaddr(addr))
        except java.lang.Exception, jlx:
            raise _map_exception(jlx)

    def connect(self, addr):
        "This signifies a client socket"
        self._do_connect(addr)
        self._setup()

    def connect_ex(self, addr):
        "This signifies a client socket"
        if not self.sock_impl:
            self._do_connect(addr)
        if self.sock_impl.finish_connect():
            self._setup()
            if self.mode == MODE_NONBLOCKING:
                return errno.EISCONN
            return 0
        return errno.EINPROGRESS

    def _setup(self):
        if self.mode != MODE_NONBLOCKING:
            self.istream = self.sock_impl.jsocket.getInputStream()
            self.ostream = self.sock_impl.jsocket.getOutputStream()

    def recv(self, n):
        try:
            if not self.sock_impl: raise error(errno.ENOTCONN, 'Socket is not connected')
            if self.sock_impl.jchannel.isConnectionPending():
                self.sock_impl.jchannel.finishConnect()
            data = jarray.zeros(n, 'b')
            m = self.sock_impl.read(data)
            if m == -1:#indicates EOF has been reached, so we just return the empty string
                return ""
            elif m <= 0:
                if self.mode == MODE_NONBLOCKING:
                    raise would_block_error()
                return ""
            if m < n:
                data = data[:m]
            return data.tostring()
        except java.lang.Exception, jlx:
            raise _map_exception(jlx)

    def recvfrom(self, n):
        return self.recv(n), None

    def send(self, s):
        try:
            if not self.sock_impl: raise error(errno.ENOTCONN, 'Socket is not connected')
            if self.sock_impl.jchannel.isConnectionPending():
                self.sock_impl.jchannel.finishConnect()
            numwritten = self.sock_impl.write(s)
            if numwritten == 0 and self.mode == MODE_NONBLOCKING:
                raise would_block_error()
            return numwritten
        except java.lang.Exception, jlx:
            raise _map_exception(jlx)

    sendall = send

    def getsockname(self):
        try:
            if not self.sock_impl:
                host, port = self.local_addr or ("", 0)
                host = java.net.InetAddress.getByName(host).getHostAddress()
            else:
                if self.server:
                    host = self.sock_impl.jsocket.getInetAddress().getHostAddress()
                else:
                    host = self.sock_impl.jsocket.getLocalAddress().getHostAddress()
                port = self.sock_impl.jsocket.getLocalPort()
            return (host, port)
        except java.lang.Exception, jlx:
            raise _map_exception(jlx)

    def getpeername(self):
        try:
            assert self.sock_impl
            assert not self.server
            host = self.sock_impl.jsocket.getInetAddress().getHostAddress()
            port = self.sock_impl.jsocket.getPort()
            return (host, port)
        except java.lang.Exception, jlx:
            raise _map_exception(jlx)

    def close(self):
        try:
            if self.istream:
                self.istream.close()
            if self.ostream:
                self.ostream.close()
            if self.sock_impl:
                self.sock_impl.close()
        except java.lang.Exception, jlx:
            raise _map_exception(jlx)


class _udpsocket(_nonblocking_api_mixin):

    sock_impl = None
    connected = False

    def __init__(self):
        _nonblocking_api_mixin.__init__(self)

    def bind(self, addr):
        try:
            assert not self.sock_impl
            self.sock_impl = _datagram_socket_impl(_get_jsockaddr(addr, True), self.pending_options[ (SOL_SOCKET, SO_REUSEADDR) ])
            self._config()
        except java.lang.Exception, jlx:
            raise _map_exception(jlx)

    def _do_connect(self, addr):
        try:
            assert not self.connected, "Datagram Socket is already connected"
            if not self.sock_impl:
                self.sock_impl = _datagram_socket_impl()
                self._config()
                self.sock_impl.connect(_get_jsockaddr(addr))
            self.connected = True
        except java.lang.Exception, jlx:
            raise _map_exception(jlx)

    def connect(self, addr):
        self._do_connect(addr)

    def connect_ex(self, addr):
        if not self.sock_impl:
            self._do_connect(addr)
        return 0

    def sendto(self, data, p1, p2=None):
        try:
            if not p2:
                flags, addr = 0, p1
            else:
                flags, addr = 0, p2
            if not self.sock_impl:
                self.sock_impl = _datagram_socket_impl()
                self._config()
            byte_array = java.lang.String(data).getBytes('iso-8859-1')
            result = self.sock_impl.sendto(byte_array, _get_jsockaddr(addr, True), flags)
            return result
        except java.lang.Exception, jlx:
            raise _map_exception(jlx)

    def send(self, data, flags=None):
        if not self.connected: raise error(errno.ENOTCONN, "Socket is not connected")
        byte_array = java.lang.String(data).getBytes('iso-8859-1')
        return self.sock_impl.send(byte_array, flags)

    def recvfrom(self, num_bytes, flags=None):
        """
        There is some disagreement as to what the behaviour should be if
        a recvfrom operation is requested on an unbound socket.
        See the following links for more information
        http://bugs.jython.org/issue1005
        http://bugs.sun.com/view_bug.do?bug_id=6621689
        """
        try:
            # This is the old 2.1 behaviour
            #assert self.sock_impl
            # This is amak's preferred interpretation
            #raise error(errno.ENOTCONN, "Recvfrom on unbound udp socket meaningless operation")
            # And this is the option for cpython compatibility
            if not self.sock_impl:
                self.sock_impl = _datagram_socket_impl()
                self._config()
            return self.sock_impl.recvfrom(num_bytes, flags)
        except java.lang.Exception, jlx:
            raise _map_exception(jlx)

    def recv(self, num_bytes, flags=None):
        if not self.sock_impl: raise error(errno.ENOTCONN, "Socket is not connected")
        try:
            return self.sock_impl.recv(num_bytes, flags)
        except java.lang.Exception, jlx:
            raise _map_exception(jlx)

    def getsockname(self):
        try:
            assert self.sock_impl
            host = self.sock_impl.jsocket.getLocalAddress().getHostAddress()
            port = self.sock_impl.jsocket.getLocalPort()
            return (host, port)
        except java.lang.Exception, jlx:
            raise _map_exception(jlx)

    def getpeername(self):
        try:
            assert self.sock
            host = self.sock_impl.jsocket.getInetAddress().getHostAddress()
            port = self.sock_impl.jsocket.getPort()
            return (host, port)
        except java.lang.Exception, jlx:
            raise _map_exception(jlx)

    def __del__(self):
        self.close()

_socketmethods = (
    'bind', 'connect', 'connect_ex', 'fileno', 'listen',
    'getpeername', 'getsockname', 'getsockopt', 'setsockopt',
    'sendall', 'setblocking',
    'settimeout', 'gettimeout', 'shutdown', 'getchannel')

# All the method names that must be delegated to either the real socket
# object or the _closedsocket object.
_delegate_methods = ("recv", "recvfrom", "recv_into", "recvfrom_into",
                     "send", "sendto")

class _closedsocket(object):
    __slots__ = []
    def _dummy(*args):
        raise error(errno.EBADF, 'Bad file descriptor')
    # All _delegate_methods must also be initialized here.
    send = recv = recv_into = sendto = recvfrom = recvfrom_into = _dummy
    __getattr__ = _dummy

_active_sockets = set()

def _closeActiveSockets():
    for socket in _active_sockets.copy():
        try:
            socket.close()
        except error:
            msg = 'Problem closing socket: %s: %r' % (socket, sys.exc_info())
            print >> sys.stderr, msg

class _socketobject(object):

    __doc__ = _realsocket.__doc__

    __slots__ = ["_sock", "__weakref__"] + list(_delegate_methods)

    def __init__(self, family=AF_INET, type=SOCK_STREAM, proto=0, _sock=None):
        if _sock is None:
            _sock = _realsocket(family, type, proto)
            _sock.reference_count += 1
        elif isinstance(_sock, _nonblocking_api_mixin):
            _sock.reference_count += 1
        self._sock = _sock
        for method in _delegate_methods:
            meth = getattr(_sock, method, None)
            if meth:
                setattr(self, method, meth)
        _active_sockets.add(self)

    def close(self):
        try:
            _active_sockets.remove(self)
        except KeyError:
            pass
        _sock = self._sock
        if isinstance(_sock, _nonblocking_api_mixin):
            _sock.close_lock.acquire()
            try:
                _sock.reference_count -=1
                if not _sock.reference_count:
                    _sock.close()
                self._sock = _closedsocket()
                dummy = self._sock._dummy
                for method in _delegate_methods:
                    setattr(self, method, dummy)
                self.send = self.recv = self.sendto = self.recvfrom = \
                    self._sock._dummy
            finally:
                _sock.close_lock.release()
    #close.__doc__ = _realsocket.close.__doc__

    def accept(self):
        sock, addr = self._sock.accept()
        return _socketobject(_sock=sock), addr
    #accept.__doc__ = _realsocket.accept.__doc__

    def dup(self):
        """dup() -> socket object

        Return a new socket object connected to the same system resource."""
        _sock = self._sock
        if not isinstance(_sock, _nonblocking_api_mixin):
            return _socketobject(_sock=_sock)

        _sock.close_lock.acquire()
        try:
            duped = _socketobject(_sock=_sock)
        finally:
            _sock.close_lock.release()
        return duped

    def makefile(self, mode='r', bufsize=-1):
        """makefile([mode[, bufsize]]) -> file object

        Return a regular file object corresponding to the socket.  The mode
        and bufsize arguments are as for the built-in open() function."""
        _sock = self._sock
        if not isinstance(_sock, _nonblocking_api_mixin):
            return _fileobject(_sock, mode, bufsize)

        _sock.close_lock.acquire()
        try:
            fileobject = _fileobject(_sock, mode, bufsize)
        finally:
            _sock.close_lock.release()
        return fileobject

    family = property(lambda self: self._sock.family, doc="the socket family")
    type = property(lambda self: self._sock.type, doc="the socket type")
    proto = property(lambda self: self._sock.proto, doc="the socket protocol")

    _s = ("def %s(self, *args): return self._sock.%s(*args)\n\n"
          #"%s.__doc__ = _realsocket.%s.__doc__\n")
          )
    for _m in _socketmethods:
        #exec _s % (_m, _m, _m, _m)
        exec _s % (_m, _m)
    del _m, _s

socket = SocketType = _socketobject

class _fileobject(object):
    """Faux file object attached to a socket object."""

    default_bufsize = 8192
    name = "<socket>"

    __slots__ = ["mode", "bufsize", "softspace",
                 # "closed" is a property, see below
                 "_sock", "_rbufsize", "_wbufsize", "_rbuf", "_wbuf",
                 "_close"]

    def __init__(self, sock, mode='rb', bufsize=-1, close=False):
        self._sock = sock
        if isinstance(sock, _nonblocking_api_mixin):
            sock.reference_count += 1
        self.mode = mode # Not actually used in this version
        if bufsize < 0:
            bufsize = self.default_bufsize
        self.bufsize = bufsize
        self.softspace = False
        if bufsize == 0:
            self._rbufsize = 1
        elif bufsize == 1:
            self._rbufsize = self.default_bufsize
        else:
            self._rbufsize = bufsize
        self._wbufsize = bufsize
        self._rbuf = "" # A string
        self._wbuf = [] # A list of strings
        self._close = close

    def _getclosed(self):
        return self._sock is None
    closed = property(_getclosed, doc="True if the file is closed")

    def close(self):
        try:
            if self._sock:
                self.flush()
        finally:
            if self._sock:
                if isinstance(self._sock, _nonblocking_api_mixin):
                    self._sock.reference_count -= 1
                    if not self._sock.reference_count or self._close:
                        self._sock.close()
                elif self._close:
                    self._sock.close()
            self._sock = None

    def __del__(self):
        try:
            self.close()
        except:
            # close() may fail if __init__ didn't complete
            pass

    def flush(self):
        if self._wbuf:
            buffer = "".join(self._wbuf)
            self._wbuf = []
            self._sock.sendall(buffer)

    def fileno(self):
        return self._sock.fileno()

    def write(self, data):
        data = str(data) # XXX Should really reject non-string non-buffers
        if not data:
            return
        self._wbuf.append(data)
        if (self._wbufsize == 0 or
            self._wbufsize == 1 and '\n' in data or
            self._get_wbuf_len() >= self._wbufsize):
            self.flush()

    def writelines(self, list):
        # XXX We could do better here for very long lists
        # XXX Should really reject non-string non-buffers
        self._wbuf.extend(filter(None, map(str, list)))
        if (self._wbufsize <= 1 or
            self._get_wbuf_len() >= self._wbufsize):
            self.flush()

    def _get_wbuf_len(self):
        buf_len = 0
        for x in self._wbuf:
            buf_len += len(x)
        return buf_len

    def read(self, size=-1):
        data = self._rbuf
        if size < 0:
            # Read until EOF
            buffers = []
            if data:
                buffers.append(data)
            self._rbuf = ""
            if self._rbufsize <= 1:
                recv_size = self.default_bufsize
            else:
                recv_size = self._rbufsize
            while True:
                data = self._sock.recv(recv_size)
                if not data:
                    break
                buffers.append(data)
            return "".join(buffers)
        else:
            # Read until size bytes or EOF seen, whichever comes first
            buf_len = len(data)
            if buf_len >= size:
                self._rbuf = data[size:]
                return data[:size]
            buffers = []
            if data:
                buffers.append(data)
            self._rbuf = ""
            while True:
                left = size - buf_len
                recv_size = max(self._rbufsize, left)
                data = self._sock.recv(recv_size)
                if not data:
                    break
                buffers.append(data)
                n = len(data)
                if n >= left:
                    self._rbuf = data[left:]
                    buffers[-1] = data[:left]
                    break
                buf_len += n
            return "".join(buffers)

    def readline(self, size=-1):
        data = self._rbuf
        if size < 0:
            # Read until \n or EOF, whichever comes first
            if self._rbufsize <= 1:
                # Speed up unbuffered case
                assert data == ""
                buffers = []
                recv = self._sock.recv
                while data != "\n":
                    data = recv(1)
                    if not data:
                        break
                    buffers.append(data)
                return "".join(buffers)
            nl = data.find('\n')
            if nl >= 0:
                nl += 1
                self._rbuf = data[nl:]
                return data[:nl]
            buffers = []
            if data:
                buffers.append(data)
            self._rbuf = ""
            while True:
                data = self._sock.recv(self._rbufsize)
                if not data:
                    break
                buffers.append(data)
                nl = data.find('\n')
                if nl >= 0:
                    nl += 1
                    self._rbuf = data[nl:]
                    buffers[-1] = data[:nl]
                    break
            return "".join(buffers)
        else:
            # Read until size bytes or \n or EOF seen, whichever comes first
            nl = data.find('\n', 0, size)
            if nl >= 0:
                nl += 1
                self._rbuf = data[nl:]
                return data[:nl]
            buf_len = len(data)
            if buf_len >= size:
                self._rbuf = data[size:]
                return data[:size]
            buffers = []
            if data:
                buffers.append(data)
            self._rbuf = ""
            while True:
                data = self._sock.recv(self._rbufsize)
                if not data:
                    break
                buffers.append(data)
                left = size - buf_len
                nl = data.find('\n', 0, left)
                if nl >= 0:
                    nl += 1
                    self._rbuf = data[nl:]
                    buffers[-1] = data[:nl]
                    break
                n = len(data)
                if n >= left:
                    self._rbuf = data[left:]
                    buffers[-1] = data[:left]
                    break
                buf_len += n
            return "".join(buffers)

    def readlines(self, sizehint=0):
        total = 0
        list = []
        while True:
            line = self.readline()
            if not line:
                break
            list.append(line)
            total += len(line)
            if sizehint and total >= sizehint:
                break
        return list

    # Iterator protocols

    def __iter__(self):
        return self

    def next(self):
        line = self.readline()
        if not line:
            raise StopIteration
        return line


# Define the SSL support

class ssl:

    def __init__(self, plain_sock, keyfile=None, certfile=None):
        try:
            self.ssl_sock = self._make_ssl_socket(plain_sock)
            self._in_buf = java.io.BufferedInputStream(self.ssl_sock.getInputStream())
            self._out_buf = java.io.BufferedOutputStream(self.ssl_sock.getOutputStream())
        except java.lang.Exception, jlx:
            raise _map_exception(jlx)

    def _make_ssl_socket(self, plain_socket, auto_close=0):
        java_net_socket = plain_socket._get_jsocket()
        assert isinstance(java_net_socket, java.net.Socket)
        host = java_net_socket.getInetAddress().getHostAddress()
        port = java_net_socket.getPort()
        factory = javax.net.ssl.SSLSocketFactory.getDefault();
        ssl_socket = factory.createSocket(java_net_socket, host, port, auto_close)
        ssl_socket.setEnabledCipherSuites(ssl_socket.getSupportedCipherSuites())
        ssl_socket.startHandshake()
        return ssl_socket

    def read(self, n=4096):
        try:
            data = jarray.zeros(n, 'b')
            m = self._in_buf.read(data, 0, n)
            if m <= 0:
                return ""
            if m < n:
                data = data[:m]
            return data.tostring()
        except java.lang.Exception, jlx:
            raise _map_exception(jlx)

    def write(self, s):
        try:
            self._out_buf.write(s)
            self._out_buf.flush()
            return len(s)
        except java.lang.Exception, jlx:
            raise _map_exception(jlx)

    def _get_server_cert(self):
        try:
            return self.ssl_sock.getSession().getPeerCertificates()[0]
        except java.lang.Exception, jlx:
            raise _map_exception(jlx)

    def server(self):
        cert = self._get_server_cert()
        return cert.getSubjectDN().toString()

    def issuer(self):
        cert = self._get_server_cert()
        return cert.getIssuerDN().toString()

_realssl = ssl
def ssl(sock, keyfile=None, certfile=None):
    if hasattr(sock, "_sock"):
        sock = sock._sock
    return _realssl(sock, keyfile, certfile)

def test():
    s = socket(AF_INET, SOCK_STREAM)
    s.connect(("", 80))
    s.send("GET / HTTP/1.0\r\n\r\n")
    while 1:
        data = s.recv(2000)
        print data
        if not data:
            break

if __name__ == '__main__':
    test()
