Merged gcj-eclipse branch to trunk.
From-SVN: r120621
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
/* DefaultProxySelector.java --
|
||||
Copyright (C) 2006 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.net;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Proxy;
|
||||
import java.net.ProxySelector;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public final class DefaultProxySelector
|
||||
extends ProxySelector
|
||||
{
|
||||
private static final List<Proxy> proxies = new ArrayList<Proxy>();
|
||||
|
||||
static
|
||||
{
|
||||
// The default proxy selector supports only direct connections.
|
||||
proxies.add(Proxy.NO_PROXY);
|
||||
}
|
||||
|
||||
public DefaultProxySelector()
|
||||
{
|
||||
// Do nothing by default.
|
||||
}
|
||||
|
||||
public void connectFailed(URI uri, SocketAddress sa, IOException ioe)
|
||||
{
|
||||
if (uri == null || sa == null || ioe == null)
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
// Do nothing by default.
|
||||
}
|
||||
|
||||
public List<Proxy> select(URI uri)
|
||||
{
|
||||
if (uri == null)
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
return proxies;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/* PlainDatagramSocketImpl.java -- Default DatagramSocket implementation
|
||||
Copyright (C) 1998, 1999, 2001, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998, 1999, 2001, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@@ -38,13 +38,19 @@ exception statement from your version. */
|
||||
|
||||
package gnu.java.net;
|
||||
|
||||
import gnu.java.nio.VMChannel;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.DatagramSocketImpl;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.SocketException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* Written using on-line Java Platform 1.2 API Specification, as well
|
||||
@@ -62,11 +68,12 @@ import java.net.SocketException;
|
||||
*/
|
||||
public final class PlainDatagramSocketImpl extends DatagramSocketImpl
|
||||
{
|
||||
|
||||
private final VMChannel channel;
|
||||
|
||||
/**
|
||||
* This is the actual underlying file descriptor
|
||||
* The platform-specific socket implementation.
|
||||
*/
|
||||
int native_fd = -1;
|
||||
private final VMPlainSocketImpl impl;
|
||||
|
||||
/**
|
||||
* Lock object to serialize threads wanting to receive
|
||||
@@ -81,25 +88,26 @@ public final class PlainDatagramSocketImpl extends DatagramSocketImpl
|
||||
/**
|
||||
* Default do nothing constructor
|
||||
*/
|
||||
public PlainDatagramSocketImpl()
|
||||
public PlainDatagramSocketImpl() throws IOException
|
||||
{
|
||||
// Nothing to do here.
|
||||
channel = new VMChannel();
|
||||
impl = new VMPlainSocketImpl(channel);
|
||||
}
|
||||
|
||||
protected void finalize() throws Throwable
|
||||
/*protected void finalize() throws Throwable
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (native_fd != -1)
|
||||
if (channel.getState().isValid())
|
||||
close();
|
||||
}
|
||||
super.finalize();
|
||||
}
|
||||
}*/
|
||||
|
||||
public int getNativeFD()
|
||||
/*public int getNativeFD()
|
||||
{
|
||||
return native_fd;
|
||||
}
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Binds this socket to a particular port and interface
|
||||
@@ -109,20 +117,46 @@ public final class PlainDatagramSocketImpl extends DatagramSocketImpl
|
||||
*
|
||||
* @exception SocketException If an error occurs
|
||||
*/
|
||||
protected synchronized void bind(int port, InetAddress addr)
|
||||
protected synchronized void bind(int port, InetAddress addr)
|
||||
throws SocketException
|
||||
{
|
||||
VMPlainDatagramSocketImpl.bind(this, port, addr);
|
||||
}
|
||||
{
|
||||
try
|
||||
{
|
||||
impl.bind(new InetSocketAddress(addr, port));
|
||||
}
|
||||
catch (SocketException se)
|
||||
{
|
||||
throw se;
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
SocketException se = new SocketException();
|
||||
se.initCause(ioe);
|
||||
throw se;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new datagram socket
|
||||
*
|
||||
* @exception SocketException If an error occurs
|
||||
*/
|
||||
protected synchronized void create() throws SocketException
|
||||
protected synchronized void create() throws SocketException
|
||||
{
|
||||
VMPlainDatagramSocketImpl.create(this);
|
||||
try
|
||||
{
|
||||
channel.initSocket(false);
|
||||
}
|
||||
catch (SocketException se)
|
||||
{
|
||||
throw se;
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
SocketException se = new SocketException();
|
||||
se.initCause(ioe);
|
||||
throw se;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -135,7 +169,7 @@ public final class PlainDatagramSocketImpl extends DatagramSocketImpl
|
||||
*/
|
||||
protected void connect(InetAddress addr, int port) throws SocketException
|
||||
{
|
||||
VMPlainDatagramSocketImpl.connect(this, addr, port);
|
||||
channel.connect(new InetSocketAddress(addr, port), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -147,8 +181,14 @@ public final class PlainDatagramSocketImpl extends DatagramSocketImpl
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (native_fd != -1)
|
||||
close();
|
||||
try
|
||||
{
|
||||
if (channel.getState().isValid())
|
||||
channel.disconnect();
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,7 +201,7 @@ public final class PlainDatagramSocketImpl extends DatagramSocketImpl
|
||||
*/
|
||||
protected synchronized void setTimeToLive(int ttl) throws IOException
|
||||
{
|
||||
setOption(VMPlainDatagramSocketImpl.IP_TTL, new Integer(ttl));
|
||||
impl.setTimeToLive(ttl);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -173,14 +213,26 @@ public final class PlainDatagramSocketImpl extends DatagramSocketImpl
|
||||
*/
|
||||
protected synchronized int getTimeToLive() throws IOException
|
||||
{
|
||||
Object obj = getOption(VMPlainDatagramSocketImpl.IP_TTL);
|
||||
|
||||
if (! (obj instanceof Integer))
|
||||
throw new IOException("Internal Error");
|
||||
|
||||
return ((Integer) obj).intValue();
|
||||
return impl.getTimeToLive();
|
||||
}
|
||||
|
||||
protected int getLocalPort()
|
||||
{
|
||||
if (channel == null)
|
||||
return -1;
|
||||
|
||||
try
|
||||
{
|
||||
InetSocketAddress local = channel.getLocalAddress();
|
||||
if (local == null)
|
||||
return -1;
|
||||
return local.getPort();
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a packet of data to a remote host
|
||||
@@ -191,13 +243,30 @@ public final class PlainDatagramSocketImpl extends DatagramSocketImpl
|
||||
*/
|
||||
protected void send(DatagramPacket packet) throws IOException
|
||||
{
|
||||
if (native_fd != -1)
|
||||
synchronized (SEND_LOCK)
|
||||
{
|
||||
synchronized(SEND_LOCK)
|
||||
ByteBuffer buf = ByteBuffer.wrap(packet.getData(),
|
||||
packet.getOffset(),
|
||||
packet.getLength());
|
||||
InetAddress remote = packet.getAddress();
|
||||
int port = packet.getPort();
|
||||
if (remote == null)
|
||||
throw new NullPointerException();
|
||||
if (port <= 0)
|
||||
throw new SocketException("invalid port " + port);
|
||||
while (true)
|
||||
{
|
||||
VMPlainDatagramSocketImpl.send(this, packet);
|
||||
try
|
||||
{
|
||||
channel.send(buf, new InetSocketAddress(remote, port));
|
||||
break;
|
||||
}
|
||||
catch (InterruptedIOException ioe)
|
||||
{
|
||||
// Ignore; interrupted system call.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -210,48 +279,123 @@ public final class PlainDatagramSocketImpl extends DatagramSocketImpl
|
||||
protected void receive(DatagramPacket packet)
|
||||
throws IOException
|
||||
{
|
||||
synchronized(RECEIVE_LOCK)
|
||||
{
|
||||
VMPlainDatagramSocketImpl.receive(this, packet);
|
||||
}
|
||||
synchronized(RECEIVE_LOCK)
|
||||
{
|
||||
ByteBuffer buf = ByteBuffer.wrap(packet.getData(),
|
||||
packet.getOffset(),
|
||||
packet.getLength());
|
||||
SocketAddress addr = null;
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
addr = channel.receive(buf);
|
||||
break;
|
||||
}
|
||||
catch (SocketTimeoutException ste)
|
||||
{
|
||||
throw ste;
|
||||
}
|
||||
catch (InterruptedIOException iioe)
|
||||
{
|
||||
// Ignore. Loop.
|
||||
}
|
||||
}
|
||||
if (addr != null)
|
||||
packet.setSocketAddress(addr);
|
||||
packet.setLength(buf.position() - packet.getOffset());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of an option on the socket
|
||||
*
|
||||
* @param option_id The identifier of the option to set
|
||||
* @param val The value of the option to set
|
||||
* @param optionId The identifier of the option to set
|
||||
* @param value The value of the option to set
|
||||
*
|
||||
* @exception SocketException If an error occurs
|
||||
*/
|
||||
public synchronized void setOption(int option_id, Object val)
|
||||
public synchronized void setOption(int optionId, Object value)
|
||||
throws SocketException
|
||||
{
|
||||
VMPlainDatagramSocketImpl.setOption(this, option_id, val);
|
||||
}
|
||||
{
|
||||
switch (optionId)
|
||||
{
|
||||
case IP_MULTICAST_IF:
|
||||
case IP_MULTICAST_IF2:
|
||||
impl.setMulticastInterface(optionId, (InetAddress) value);
|
||||
break;
|
||||
|
||||
case IP_MULTICAST_LOOP:
|
||||
case SO_BROADCAST:
|
||||
case SO_KEEPALIVE:
|
||||
case SO_OOBINLINE:
|
||||
case TCP_NODELAY:
|
||||
case IP_TOS:
|
||||
case SO_LINGER:
|
||||
case SO_RCVBUF:
|
||||
case SO_SNDBUF:
|
||||
case SO_TIMEOUT:
|
||||
case SO_REUSEADDR:
|
||||
impl.setOption(optionId, value);
|
||||
return;
|
||||
|
||||
default:
|
||||
throw new SocketException("cannot set option " + optionId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the value of an option on the socket
|
||||
*
|
||||
* @param option_id The identifier of the option to retrieve
|
||||
* @param optionId The identifier of the option to retrieve
|
||||
*
|
||||
* @return The value of the option
|
||||
*
|
||||
* @exception SocketException If an error occurs
|
||||
*/
|
||||
public synchronized Object getOption(int option_id)
|
||||
public synchronized Object getOption(int optionId)
|
||||
throws SocketException
|
||||
{
|
||||
return VMPlainDatagramSocketImpl.getOption(this, option_id);
|
||||
}
|
||||
{
|
||||
if (optionId == SO_BINDADDR)
|
||||
{
|
||||
try
|
||||
{
|
||||
InetSocketAddress local = channel.getLocalAddress();
|
||||
if (local == null)
|
||||
return null;
|
||||
return local.getAddress();
|
||||
}
|
||||
catch (SocketException se)
|
||||
{
|
||||
throw se;
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
SocketException se = new SocketException();
|
||||
se.initCause(ioe);
|
||||
throw se;
|
||||
}
|
||||
}
|
||||
if (optionId == IP_MULTICAST_IF || optionId == IP_MULTICAST_IF2)
|
||||
return impl.getMulticastInterface(optionId);
|
||||
|
||||
return impl.getOption(optionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the socket
|
||||
*/
|
||||
protected synchronized void close()
|
||||
{
|
||||
VMPlainDatagramSocketImpl.close(this);
|
||||
try
|
||||
{
|
||||
if (channel.getState().isValid())
|
||||
channel.close();
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -291,7 +435,7 @@ public final class PlainDatagramSocketImpl extends DatagramSocketImpl
|
||||
*/
|
||||
protected synchronized void join(InetAddress addr) throws IOException
|
||||
{
|
||||
VMPlainDatagramSocketImpl.join(this,addr);
|
||||
impl.join(addr);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -303,7 +447,7 @@ public final class PlainDatagramSocketImpl extends DatagramSocketImpl
|
||||
*/
|
||||
protected synchronized void leave(InetAddress addr) throws IOException
|
||||
{
|
||||
VMPlainDatagramSocketImpl.leave(this, addr);
|
||||
impl.leave(addr);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -323,12 +467,20 @@ public final class PlainDatagramSocketImpl extends DatagramSocketImpl
|
||||
public void joinGroup(SocketAddress address, NetworkInterface netIf)
|
||||
throws IOException
|
||||
{
|
||||
VMPlainDatagramSocketImpl.joinGroup(this, address, netIf);
|
||||
if (address == null)
|
||||
throw new NullPointerException();
|
||||
if (!(address instanceof InetSocketAddress))
|
||||
throw new SocketException("unknown address type");
|
||||
impl.joinGroup((InetSocketAddress) address, netIf);
|
||||
}
|
||||
|
||||
public void leaveGroup(SocketAddress address, NetworkInterface netIf)
|
||||
throws IOException
|
||||
{
|
||||
VMPlainDatagramSocketImpl.leaveGroup(this, address, netIf);
|
||||
if (address == null)
|
||||
throw new NullPointerException();
|
||||
if (!(address instanceof InetSocketAddress))
|
||||
throw new SocketException("unknown address type");
|
||||
impl.leaveGroup((InetSocketAddress) address, netIf);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,13 +39,20 @@ exception statement from your version. */
|
||||
|
||||
package gnu.java.net;
|
||||
|
||||
import gnu.java.nio.SocketChannelImpl;
|
||||
import gnu.java.nio.VMChannel;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.SocketException;
|
||||
import java.net.SocketImpl;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* Written using on-line Java Platform 1.2 API Specification, as well
|
||||
@@ -63,17 +70,13 @@ import java.net.SocketImpl;
|
||||
* @author Nic Ferrier (nferrier@tapsellferrier.co.uk)
|
||||
* @author Aaron M. Renn (arenn@urbanophile.com)
|
||||
*/
|
||||
public final class PlainSocketImpl extends SocketImpl
|
||||
public class PlainSocketImpl extends SocketImpl
|
||||
{
|
||||
|
||||
/**
|
||||
* The OS file handle representing the socket.
|
||||
* This is used for reads and writes to/from the socket and
|
||||
* to close it.
|
||||
*
|
||||
* When the socket is closed this is reset to -1.
|
||||
* The underlying plain socket VM implementation.
|
||||
*/
|
||||
int native_fd = -1;
|
||||
protected VMPlainSocketImpl impl;
|
||||
|
||||
/**
|
||||
* A cached copy of the in stream for reading from the socket.
|
||||
@@ -90,7 +93,13 @@ public final class PlainSocketImpl extends SocketImpl
|
||||
* is being invoked on this socket.
|
||||
*/
|
||||
private boolean inChannelOperation;
|
||||
|
||||
|
||||
/**
|
||||
* The socket channel we use for IO operation. Package-private for
|
||||
* use by inner classes.
|
||||
*/
|
||||
SocketChannelImpl channel;
|
||||
|
||||
/**
|
||||
* Indicates whether we should ignore whether any associated
|
||||
* channel is set to non-blocking mode. Certain operations
|
||||
@@ -117,29 +126,7 @@ public final class PlainSocketImpl extends SocketImpl
|
||||
*/
|
||||
public PlainSocketImpl()
|
||||
{
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
protected void finalize() throws Throwable
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (native_fd != -1)
|
||||
try
|
||||
{
|
||||
close();
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
// Nothing we can do about it.
|
||||
}
|
||||
}
|
||||
super.finalize();
|
||||
}
|
||||
|
||||
public int getNativeFD()
|
||||
{
|
||||
return native_fd;
|
||||
this.impl = new VMPlainSocketImpl();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -155,7 +142,24 @@ public final class PlainSocketImpl extends SocketImpl
|
||||
*/
|
||||
public void setOption(int optionId, Object value) throws SocketException
|
||||
{
|
||||
VMPlainSocketImpl.setOption(this, optionId, value);
|
||||
switch (optionId)
|
||||
{
|
||||
case SO_LINGER:
|
||||
case IP_MULTICAST_LOOP:
|
||||
case SO_BROADCAST:
|
||||
case SO_KEEPALIVE:
|
||||
case SO_OOBINLINE:
|
||||
case TCP_NODELAY:
|
||||
case IP_TOS:
|
||||
case SO_RCVBUF:
|
||||
case SO_SNDBUF:
|
||||
case SO_TIMEOUT:
|
||||
case SO_REUSEADDR:
|
||||
impl.setOption(optionId, value);
|
||||
return;
|
||||
default:
|
||||
throw new SocketException("Unrecognized TCP option: " + optionId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -171,17 +175,49 @@ public final class PlainSocketImpl extends SocketImpl
|
||||
*/
|
||||
public Object getOption(int optionId) throws SocketException
|
||||
{
|
||||
return VMPlainSocketImpl.getOption(this, optionId);
|
||||
if (optionId == SO_BINDADDR)
|
||||
{
|
||||
try
|
||||
{
|
||||
return channel.getVMChannel().getLocalAddress().getAddress();
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
SocketException se = new SocketException();
|
||||
se.initCause(ioe);
|
||||
throw se;
|
||||
}
|
||||
}
|
||||
|
||||
// This filters options which are invalid for TCP.
|
||||
switch (optionId)
|
||||
{
|
||||
case SO_LINGER:
|
||||
case IP_MULTICAST_LOOP:
|
||||
case SO_BROADCAST:
|
||||
case SO_KEEPALIVE:
|
||||
case SO_OOBINLINE:
|
||||
case TCP_NODELAY:
|
||||
case IP_TOS:
|
||||
case SO_RCVBUF:
|
||||
case SO_SNDBUF:
|
||||
case SO_TIMEOUT:
|
||||
case SO_REUSEADDR:
|
||||
return impl.getOption(optionId);
|
||||
default:
|
||||
throw new SocketException("Unrecognized TCP option: " + optionId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void shutdownInput() throws IOException
|
||||
{
|
||||
VMPlainSocketImpl.shutdownInput(this);
|
||||
impl.shutdownInput();
|
||||
}
|
||||
|
||||
public void shutdownOutput() throws IOException
|
||||
{
|
||||
VMPlainSocketImpl.shutdownOutput(this);
|
||||
impl.shutdownOutput();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -195,7 +231,11 @@ public final class PlainSocketImpl extends SocketImpl
|
||||
*/
|
||||
protected synchronized void create(boolean stream) throws IOException
|
||||
{
|
||||
VMPlainSocketImpl.create(this);
|
||||
channel = new SocketChannelImpl(false);
|
||||
VMChannel vmchannel = channel.getVMChannel();
|
||||
vmchannel.initSocket(stream);
|
||||
channel.configureBlocking(true);
|
||||
impl.getState().setChannelFD(vmchannel.getState());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -222,7 +262,7 @@ public final class PlainSocketImpl extends SocketImpl
|
||||
*/
|
||||
protected void connect(InetAddress addr, int port) throws IOException
|
||||
{
|
||||
VMPlainSocketImpl.connect(this, addr, port);
|
||||
connect(new InetSocketAddress(addr, port), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -236,7 +276,17 @@ public final class PlainSocketImpl extends SocketImpl
|
||||
protected synchronized void connect(SocketAddress address, int timeout)
|
||||
throws IOException
|
||||
{
|
||||
VMPlainSocketImpl.connect(this, address, timeout);
|
||||
if (channel == null)
|
||||
create(true);
|
||||
boolean connected = channel.connect(address, timeout);
|
||||
if (!connected)
|
||||
throw new SocketTimeoutException("connect timed out");
|
||||
|
||||
// Using the given SocketAddress is important to preserve
|
||||
// hostnames given by the caller.
|
||||
InetSocketAddress addr = (InetSocketAddress) address;
|
||||
this.address = addr.getAddress();
|
||||
this.port = addr.getPort();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -251,7 +301,10 @@ public final class PlainSocketImpl extends SocketImpl
|
||||
protected synchronized void bind(InetAddress addr, int port)
|
||||
throws IOException
|
||||
{
|
||||
VMPlainSocketImpl.bind(this, addr, port);
|
||||
if (channel == null)
|
||||
create(true);
|
||||
impl.bind(new InetSocketAddress(addr, port));
|
||||
localport = channel.getVMChannel().getLocalAddress().getPort();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -267,7 +320,7 @@ public final class PlainSocketImpl extends SocketImpl
|
||||
protected synchronized void listen(int queuelen)
|
||||
throws IOException
|
||||
{
|
||||
VMPlainSocketImpl.listen(this, queuelen);
|
||||
impl.listen(queuelen);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -279,7 +332,19 @@ public final class PlainSocketImpl extends SocketImpl
|
||||
protected synchronized void accept(SocketImpl impl)
|
||||
throws IOException
|
||||
{
|
||||
VMPlainSocketImpl.accept(this, impl);
|
||||
if (channel == null)
|
||||
create(true);
|
||||
if (!(impl instanceof PlainSocketImpl))
|
||||
throw new IOException("incompatible SocketImpl: "
|
||||
+ impl.getClass().getName());
|
||||
PlainSocketImpl that = (PlainSocketImpl) impl;
|
||||
VMChannel c = channel.getVMChannel().accept();
|
||||
that.impl.getState().setChannelFD(c.getState());
|
||||
that.channel = new SocketChannelImpl(c);
|
||||
that.setOption(SO_REUSEADDR, Boolean.TRUE);
|
||||
// Reset the inherited timeout.
|
||||
that.setOption(SO_TIMEOUT, Integer.valueOf(0));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -292,7 +357,9 @@ public final class PlainSocketImpl extends SocketImpl
|
||||
*/
|
||||
protected int available() throws IOException
|
||||
{
|
||||
return VMPlainSocketImpl.available(this);
|
||||
if (channel == null)
|
||||
throw new SocketException("not connected");
|
||||
return channel.getVMChannel().available();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -308,65 +375,16 @@ public final class PlainSocketImpl extends SocketImpl
|
||||
*/
|
||||
protected void close() throws IOException
|
||||
{
|
||||
VMPlainSocketImpl.close(this);
|
||||
if (impl.getState().isValid())
|
||||
impl.close();
|
||||
|
||||
address = null;
|
||||
port = -1;
|
||||
}
|
||||
|
||||
public void sendUrgentData(int data)
|
||||
public void sendUrgentData(int data) throws IOException
|
||||
{
|
||||
VMPlainSocketImpl.sendUrgendData(this, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method used by SocketInputStream for reading data from
|
||||
* the connection. Reads up to len bytes of data into the buffer
|
||||
* buf starting at offset bytes into the buffer.
|
||||
*
|
||||
* @return the actual number of bytes read or -1 if end of stream.
|
||||
*
|
||||
* @throws IOException if an error occurs
|
||||
*/
|
||||
protected int read(byte[] buf, int offset, int len)
|
||||
throws IOException
|
||||
{
|
||||
return VMPlainSocketImpl.read(this, buf, offset, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method used by SocketInputStream for reading data from
|
||||
* the connection. Reads and returns one byte of data.
|
||||
*
|
||||
* @return the read byte
|
||||
*
|
||||
* @throws IOException if an error occurs
|
||||
*/
|
||||
protected int read()
|
||||
throws IOException
|
||||
{
|
||||
return VMPlainSocketImpl.read(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method used by SocketOuputStream for writing data to
|
||||
* the connection. Writes up to len bytes of data from the buffer
|
||||
* buf starting at offset bytes into the buffer.
|
||||
*
|
||||
* @throws IOException If an error occurs
|
||||
*/
|
||||
protected void write(byte[] buf, int offset, int len)
|
||||
throws IOException
|
||||
{
|
||||
VMPlainSocketImpl.write(this, buf, offset, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method used by SocketOuputStream for writing data to
|
||||
* the connection. Writes up one byte to the socket.
|
||||
*
|
||||
* @throws IOException If an error occurs
|
||||
*/
|
||||
protected void write(int data) throws IOException
|
||||
{
|
||||
VMPlainSocketImpl.write(this, data);
|
||||
impl.sendUrgentData(data);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -400,6 +418,95 @@ public final class PlainSocketImpl extends SocketImpl
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
public VMChannel getVMChannel()
|
||||
{
|
||||
if (channel == null)
|
||||
return null;
|
||||
return channel.getVMChannel();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.net.SocketImpl#getInetAddress()
|
||||
*/
|
||||
protected InetAddress getInetAddress()
|
||||
{
|
||||
if (channel == null)
|
||||
return null;
|
||||
|
||||
try
|
||||
{
|
||||
InetSocketAddress remote = channel.getVMChannel().getPeerAddress();
|
||||
if (remote == null)
|
||||
return null;
|
||||
// To mimic behavior of the RI the InetAddress instance which was
|
||||
// used to establish the connection is returned instead of one that
|
||||
// was created by the native layer (this preserves exact hostnames).
|
||||
if (address != null)
|
||||
return address;
|
||||
|
||||
return remote.getAddress();
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.net.SocketImpl#getLocalPort()
|
||||
*/
|
||||
protected int getLocalPort()
|
||||
{
|
||||
if (channel == null)
|
||||
return -1;
|
||||
try
|
||||
{
|
||||
InetSocketAddress local = channel.getVMChannel().getLocalAddress();
|
||||
if (local == null)
|
||||
return -1;
|
||||
return local.getPort();
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public InetSocketAddress getLocalAddress()
|
||||
{
|
||||
if (channel == null)
|
||||
return null;
|
||||
try
|
||||
{
|
||||
return channel.getVMChannel().getLocalAddress();
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.net.SocketImpl#getPort()
|
||||
*/
|
||||
protected int getPort()
|
||||
{
|
||||
if (channel == null)
|
||||
return -1;
|
||||
|
||||
try
|
||||
{
|
||||
InetSocketAddress remote = channel.getVMChannel().getPeerAddress();
|
||||
if (remote == null)
|
||||
return -1;
|
||||
return remote.getPort();
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class contains an implementation of <code>InputStream</code> for
|
||||
@@ -437,7 +544,23 @@ public final class PlainSocketImpl extends SocketImpl
|
||||
*/
|
||||
public int read() throws IOException
|
||||
{
|
||||
return PlainSocketImpl.this.read();
|
||||
if (channel == null)
|
||||
throw new SocketException("not connected");
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
return channel.getVMChannel().read();
|
||||
}
|
||||
catch (SocketTimeoutException ste)
|
||||
{
|
||||
throw ste;
|
||||
}
|
||||
catch (InterruptedIOException iioe)
|
||||
{
|
||||
// Ignore; NIO may throw this; net io shouldn't
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -454,12 +577,24 @@ public final class PlainSocketImpl extends SocketImpl
|
||||
*/
|
||||
public int read (byte[] buf, int offset, int len) throws IOException
|
||||
{
|
||||
int bytes_read = PlainSocketImpl.this.read (buf, offset, len);
|
||||
|
||||
if (bytes_read == 0)
|
||||
return -1;
|
||||
|
||||
return bytes_read;
|
||||
if (channel == null)
|
||||
throw new SocketException("not connected");
|
||||
ByteBuffer b = ByteBuffer.wrap(buf, offset, len);
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
return channel.read(b);
|
||||
}
|
||||
catch (SocketTimeoutException ste)
|
||||
{
|
||||
throw ste;
|
||||
}
|
||||
catch (InterruptedIOException iioe)
|
||||
{
|
||||
// Ignored; NIO may throw this; net IO not.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -495,7 +630,20 @@ public final class PlainSocketImpl extends SocketImpl
|
||||
*/
|
||||
public void write(int b) throws IOException
|
||||
{
|
||||
PlainSocketImpl.this.write(b);
|
||||
if (channel == null)
|
||||
throw new SocketException("not connected");
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
channel.getVMChannel().write(b);
|
||||
return;
|
||||
}
|
||||
catch (InterruptedIOException iioe)
|
||||
{
|
||||
// Ignored.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -510,7 +658,21 @@ public final class PlainSocketImpl extends SocketImpl
|
||||
*/
|
||||
public void write (byte[] buf, int offset, int len) throws IOException
|
||||
{
|
||||
PlainSocketImpl.this.write (buf, offset, len);
|
||||
if (channel == null)
|
||||
throw new SocketException("not connected");
|
||||
ByteBuffer b = ByteBuffer.wrap(buf, offset, len);
|
||||
while (b.hasRemaining())
|
||||
{
|
||||
try
|
||||
{
|
||||
if (channel.write(b) == -1)
|
||||
throw new IOException("channel has been closed");
|
||||
}
|
||||
catch (InterruptedIOException iioe)
|
||||
{
|
||||
// Ignored.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,8 @@ exception statement from your version. */
|
||||
|
||||
package gnu.java.net.local;
|
||||
|
||||
import gnu.classpath.Configuration;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
@@ -66,7 +68,10 @@ final class LocalSocketImpl extends SocketImpl
|
||||
{
|
||||
try
|
||||
{
|
||||
System.loadLibrary ("javanet");
|
||||
if (Configuration.INIT_LOAD_LIBRARY)
|
||||
{
|
||||
System.loadLibrary ("javanet");
|
||||
}
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
|
||||
@@ -48,6 +48,7 @@ import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketException;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@@ -227,10 +228,16 @@ public class HTTPConnection
|
||||
* @param secure whether to use a secure connection
|
||||
* @param connectionTimeout the connection timeout
|
||||
* @param timeout the socket read timeout
|
||||
*
|
||||
* @throws IllegalArgumentException if either connectionTimeout or
|
||||
* timeout less than zero.
|
||||
*/
|
||||
public HTTPConnection(String hostname, int port, boolean secure,
|
||||
int connectionTimeout, int timeout)
|
||||
{
|
||||
if (connectionTimeout < 0 || timeout < 0)
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
this.hostname = hostname;
|
||||
this.port = port;
|
||||
this.secure = secure;
|
||||
@@ -471,14 +478,32 @@ public class HTTPConnection
|
||||
{
|
||||
String ttl =
|
||||
SystemProperties.getProperty("classpath.net.http.keepAliveTTL");
|
||||
connectionTTL = (ttl != null && ttl.length() > 0) ?
|
||||
1000 * Math.max(1, Integer.parseInt(ttl)) : 10000;
|
||||
connectionTTL = 10000;
|
||||
if (ttl != null && ttl.length() > 0)
|
||||
try
|
||||
{
|
||||
int v = 1000 * Integer.parseInt(ttl);
|
||||
if (v >= 0)
|
||||
connectionTTL = v;
|
||||
}
|
||||
catch (NumberFormatException _)
|
||||
{
|
||||
// Ignore.
|
||||
}
|
||||
|
||||
String mc = SystemProperties.getProperty("http.maxConnections");
|
||||
maxConnections = (mc != null && mc.length() > 0) ?
|
||||
Math.max(Integer.parseInt(mc), 1) : 5;
|
||||
if (maxConnections < 1)
|
||||
maxConnections = 1;
|
||||
maxConnections = 5;
|
||||
if (mc != null && mc.length() > 0)
|
||||
try
|
||||
{
|
||||
int v = Integer.parseInt(mc);
|
||||
if (v > 0)
|
||||
maxConnections = v;
|
||||
}
|
||||
catch (NumberFormatException _)
|
||||
{
|
||||
// Ignore.
|
||||
}
|
||||
|
||||
HTTPConnection c = null;
|
||||
|
||||
@@ -490,12 +515,23 @@ public class HTTPConnection
|
||||
{
|
||||
c = cc;
|
||||
it.remove();
|
||||
// Update the timeout.
|
||||
if (c.socket != null)
|
||||
try
|
||||
{
|
||||
c.socket.setSoTimeout(timeout);
|
||||
}
|
||||
catch (SocketException _)
|
||||
{
|
||||
// Ignore.
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (c == null)
|
||||
{
|
||||
c = new HTTPConnection(host, port, secure, connectionTimeout, timeout);
|
||||
c = new HTTPConnection(host, port, secure,
|
||||
connectionTimeout, timeout);
|
||||
c.setPool(this);
|
||||
}
|
||||
return c;
|
||||
|
||||
@@ -75,7 +75,7 @@ public class HTTPURLConnection
|
||||
|
||||
// These are package private for use in anonymous inner classes.
|
||||
String proxyHostname;
|
||||
int proxyPort;
|
||||
int proxyPort = -1;
|
||||
String agent;
|
||||
boolean keepAlive;
|
||||
|
||||
@@ -99,18 +99,21 @@ public class HTTPURLConnection
|
||||
{
|
||||
super(url);
|
||||
requestHeaders = new Headers();
|
||||
proxyHostname = SystemProperties.getProperty("http.proxyHost");
|
||||
if (proxyHostname != null && proxyHostname.length() > 0)
|
||||
String proxy = SystemProperties.getProperty("http.proxyHost");
|
||||
if (proxy != null && proxy.length() > 0)
|
||||
{
|
||||
String port = SystemProperties.getProperty("http.proxyPort");
|
||||
if (port != null && port.length() > 0)
|
||||
{
|
||||
proxyPort = Integer.parseInt(port);
|
||||
}
|
||||
else
|
||||
{
|
||||
proxyHostname = null;
|
||||
proxyPort = -1;
|
||||
try
|
||||
{
|
||||
proxyPort = Integer.parseInt(port);
|
||||
proxyHostname = proxy;
|
||||
}
|
||||
catch (NumberFormatException _)
|
||||
{
|
||||
// Ignore.
|
||||
}
|
||||
}
|
||||
}
|
||||
agent = SystemProperties.getProperty("http.agent");
|
||||
@@ -354,11 +357,14 @@ public class HTTPURLConnection
|
||||
HTTPConnection connection;
|
||||
if (keepAlive)
|
||||
{
|
||||
connection = HTTPConnection.Pool.instance.get(host, port, secure, getConnectTimeout(), 0);
|
||||
connection = HTTPConnection.Pool.instance.get(host, port, secure,
|
||||
getConnectTimeout(),
|
||||
getReadTimeout());
|
||||
}
|
||||
else
|
||||
{
|
||||
connection = new HTTPConnection(host, port, secure, 0, getConnectTimeout());
|
||||
connection = new HTTPConnection(host, port, secure,
|
||||
getConnectTimeout(), getReadTimeout());
|
||||
}
|
||||
return connection;
|
||||
}
|
||||
@@ -662,23 +668,23 @@ public class HTTPURLConnection
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the connection timeout speed, in milliseconds, or zero if the timeout
|
||||
* Set the read timeout, in milliseconds, or zero if the timeout
|
||||
* is to be considered infinite.
|
||||
*
|
||||
* Overloaded.
|
||||
*
|
||||
*/
|
||||
public void setConnectTimeout(int timeout)
|
||||
public void setReadTimeout(int timeout)
|
||||
throws IllegalArgumentException
|
||||
{
|
||||
super.setConnectTimeout( timeout );
|
||||
if( connection == null )
|
||||
super.setReadTimeout(timeout);
|
||||
if (connection == null)
|
||||
return;
|
||||
try
|
||||
{
|
||||
connection.getSocket().setSoTimeout( timeout );
|
||||
connection.getSocket().setSoTimeout(timeout);
|
||||
}
|
||||
catch(IOException se)
|
||||
catch (IOException se)
|
||||
{
|
||||
// Ignore socket exceptions.
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* gnu.java.net.protocol.jar.Handler - jar protocol handler for java.net
|
||||
Copyright (C) 1999, 2002, 2003, 2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 1999, 2002, 2003, 2005, 2006 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@@ -45,6 +45,9 @@ import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.URLStreamHandler;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
/**
|
||||
* @author Kresten Krab Thorup (krab@gnu.org)
|
||||
@@ -114,7 +117,7 @@ public class Handler extends URLStreamHandler
|
||||
file = file.substring(0, idx + 1) + url_string;
|
||||
}
|
||||
|
||||
setURL (url, "jar", url.getHost(), url.getPort(), file, null);
|
||||
setURL (url, "jar", url.getHost(), url.getPort(), flat(file), null);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -148,6 +151,45 @@ public class Handler extends URLStreamHandler
|
||||
setURL (url, "jar", url.getHost(), url.getPort(), url_string, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the given jar url string 'flat' by removing any . and .. from
|
||||
* jar file path because ZipFile entries can only handle flat paths.
|
||||
* Inside jar files '/' is always the path separator.
|
||||
*/
|
||||
private static String flat(String url_string)
|
||||
{
|
||||
int jar_stop = url_string.indexOf("!/");
|
||||
String jar_path = url_string.substring(jar_stop + 1, url_string.length());
|
||||
|
||||
if (jar_path.indexOf("/.") < 0)
|
||||
return url_string;
|
||||
|
||||
ArrayList tokens = new ArrayList();
|
||||
StringTokenizer st = new StringTokenizer(jar_path, "/");
|
||||
while (st.hasMoreTokens())
|
||||
{
|
||||
String token = st.nextToken();
|
||||
if (token.equals("."))
|
||||
continue;
|
||||
else if (token.equals(".."))
|
||||
{
|
||||
if (! tokens.isEmpty())
|
||||
tokens.remove(tokens.size() - 1);
|
||||
}
|
||||
else
|
||||
tokens.add(token);
|
||||
}
|
||||
|
||||
StringBuffer path = new StringBuffer(url_string.length());
|
||||
path.append(url_string.substring(0, jar_stop + 1));
|
||||
|
||||
Iterator it = tokens.iterator();
|
||||
while (it.hasNext())
|
||||
path.append('/').append(it.next());
|
||||
|
||||
return path.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method converts a Jar URL object into a String.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user