Merged gcj-eclipse branch to trunk.

From-SVN: r120621
This commit is contained in:
Tom Tromey
2007-01-09 19:58:05 +00:00
parent c648dedbde
commit 97b8365caf
17478 changed files with 606493 additions and 100744 deletions
@@ -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.
*