feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
367
jdkSrc/jdk8/java/net/AbstractPlainDatagramSocketImpl.java
Normal file
367
jdkSrc/jdk8/java/net/AbstractPlainDatagramSocketImpl.java
Normal file
@@ -0,0 +1,367 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package java.net;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.IOException;
|
||||
import java.security.AccessController;
|
||||
import sun.net.ResourceManager;
|
||||
|
||||
/**
|
||||
* Abstract datagram and multicast socket implementation base class.
|
||||
* Note: This is not a public class, so that applets cannot call
|
||||
* into the implementation directly and hence cannot bypass the
|
||||
* security checks present in the DatagramSocket and MulticastSocket
|
||||
* classes.
|
||||
*
|
||||
* @author Pavani Diwanji
|
||||
*/
|
||||
|
||||
abstract class AbstractPlainDatagramSocketImpl extends DatagramSocketImpl
|
||||
{
|
||||
/* timeout value for receive() */
|
||||
int timeout = 0;
|
||||
boolean connected = false;
|
||||
private int trafficClass = 0;
|
||||
protected InetAddress connectedAddress = null;
|
||||
private int connectedPort = -1;
|
||||
|
||||
private static final String os = AccessController.doPrivileged(
|
||||
new sun.security.action.GetPropertyAction("os.name")
|
||||
);
|
||||
|
||||
/**
|
||||
* flag set if the native connect() call not to be used
|
||||
*/
|
||||
private final static boolean connectDisabled = os.contains("OS X");
|
||||
|
||||
/**
|
||||
* Load net library into runtime.
|
||||
*/
|
||||
static {
|
||||
java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
System.loadLibrary("net");
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a datagram socket
|
||||
*/
|
||||
protected synchronized void create() throws SocketException {
|
||||
ResourceManager.beforeUdpCreate();
|
||||
fd = new FileDescriptor();
|
||||
try {
|
||||
datagramSocketCreate();
|
||||
} catch (SocketException ioe) {
|
||||
ResourceManager.afterUdpClose();
|
||||
fd = null;
|
||||
throw ioe;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds a datagram socket to a local port.
|
||||
*/
|
||||
protected synchronized void bind(int lport, InetAddress laddr)
|
||||
throws SocketException {
|
||||
bind0(lport, laddr);
|
||||
}
|
||||
|
||||
protected abstract void bind0(int lport, InetAddress laddr)
|
||||
throws SocketException;
|
||||
|
||||
/**
|
||||
* Sends a datagram packet. The packet contains the data and the
|
||||
* destination address to send the packet to.
|
||||
* @param p the packet to be sent.
|
||||
*/
|
||||
protected abstract void send(DatagramPacket p) throws IOException;
|
||||
|
||||
/**
|
||||
* Connects a datagram socket to a remote destination. This associates the remote
|
||||
* address with the local socket so that datagrams may only be sent to this destination
|
||||
* and received from this destination.
|
||||
* @param address the remote InetAddress to connect to
|
||||
* @param port the remote port number
|
||||
*/
|
||||
protected void connect(InetAddress address, int port) throws SocketException {
|
||||
connect0(address, port);
|
||||
connectedAddress = address;
|
||||
connectedPort = port;
|
||||
connected = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnects a previously connected socket. Does nothing if the socket was
|
||||
* not connected already.
|
||||
*/
|
||||
protected void disconnect() {
|
||||
disconnect0(connectedAddress.holder().getFamily());
|
||||
connected = false;
|
||||
connectedAddress = null;
|
||||
connectedPort = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Peek at the packet to see who it is from.
|
||||
* @param i the address to populate with the sender address
|
||||
*/
|
||||
protected abstract int peek(InetAddress i) throws IOException;
|
||||
protected abstract int peekData(DatagramPacket p) throws IOException;
|
||||
/**
|
||||
* Receive the datagram packet.
|
||||
* @param p the packet to receive into
|
||||
*/
|
||||
protected synchronized void receive(DatagramPacket p)
|
||||
throws IOException {
|
||||
receive0(p);
|
||||
}
|
||||
|
||||
protected abstract void receive0(DatagramPacket p)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Set the TTL (time-to-live) option.
|
||||
* @param ttl TTL to be set.
|
||||
*/
|
||||
protected abstract void setTimeToLive(int ttl) throws IOException;
|
||||
|
||||
/**
|
||||
* Get the TTL (time-to-live) option.
|
||||
*/
|
||||
protected abstract int getTimeToLive() throws IOException;
|
||||
|
||||
/**
|
||||
* Set the TTL (time-to-live) option.
|
||||
* @param ttl TTL to be set.
|
||||
*/
|
||||
@Deprecated
|
||||
protected abstract void setTTL(byte ttl) throws IOException;
|
||||
|
||||
/**
|
||||
* Get the TTL (time-to-live) option.
|
||||
*/
|
||||
@Deprecated
|
||||
protected abstract byte getTTL() throws IOException;
|
||||
|
||||
/**
|
||||
* Join the multicast group.
|
||||
* @param inetaddr multicast address to join.
|
||||
*/
|
||||
protected void join(InetAddress inetaddr) throws IOException {
|
||||
join(inetaddr, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Leave the multicast group.
|
||||
* @param inetaddr multicast address to leave.
|
||||
*/
|
||||
protected void leave(InetAddress inetaddr) throws IOException {
|
||||
leave(inetaddr, null);
|
||||
}
|
||||
/**
|
||||
* Join the multicast group.
|
||||
* @param mcastaddr multicast address to join.
|
||||
* @param netIf specifies the local interface to receive multicast
|
||||
* datagram packets
|
||||
* @throws IllegalArgumentException if mcastaddr is null or is a
|
||||
* SocketAddress subclass not supported by this socket
|
||||
* @since 1.4
|
||||
*/
|
||||
|
||||
protected void joinGroup(SocketAddress mcastaddr, NetworkInterface netIf)
|
||||
throws IOException {
|
||||
if (mcastaddr == null || !(mcastaddr instanceof InetSocketAddress))
|
||||
throw new IllegalArgumentException("Unsupported address type");
|
||||
join(((InetSocketAddress)mcastaddr).getAddress(), netIf);
|
||||
}
|
||||
|
||||
protected abstract void join(InetAddress inetaddr, NetworkInterface netIf)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Leave the multicast group.
|
||||
* @param mcastaddr multicast address to leave.
|
||||
* @param netIf specified the local interface to leave the group at
|
||||
* @throws IllegalArgumentException if mcastaddr is null or is a
|
||||
* SocketAddress subclass not supported by this socket
|
||||
* @since 1.4
|
||||
*/
|
||||
protected void leaveGroup(SocketAddress mcastaddr, NetworkInterface netIf)
|
||||
throws IOException {
|
||||
if (mcastaddr == null || !(mcastaddr instanceof InetSocketAddress))
|
||||
throw new IllegalArgumentException("Unsupported address type");
|
||||
leave(((InetSocketAddress)mcastaddr).getAddress(), netIf);
|
||||
}
|
||||
|
||||
protected abstract void leave(InetAddress inetaddr, NetworkInterface netIf)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Close the socket.
|
||||
*/
|
||||
protected void close() {
|
||||
if (fd != null) {
|
||||
datagramSocketClose();
|
||||
ResourceManager.afterUdpClose();
|
||||
fd = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isClosed() {
|
||||
return (fd == null) ? true : false;
|
||||
}
|
||||
|
||||
protected void finalize() {
|
||||
close();
|
||||
}
|
||||
|
||||
/**
|
||||
* set a value - since we only support (setting) binary options
|
||||
* here, o must be a Boolean
|
||||
*/
|
||||
|
||||
public void setOption(int optID, Object o) throws SocketException {
|
||||
if (isClosed()) {
|
||||
throw new SocketException("Socket Closed");
|
||||
}
|
||||
switch (optID) {
|
||||
/* check type safety b4 going native. These should never
|
||||
* fail, since only java.Socket* has access to
|
||||
* PlainSocketImpl.setOption().
|
||||
*/
|
||||
case SO_TIMEOUT:
|
||||
if (o == null || !(o instanceof Integer)) {
|
||||
throw new SocketException("bad argument for SO_TIMEOUT");
|
||||
}
|
||||
int tmp = ((Integer) o).intValue();
|
||||
if (tmp < 0)
|
||||
throw new IllegalArgumentException("timeout < 0");
|
||||
timeout = tmp;
|
||||
return;
|
||||
case IP_TOS:
|
||||
if (o == null || !(o instanceof Integer)) {
|
||||
throw new SocketException("bad argument for IP_TOS");
|
||||
}
|
||||
trafficClass = ((Integer)o).intValue();
|
||||
break;
|
||||
case SO_REUSEADDR:
|
||||
if (o == null || !(o instanceof Boolean)) {
|
||||
throw new SocketException("bad argument for SO_REUSEADDR");
|
||||
}
|
||||
break;
|
||||
case SO_BROADCAST:
|
||||
if (o == null || !(o instanceof Boolean)) {
|
||||
throw new SocketException("bad argument for SO_BROADCAST");
|
||||
}
|
||||
break;
|
||||
case SO_BINDADDR:
|
||||
throw new SocketException("Cannot re-bind Socket");
|
||||
case SO_RCVBUF:
|
||||
case SO_SNDBUF:
|
||||
if (o == null || !(o instanceof Integer) ||
|
||||
((Integer)o).intValue() < 0) {
|
||||
throw new SocketException("bad argument for SO_SNDBUF or " +
|
||||
"SO_RCVBUF");
|
||||
}
|
||||
break;
|
||||
case IP_MULTICAST_IF:
|
||||
if (o == null || !(o instanceof InetAddress))
|
||||
throw new SocketException("bad argument for IP_MULTICAST_IF");
|
||||
break;
|
||||
case IP_MULTICAST_IF2:
|
||||
if (o == null || !(o instanceof NetworkInterface))
|
||||
throw new SocketException("bad argument for IP_MULTICAST_IF2");
|
||||
break;
|
||||
case IP_MULTICAST_LOOP:
|
||||
if (o == null || !(o instanceof Boolean))
|
||||
throw new SocketException("bad argument for IP_MULTICAST_LOOP");
|
||||
break;
|
||||
default:
|
||||
throw new SocketException("invalid option: " + optID);
|
||||
}
|
||||
socketSetOption(optID, o);
|
||||
}
|
||||
|
||||
/*
|
||||
* get option's state - set or not
|
||||
*/
|
||||
|
||||
public Object getOption(int optID) throws SocketException {
|
||||
if (isClosed()) {
|
||||
throw new SocketException("Socket Closed");
|
||||
}
|
||||
|
||||
Object result;
|
||||
|
||||
switch (optID) {
|
||||
case SO_TIMEOUT:
|
||||
result = new Integer(timeout);
|
||||
break;
|
||||
|
||||
case IP_TOS:
|
||||
result = socketGetOption(optID);
|
||||
if ( ((Integer)result).intValue() == -1) {
|
||||
result = new Integer(trafficClass);
|
||||
}
|
||||
break;
|
||||
|
||||
case SO_BINDADDR:
|
||||
case IP_MULTICAST_IF:
|
||||
case IP_MULTICAST_IF2:
|
||||
case SO_RCVBUF:
|
||||
case SO_SNDBUF:
|
||||
case IP_MULTICAST_LOOP:
|
||||
case SO_REUSEADDR:
|
||||
case SO_BROADCAST:
|
||||
result = socketGetOption(optID);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new SocketException("invalid option: " + optID);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
protected abstract void datagramSocketCreate() throws SocketException;
|
||||
protected abstract void datagramSocketClose();
|
||||
protected abstract void socketSetOption(int opt, Object val)
|
||||
throws SocketException;
|
||||
protected abstract Object socketGetOption(int opt) throws SocketException;
|
||||
|
||||
protected abstract void connect0(InetAddress address, int port) throws SocketException;
|
||||
protected abstract void disconnect0(int family);
|
||||
|
||||
protected boolean nativeConnectDisabled() {
|
||||
return connectDisabled;
|
||||
}
|
||||
|
||||
abstract int dataAvailable();
|
||||
}
|
||||
726
jdkSrc/jdk8/java/net/AbstractPlainSocketImpl.java
Normal file
726
jdkSrc/jdk8/java/net/AbstractPlainSocketImpl.java
Normal file
@@ -0,0 +1,726 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.FileDescriptor;
|
||||
|
||||
import sun.net.ConnectionResetException;
|
||||
import sun.net.NetHooks;
|
||||
import sun.net.ResourceManager;
|
||||
|
||||
/**
|
||||
* Default Socket Implementation. This implementation does
|
||||
* not implement any security checks.
|
||||
* Note this class should <b>NOT</b> be public.
|
||||
*
|
||||
* @author Steven B. Byrne
|
||||
*/
|
||||
abstract class AbstractPlainSocketImpl extends SocketImpl
|
||||
{
|
||||
/* instance variable for SO_TIMEOUT */
|
||||
int timeout; // timeout in millisec
|
||||
// traffic class
|
||||
private int trafficClass;
|
||||
|
||||
private boolean shut_rd = false;
|
||||
private boolean shut_wr = false;
|
||||
|
||||
private SocketInputStream socketInputStream = null;
|
||||
private SocketOutputStream socketOutputStream = null;
|
||||
|
||||
/* number of threads using the FileDescriptor */
|
||||
protected int fdUseCount = 0;
|
||||
|
||||
/* lock when increment/decrementing fdUseCount */
|
||||
protected final Object fdLock = new Object();
|
||||
|
||||
/* indicates a close is pending on the file descriptor */
|
||||
protected boolean closePending = false;
|
||||
|
||||
/* indicates connection reset state */
|
||||
private int CONNECTION_NOT_RESET = 0;
|
||||
private int CONNECTION_RESET_PENDING = 1;
|
||||
private int CONNECTION_RESET = 2;
|
||||
private int resetState;
|
||||
private final Object resetLock = new Object();
|
||||
|
||||
/* whether this Socket is a stream (TCP) socket or not (UDP)
|
||||
*/
|
||||
protected boolean stream;
|
||||
|
||||
/**
|
||||
* Load net library into runtime.
|
||||
*/
|
||||
static {
|
||||
java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
System.loadLibrary("net");
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a socket with a boolean that specifies whether this
|
||||
* is a stream socket (true) or an unconnected UDP socket (false).
|
||||
*/
|
||||
protected synchronized void create(boolean stream) throws IOException {
|
||||
this.stream = stream;
|
||||
if (!stream) {
|
||||
ResourceManager.beforeUdpCreate();
|
||||
// only create the fd after we know we will be able to create the socket
|
||||
fd = new FileDescriptor();
|
||||
try {
|
||||
socketCreate(false);
|
||||
} catch (IOException ioe) {
|
||||
ResourceManager.afterUdpClose();
|
||||
fd = null;
|
||||
throw ioe;
|
||||
}
|
||||
} else {
|
||||
fd = new FileDescriptor();
|
||||
socketCreate(true);
|
||||
}
|
||||
if (socket != null)
|
||||
socket.setCreated();
|
||||
if (serverSocket != null)
|
||||
serverSocket.setCreated();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a socket and connects it to the specified port on
|
||||
* the specified host.
|
||||
* @param host the specified host
|
||||
* @param port the specified port
|
||||
*/
|
||||
protected void connect(String host, int port)
|
||||
throws UnknownHostException, IOException
|
||||
{
|
||||
boolean connected = false;
|
||||
try {
|
||||
InetAddress address = InetAddress.getByName(host);
|
||||
this.port = port;
|
||||
this.address = address;
|
||||
|
||||
connectToAddress(address, port, timeout);
|
||||
connected = true;
|
||||
} finally {
|
||||
if (!connected) {
|
||||
try {
|
||||
close();
|
||||
} catch (IOException ioe) {
|
||||
/* Do nothing. If connect threw an exception then
|
||||
it will be passed up the call stack */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a socket and connects it to the specified address on
|
||||
* the specified port.
|
||||
* @param address the address
|
||||
* @param port the specified port
|
||||
*/
|
||||
protected void connect(InetAddress address, int port) throws IOException {
|
||||
this.port = port;
|
||||
this.address = address;
|
||||
|
||||
try {
|
||||
connectToAddress(address, port, timeout);
|
||||
return;
|
||||
} catch (IOException e) {
|
||||
// everything failed
|
||||
close();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a socket and connects it to the specified address on
|
||||
* the specified port.
|
||||
* @param address the address
|
||||
* @param timeout the timeout value in milliseconds, or zero for no timeout.
|
||||
* @throws IOException if connection fails
|
||||
* @throws IllegalArgumentException if address is null or is a
|
||||
* SocketAddress subclass not supported by this socket
|
||||
* @since 1.4
|
||||
*/
|
||||
protected void connect(SocketAddress address, int timeout)
|
||||
throws IOException {
|
||||
boolean connected = false;
|
||||
try {
|
||||
if (address == null || !(address instanceof InetSocketAddress))
|
||||
throw new IllegalArgumentException("unsupported address type");
|
||||
InetSocketAddress addr = (InetSocketAddress) address;
|
||||
if (addr.isUnresolved())
|
||||
throw new UnknownHostException(addr.getHostName());
|
||||
this.port = addr.getPort();
|
||||
this.address = addr.getAddress();
|
||||
|
||||
connectToAddress(this.address, port, timeout);
|
||||
connected = true;
|
||||
} finally {
|
||||
if (!connected) {
|
||||
try {
|
||||
close();
|
||||
} catch (IOException ioe) {
|
||||
/* Do nothing. If connect threw an exception then
|
||||
it will be passed up the call stack */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void connectToAddress(InetAddress address, int port, int timeout) throws IOException {
|
||||
if (address.isAnyLocalAddress()) {
|
||||
doConnect(InetAddress.getLocalHost(), port, timeout);
|
||||
} else {
|
||||
doConnect(address, port, timeout);
|
||||
}
|
||||
}
|
||||
|
||||
public void setOption(int opt, Object val) throws SocketException {
|
||||
if (isClosedOrPending()) {
|
||||
throw new SocketException("Socket Closed");
|
||||
}
|
||||
boolean on = true;
|
||||
switch (opt) {
|
||||
/* check type safety b4 going native. These should never
|
||||
* fail, since only java.Socket* has access to
|
||||
* PlainSocketImpl.setOption().
|
||||
*/
|
||||
case SO_LINGER:
|
||||
if (val == null || (!(val instanceof Integer) && !(val instanceof Boolean)))
|
||||
throw new SocketException("Bad parameter for option");
|
||||
if (val instanceof Boolean) {
|
||||
/* true only if disabling - enabling should be Integer */
|
||||
on = false;
|
||||
}
|
||||
break;
|
||||
case SO_TIMEOUT:
|
||||
if (val == null || (!(val instanceof Integer)))
|
||||
throw new SocketException("Bad parameter for SO_TIMEOUT");
|
||||
int tmp = ((Integer) val).intValue();
|
||||
if (tmp < 0)
|
||||
throw new IllegalArgumentException("timeout < 0");
|
||||
timeout = tmp;
|
||||
break;
|
||||
case IP_TOS:
|
||||
if (val == null || !(val instanceof Integer)) {
|
||||
throw new SocketException("bad argument for IP_TOS");
|
||||
}
|
||||
trafficClass = ((Integer)val).intValue();
|
||||
break;
|
||||
case SO_BINDADDR:
|
||||
throw new SocketException("Cannot re-bind socket");
|
||||
case TCP_NODELAY:
|
||||
if (val == null || !(val instanceof Boolean))
|
||||
throw new SocketException("bad parameter for TCP_NODELAY");
|
||||
on = ((Boolean)val).booleanValue();
|
||||
break;
|
||||
case SO_SNDBUF:
|
||||
case SO_RCVBUF:
|
||||
if (val == null || !(val instanceof Integer) ||
|
||||
!(((Integer)val).intValue() > 0)) {
|
||||
throw new SocketException("bad parameter for SO_SNDBUF " +
|
||||
"or SO_RCVBUF");
|
||||
}
|
||||
break;
|
||||
case SO_KEEPALIVE:
|
||||
if (val == null || !(val instanceof Boolean))
|
||||
throw new SocketException("bad parameter for SO_KEEPALIVE");
|
||||
on = ((Boolean)val).booleanValue();
|
||||
break;
|
||||
case SO_OOBINLINE:
|
||||
if (val == null || !(val instanceof Boolean))
|
||||
throw new SocketException("bad parameter for SO_OOBINLINE");
|
||||
on = ((Boolean)val).booleanValue();
|
||||
break;
|
||||
case SO_REUSEADDR:
|
||||
if (val == null || !(val instanceof Boolean))
|
||||
throw new SocketException("bad parameter for SO_REUSEADDR");
|
||||
on = ((Boolean)val).booleanValue();
|
||||
break;
|
||||
default:
|
||||
throw new SocketException("unrecognized TCP option: " + opt);
|
||||
}
|
||||
socketSetOption(opt, on, val);
|
||||
}
|
||||
public Object getOption(int opt) throws SocketException {
|
||||
if (isClosedOrPending()) {
|
||||
throw new SocketException("Socket Closed");
|
||||
}
|
||||
if (opt == SO_TIMEOUT) {
|
||||
return new Integer(timeout);
|
||||
}
|
||||
int ret = 0;
|
||||
/*
|
||||
* The native socketGetOption() knows about 3 options.
|
||||
* The 32 bit value it returns will be interpreted according
|
||||
* to what we're asking. A return of -1 means it understands
|
||||
* the option but its turned off. It will raise a SocketException
|
||||
* if "opt" isn't one it understands.
|
||||
*/
|
||||
|
||||
switch (opt) {
|
||||
case TCP_NODELAY:
|
||||
ret = socketGetOption(opt, null);
|
||||
return Boolean.valueOf(ret != -1);
|
||||
case SO_OOBINLINE:
|
||||
ret = socketGetOption(opt, null);
|
||||
return Boolean.valueOf(ret != -1);
|
||||
case SO_LINGER:
|
||||
ret = socketGetOption(opt, null);
|
||||
return (ret == -1) ? Boolean.FALSE: (Object)(new Integer(ret));
|
||||
case SO_REUSEADDR:
|
||||
ret = socketGetOption(opt, null);
|
||||
return Boolean.valueOf(ret != -1);
|
||||
case SO_BINDADDR:
|
||||
InetAddressContainer in = new InetAddressContainer();
|
||||
ret = socketGetOption(opt, in);
|
||||
return in.addr;
|
||||
case SO_SNDBUF:
|
||||
case SO_RCVBUF:
|
||||
ret = socketGetOption(opt, null);
|
||||
return new Integer(ret);
|
||||
case IP_TOS:
|
||||
try {
|
||||
ret = socketGetOption(opt, null);
|
||||
if (ret == -1) { // ipv6 tos
|
||||
return trafficClass;
|
||||
} else {
|
||||
return ret;
|
||||
}
|
||||
} catch (SocketException se) {
|
||||
// TODO - should make better effort to read TOS or TCLASS
|
||||
return trafficClass; // ipv6 tos
|
||||
}
|
||||
case SO_KEEPALIVE:
|
||||
ret = socketGetOption(opt, null);
|
||||
return Boolean.valueOf(ret != -1);
|
||||
// should never get here
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The workhorse of the connection operation. Tries several times to
|
||||
* establish a connection to the given <host, port>. If unsuccessful,
|
||||
* throws an IOException indicating what went wrong.
|
||||
*/
|
||||
|
||||
synchronized void doConnect(InetAddress address, int port, int timeout) throws IOException {
|
||||
synchronized (fdLock) {
|
||||
if (!closePending && (socket == null || !socket.isBound())) {
|
||||
NetHooks.beforeTcpConnect(fd, address, port);
|
||||
}
|
||||
}
|
||||
try {
|
||||
acquireFD();
|
||||
try {
|
||||
socketConnect(address, port, timeout);
|
||||
/* socket may have been closed during poll/select */
|
||||
synchronized (fdLock) {
|
||||
if (closePending) {
|
||||
throw new SocketException ("Socket closed");
|
||||
}
|
||||
}
|
||||
// If we have a ref. to the Socket, then sets the flags
|
||||
// created, bound & connected to true.
|
||||
// This is normally done in Socket.connect() but some
|
||||
// subclasses of Socket may call impl.connect() directly!
|
||||
if (socket != null) {
|
||||
socket.setBound();
|
||||
socket.setConnected();
|
||||
}
|
||||
} finally {
|
||||
releaseFD();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
close();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds the socket to the specified address of the specified local port.
|
||||
* @param address the address
|
||||
* @param lport the port
|
||||
*/
|
||||
protected synchronized void bind(InetAddress address, int lport)
|
||||
throws IOException
|
||||
{
|
||||
synchronized (fdLock) {
|
||||
if (!closePending && (socket == null || !socket.isBound())) {
|
||||
NetHooks.beforeTcpBind(fd, address, lport);
|
||||
}
|
||||
}
|
||||
socketBind(address, lport);
|
||||
if (socket != null)
|
||||
socket.setBound();
|
||||
if (serverSocket != null)
|
||||
serverSocket.setBound();
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens, for a specified amount of time, for connections.
|
||||
* @param count the amount of time to listen for connections
|
||||
*/
|
||||
protected synchronized void listen(int count) throws IOException {
|
||||
socketListen(count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts connections.
|
||||
* @param s the connection
|
||||
*/
|
||||
protected void accept(SocketImpl s) throws IOException {
|
||||
acquireFD();
|
||||
try {
|
||||
socketAccept(s);
|
||||
} finally {
|
||||
releaseFD();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an InputStream for this socket.
|
||||
*/
|
||||
protected synchronized InputStream getInputStream() throws IOException {
|
||||
synchronized (fdLock) {
|
||||
if (isClosedOrPending())
|
||||
throw new IOException("Socket Closed");
|
||||
if (shut_rd)
|
||||
throw new IOException("Socket input is shutdown");
|
||||
if (socketInputStream == null)
|
||||
socketInputStream = new SocketInputStream(this);
|
||||
}
|
||||
return socketInputStream;
|
||||
}
|
||||
|
||||
void setInputStream(SocketInputStream in) {
|
||||
socketInputStream = in;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an OutputStream for this socket.
|
||||
*/
|
||||
protected synchronized OutputStream getOutputStream() throws IOException {
|
||||
synchronized (fdLock) {
|
||||
if (isClosedOrPending())
|
||||
throw new IOException("Socket Closed");
|
||||
if (shut_wr)
|
||||
throw new IOException("Socket output is shutdown");
|
||||
if (socketOutputStream == null)
|
||||
socketOutputStream = new SocketOutputStream(this);
|
||||
}
|
||||
return socketOutputStream;
|
||||
}
|
||||
|
||||
void setFileDescriptor(FileDescriptor fd) {
|
||||
this.fd = fd;
|
||||
}
|
||||
|
||||
void setAddress(InetAddress address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
void setPort(int port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
void setLocalPort(int localport) {
|
||||
this.localport = localport;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of bytes that can be read without blocking.
|
||||
*/
|
||||
protected synchronized int available() throws IOException {
|
||||
if (isClosedOrPending()) {
|
||||
throw new IOException("Stream closed.");
|
||||
}
|
||||
|
||||
/*
|
||||
* If connection has been reset or shut down for input, then return 0
|
||||
* to indicate there are no buffered bytes.
|
||||
*/
|
||||
if (isConnectionReset() || shut_rd) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If no bytes available and we were previously notified
|
||||
* of a connection reset then we move to the reset state.
|
||||
*
|
||||
* If are notified of a connection reset then check
|
||||
* again if there are bytes buffered on the socket.
|
||||
*/
|
||||
int n = 0;
|
||||
try {
|
||||
n = socketAvailable();
|
||||
if (n == 0 && isConnectionResetPending()) {
|
||||
setConnectionReset();
|
||||
}
|
||||
} catch (ConnectionResetException exc1) {
|
||||
setConnectionResetPending();
|
||||
try {
|
||||
n = socketAvailable();
|
||||
if (n == 0) {
|
||||
setConnectionReset();
|
||||
}
|
||||
} catch (ConnectionResetException exc2) {
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the socket.
|
||||
*/
|
||||
protected void close() throws IOException {
|
||||
synchronized(fdLock) {
|
||||
if (fd != null) {
|
||||
if (!stream) {
|
||||
ResourceManager.afterUdpClose();
|
||||
}
|
||||
if (fdUseCount == 0) {
|
||||
if (closePending) {
|
||||
return;
|
||||
}
|
||||
closePending = true;
|
||||
/*
|
||||
* We close the FileDescriptor in two-steps - first the
|
||||
* "pre-close" which closes the socket but doesn't
|
||||
* release the underlying file descriptor. This operation
|
||||
* may be lengthy due to untransmitted data and a long
|
||||
* linger interval. Once the pre-close is done we do the
|
||||
* actual socket to release the fd.
|
||||
*/
|
||||
try {
|
||||
socketPreClose();
|
||||
} finally {
|
||||
socketClose();
|
||||
}
|
||||
fd = null;
|
||||
return;
|
||||
} else {
|
||||
/*
|
||||
* If a thread has acquired the fd and a close
|
||||
* isn't pending then use a deferred close.
|
||||
* Also decrement fdUseCount to signal the last
|
||||
* thread that releases the fd to close it.
|
||||
*/
|
||||
if (!closePending) {
|
||||
closePending = true;
|
||||
fdUseCount--;
|
||||
socketPreClose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void reset() throws IOException {
|
||||
if (fd != null) {
|
||||
socketClose();
|
||||
}
|
||||
fd = null;
|
||||
super.reset();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Shutdown read-half of the socket connection;
|
||||
*/
|
||||
protected void shutdownInput() throws IOException {
|
||||
if (fd != null) {
|
||||
socketShutdown(SHUT_RD);
|
||||
if (socketInputStream != null) {
|
||||
socketInputStream.setEOF(true);
|
||||
}
|
||||
shut_rd = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shutdown write-half of the socket connection;
|
||||
*/
|
||||
protected void shutdownOutput() throws IOException {
|
||||
if (fd != null) {
|
||||
socketShutdown(SHUT_WR);
|
||||
shut_wr = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean supportsUrgentData () {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void sendUrgentData (int data) throws IOException {
|
||||
if (fd == null) {
|
||||
throw new IOException("Socket Closed");
|
||||
}
|
||||
socketSendUrgentData (data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans up if the user forgets to close it.
|
||||
*/
|
||||
protected void finalize() throws IOException {
|
||||
close();
|
||||
}
|
||||
|
||||
/*
|
||||
* "Acquires" and returns the FileDescriptor for this impl
|
||||
*
|
||||
* A corresponding releaseFD is required to "release" the
|
||||
* FileDescriptor.
|
||||
*/
|
||||
FileDescriptor acquireFD() {
|
||||
synchronized (fdLock) {
|
||||
fdUseCount++;
|
||||
return fd;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* "Release" the FileDescriptor for this impl.
|
||||
*
|
||||
* If the use count goes to -1 then the socket is closed.
|
||||
*/
|
||||
void releaseFD() {
|
||||
synchronized (fdLock) {
|
||||
fdUseCount--;
|
||||
if (fdUseCount == -1) {
|
||||
if (fd != null) {
|
||||
try {
|
||||
socketClose();
|
||||
} catch (IOException e) {
|
||||
} finally {
|
||||
fd = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isConnectionReset() {
|
||||
synchronized (resetLock) {
|
||||
return (resetState == CONNECTION_RESET);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isConnectionResetPending() {
|
||||
synchronized (resetLock) {
|
||||
return (resetState == CONNECTION_RESET_PENDING);
|
||||
}
|
||||
}
|
||||
|
||||
public void setConnectionReset() {
|
||||
synchronized (resetLock) {
|
||||
resetState = CONNECTION_RESET;
|
||||
}
|
||||
}
|
||||
|
||||
public void setConnectionResetPending() {
|
||||
synchronized (resetLock) {
|
||||
if (resetState == CONNECTION_NOT_RESET) {
|
||||
resetState = CONNECTION_RESET_PENDING;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Return true if already closed or close is pending
|
||||
*/
|
||||
public boolean isClosedOrPending() {
|
||||
/*
|
||||
* Lock on fdLock to ensure that we wait if a
|
||||
* close is in progress.
|
||||
*/
|
||||
synchronized (fdLock) {
|
||||
if (closePending || (fd == null)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the current value of SO_TIMEOUT
|
||||
*/
|
||||
public int getTimeout() {
|
||||
return timeout;
|
||||
}
|
||||
|
||||
/*
|
||||
* "Pre-close" a socket by dup'ing the file descriptor - this enables
|
||||
* the socket to be closed without releasing the file descriptor.
|
||||
*/
|
||||
private void socketPreClose() throws IOException {
|
||||
socketClose0(true);
|
||||
}
|
||||
|
||||
/*
|
||||
* Close the socket (and release the file descriptor).
|
||||
*/
|
||||
protected void socketClose() throws IOException {
|
||||
socketClose0(false);
|
||||
}
|
||||
|
||||
abstract void socketCreate(boolean isServer) throws IOException;
|
||||
abstract void socketConnect(InetAddress address, int port, int timeout)
|
||||
throws IOException;
|
||||
abstract void socketBind(InetAddress address, int port)
|
||||
throws IOException;
|
||||
abstract void socketListen(int count)
|
||||
throws IOException;
|
||||
abstract void socketAccept(SocketImpl s)
|
||||
throws IOException;
|
||||
abstract int socketAvailable()
|
||||
throws IOException;
|
||||
abstract void socketClose0(boolean useDeferredClose)
|
||||
throws IOException;
|
||||
abstract void socketShutdown(int howto)
|
||||
throws IOException;
|
||||
abstract void socketSetOption(int cmd, boolean on, Object value)
|
||||
throws SocketException;
|
||||
abstract int socketGetOption(int opt, Object iaContainerObj) throws SocketException;
|
||||
abstract void socketSendUrgentData(int data)
|
||||
throws IOException;
|
||||
|
||||
public final static int SHUT_RD = 0;
|
||||
public final static int SHUT_WR = 1;
|
||||
}
|
||||
425
jdkSrc/jdk8/java/net/Authenticator.java
Normal file
425
jdkSrc/jdk8/java/net/Authenticator.java
Normal file
@@ -0,0 +1,425 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
/**
|
||||
* The class Authenticator represents an object that knows how to obtain
|
||||
* authentication for a network connection. Usually, it will do this
|
||||
* by prompting the user for information.
|
||||
* <p>
|
||||
* Applications use this class by overriding {@link
|
||||
* #getPasswordAuthentication()} in a sub-class. This method will
|
||||
* typically use the various getXXX() accessor methods to get information
|
||||
* about the entity requesting authentication. It must then acquire a
|
||||
* username and password either by interacting with the user or through
|
||||
* some other non-interactive means. The credentials are then returned
|
||||
* as a {@link PasswordAuthentication} return value.
|
||||
* <p>
|
||||
* An instance of this concrete sub-class is then registered
|
||||
* with the system by calling {@link #setDefault(Authenticator)}.
|
||||
* When authentication is required, the system will invoke one of the
|
||||
* requestPasswordAuthentication() methods which in turn will call the
|
||||
* getPasswordAuthentication() method of the registered object.
|
||||
* <p>
|
||||
* All methods that request authentication have a default implementation
|
||||
* that fails.
|
||||
*
|
||||
* @see java.net.Authenticator#setDefault(java.net.Authenticator)
|
||||
* @see java.net.Authenticator#getPasswordAuthentication()
|
||||
*
|
||||
* @author Bill Foote
|
||||
* @since 1.2
|
||||
*/
|
||||
|
||||
// There are no abstract methods, but to be useful the user must
|
||||
// subclass.
|
||||
public abstract
|
||||
class Authenticator {
|
||||
|
||||
// The system-wide authenticator object. See setDefault().
|
||||
private static Authenticator theAuthenticator;
|
||||
|
||||
private String requestingHost;
|
||||
private InetAddress requestingSite;
|
||||
private int requestingPort;
|
||||
private String requestingProtocol;
|
||||
private String requestingPrompt;
|
||||
private String requestingScheme;
|
||||
private URL requestingURL;
|
||||
private RequestorType requestingAuthType;
|
||||
|
||||
/**
|
||||
* The type of the entity requesting authentication.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public enum RequestorType {
|
||||
/**
|
||||
* Entity requesting authentication is a HTTP proxy server.
|
||||
*/
|
||||
PROXY,
|
||||
/**
|
||||
* Entity requesting authentication is a HTTP origin server.
|
||||
*/
|
||||
SERVER
|
||||
}
|
||||
|
||||
private void reset() {
|
||||
requestingHost = null;
|
||||
requestingSite = null;
|
||||
requestingPort = -1;
|
||||
requestingProtocol = null;
|
||||
requestingPrompt = null;
|
||||
requestingScheme = null;
|
||||
requestingURL = null;
|
||||
requestingAuthType = RequestorType.SERVER;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the authenticator that will be used by the networking code
|
||||
* when a proxy or an HTTP server asks for authentication.
|
||||
* <p>
|
||||
* First, if there is a security manager, its {@code checkPermission}
|
||||
* method is called with a
|
||||
* {@code NetPermission("setDefaultAuthenticator")} permission.
|
||||
* This may result in a java.lang.SecurityException.
|
||||
*
|
||||
* @param a The authenticator to be set. If a is {@code null} then
|
||||
* any previously set authenticator is removed.
|
||||
*
|
||||
* @throws SecurityException
|
||||
* if a security manager exists and its
|
||||
* {@code checkPermission} method doesn't allow
|
||||
* setting the default authenticator.
|
||||
*
|
||||
* @see SecurityManager#checkPermission
|
||||
* @see java.net.NetPermission
|
||||
*/
|
||||
public synchronized static void setDefault(Authenticator a) {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
NetPermission setDefaultPermission
|
||||
= new NetPermission("setDefaultAuthenticator");
|
||||
sm.checkPermission(setDefaultPermission);
|
||||
}
|
||||
|
||||
theAuthenticator = a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ask the authenticator that has been registered with the system
|
||||
* for a password.
|
||||
* <p>
|
||||
* First, if there is a security manager, its {@code checkPermission}
|
||||
* method is called with a
|
||||
* {@code NetPermission("requestPasswordAuthentication")} permission.
|
||||
* This may result in a java.lang.SecurityException.
|
||||
*
|
||||
* @param addr The InetAddress of the site requesting authorization,
|
||||
* or null if not known.
|
||||
* @param port the port for the requested connection
|
||||
* @param protocol The protocol that's requesting the connection
|
||||
* ({@link java.net.Authenticator#getRequestingProtocol()})
|
||||
* @param prompt A prompt string for the user
|
||||
* @param scheme The authentication scheme
|
||||
*
|
||||
* @return The username/password, or null if one can't be gotten.
|
||||
*
|
||||
* @throws SecurityException
|
||||
* if a security manager exists and its
|
||||
* {@code checkPermission} method doesn't allow
|
||||
* the password authentication request.
|
||||
*
|
||||
* @see SecurityManager#checkPermission
|
||||
* @see java.net.NetPermission
|
||||
*/
|
||||
public static PasswordAuthentication requestPasswordAuthentication(
|
||||
InetAddress addr,
|
||||
int port,
|
||||
String protocol,
|
||||
String prompt,
|
||||
String scheme) {
|
||||
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
NetPermission requestPermission
|
||||
= new NetPermission("requestPasswordAuthentication");
|
||||
sm.checkPermission(requestPermission);
|
||||
}
|
||||
|
||||
Authenticator a = theAuthenticator;
|
||||
if (a == null) {
|
||||
return null;
|
||||
} else {
|
||||
synchronized(a) {
|
||||
a.reset();
|
||||
a.requestingSite = addr;
|
||||
a.requestingPort = port;
|
||||
a.requestingProtocol = protocol;
|
||||
a.requestingPrompt = prompt;
|
||||
a.requestingScheme = scheme;
|
||||
return a.getPasswordAuthentication();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ask the authenticator that has been registered with the system
|
||||
* for a password. This is the preferred method for requesting a password
|
||||
* because the hostname can be provided in cases where the InetAddress
|
||||
* is not available.
|
||||
* <p>
|
||||
* First, if there is a security manager, its {@code checkPermission}
|
||||
* method is called with a
|
||||
* {@code NetPermission("requestPasswordAuthentication")} permission.
|
||||
* This may result in a java.lang.SecurityException.
|
||||
*
|
||||
* @param host The hostname of the site requesting authentication.
|
||||
* @param addr The InetAddress of the site requesting authentication,
|
||||
* or null if not known.
|
||||
* @param port the port for the requested connection.
|
||||
* @param protocol The protocol that's requesting the connection
|
||||
* ({@link java.net.Authenticator#getRequestingProtocol()})
|
||||
* @param prompt A prompt string for the user which identifies the authentication realm.
|
||||
* @param scheme The authentication scheme
|
||||
*
|
||||
* @return The username/password, or null if one can't be gotten.
|
||||
*
|
||||
* @throws SecurityException
|
||||
* if a security manager exists and its
|
||||
* {@code checkPermission} method doesn't allow
|
||||
* the password authentication request.
|
||||
*
|
||||
* @see SecurityManager#checkPermission
|
||||
* @see java.net.NetPermission
|
||||
* @since 1.4
|
||||
*/
|
||||
public static PasswordAuthentication requestPasswordAuthentication(
|
||||
String host,
|
||||
InetAddress addr,
|
||||
int port,
|
||||
String protocol,
|
||||
String prompt,
|
||||
String scheme) {
|
||||
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
NetPermission requestPermission
|
||||
= new NetPermission("requestPasswordAuthentication");
|
||||
sm.checkPermission(requestPermission);
|
||||
}
|
||||
|
||||
Authenticator a = theAuthenticator;
|
||||
if (a == null) {
|
||||
return null;
|
||||
} else {
|
||||
synchronized(a) {
|
||||
a.reset();
|
||||
a.requestingHost = host;
|
||||
a.requestingSite = addr;
|
||||
a.requestingPort = port;
|
||||
a.requestingProtocol = protocol;
|
||||
a.requestingPrompt = prompt;
|
||||
a.requestingScheme = scheme;
|
||||
return a.getPasswordAuthentication();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ask the authenticator that has been registered with the system
|
||||
* for a password.
|
||||
* <p>
|
||||
* First, if there is a security manager, its {@code checkPermission}
|
||||
* method is called with a
|
||||
* {@code NetPermission("requestPasswordAuthentication")} permission.
|
||||
* This may result in a java.lang.SecurityException.
|
||||
*
|
||||
* @param host The hostname of the site requesting authentication.
|
||||
* @param addr The InetAddress of the site requesting authorization,
|
||||
* or null if not known.
|
||||
* @param port the port for the requested connection
|
||||
* @param protocol The protocol that's requesting the connection
|
||||
* ({@link java.net.Authenticator#getRequestingProtocol()})
|
||||
* @param prompt A prompt string for the user
|
||||
* @param scheme The authentication scheme
|
||||
* @param url The requesting URL that caused the authentication
|
||||
* @param reqType The type (server or proxy) of the entity requesting
|
||||
* authentication.
|
||||
*
|
||||
* @return The username/password, or null if one can't be gotten.
|
||||
*
|
||||
* @throws SecurityException
|
||||
* if a security manager exists and its
|
||||
* {@code checkPermission} method doesn't allow
|
||||
* the password authentication request.
|
||||
*
|
||||
* @see SecurityManager#checkPermission
|
||||
* @see java.net.NetPermission
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public static PasswordAuthentication requestPasswordAuthentication(
|
||||
String host,
|
||||
InetAddress addr,
|
||||
int port,
|
||||
String protocol,
|
||||
String prompt,
|
||||
String scheme,
|
||||
URL url,
|
||||
RequestorType reqType) {
|
||||
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
NetPermission requestPermission
|
||||
= new NetPermission("requestPasswordAuthentication");
|
||||
sm.checkPermission(requestPermission);
|
||||
}
|
||||
|
||||
Authenticator a = theAuthenticator;
|
||||
if (a == null) {
|
||||
return null;
|
||||
} else {
|
||||
synchronized(a) {
|
||||
a.reset();
|
||||
a.requestingHost = host;
|
||||
a.requestingSite = addr;
|
||||
a.requestingPort = port;
|
||||
a.requestingProtocol = protocol;
|
||||
a.requestingPrompt = prompt;
|
||||
a.requestingScheme = scheme;
|
||||
a.requestingURL = url;
|
||||
a.requestingAuthType = reqType;
|
||||
return a.getPasswordAuthentication();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@code hostname} of the
|
||||
* site or proxy requesting authentication, or {@code null}
|
||||
* if not available.
|
||||
*
|
||||
* @return the hostname of the connection requiring authentication, or null
|
||||
* if it's not available.
|
||||
* @since 1.4
|
||||
*/
|
||||
protected final String getRequestingHost() {
|
||||
return requestingHost;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@code InetAddress} of the
|
||||
* site requesting authorization, or {@code null}
|
||||
* if not available.
|
||||
*
|
||||
* @return the InetAddress of the site requesting authorization, or null
|
||||
* if it's not available.
|
||||
*/
|
||||
protected final InetAddress getRequestingSite() {
|
||||
return requestingSite;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the port number for the requested connection.
|
||||
* @return an {@code int} indicating the
|
||||
* port for the requested connection.
|
||||
*/
|
||||
protected final int getRequestingPort() {
|
||||
return requestingPort;
|
||||
}
|
||||
|
||||
/**
|
||||
* Give the protocol that's requesting the connection. Often this
|
||||
* will be based on a URL, but in a future JDK it could be, for
|
||||
* example, "SOCKS" for a password-protected SOCKS5 firewall.
|
||||
*
|
||||
* @return the protocol, optionally followed by "/version", where
|
||||
* version is a version number.
|
||||
*
|
||||
* @see java.net.URL#getProtocol()
|
||||
*/
|
||||
protected final String getRequestingProtocol() {
|
||||
return requestingProtocol;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the prompt string given by the requestor.
|
||||
*
|
||||
* @return the prompt string given by the requestor (realm for
|
||||
* http requests)
|
||||
*/
|
||||
protected final String getRequestingPrompt() {
|
||||
return requestingPrompt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the scheme of the requestor (the HTTP scheme
|
||||
* for an HTTP firewall, for example).
|
||||
*
|
||||
* @return the scheme of the requestor
|
||||
*
|
||||
*/
|
||||
protected final String getRequestingScheme() {
|
||||
return requestingScheme;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when password authorization is needed. Subclasses should
|
||||
* override the default implementation, which returns null.
|
||||
* @return The PasswordAuthentication collected from the
|
||||
* user, or null if none is provided.
|
||||
*/
|
||||
protected PasswordAuthentication getPasswordAuthentication() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL that resulted in this
|
||||
* request for authentication.
|
||||
*
|
||||
* @since 1.5
|
||||
*
|
||||
* @return the requesting URL
|
||||
*
|
||||
*/
|
||||
protected URL getRequestingURL () {
|
||||
return requestingURL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the requestor is a Proxy or a Server.
|
||||
*
|
||||
* @since 1.5
|
||||
*
|
||||
* @return the authentication type of the requestor
|
||||
*
|
||||
*/
|
||||
protected RequestorType getRequestorType () {
|
||||
return requestingAuthType;
|
||||
}
|
||||
}
|
||||
54
jdkSrc/jdk8/java/net/BindException.java
Normal file
54
jdkSrc/jdk8/java/net/BindException.java
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
/**
|
||||
* Signals that an error occurred while attempting to bind a
|
||||
* socket to a local address and port. Typically, the port is
|
||||
* in use, or the requested local address could not be assigned.
|
||||
*
|
||||
* @since JDK1.1
|
||||
*/
|
||||
|
||||
public class BindException extends SocketException {
|
||||
private static final long serialVersionUID = -5945005768251722951L;
|
||||
|
||||
/**
|
||||
* Constructs a new BindException with the specified detail
|
||||
* message as to why the bind error occurred.
|
||||
* A detail message is a String that gives a specific
|
||||
* description of this error.
|
||||
* @param msg the detail message
|
||||
*/
|
||||
public BindException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new BindException with no detailed message.
|
||||
*/
|
||||
public BindException() {}
|
||||
}
|
||||
63
jdkSrc/jdk8/java/net/CacheRequest.java
Normal file
63
jdkSrc/jdk8/java/net/CacheRequest.java
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Represents channels for storing resources in the
|
||||
* ResponseCache. Instances of such a class provide an
|
||||
* OutputStream object which is called by protocol handlers to
|
||||
* store the resource data into the cache, and also an abort() method
|
||||
* which allows a cache store operation to be interrupted and
|
||||
* abandoned. If an IOException is encountered while reading the
|
||||
* response or writing to the cache, the current cache store operation
|
||||
* will be aborted.
|
||||
*
|
||||
* @author Yingxian Wang
|
||||
* @since 1.5
|
||||
*/
|
||||
public abstract class CacheRequest {
|
||||
|
||||
/**
|
||||
* Returns an OutputStream to which the response body can be
|
||||
* written.
|
||||
*
|
||||
* @return an OutputStream to which the response body can
|
||||
* be written
|
||||
* @throws IOException if an I/O error occurs while
|
||||
* writing the response body
|
||||
*/
|
||||
public abstract OutputStream getBody() throws IOException;
|
||||
|
||||
/**
|
||||
* Aborts the attempt to cache the response. If an IOException is
|
||||
* encountered while reading the response or writing to the cache,
|
||||
* the current cache store operation will be abandoned.
|
||||
*/
|
||||
public abstract void abort();
|
||||
}
|
||||
64
jdkSrc/jdk8/java/net/CacheResponse.java
Normal file
64
jdkSrc/jdk8/java/net/CacheResponse.java
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.Map;
|
||||
import java.util.List;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Represent channels for retrieving resources from the
|
||||
* ResponseCache. Instances of such a class provide an
|
||||
* InputStream that returns the entity body, and also a
|
||||
* getHeaders() method which returns the associated response headers.
|
||||
*
|
||||
* @author Yingxian Wang
|
||||
* @since 1.5
|
||||
*/
|
||||
public abstract class CacheResponse {
|
||||
|
||||
/**
|
||||
* Returns the response headers as a Map.
|
||||
*
|
||||
* @return An immutable Map from response header field names to
|
||||
* lists of field values. The status line has null as its
|
||||
* field name.
|
||||
* @throws IOException if an I/O error occurs
|
||||
* while getting the response headers
|
||||
*/
|
||||
public abstract Map<String, List<String>> getHeaders() throws IOException;
|
||||
|
||||
/**
|
||||
* Returns the response body as an InputStream.
|
||||
*
|
||||
* @return an InputStream from which the response body can
|
||||
* be accessed
|
||||
* @throws IOException if an I/O error occurs while
|
||||
* getting the response body
|
||||
*/
|
||||
public abstract InputStream getBody() throws IOException;
|
||||
}
|
||||
54
jdkSrc/jdk8/java/net/ConnectException.java
Normal file
54
jdkSrc/jdk8/java/net/ConnectException.java
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
/**
|
||||
* Signals that an error occurred while attempting to connect a
|
||||
* socket to a remote address and port. Typically, the connection
|
||||
* was refused remotely (e.g., no process is listening on the
|
||||
* remote address/port).
|
||||
*
|
||||
* @since JDK1.1
|
||||
*/
|
||||
public class ConnectException extends SocketException {
|
||||
private static final long serialVersionUID = 3831404271622369215L;
|
||||
|
||||
/**
|
||||
* Constructs a new ConnectException with the specified detail
|
||||
* message as to why the connect error occurred.
|
||||
* A detail message is a String that gives a specific
|
||||
* description of this error.
|
||||
* @param msg the detail message
|
||||
*/
|
||||
public ConnectException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new ConnectException with no detailed message.
|
||||
*/
|
||||
public ConnectException() {}
|
||||
}
|
||||
111
jdkSrc/jdk8/java/net/ContentHandler.java
Normal file
111
jdkSrc/jdk8/java/net/ContentHandler.java
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* The abstract class {@code ContentHandler} is the superclass
|
||||
* of all classes that read an {@code Object} from a
|
||||
* {@code URLConnection}.
|
||||
* <p>
|
||||
* An application does not generally call the
|
||||
* {@code getContent} method in this class directly. Instead, an
|
||||
* application calls the {@code getContent} method in class
|
||||
* {@code URL} or in {@code URLConnection}.
|
||||
* The application's content handler factory (an instance of a class that
|
||||
* implements the interface {@code ContentHandlerFactory} set
|
||||
* up by a call to {@code setContentHandler}) is
|
||||
* called with a {@code String} giving the MIME type of the
|
||||
* object being received on the socket. The factory returns an
|
||||
* instance of a subclass of {@code ContentHandler}, and its
|
||||
* {@code getContent} method is called to create the object.
|
||||
* <p>
|
||||
* If no content handler could be found, URLConnection will
|
||||
* look for a content handler in a user-defineable set of places.
|
||||
* By default it looks in sun.net.www.content, but users can define a
|
||||
* vertical-bar delimited set of class prefixes to search through in
|
||||
* addition by defining the java.content.handler.pkgs property.
|
||||
* The class name must be of the form:
|
||||
* <pre>
|
||||
* {package-prefix}.{major}.{minor}
|
||||
* e.g.
|
||||
* YoyoDyne.experimental.text.plain
|
||||
* </pre>
|
||||
* If the loading of the content handler class would be performed by
|
||||
* a classloader that is outside of the delegation chain of the caller,
|
||||
* the JVM will need the RuntimePermission "getClassLoader".
|
||||
*
|
||||
* @author James Gosling
|
||||
* @see java.net.ContentHandler#getContent(java.net.URLConnection)
|
||||
* @see java.net.ContentHandlerFactory
|
||||
* @see java.net.URL#getContent()
|
||||
* @see java.net.URLConnection
|
||||
* @see java.net.URLConnection#getContent()
|
||||
* @see java.net.URLConnection#setContentHandlerFactory(java.net.ContentHandlerFactory)
|
||||
* @since JDK1.0
|
||||
*/
|
||||
abstract public class ContentHandler {
|
||||
/**
|
||||
* Given a URL connect stream positioned at the beginning of the
|
||||
* representation of an object, this method reads that stream and
|
||||
* creates an object from it.
|
||||
*
|
||||
* @param urlc a URL connection.
|
||||
* @return the object read by the {@code ContentHandler}.
|
||||
* @exception IOException if an I/O error occurs while reading the object.
|
||||
*/
|
||||
abstract public Object getContent(URLConnection urlc) throws IOException;
|
||||
|
||||
/**
|
||||
* Given a URL connect stream positioned at the beginning of the
|
||||
* representation of an object, this method reads that stream and
|
||||
* creates an object that matches one of the types specified.
|
||||
*
|
||||
* The default implementation of this method should call getContent()
|
||||
* and screen the return type for a match of the suggested types.
|
||||
*
|
||||
* @param urlc a URL connection.
|
||||
* @param classes an array of types requested
|
||||
* @return the object read by the {@code ContentHandler} that is
|
||||
* the first match of the suggested types.
|
||||
* null if none of the requested are supported.
|
||||
* @exception IOException if an I/O error occurs while reading the object.
|
||||
* @since 1.3
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public Object getContent(URLConnection urlc, Class[] classes) throws IOException {
|
||||
Object obj = getContent(urlc);
|
||||
|
||||
for (int i = 0; i < classes.length; i++) {
|
||||
if (classes[i].isInstance(obj)) {
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
54
jdkSrc/jdk8/java/net/ContentHandlerFactory.java
Normal file
54
jdkSrc/jdk8/java/net/ContentHandlerFactory.java
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
/**
|
||||
* This interface defines a factory for content handlers. An
|
||||
* implementation of this interface should map a MIME type into an
|
||||
* instance of {@code ContentHandler}.
|
||||
* <p>
|
||||
* This interface is used by the {@code URLStreamHandler} class
|
||||
* to create a {@code ContentHandler} for a MIME type.
|
||||
*
|
||||
* @author James Gosling
|
||||
* @see java.net.ContentHandler
|
||||
* @see java.net.URLStreamHandler
|
||||
* @since JDK1.0
|
||||
*/
|
||||
public interface ContentHandlerFactory {
|
||||
/**
|
||||
* Creates a new {@code ContentHandler} to read an object from
|
||||
* a {@code URLStreamHandler}.
|
||||
*
|
||||
* @param mimetype the MIME type for which a content handler is desired.
|
||||
|
||||
* @return a new {@code ContentHandler} to read an object from a
|
||||
* {@code URLStreamHandler}.
|
||||
* @see java.net.ContentHandler
|
||||
* @see java.net.URLStreamHandler
|
||||
*/
|
||||
ContentHandler createContentHandler(String mimetype);
|
||||
}
|
||||
150
jdkSrc/jdk8/java/net/CookieHandler.java
Normal file
150
jdkSrc/jdk8/java/net/CookieHandler.java
Normal file
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.List;
|
||||
import java.io.IOException;
|
||||
import sun.security.util.SecurityConstants;
|
||||
|
||||
/**
|
||||
* A CookieHandler object provides a callback mechanism to hook up a
|
||||
* HTTP state management policy implementation into the HTTP protocol
|
||||
* handler. The HTTP state management mechanism specifies a way to
|
||||
* create a stateful session with HTTP requests and responses.
|
||||
*
|
||||
* <p>A system-wide CookieHandler that to used by the HTTP protocol
|
||||
* handler can be registered by doing a
|
||||
* CookieHandler.setDefault(CookieHandler). The currently registered
|
||||
* CookieHandler can be retrieved by calling
|
||||
* CookieHandler.getDefault().
|
||||
*
|
||||
* For more information on HTTP state management, see <a
|
||||
* href="http://www.ietf.org/rfc/rfc2965.txt"><i>RFC 2965: HTTP
|
||||
* State Management Mechanism</i></a>
|
||||
*
|
||||
* @author Yingxian Wang
|
||||
* @since 1.5
|
||||
*/
|
||||
public abstract class CookieHandler {
|
||||
/**
|
||||
* The system-wide cookie handler that will apply cookies to the
|
||||
* request headers and manage cookies from the response headers.
|
||||
*
|
||||
* @see setDefault(CookieHandler)
|
||||
* @see getDefault()
|
||||
*/
|
||||
private static CookieHandler cookieHandler;
|
||||
|
||||
/**
|
||||
* Gets the system-wide cookie handler.
|
||||
*
|
||||
* @return the system-wide cookie handler; A null return means
|
||||
* there is no system-wide cookie handler currently set.
|
||||
* @throws SecurityException
|
||||
* If a security manager has been installed and it denies
|
||||
* {@link NetPermission}{@code ("getCookieHandler")}
|
||||
* @see #setDefault(CookieHandler)
|
||||
*/
|
||||
public synchronized static CookieHandler getDefault() {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
sm.checkPermission(SecurityConstants.GET_COOKIEHANDLER_PERMISSION);
|
||||
}
|
||||
return cookieHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets (or unsets) the system-wide cookie handler.
|
||||
*
|
||||
* Note: non-standard http protocol handlers may ignore this setting.
|
||||
*
|
||||
* @param cHandler The HTTP cookie handler, or
|
||||
* {@code null} to unset.
|
||||
* @throws SecurityException
|
||||
* If a security manager has been installed and it denies
|
||||
* {@link NetPermission}{@code ("setCookieHandler")}
|
||||
* @see #getDefault()
|
||||
*/
|
||||
public synchronized static void setDefault(CookieHandler cHandler) {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
sm.checkPermission(SecurityConstants.SET_COOKIEHANDLER_PERMISSION);
|
||||
}
|
||||
cookieHandler = cHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all the applicable cookies from a cookie cache for the
|
||||
* specified uri in the request header.
|
||||
*
|
||||
* <P>The {@code URI} passed as an argument specifies the intended use for
|
||||
* the cookies. In particular the scheme should reflect whether the cookies
|
||||
* will be sent over http, https or used in another context like javascript.
|
||||
* The host part should reflect either the destination of the cookies or
|
||||
* their origin in the case of javascript.</P>
|
||||
* <P>It is up to the implementation to take into account the {@code URI} and
|
||||
* the cookies attributes and security settings to determine which ones
|
||||
* should be returned.</P>
|
||||
*
|
||||
* <P>HTTP protocol implementers should make sure that this method is
|
||||
* called after all request headers related to choosing cookies
|
||||
* are added, and before the request is sent.</P>
|
||||
*
|
||||
* @param uri a {@code URI} representing the intended use for the
|
||||
* cookies
|
||||
* @param requestHeaders - a Map from request header
|
||||
* field names to lists of field values representing
|
||||
* the current request headers
|
||||
* @return an immutable map from state management headers, with
|
||||
* field names "Cookie" or "Cookie2" to a list of
|
||||
* cookies containing state information
|
||||
*
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws IllegalArgumentException if either argument is null
|
||||
* @see #put(URI, Map)
|
||||
*/
|
||||
public abstract Map<String, List<String>>
|
||||
get(URI uri, Map<String, List<String>> requestHeaders)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Sets all the applicable cookies, examples are response header
|
||||
* fields that are named Set-Cookie2, present in the response
|
||||
* headers into a cookie cache.
|
||||
*
|
||||
* @param uri a {@code URI} where the cookies come from
|
||||
* @param responseHeaders an immutable map from field names to
|
||||
* lists of field values representing the response
|
||||
* header fields returned
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws IllegalArgumentException if either argument is null
|
||||
* @see #get(URI, Map)
|
||||
*/
|
||||
public abstract void
|
||||
put(URI uri, Map<String, List<String>> responseHeaders)
|
||||
throws IOException;
|
||||
}
|
||||
448
jdkSrc/jdk8/java/net/CookieManager.java
Normal file
448
jdkSrc/jdk8/java/net/CookieManager.java
Normal file
@@ -0,0 +1,448 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.List;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.io.IOException;
|
||||
import sun.util.logging.PlatformLogger;
|
||||
|
||||
/**
|
||||
* CookieManager provides a concrete implementation of {@link CookieHandler},
|
||||
* which separates the storage of cookies from the policy surrounding accepting
|
||||
* and rejecting cookies. A CookieManager is initialized with a {@link CookieStore}
|
||||
* which manages storage, and a {@link CookiePolicy} object, which makes
|
||||
* policy decisions on cookie acceptance/rejection.
|
||||
*
|
||||
* <p> The HTTP cookie management in java.net package looks like:
|
||||
* <blockquote>
|
||||
* <pre>{@code
|
||||
* use
|
||||
* CookieHandler <------- HttpURLConnection
|
||||
* ^
|
||||
* | impl
|
||||
* | use
|
||||
* CookieManager -------> CookiePolicy
|
||||
* | use
|
||||
* |--------> HttpCookie
|
||||
* | ^
|
||||
* | | use
|
||||
* | use |
|
||||
* |--------> CookieStore
|
||||
* ^
|
||||
* | impl
|
||||
* |
|
||||
* Internal in-memory implementation
|
||||
* }</pre>
|
||||
* <ul>
|
||||
* <li>
|
||||
* CookieHandler is at the core of cookie management. User can call
|
||||
* CookieHandler.setDefault to set a concrete CookieHanlder implementation
|
||||
* to be used.
|
||||
* </li>
|
||||
* <li>
|
||||
* CookiePolicy.shouldAccept will be called by CookieManager.put to see whether
|
||||
* or not one cookie should be accepted and put into cookie store. User can use
|
||||
* any of three pre-defined CookiePolicy, namely ACCEPT_ALL, ACCEPT_NONE and
|
||||
* ACCEPT_ORIGINAL_SERVER, or user can define his own CookiePolicy implementation
|
||||
* and tell CookieManager to use it.
|
||||
* </li>
|
||||
* <li>
|
||||
* CookieStore is the place where any accepted HTTP cookie is stored in.
|
||||
* If not specified when created, a CookieManager instance will use an internal
|
||||
* in-memory implementation. Or user can implements one and tell CookieManager
|
||||
* to use it.
|
||||
* </li>
|
||||
* <li>
|
||||
* Currently, only CookieStore.add(URI, HttpCookie) and CookieStore.get(URI)
|
||||
* are used by CookieManager. Others are for completeness and might be needed
|
||||
* by a more sophisticated CookieStore implementation, e.g. a NetscapeCookieSotre.
|
||||
* </li>
|
||||
* </ul>
|
||||
* </blockquote>
|
||||
*
|
||||
* <p>There're various ways user can hook up his own HTTP cookie management behavior, e.g.
|
||||
* <blockquote>
|
||||
* <ul>
|
||||
* <li>Use CookieHandler.setDefault to set a brand new {@link CookieHandler} implementation
|
||||
* <li>Let CookieManager be the default {@link CookieHandler} implementation,
|
||||
* but implement user's own {@link CookieStore} and {@link CookiePolicy}
|
||||
* and tell default CookieManager to use them:
|
||||
* <blockquote><pre>
|
||||
* // this should be done at the beginning of an HTTP session
|
||||
* CookieHandler.setDefault(new CookieManager(new MyCookieStore(), new MyCookiePolicy()));
|
||||
* </pre></blockquote>
|
||||
* <li>Let CookieManager be the default {@link CookieHandler} implementation, but
|
||||
* use customized {@link CookiePolicy}:
|
||||
* <blockquote><pre>
|
||||
* // this should be done at the beginning of an HTTP session
|
||||
* CookieHandler.setDefault(new CookieManager());
|
||||
* // this can be done at any point of an HTTP session
|
||||
* ((CookieManager)CookieHandler.getDefault()).setCookiePolicy(new MyCookiePolicy());
|
||||
* </pre></blockquote>
|
||||
* </ul>
|
||||
* </blockquote>
|
||||
*
|
||||
* <p>The implementation conforms to <a href="http://www.ietf.org/rfc/rfc2965.txt">RFC 2965</a>, section 3.3.
|
||||
*
|
||||
* @see CookiePolicy
|
||||
* @author Edward Wang
|
||||
* @since 1.6
|
||||
*/
|
||||
public class CookieManager extends CookieHandler
|
||||
{
|
||||
/* ---------------- Fields -------------- */
|
||||
|
||||
private CookiePolicy policyCallback;
|
||||
|
||||
|
||||
private CookieStore cookieJar = null;
|
||||
|
||||
|
||||
/* ---------------- Ctors -------------- */
|
||||
|
||||
/**
|
||||
* Create a new cookie manager.
|
||||
*
|
||||
* <p>This constructor will create new cookie manager with default
|
||||
* cookie store and accept policy. The effect is same as
|
||||
* {@code CookieManager(null, null)}.
|
||||
*/
|
||||
public CookieManager() {
|
||||
this(null, null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a new cookie manager with specified cookie store and cookie policy.
|
||||
*
|
||||
* @param store a {@code CookieStore} to be used by cookie manager.
|
||||
* if {@code null}, cookie manager will use a default one,
|
||||
* which is an in-memory CookieStore implementation.
|
||||
* @param cookiePolicy a {@code CookiePolicy} instance
|
||||
* to be used by cookie manager as policy callback.
|
||||
* if {@code null}, ACCEPT_ORIGINAL_SERVER will
|
||||
* be used.
|
||||
*/
|
||||
public CookieManager(CookieStore store,
|
||||
CookiePolicy cookiePolicy)
|
||||
{
|
||||
// use default cookie policy if not specify one
|
||||
policyCallback = (cookiePolicy == null) ? CookiePolicy.ACCEPT_ORIGINAL_SERVER
|
||||
: cookiePolicy;
|
||||
|
||||
// if not specify CookieStore to use, use default one
|
||||
if (store == null) {
|
||||
cookieJar = new InMemoryCookieStore();
|
||||
} else {
|
||||
cookieJar = store;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ---------------- Public operations -------------- */
|
||||
|
||||
/**
|
||||
* To set the cookie policy of this cookie manager.
|
||||
*
|
||||
* <p> A instance of {@code CookieManager} will have
|
||||
* cookie policy ACCEPT_ORIGINAL_SERVER by default. Users always
|
||||
* can call this method to set another cookie policy.
|
||||
*
|
||||
* @param cookiePolicy the cookie policy. Can be {@code null}, which
|
||||
* has no effects on current cookie policy.
|
||||
*/
|
||||
public void setCookiePolicy(CookiePolicy cookiePolicy) {
|
||||
if (cookiePolicy != null) policyCallback = cookiePolicy;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* To retrieve current cookie store.
|
||||
*
|
||||
* @return the cookie store currently used by cookie manager.
|
||||
*/
|
||||
public CookieStore getCookieStore() {
|
||||
return cookieJar;
|
||||
}
|
||||
|
||||
|
||||
public Map<String, List<String>>
|
||||
get(URI uri, Map<String, List<String>> requestHeaders)
|
||||
throws IOException
|
||||
{
|
||||
// pre-condition check
|
||||
if (uri == null || requestHeaders == null) {
|
||||
throw new IllegalArgumentException("Argument is null");
|
||||
}
|
||||
|
||||
Map<String, List<String>> cookieMap =
|
||||
new java.util.HashMap<String, List<String>>();
|
||||
// if there's no default CookieStore, no way for us to get any cookie
|
||||
if (cookieJar == null)
|
||||
return Collections.unmodifiableMap(cookieMap);
|
||||
|
||||
boolean secureLink = "https".equalsIgnoreCase(uri.getScheme());
|
||||
List<HttpCookie> cookies = new java.util.ArrayList<HttpCookie>();
|
||||
String path = uri.getPath();
|
||||
if (path == null || path.isEmpty()) {
|
||||
path = "/";
|
||||
}
|
||||
for (HttpCookie cookie : cookieJar.get(uri)) {
|
||||
// apply path-matches rule (RFC 2965 sec. 3.3.4)
|
||||
// and check for the possible "secure" tag (i.e. don't send
|
||||
// 'secure' cookies over unsecure links)
|
||||
if (pathMatches(path, cookie.getPath()) &&
|
||||
(secureLink || !cookie.getSecure())) {
|
||||
// Enforce httponly attribute
|
||||
if (cookie.isHttpOnly()) {
|
||||
String s = uri.getScheme();
|
||||
if (!"http".equalsIgnoreCase(s) && !"https".equalsIgnoreCase(s)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// Let's check the authorize port list if it exists
|
||||
String ports = cookie.getPortlist();
|
||||
if (ports != null && !ports.isEmpty()) {
|
||||
int port = uri.getPort();
|
||||
if (port == -1) {
|
||||
port = "https".equals(uri.getScheme()) ? 443 : 80;
|
||||
}
|
||||
if (isInPortList(ports, port)) {
|
||||
cookies.add(cookie);
|
||||
}
|
||||
} else {
|
||||
cookies.add(cookie);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// apply sort rule (RFC 2965 sec. 3.3.4)
|
||||
List<String> cookieHeader = sortByPath(cookies);
|
||||
|
||||
cookieMap.put("Cookie", cookieHeader);
|
||||
return Collections.unmodifiableMap(cookieMap);
|
||||
}
|
||||
|
||||
public void
|
||||
put(URI uri, Map<String, List<String>> responseHeaders)
|
||||
throws IOException
|
||||
{
|
||||
// pre-condition check
|
||||
if (uri == null || responseHeaders == null) {
|
||||
throw new IllegalArgumentException("Argument is null");
|
||||
}
|
||||
|
||||
|
||||
// if there's no default CookieStore, no need to remember any cookie
|
||||
if (cookieJar == null)
|
||||
return;
|
||||
|
||||
PlatformLogger logger = PlatformLogger.getLogger("java.net.CookieManager");
|
||||
for (String headerKey : responseHeaders.keySet()) {
|
||||
// RFC 2965 3.2.2, key must be 'Set-Cookie2'
|
||||
// we also accept 'Set-Cookie' here for backward compatibility
|
||||
if (headerKey == null
|
||||
|| !(headerKey.equalsIgnoreCase("Set-Cookie2")
|
||||
|| headerKey.equalsIgnoreCase("Set-Cookie")
|
||||
)
|
||||
)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (String headerValue : responseHeaders.get(headerKey)) {
|
||||
try {
|
||||
List<HttpCookie> cookies;
|
||||
try {
|
||||
cookies = HttpCookie.parse(headerValue);
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Bogus header, make an empty list and log the error
|
||||
cookies = java.util.Collections.emptyList();
|
||||
if (logger.isLoggable(PlatformLogger.Level.SEVERE)) {
|
||||
logger.severe("Invalid cookie for " + uri + ": " + headerValue);
|
||||
}
|
||||
}
|
||||
for (HttpCookie cookie : cookies) {
|
||||
if (cookie.getPath() == null) {
|
||||
// If no path is specified, then by default
|
||||
// the path is the directory of the page/doc
|
||||
String path = uri.getPath();
|
||||
if (!path.endsWith("/")) {
|
||||
int i = path.lastIndexOf("/");
|
||||
if (i > 0) {
|
||||
path = path.substring(0, i + 1);
|
||||
} else {
|
||||
path = "/";
|
||||
}
|
||||
}
|
||||
cookie.setPath(path);
|
||||
}
|
||||
|
||||
// As per RFC 2965, section 3.3.1:
|
||||
// Domain Defaults to the effective request-host. (Note that because
|
||||
// there is no dot at the beginning of effective request-host,
|
||||
// the default Domain can only domain-match itself.)
|
||||
if (cookie.getDomain() == null) {
|
||||
String host = uri.getHost();
|
||||
if (host != null && !host.contains("."))
|
||||
host += ".local";
|
||||
cookie.setDomain(host);
|
||||
}
|
||||
String ports = cookie.getPortlist();
|
||||
if (ports != null) {
|
||||
int port = uri.getPort();
|
||||
if (port == -1) {
|
||||
port = "https".equals(uri.getScheme()) ? 443 : 80;
|
||||
}
|
||||
if (ports.isEmpty()) {
|
||||
// Empty port list means this should be restricted
|
||||
// to the incoming URI port
|
||||
cookie.setPortlist("" + port );
|
||||
if (shouldAcceptInternal(uri, cookie)) {
|
||||
cookieJar.add(uri, cookie);
|
||||
}
|
||||
} else {
|
||||
// Only store cookies with a port list
|
||||
// IF the URI port is in that list, as per
|
||||
// RFC 2965 section 3.3.2
|
||||
if (isInPortList(ports, port) &&
|
||||
shouldAcceptInternal(uri, cookie)) {
|
||||
cookieJar.add(uri, cookie);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (shouldAcceptInternal(uri, cookie)) {
|
||||
cookieJar.add(uri, cookie);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
// invalid set-cookie header string
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ---------------- Private operations -------------- */
|
||||
|
||||
// to determine whether or not accept this cookie
|
||||
private boolean shouldAcceptInternal(URI uri, HttpCookie cookie) {
|
||||
try {
|
||||
return policyCallback.shouldAccept(uri, cookie);
|
||||
} catch (Exception ignored) { // pretect against malicious callback
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static private boolean isInPortList(String lst, int port) {
|
||||
int i = lst.indexOf(",");
|
||||
int val = -1;
|
||||
while (i > 0) {
|
||||
try {
|
||||
val = Integer.parseInt(lst.substring(0, i));
|
||||
if (val == port) {
|
||||
return true;
|
||||
}
|
||||
} catch (NumberFormatException numberFormatException) {
|
||||
}
|
||||
lst = lst.substring(i+1);
|
||||
i = lst.indexOf(",");
|
||||
}
|
||||
if (!lst.isEmpty()) {
|
||||
try {
|
||||
val = Integer.parseInt(lst);
|
||||
if (val == port) {
|
||||
return true;
|
||||
}
|
||||
} catch (NumberFormatException numberFormatException) {
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* path-matches algorithm, as defined by RFC 2965
|
||||
*/
|
||||
private boolean pathMatches(String path, String pathToMatchWith) {
|
||||
if (path == pathToMatchWith)
|
||||
return true;
|
||||
if (path == null || pathToMatchWith == null)
|
||||
return false;
|
||||
if (path.startsWith(pathToMatchWith))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* sort cookies with respect to their path: those with more specific Path attributes
|
||||
* precede those with less specific, as defined in RFC 2965 sec. 3.3.4
|
||||
*/
|
||||
private List<String> sortByPath(List<HttpCookie> cookies) {
|
||||
Collections.sort(cookies, new CookiePathComparator());
|
||||
|
||||
List<String> cookieHeader = new java.util.ArrayList<String>();
|
||||
for (HttpCookie cookie : cookies) {
|
||||
// Netscape cookie spec and RFC 2965 have different format of Cookie
|
||||
// header; RFC 2965 requires a leading $Version="1" string while Netscape
|
||||
// does not.
|
||||
// The workaround here is to add a $Version="1" string in advance
|
||||
if (cookies.indexOf(cookie) == 0 && cookie.getVersion() > 0) {
|
||||
cookieHeader.add("$Version=\"1\"");
|
||||
}
|
||||
|
||||
cookieHeader.add(cookie.toString());
|
||||
}
|
||||
return cookieHeader;
|
||||
}
|
||||
|
||||
|
||||
static class CookiePathComparator implements Comparator<HttpCookie> {
|
||||
public int compare(HttpCookie c1, HttpCookie c2) {
|
||||
if (c1 == c2) return 0;
|
||||
if (c1 == null) return -1;
|
||||
if (c2 == null) return 1;
|
||||
|
||||
// path rule only applies to the cookies with same name
|
||||
if (!c1.getName().equals(c2.getName())) return 0;
|
||||
|
||||
// those with more specific Path attributes precede those with less specific
|
||||
if (c1.getPath().startsWith(c2.getPath()))
|
||||
return -1;
|
||||
else if (c2.getPath().startsWith(c1.getPath()))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
78
jdkSrc/jdk8/java/net/CookiePolicy.java
Normal file
78
jdkSrc/jdk8/java/net/CookiePolicy.java
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
/**
|
||||
* CookiePolicy implementations decide which cookies should be accepted
|
||||
* and which should be rejected. Three pre-defined policy implementations
|
||||
* are provided, namely ACCEPT_ALL, ACCEPT_NONE and ACCEPT_ORIGINAL_SERVER.
|
||||
*
|
||||
* <p>See RFC 2965 sec. 3.3 and 7 for more detail.
|
||||
*
|
||||
* @author Edward Wang
|
||||
* @since 1.6
|
||||
*/
|
||||
public interface CookiePolicy {
|
||||
/**
|
||||
* One pre-defined policy which accepts all cookies.
|
||||
*/
|
||||
public static final CookiePolicy ACCEPT_ALL = new CookiePolicy(){
|
||||
public boolean shouldAccept(URI uri, HttpCookie cookie) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* One pre-defined policy which accepts no cookies.
|
||||
*/
|
||||
public static final CookiePolicy ACCEPT_NONE = new CookiePolicy(){
|
||||
public boolean shouldAccept(URI uri, HttpCookie cookie) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* One pre-defined policy which only accepts cookies from original server.
|
||||
*/
|
||||
public static final CookiePolicy ACCEPT_ORIGINAL_SERVER = new CookiePolicy(){
|
||||
public boolean shouldAccept(URI uri, HttpCookie cookie) {
|
||||
if (uri == null || cookie == null)
|
||||
return false;
|
||||
return HttpCookie.domainMatches(cookie.getDomain(), uri.getHost());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Will be called to see whether or not this cookie should be accepted.
|
||||
*
|
||||
* @param uri the URI to consult accept policy with
|
||||
* @param cookie the HttpCookie object in question
|
||||
* @return {@code true} if this cookie should be accepted;
|
||||
* otherwise, {@code false}
|
||||
*/
|
||||
public boolean shouldAccept(URI uri, HttpCookie cookie);
|
||||
}
|
||||
129
jdkSrc/jdk8/java/net/CookieStore.java
Normal file
129
jdkSrc/jdk8/java/net/CookieStore.java
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A CookieStore object represents a storage for cookie. Can store and retrieve
|
||||
* cookies.
|
||||
*
|
||||
* <p>{@link CookieManager} will call {@code CookieStore.add} to save cookies
|
||||
* for every incoming HTTP response, and call {@code CookieStore.get} to
|
||||
* retrieve cookie for every outgoing HTTP request. A CookieStore
|
||||
* is responsible for removing HttpCookie instances which have expired.
|
||||
*
|
||||
* @author Edward Wang
|
||||
* @since 1.6
|
||||
*/
|
||||
public interface CookieStore {
|
||||
/**
|
||||
* Adds one HTTP cookie to the store. This is called for every
|
||||
* incoming HTTP response.
|
||||
*
|
||||
* <p>A cookie to store may or may not be associated with an URI. If it
|
||||
* is not associated with an URI, the cookie's domain and path attribute
|
||||
* will indicate where it comes from. If it is associated with an URI and
|
||||
* its domain and path attribute are not specified, given URI will indicate
|
||||
* where this cookie comes from.
|
||||
*
|
||||
* <p>If a cookie corresponding to the given URI already exists,
|
||||
* then it is replaced with the new one.
|
||||
*
|
||||
* @param uri the uri this cookie associated with.
|
||||
* if {@code null}, this cookie will not be associated
|
||||
* with an URI
|
||||
* @param cookie the cookie to store
|
||||
*
|
||||
* @throws NullPointerException if {@code cookie} is {@code null}
|
||||
*
|
||||
* @see #get
|
||||
*
|
||||
*/
|
||||
public void add(URI uri, HttpCookie cookie);
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve cookies associated with given URI, or whose domain matches the
|
||||
* given URI. Only cookies that have not expired are returned.
|
||||
* This is called for every outgoing HTTP request.
|
||||
*
|
||||
* @return an immutable list of HttpCookie,
|
||||
* return empty list if no cookies match the given URI
|
||||
*
|
||||
* @param uri the uri associated with the cookies to be returned
|
||||
*
|
||||
* @throws NullPointerException if {@code uri} is {@code null}
|
||||
*
|
||||
* @see #add
|
||||
*
|
||||
*/
|
||||
public List<HttpCookie> get(URI uri);
|
||||
|
||||
|
||||
/**
|
||||
* Get all not-expired cookies in cookie store.
|
||||
*
|
||||
* @return an immutable list of http cookies;
|
||||
* return empty list if there's no http cookie in store
|
||||
*/
|
||||
public List<HttpCookie> getCookies();
|
||||
|
||||
|
||||
/**
|
||||
* Get all URIs which identify the cookies in this cookie store.
|
||||
*
|
||||
* @return an immutable list of URIs;
|
||||
* return empty list if no cookie in this cookie store
|
||||
* is associated with an URI
|
||||
*/
|
||||
public List<URI> getURIs();
|
||||
|
||||
|
||||
/**
|
||||
* Remove a cookie from store.
|
||||
*
|
||||
* @param uri the uri this cookie associated with.
|
||||
* if {@code null}, the cookie to be removed is not associated
|
||||
* with an URI when added; if not {@code null}, the cookie
|
||||
* to be removed is associated with the given URI when added.
|
||||
* @param cookie the cookie to remove
|
||||
*
|
||||
* @return {@code true} if this store contained the specified cookie
|
||||
*
|
||||
* @throws NullPointerException if {@code cookie} is {@code null}
|
||||
*/
|
||||
public boolean remove(URI uri, HttpCookie cookie);
|
||||
|
||||
|
||||
/**
|
||||
* Remove all cookies in this cookie store.
|
||||
*
|
||||
* @return {@code true} if this store changed as a result of the call
|
||||
*/
|
||||
public boolean removeAll();
|
||||
}
|
||||
388
jdkSrc/jdk8/java/net/DatagramPacket.java
Normal file
388
jdkSrc/jdk8/java/net/DatagramPacket.java
Normal file
@@ -0,0 +1,388 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
/**
|
||||
* This class represents a datagram packet.
|
||||
* <p>
|
||||
* Datagram packets are used to implement a connectionless packet
|
||||
* delivery service. Each message is routed from one machine to
|
||||
* another based solely on information contained within that packet.
|
||||
* Multiple packets sent from one machine to another might be routed
|
||||
* differently, and might arrive in any order. Packet delivery is
|
||||
* not guaranteed.
|
||||
*
|
||||
* @author Pavani Diwanji
|
||||
* @author Benjamin Renaud
|
||||
* @since JDK1.0
|
||||
*/
|
||||
public final
|
||||
class DatagramPacket {
|
||||
|
||||
/**
|
||||
* Perform class initialization
|
||||
*/
|
||||
static {
|
||||
java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
System.loadLibrary("net");
|
||||
return null;
|
||||
}
|
||||
});
|
||||
init();
|
||||
}
|
||||
|
||||
/*
|
||||
* The fields of this class are package-private since DatagramSocketImpl
|
||||
* classes needs to access them.
|
||||
*/
|
||||
byte[] buf;
|
||||
int offset;
|
||||
int length;
|
||||
int bufLength;
|
||||
InetAddress address;
|
||||
int port;
|
||||
|
||||
/**
|
||||
* Constructs a {@code DatagramPacket} for receiving packets of
|
||||
* length {@code length}, specifying an offset into the buffer.
|
||||
* <p>
|
||||
* The {@code length} argument must be less than or equal to
|
||||
* {@code buf.length}.
|
||||
*
|
||||
* @param buf buffer for holding the incoming datagram.
|
||||
* @param offset the offset for the buffer
|
||||
* @param length the number of bytes to read.
|
||||
*
|
||||
* @since 1.2
|
||||
*/
|
||||
public DatagramPacket(byte buf[], int offset, int length) {
|
||||
setData(buf, offset, length);
|
||||
this.address = null;
|
||||
this.port = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a {@code DatagramPacket} for receiving packets of
|
||||
* length {@code length}.
|
||||
* <p>
|
||||
* The {@code length} argument must be less than or equal to
|
||||
* {@code buf.length}.
|
||||
*
|
||||
* @param buf buffer for holding the incoming datagram.
|
||||
* @param length the number of bytes to read.
|
||||
*/
|
||||
public DatagramPacket(byte buf[], int length) {
|
||||
this (buf, 0, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a datagram packet for sending packets of length
|
||||
* {@code length} with offset {@code ioffset}to the
|
||||
* specified port number on the specified host. The
|
||||
* {@code length} argument must be less than or equal to
|
||||
* {@code buf.length}.
|
||||
*
|
||||
* @param buf the packet data.
|
||||
* @param offset the packet data offset.
|
||||
* @param length the packet data length.
|
||||
* @param address the destination address.
|
||||
* @param port the destination port number.
|
||||
* @see java.net.InetAddress
|
||||
*
|
||||
* @since 1.2
|
||||
*/
|
||||
public DatagramPacket(byte buf[], int offset, int length,
|
||||
InetAddress address, int port) {
|
||||
setData(buf, offset, length);
|
||||
setAddress(address);
|
||||
setPort(port);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a datagram packet for sending packets of length
|
||||
* {@code length} with offset {@code ioffset}to the
|
||||
* specified port number on the specified host. The
|
||||
* {@code length} argument must be less than or equal to
|
||||
* {@code buf.length}.
|
||||
*
|
||||
* @param buf the packet data.
|
||||
* @param offset the packet data offset.
|
||||
* @param length the packet data length.
|
||||
* @param address the destination socket address.
|
||||
* @throws IllegalArgumentException if address type is not supported
|
||||
* @see java.net.InetAddress
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
public DatagramPacket(byte buf[], int offset, int length, SocketAddress address) {
|
||||
setData(buf, offset, length);
|
||||
setSocketAddress(address);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a datagram packet for sending packets of length
|
||||
* {@code length} to the specified port number on the specified
|
||||
* host. The {@code length} argument must be less than or equal
|
||||
* to {@code buf.length}.
|
||||
*
|
||||
* @param buf the packet data.
|
||||
* @param length the packet length.
|
||||
* @param address the destination address.
|
||||
* @param port the destination port number.
|
||||
* @see java.net.InetAddress
|
||||
*/
|
||||
public DatagramPacket(byte buf[], int length,
|
||||
InetAddress address, int port) {
|
||||
this(buf, 0, length, address, port);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a datagram packet for sending packets of length
|
||||
* {@code length} to the specified port number on the specified
|
||||
* host. The {@code length} argument must be less than or equal
|
||||
* to {@code buf.length}.
|
||||
*
|
||||
* @param buf the packet data.
|
||||
* @param length the packet length.
|
||||
* @param address the destination address.
|
||||
* @throws IllegalArgumentException if address type is not supported
|
||||
* @since 1.4
|
||||
* @see java.net.InetAddress
|
||||
*/
|
||||
public DatagramPacket(byte buf[], int length, SocketAddress address) {
|
||||
this(buf, 0, length, address);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the IP address of the machine to which this datagram is being
|
||||
* sent or from which the datagram was received.
|
||||
*
|
||||
* @return the IP address of the machine to which this datagram is being
|
||||
* sent or from which the datagram was received.
|
||||
* @see java.net.InetAddress
|
||||
* @see #setAddress(java.net.InetAddress)
|
||||
*/
|
||||
public synchronized InetAddress getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the port number on the remote host to which this datagram is
|
||||
* being sent or from which the datagram was received.
|
||||
*
|
||||
* @return the port number on the remote host to which this datagram is
|
||||
* being sent or from which the datagram was received.
|
||||
* @see #setPort(int)
|
||||
*/
|
||||
public synchronized int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data buffer. The data received or the data to be sent
|
||||
* starts from the {@code offset} in the buffer,
|
||||
* and runs for {@code length} long.
|
||||
*
|
||||
* @return the buffer used to receive or send data
|
||||
* @see #setData(byte[], int, int)
|
||||
*/
|
||||
public synchronized byte[] getData() {
|
||||
return buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the offset of the data to be sent or the offset of the
|
||||
* data received.
|
||||
*
|
||||
* @return the offset of the data to be sent or the offset of the
|
||||
* data received.
|
||||
*
|
||||
* @since 1.2
|
||||
*/
|
||||
public synchronized int getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length of the data to be sent or the length of the
|
||||
* data received.
|
||||
*
|
||||
* @return the length of the data to be sent or the length of the
|
||||
* data received.
|
||||
* @see #setLength(int)
|
||||
*/
|
||||
public synchronized int getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the data buffer for this packet. This sets the
|
||||
* data, length and offset of the packet.
|
||||
*
|
||||
* @param buf the buffer to set for this packet
|
||||
*
|
||||
* @param offset the offset into the data
|
||||
*
|
||||
* @param length the length of the data
|
||||
* and/or the length of the buffer used to receive data
|
||||
*
|
||||
* @exception NullPointerException if the argument is null
|
||||
*
|
||||
* @see #getData
|
||||
* @see #getOffset
|
||||
* @see #getLength
|
||||
*
|
||||
* @since 1.2
|
||||
*/
|
||||
public synchronized void setData(byte[] buf, int offset, int length) {
|
||||
/* this will check to see if buf is null */
|
||||
if (length < 0 || offset < 0 ||
|
||||
(length + offset) < 0 ||
|
||||
((length + offset) > buf.length)) {
|
||||
throw new IllegalArgumentException("illegal length or offset");
|
||||
}
|
||||
this.buf = buf;
|
||||
this.length = length;
|
||||
this.bufLength = length;
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the IP address of the machine to which this datagram
|
||||
* is being sent.
|
||||
* @param iaddr the {@code InetAddress}
|
||||
* @since JDK1.1
|
||||
* @see #getAddress()
|
||||
*/
|
||||
public synchronized void setAddress(InetAddress iaddr) {
|
||||
address = iaddr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the port number on the remote host to which this datagram
|
||||
* is being sent.
|
||||
* @param iport the port number
|
||||
* @since JDK1.1
|
||||
* @see #getPort()
|
||||
*/
|
||||
public synchronized void setPort(int iport) {
|
||||
if (iport < 0 || iport > 0xFFFF) {
|
||||
throw new IllegalArgumentException("Port out of range:"+ iport);
|
||||
}
|
||||
port = iport;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the SocketAddress (usually IP address + port number) of the remote
|
||||
* host to which this datagram is being sent.
|
||||
*
|
||||
* @param address the {@code SocketAddress}
|
||||
* @throws IllegalArgumentException if address is null or is a
|
||||
* SocketAddress subclass not supported by this socket
|
||||
*
|
||||
* @since 1.4
|
||||
* @see #getSocketAddress
|
||||
*/
|
||||
public synchronized void setSocketAddress(SocketAddress address) {
|
||||
if (address == null || !(address instanceof InetSocketAddress))
|
||||
throw new IllegalArgumentException("unsupported address type");
|
||||
InetSocketAddress addr = (InetSocketAddress) address;
|
||||
if (addr.isUnresolved())
|
||||
throw new IllegalArgumentException("unresolved address");
|
||||
setAddress(addr.getAddress());
|
||||
setPort(addr.getPort());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the SocketAddress (usually IP address + port number) of the remote
|
||||
* host that this packet is being sent to or is coming from.
|
||||
*
|
||||
* @return the {@code SocketAddress}
|
||||
* @since 1.4
|
||||
* @see #setSocketAddress
|
||||
*/
|
||||
public synchronized SocketAddress getSocketAddress() {
|
||||
return new InetSocketAddress(getAddress(), getPort());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the data buffer for this packet. With the offset of
|
||||
* this DatagramPacket set to 0, and the length set to
|
||||
* the length of {@code buf}.
|
||||
*
|
||||
* @param buf the buffer to set for this packet.
|
||||
*
|
||||
* @exception NullPointerException if the argument is null.
|
||||
*
|
||||
* @see #getLength
|
||||
* @see #getData
|
||||
*
|
||||
* @since JDK1.1
|
||||
*/
|
||||
public synchronized void setData(byte[] buf) {
|
||||
if (buf == null) {
|
||||
throw new NullPointerException("null packet buffer");
|
||||
}
|
||||
this.buf = buf;
|
||||
this.offset = 0;
|
||||
this.length = buf.length;
|
||||
this.bufLength = buf.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the length for this packet. The length of the packet is
|
||||
* the number of bytes from the packet's data buffer that will be
|
||||
* sent, or the number of bytes of the packet's data buffer that
|
||||
* will be used for receiving data. The length must be lesser or
|
||||
* equal to the offset plus the length of the packet's buffer.
|
||||
*
|
||||
* @param length the length to set for this packet.
|
||||
*
|
||||
* @exception IllegalArgumentException if the length is negative
|
||||
* of if the length is greater than the packet's data buffer
|
||||
* length.
|
||||
*
|
||||
* @see #getLength
|
||||
* @see #setData
|
||||
*
|
||||
* @since JDK1.1
|
||||
*/
|
||||
public synchronized void setLength(int length) {
|
||||
if ((length + offset) > buf.length || length < 0 ||
|
||||
(length + offset) < 0) {
|
||||
throw new IllegalArgumentException("illegal length");
|
||||
}
|
||||
this.length = length;
|
||||
this.bufLength = this.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform class load-time initializations.
|
||||
*/
|
||||
private native static void init();
|
||||
}
|
||||
1314
jdkSrc/jdk8/java/net/DatagramSocket.java
Normal file
1314
jdkSrc/jdk8/java/net/DatagramSocket.java
Normal file
File diff suppressed because it is too large
Load Diff
314
jdkSrc/jdk8/java/net/DatagramSocketImpl.java
Normal file
314
jdkSrc/jdk8/java/net/DatagramSocketImpl.java
Normal file
@@ -0,0 +1,314 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.IOException;
|
||||
import java.io.InterruptedIOException;
|
||||
|
||||
/**
|
||||
* Abstract datagram and multicast socket implementation base class.
|
||||
* @author Pavani Diwanji
|
||||
* @since JDK1.1
|
||||
*/
|
||||
|
||||
public abstract class DatagramSocketImpl implements SocketOptions {
|
||||
|
||||
/**
|
||||
* The local port number.
|
||||
*/
|
||||
protected int localPort;
|
||||
|
||||
/**
|
||||
* The file descriptor object.
|
||||
*/
|
||||
protected FileDescriptor fd;
|
||||
|
||||
int dataAvailable() {
|
||||
// default impl returns zero, which disables the calling
|
||||
// functionality
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* The DatagramSocket or MulticastSocket
|
||||
* that owns this impl
|
||||
*/
|
||||
DatagramSocket socket;
|
||||
|
||||
void setDatagramSocket(DatagramSocket socket) {
|
||||
this.socket = socket;
|
||||
}
|
||||
|
||||
DatagramSocket getDatagramSocket() {
|
||||
return socket;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a datagram socket.
|
||||
* @exception SocketException if there is an error in the
|
||||
* underlying protocol, such as a TCP error.
|
||||
*/
|
||||
protected abstract void create() throws SocketException;
|
||||
|
||||
/**
|
||||
* Binds a datagram socket to a local port and address.
|
||||
* @param lport the local port
|
||||
* @param laddr the local address
|
||||
* @exception SocketException if there is an error in the
|
||||
* underlying protocol, such as a TCP error.
|
||||
*/
|
||||
protected abstract void bind(int lport, InetAddress laddr) throws SocketException;
|
||||
|
||||
/**
|
||||
* Sends a datagram packet. The packet contains the data and the
|
||||
* destination address to send the packet to.
|
||||
* @param p the packet to be sent.
|
||||
* @exception IOException if an I/O exception occurs while sending the
|
||||
* datagram packet.
|
||||
* @exception PortUnreachableException may be thrown if the socket is connected
|
||||
* to a currently unreachable destination. Note, there is no guarantee that
|
||||
* the exception will be thrown.
|
||||
*/
|
||||
protected abstract void send(DatagramPacket p) throws IOException;
|
||||
|
||||
/**
|
||||
* Connects a datagram socket to a remote destination. This associates the remote
|
||||
* address with the local socket so that datagrams may only be sent to this destination
|
||||
* and received from this destination. This may be overridden to call a native
|
||||
* system connect.
|
||||
*
|
||||
* <p>If the remote destination to which the socket is connected does not
|
||||
* exist, or is otherwise unreachable, and if an ICMP destination unreachable
|
||||
* packet has been received for that address, then a subsequent call to
|
||||
* send or receive may throw a PortUnreachableException.
|
||||
* Note, there is no guarantee that the exception will be thrown.
|
||||
* @param address the remote InetAddress to connect to
|
||||
* @param port the remote port number
|
||||
* @exception SocketException may be thrown if the socket cannot be
|
||||
* connected to the remote destination
|
||||
* @since 1.4
|
||||
*/
|
||||
protected void connect(InetAddress address, int port) throws SocketException {}
|
||||
|
||||
/**
|
||||
* Disconnects a datagram socket from its remote destination.
|
||||
* @since 1.4
|
||||
*/
|
||||
protected void disconnect() {}
|
||||
|
||||
/**
|
||||
* Peek at the packet to see who it is from. Updates the specified {@code InetAddress}
|
||||
* to the address which the packet came from.
|
||||
* @param i an InetAddress object
|
||||
* @return the port number which the packet came from.
|
||||
* @exception IOException if an I/O exception occurs
|
||||
* @exception PortUnreachableException may be thrown if the socket is connected
|
||||
* to a currently unreachable destination. Note, there is no guarantee that the
|
||||
* exception will be thrown.
|
||||
*/
|
||||
protected abstract int peek(InetAddress i) throws IOException;
|
||||
|
||||
/**
|
||||
* Peek at the packet to see who it is from. The data is copied into the specified
|
||||
* {@code DatagramPacket}. The data is returned,
|
||||
* but not consumed, so that a subsequent peekData/receive operation
|
||||
* will see the same data.
|
||||
* @param p the Packet Received.
|
||||
* @return the port number which the packet came from.
|
||||
* @exception IOException if an I/O exception occurs
|
||||
* @exception PortUnreachableException may be thrown if the socket is connected
|
||||
* to a currently unreachable destination. Note, there is no guarantee that the
|
||||
* exception will be thrown.
|
||||
* @since 1.4
|
||||
*/
|
||||
protected abstract int peekData(DatagramPacket p) throws IOException;
|
||||
/**
|
||||
* Receive the datagram packet.
|
||||
* @param p the Packet Received.
|
||||
* @exception IOException if an I/O exception occurs
|
||||
* while receiving the datagram packet.
|
||||
* @exception PortUnreachableException may be thrown if the socket is connected
|
||||
* to a currently unreachable destination. Note, there is no guarantee that the
|
||||
* exception will be thrown.
|
||||
*/
|
||||
protected abstract void receive(DatagramPacket p) throws IOException;
|
||||
|
||||
/**
|
||||
* Set the TTL (time-to-live) option.
|
||||
* @param ttl a byte specifying the TTL value
|
||||
*
|
||||
* @deprecated use setTimeToLive instead.
|
||||
* @exception IOException if an I/O exception occurs while setting
|
||||
* the time-to-live option.
|
||||
* @see #getTTL()
|
||||
*/
|
||||
@Deprecated
|
||||
protected abstract void setTTL(byte ttl) throws IOException;
|
||||
|
||||
/**
|
||||
* Retrieve the TTL (time-to-live) option.
|
||||
*
|
||||
* @exception IOException if an I/O exception occurs
|
||||
* while retrieving the time-to-live option
|
||||
* @deprecated use getTimeToLive instead.
|
||||
* @return a byte representing the TTL value
|
||||
* @see #setTTL(byte)
|
||||
*/
|
||||
@Deprecated
|
||||
protected abstract byte getTTL() throws IOException;
|
||||
|
||||
/**
|
||||
* Set the TTL (time-to-live) option.
|
||||
* @param ttl an {@code int} specifying the time-to-live value
|
||||
* @exception IOException if an I/O exception occurs
|
||||
* while setting the time-to-live option.
|
||||
* @see #getTimeToLive()
|
||||
*/
|
||||
protected abstract void setTimeToLive(int ttl) throws IOException;
|
||||
|
||||
/**
|
||||
* Retrieve the TTL (time-to-live) option.
|
||||
* @exception IOException if an I/O exception occurs
|
||||
* while retrieving the time-to-live option
|
||||
* @return an {@code int} representing the time-to-live value
|
||||
* @see #setTimeToLive(int)
|
||||
*/
|
||||
protected abstract int getTimeToLive() throws IOException;
|
||||
|
||||
/**
|
||||
* Join the multicast group.
|
||||
* @param inetaddr multicast address to join.
|
||||
* @exception IOException if an I/O exception occurs
|
||||
* while joining the multicast group.
|
||||
*/
|
||||
protected abstract void join(InetAddress inetaddr) throws IOException;
|
||||
|
||||
/**
|
||||
* Leave the multicast group.
|
||||
* @param inetaddr multicast address to leave.
|
||||
* @exception IOException if an I/O exception occurs
|
||||
* while leaving the multicast group.
|
||||
*/
|
||||
protected abstract void leave(InetAddress inetaddr) throws IOException;
|
||||
|
||||
/**
|
||||
* Join the multicast group.
|
||||
* @param mcastaddr address to join.
|
||||
* @param netIf specifies the local interface to receive multicast
|
||||
* datagram packets
|
||||
* @throws IOException if an I/O exception occurs while joining
|
||||
* the multicast group
|
||||
* @since 1.4
|
||||
*/
|
||||
protected abstract void joinGroup(SocketAddress mcastaddr,
|
||||
NetworkInterface netIf)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Leave the multicast group.
|
||||
* @param mcastaddr address to leave.
|
||||
* @param netIf specified the local interface to leave the group at
|
||||
* @throws IOException if an I/O exception occurs while leaving
|
||||
* the multicast group
|
||||
* @since 1.4
|
||||
*/
|
||||
protected abstract void leaveGroup(SocketAddress mcastaddr,
|
||||
NetworkInterface netIf)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Close the socket.
|
||||
*/
|
||||
protected abstract void close();
|
||||
|
||||
/**
|
||||
* Gets the local port.
|
||||
* @return an {@code int} representing the local port value
|
||||
*/
|
||||
protected int getLocalPort() {
|
||||
return localPort;
|
||||
}
|
||||
|
||||
<T> void setOption(SocketOption<T> name, T value) throws IOException {
|
||||
if (name == StandardSocketOptions.SO_SNDBUF) {
|
||||
setOption(SocketOptions.SO_SNDBUF, value);
|
||||
} else if (name == StandardSocketOptions.SO_RCVBUF) {
|
||||
setOption(SocketOptions.SO_RCVBUF, value);
|
||||
} else if (name == StandardSocketOptions.SO_REUSEADDR) {
|
||||
setOption(SocketOptions.SO_REUSEADDR, value);
|
||||
} else if (name == StandardSocketOptions.IP_TOS) {
|
||||
setOption(SocketOptions.IP_TOS, value);
|
||||
} else if (name == StandardSocketOptions.IP_MULTICAST_IF &&
|
||||
(getDatagramSocket() instanceof MulticastSocket)) {
|
||||
setOption(SocketOptions.IP_MULTICAST_IF2, value);
|
||||
} else if (name == StandardSocketOptions.IP_MULTICAST_TTL &&
|
||||
(getDatagramSocket() instanceof MulticastSocket)) {
|
||||
if (! (value instanceof Integer)) {
|
||||
throw new IllegalArgumentException("not an integer");
|
||||
}
|
||||
setTimeToLive((Integer)value);
|
||||
} else if (name == StandardSocketOptions.IP_MULTICAST_LOOP &&
|
||||
(getDatagramSocket() instanceof MulticastSocket)) {
|
||||
setOption(SocketOptions.IP_MULTICAST_LOOP, value);
|
||||
} else {
|
||||
throw new UnsupportedOperationException("unsupported option");
|
||||
}
|
||||
}
|
||||
|
||||
<T> T getOption(SocketOption<T> name) throws IOException {
|
||||
if (name == StandardSocketOptions.SO_SNDBUF) {
|
||||
return (T) getOption(SocketOptions.SO_SNDBUF);
|
||||
} else if (name == StandardSocketOptions.SO_RCVBUF) {
|
||||
return (T) getOption(SocketOptions.SO_RCVBUF);
|
||||
} else if (name == StandardSocketOptions.SO_REUSEADDR) {
|
||||
return (T) getOption(SocketOptions.SO_REUSEADDR);
|
||||
} else if (name == StandardSocketOptions.IP_TOS) {
|
||||
return (T) getOption(SocketOptions.IP_TOS);
|
||||
} else if (name == StandardSocketOptions.IP_MULTICAST_IF &&
|
||||
(getDatagramSocket() instanceof MulticastSocket)) {
|
||||
return (T) getOption(SocketOptions.IP_MULTICAST_IF2);
|
||||
} else if (name == StandardSocketOptions.IP_MULTICAST_TTL &&
|
||||
(getDatagramSocket() instanceof MulticastSocket)) {
|
||||
Integer ttl = getTimeToLive();
|
||||
return (T)ttl;
|
||||
} else if (name == StandardSocketOptions.IP_MULTICAST_LOOP &&
|
||||
(getDatagramSocket() instanceof MulticastSocket)) {
|
||||
return (T) getOption(SocketOptions.IP_MULTICAST_LOOP);
|
||||
} else {
|
||||
throw new UnsupportedOperationException("unsupported option");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the datagram socket file descriptor.
|
||||
* @return a {@code FileDescriptor} object representing the datagram socket
|
||||
* file descriptor
|
||||
*/
|
||||
protected FileDescriptor getFileDescriptor() {
|
||||
return fd;
|
||||
}
|
||||
}
|
||||
46
jdkSrc/jdk8/java/net/DatagramSocketImplFactory.java
Normal file
46
jdkSrc/jdk8/java/net/DatagramSocketImplFactory.java
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
/**
|
||||
* This interface defines a factory for datagram socket implementations. It
|
||||
* is used by the classes {@code DatagramSocket} to create actual socket
|
||||
* implementations.
|
||||
*
|
||||
* @author Yingxian Wang
|
||||
* @see java.net.DatagramSocket
|
||||
* @since 1.3
|
||||
*/
|
||||
public
|
||||
interface DatagramSocketImplFactory {
|
||||
/**
|
||||
* Creates a new {@code DatagramSocketImpl} instance.
|
||||
*
|
||||
* @return a new instance of {@code DatagramSocketImpl}.
|
||||
* @see java.net.DatagramSocketImpl
|
||||
*/
|
||||
DatagramSocketImpl createDatagramSocketImpl();
|
||||
}
|
||||
142
jdkSrc/jdk8/java/net/DefaultDatagramSocketImplFactory.java
Normal file
142
jdkSrc/jdk8/java/net/DefaultDatagramSocketImplFactory.java
Normal file
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package java.net;
|
||||
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
/**
|
||||
* This class defines a factory for creating DatagramSocketImpls. It defaults
|
||||
* to creating plain DatagramSocketImpls, but may create other DatagramSocketImpls
|
||||
* by setting the impl.prefix system property.
|
||||
*
|
||||
* For Windows versions lower than Windows Vista a TwoStacksPlainDatagramSocketImpl
|
||||
* is always created. This impl supports IPv6 on these platform where available.
|
||||
*
|
||||
* On Windows platforms greater than Vista that support a dual layer TCP/IP stack
|
||||
* a DualStackPlainDatagramSocketImpl is created for DatagramSockets. For MulticastSockets
|
||||
* a TwoStacksPlainDatagramSocketImpl is always created. This is to overcome the lack
|
||||
* of behavior defined for multicasting over a dual layer socket by the RFC.
|
||||
*
|
||||
* @author Chris Hegarty
|
||||
*/
|
||||
|
||||
class DefaultDatagramSocketImplFactory
|
||||
{
|
||||
private final static Class<?> prefixImplClass;
|
||||
|
||||
/* the windows version. */
|
||||
private static float version;
|
||||
|
||||
/* java.net.preferIPv4Stack */
|
||||
private static boolean preferIPv4Stack = false;
|
||||
|
||||
/* If the version supports a dual stack TCP implementation */
|
||||
private final static boolean useDualStackImpl;
|
||||
|
||||
/* sun.net.useExclusiveBind */
|
||||
private static String exclBindProp;
|
||||
|
||||
/* True if exclusive binding is on for Windows */
|
||||
private final static boolean exclusiveBind;
|
||||
|
||||
static {
|
||||
Class<?> prefixImplClassLocal = null;
|
||||
boolean useDualStackImplLocal = false;
|
||||
boolean exclusiveBindLocal = true;
|
||||
|
||||
// Determine Windows Version.
|
||||
java.security.AccessController.doPrivileged(
|
||||
new PrivilegedAction<Object>() {
|
||||
public Object run() {
|
||||
version = 0;
|
||||
try {
|
||||
version = Float.parseFloat(System.getProperties()
|
||||
.getProperty("os.version"));
|
||||
preferIPv4Stack = Boolean.parseBoolean(
|
||||
System.getProperties()
|
||||
.getProperty(
|
||||
"java.net.preferIPv4Stack"));
|
||||
exclBindProp = System.getProperty(
|
||||
"sun.net.useExclusiveBind");
|
||||
} catch (NumberFormatException e) {
|
||||
assert false : e;
|
||||
}
|
||||
return null; // nothing to return
|
||||
}
|
||||
});
|
||||
|
||||
// (version >= 6.0) implies Vista or greater.
|
||||
if (version >= 6.0 && !preferIPv4Stack) {
|
||||
useDualStackImplLocal = true;
|
||||
}
|
||||
if (exclBindProp != null) {
|
||||
// sun.net.useExclusiveBind is true
|
||||
exclusiveBindLocal = exclBindProp.length() == 0 ? true
|
||||
: Boolean.parseBoolean(exclBindProp);
|
||||
} else if (version < 6.0) {
|
||||
exclusiveBindLocal = false;
|
||||
}
|
||||
|
||||
// impl.prefix
|
||||
String prefix = null;
|
||||
try {
|
||||
prefix = AccessController.doPrivileged(
|
||||
new sun.security.action.GetPropertyAction("impl.prefix", null));
|
||||
if (prefix != null)
|
||||
prefixImplClassLocal = Class.forName("java.net."+prefix+"DatagramSocketImpl");
|
||||
} catch (Exception e) {
|
||||
System.err.println("Can't find class: java.net." +
|
||||
prefix +
|
||||
"DatagramSocketImpl: check impl.prefix property");
|
||||
}
|
||||
|
||||
prefixImplClass = prefixImplClassLocal;
|
||||
useDualStackImpl = useDualStackImplLocal;
|
||||
exclusiveBind = exclusiveBindLocal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>DatagramSocketImpl</code> instance.
|
||||
*
|
||||
* @param isMulticast true if this impl is to be used for a MutlicastSocket
|
||||
* @return a new instance of <code>PlainDatagramSocketImpl</code>.
|
||||
*/
|
||||
static DatagramSocketImpl createDatagramSocketImpl(boolean isMulticast)
|
||||
throws SocketException {
|
||||
if (prefixImplClass != null) {
|
||||
try {
|
||||
return (DatagramSocketImpl) prefixImplClass.newInstance();
|
||||
} catch (Exception e) {
|
||||
throw new SocketException("can't instantiate DatagramSocketImpl");
|
||||
}
|
||||
} else {
|
||||
if (useDualStackImpl && !isMulticast)
|
||||
return new DualStackPlainDatagramSocketImpl(exclusiveBind);
|
||||
else
|
||||
return new TwoStacksPlainDatagramSocketImpl(exclusiveBind && !isMulticast);
|
||||
}
|
||||
}
|
||||
}
|
||||
41
jdkSrc/jdk8/java/net/DefaultInterface.java
Normal file
41
jdkSrc/jdk8/java/net/DefaultInterface.java
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
/**
|
||||
* Choose a network interface to be the default for
|
||||
* outgoing IPv6 traffic that does not specify a scope_id (and which needs one).
|
||||
*
|
||||
* Platforms that do not require a default interface may return null
|
||||
* which is what this implementation does.
|
||||
*/
|
||||
|
||||
class DefaultInterface {
|
||||
|
||||
static NetworkInterface getDefault() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
297
jdkSrc/jdk8/java/net/DualStackPlainDatagramSocketImpl.java
Normal file
297
jdkSrc/jdk8/java/net/DualStackPlainDatagramSocketImpl.java
Normal file
@@ -0,0 +1,297 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package java.net;
|
||||
|
||||
import java.io.IOException;
|
||||
import sun.misc.SharedSecrets;
|
||||
import sun.misc.JavaIOFileDescriptorAccess;
|
||||
|
||||
/**
|
||||
* This class defines the plain DatagramSocketImpl that is used on
|
||||
* Windows platforms greater than or equal to Windows Vista. These
|
||||
* platforms have a dual layer TCP/IP stack and can handle both IPv4
|
||||
* and IPV6 through a single file descriptor.
|
||||
* <p>
|
||||
* Note: Multicasting on a dual layer TCP/IP stack is always done with
|
||||
* TwoStacksPlainDatagramSocketImpl. This is to overcome the lack
|
||||
* of behavior defined for multicasting over a dual layer socket by the RFC.
|
||||
*
|
||||
* @author Chris Hegarty
|
||||
*/
|
||||
|
||||
class DualStackPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
|
||||
{
|
||||
static JavaIOFileDescriptorAccess fdAccess = SharedSecrets.getJavaIOFileDescriptorAccess();
|
||||
|
||||
static {
|
||||
initIDs();
|
||||
}
|
||||
|
||||
// true if this socket is exclusively bound
|
||||
private final boolean exclusiveBind;
|
||||
|
||||
/*
|
||||
* Set to true if SO_REUSEADDR is set after the socket is bound to
|
||||
* indicate SO_REUSEADDR is being emulated
|
||||
*/
|
||||
private boolean reuseAddressEmulated;
|
||||
|
||||
// emulates SO_REUSEADDR when exclusiveBind is true and socket is bound
|
||||
private boolean isReuseAddress;
|
||||
|
||||
DualStackPlainDatagramSocketImpl(boolean exclBind) {
|
||||
exclusiveBind = exclBind;
|
||||
}
|
||||
|
||||
protected void datagramSocketCreate() throws SocketException {
|
||||
if (fd == null)
|
||||
throw new SocketException("Socket closed");
|
||||
|
||||
int newfd = socketCreate(false /* v6Only */);
|
||||
|
||||
fdAccess.set(fd, newfd);
|
||||
}
|
||||
|
||||
protected synchronized void bind0(int lport, InetAddress laddr)
|
||||
throws SocketException {
|
||||
int nativefd = checkAndReturnNativeFD();
|
||||
|
||||
if (laddr == null)
|
||||
throw new NullPointerException("argument address");
|
||||
|
||||
socketBind(nativefd, laddr, lport, exclusiveBind);
|
||||
if (lport == 0) {
|
||||
localPort = socketLocalPort(nativefd);
|
||||
} else {
|
||||
localPort = lport;
|
||||
}
|
||||
}
|
||||
|
||||
protected synchronized int peek(InetAddress address) throws IOException {
|
||||
int nativefd = checkAndReturnNativeFD();
|
||||
|
||||
if (address == null)
|
||||
throw new NullPointerException("Null address in peek()");
|
||||
|
||||
// Use peekData()
|
||||
DatagramPacket peekPacket = new DatagramPacket(new byte[1], 1);
|
||||
int peekPort = peekData(peekPacket);
|
||||
address = peekPacket.getAddress();
|
||||
return peekPort;
|
||||
}
|
||||
|
||||
protected synchronized int peekData(DatagramPacket p) throws IOException {
|
||||
int nativefd = checkAndReturnNativeFD();
|
||||
|
||||
if (p == null)
|
||||
throw new NullPointerException("packet");
|
||||
if (p.getData() == null)
|
||||
throw new NullPointerException("packet buffer");
|
||||
|
||||
return socketReceiveOrPeekData(nativefd, p, timeout, connected, true /*peek*/);
|
||||
}
|
||||
|
||||
protected synchronized void receive0(DatagramPacket p) throws IOException {
|
||||
int nativefd = checkAndReturnNativeFD();
|
||||
|
||||
if (p == null)
|
||||
throw new NullPointerException("packet");
|
||||
if (p.getData() == null)
|
||||
throw new NullPointerException("packet buffer");
|
||||
|
||||
socketReceiveOrPeekData(nativefd, p, timeout, connected, false /*receive*/);
|
||||
}
|
||||
|
||||
protected void send(DatagramPacket p) throws IOException {
|
||||
int nativefd = checkAndReturnNativeFD();
|
||||
|
||||
if (p == null)
|
||||
throw new NullPointerException("null packet");
|
||||
|
||||
if (p.getAddress() == null ||p.getData() ==null)
|
||||
throw new NullPointerException("null address || null buffer");
|
||||
|
||||
socketSend(nativefd, p.getData(), p.getOffset(), p.getLength(),
|
||||
p.getAddress(), p.getPort(), connected);
|
||||
}
|
||||
|
||||
protected void connect0(InetAddress address, int port) throws SocketException {
|
||||
int nativefd = checkAndReturnNativeFD();
|
||||
|
||||
if (address == null)
|
||||
throw new NullPointerException("address");
|
||||
|
||||
socketConnect(nativefd, address, port);
|
||||
}
|
||||
|
||||
protected void disconnect0(int family /*unused*/) {
|
||||
if (fd == null || !fd.valid())
|
||||
return; // disconnect doesn't throw any exceptions
|
||||
|
||||
socketDisconnect(fdAccess.get(fd));
|
||||
}
|
||||
|
||||
protected void datagramSocketClose() {
|
||||
if (fd == null || !fd.valid())
|
||||
return; // close doesn't throw any exceptions
|
||||
|
||||
socketClose(fdAccess.get(fd));
|
||||
fdAccess.set(fd, -1);
|
||||
}
|
||||
|
||||
@SuppressWarnings("fallthrough")
|
||||
protected void socketSetOption(int opt, Object val) throws SocketException {
|
||||
int nativefd = checkAndReturnNativeFD();
|
||||
|
||||
int optionValue = 0;
|
||||
|
||||
switch(opt) {
|
||||
case IP_TOS :
|
||||
case SO_RCVBUF :
|
||||
case SO_SNDBUF :
|
||||
optionValue = ((Integer)val).intValue();
|
||||
break;
|
||||
case SO_REUSEADDR :
|
||||
if (exclusiveBind && localPort != 0) {
|
||||
// socket already bound, emulate SO_REUSEADDR
|
||||
reuseAddressEmulated = true;
|
||||
isReuseAddress = (Boolean)val;
|
||||
return;
|
||||
}
|
||||
//Intentional fallthrough
|
||||
case SO_BROADCAST :
|
||||
optionValue = ((Boolean)val).booleanValue() ? 1 : 0;
|
||||
break;
|
||||
default: /* shouldn't get here */
|
||||
throw new SocketException("Option not supported");
|
||||
}
|
||||
|
||||
socketSetIntOption(nativefd, opt, optionValue);
|
||||
}
|
||||
|
||||
protected Object socketGetOption(int opt) throws SocketException {
|
||||
int nativefd = checkAndReturnNativeFD();
|
||||
|
||||
// SO_BINDADDR is not a socket option.
|
||||
if (opt == SO_BINDADDR) {
|
||||
return socketLocalAddress(nativefd);
|
||||
}
|
||||
if (opt == SO_REUSEADDR && reuseAddressEmulated)
|
||||
return isReuseAddress;
|
||||
|
||||
int value = socketGetIntOption(nativefd, opt);
|
||||
Object returnValue = null;
|
||||
|
||||
switch (opt) {
|
||||
case SO_REUSEADDR :
|
||||
case SO_BROADCAST :
|
||||
returnValue = (value == 0) ? Boolean.FALSE : Boolean.TRUE;
|
||||
break;
|
||||
case IP_TOS :
|
||||
case SO_RCVBUF :
|
||||
case SO_SNDBUF :
|
||||
returnValue = new Integer(value);
|
||||
break;
|
||||
default: /* shouldn't get here */
|
||||
throw new SocketException("Option not supported");
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
/* Multicast specific methods.
|
||||
* Multicasting on a dual layer TCP/IP stack is always done with
|
||||
* TwoStacksPlainDatagramSocketImpl. This is to overcome the lack
|
||||
* of behavior defined for multicasting over a dual layer socket by the RFC.
|
||||
*/
|
||||
protected void join(InetAddress inetaddr, NetworkInterface netIf)
|
||||
throws IOException {
|
||||
throw new IOException("Method not implemented!");
|
||||
}
|
||||
|
||||
protected void leave(InetAddress inetaddr, NetworkInterface netIf)
|
||||
throws IOException {
|
||||
throw new IOException("Method not implemented!");
|
||||
}
|
||||
|
||||
protected void setTimeToLive(int ttl) throws IOException {
|
||||
throw new IOException("Method not implemented!");
|
||||
}
|
||||
|
||||
protected int getTimeToLive() throws IOException {
|
||||
throw new IOException("Method not implemented!");
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
protected void setTTL(byte ttl) throws IOException {
|
||||
throw new IOException("Method not implemented!");
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
protected byte getTTL() throws IOException {
|
||||
throw new IOException("Method not implemented!");
|
||||
}
|
||||
/* END Multicast specific methods */
|
||||
|
||||
private int checkAndReturnNativeFD() throws SocketException {
|
||||
if (fd == null || !fd.valid())
|
||||
throw new SocketException("Socket closed");
|
||||
|
||||
return fdAccess.get(fd);
|
||||
}
|
||||
|
||||
/* Native methods */
|
||||
|
||||
private static native void initIDs();
|
||||
|
||||
private static native int socketCreate(boolean v6Only);
|
||||
|
||||
private static native void socketBind(int fd, InetAddress localAddress,
|
||||
int localport, boolean exclBind) throws SocketException;
|
||||
|
||||
private static native void socketConnect(int fd, InetAddress address, int port)
|
||||
throws SocketException;
|
||||
|
||||
private static native void socketDisconnect(int fd);
|
||||
|
||||
private static native void socketClose(int fd);
|
||||
|
||||
private static native int socketLocalPort(int fd) throws SocketException;
|
||||
|
||||
private static native Object socketLocalAddress(int fd) throws SocketException;
|
||||
|
||||
private static native int socketReceiveOrPeekData(int fd, DatagramPacket packet,
|
||||
int timeout, boolean connected, boolean peek) throws IOException;
|
||||
|
||||
private static native void socketSend(int fd, byte[] data, int offset, int length,
|
||||
InetAddress address, int port, boolean connected) throws IOException;
|
||||
|
||||
private static native void socketSetIntOption(int fd, int cmd,
|
||||
int optionValue) throws SocketException;
|
||||
|
||||
private static native int socketGetIntOption(int fd, int cmd) throws SocketException;
|
||||
|
||||
native int dataAvailable();
|
||||
}
|
||||
300
jdkSrc/jdk8/java/net/DualStackPlainSocketImpl.java
Normal file
300
jdkSrc/jdk8/java/net/DualStackPlainSocketImpl.java
Normal file
@@ -0,0 +1,300 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package java.net;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.FileDescriptor;
|
||||
import sun.misc.SharedSecrets;
|
||||
import sun.misc.JavaIOFileDescriptorAccess;
|
||||
|
||||
/**
|
||||
* This class defines the plain SocketImpl that is used on Windows platforms
|
||||
* greater or equal to Windows Vista. These platforms have a dual
|
||||
* layer TCP/IP stack and can handle both IPv4 and IPV6 through a
|
||||
* single file descriptor.
|
||||
*
|
||||
* @author Chris Hegarty
|
||||
*/
|
||||
|
||||
class DualStackPlainSocketImpl extends AbstractPlainSocketImpl
|
||||
{
|
||||
static JavaIOFileDescriptorAccess fdAccess = SharedSecrets.getJavaIOFileDescriptorAccess();
|
||||
|
||||
|
||||
// true if this socket is exclusively bound
|
||||
private final boolean exclusiveBind;
|
||||
|
||||
// emulates SO_REUSEADDR when exclusiveBind is true
|
||||
private boolean isReuseAddress;
|
||||
|
||||
public DualStackPlainSocketImpl(boolean exclBind) {
|
||||
exclusiveBind = exclBind;
|
||||
}
|
||||
|
||||
public DualStackPlainSocketImpl(FileDescriptor fd, boolean exclBind) {
|
||||
this.fd = fd;
|
||||
exclusiveBind = exclBind;
|
||||
}
|
||||
|
||||
void socketCreate(boolean stream) throws IOException {
|
||||
if (fd == null)
|
||||
throw new SocketException("Socket closed");
|
||||
|
||||
int newfd = socket0(stream, false /*v6 Only*/);
|
||||
|
||||
fdAccess.set(fd, newfd);
|
||||
}
|
||||
|
||||
void socketConnect(InetAddress address, int port, int timeout)
|
||||
throws IOException {
|
||||
int nativefd = checkAndReturnNativeFD();
|
||||
|
||||
if (address == null)
|
||||
throw new NullPointerException("inet address argument is null.");
|
||||
|
||||
int connectResult;
|
||||
if (timeout <= 0) {
|
||||
connectResult = connect0(nativefd, address, port);
|
||||
} else {
|
||||
configureBlocking(nativefd, false);
|
||||
try {
|
||||
connectResult = connect0(nativefd, address, port);
|
||||
if (connectResult == WOULDBLOCK) {
|
||||
waitForConnect(nativefd, timeout);
|
||||
}
|
||||
} finally {
|
||||
configureBlocking(nativefd, true);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* We need to set the local port field. If bind was called
|
||||
* previous to the connect (by the client) then localport field
|
||||
* will already be set.
|
||||
*/
|
||||
if (localport == 0)
|
||||
localport = localPort0(nativefd);
|
||||
}
|
||||
|
||||
void socketBind(InetAddress address, int port) throws IOException {
|
||||
int nativefd = checkAndReturnNativeFD();
|
||||
|
||||
if (address == null)
|
||||
throw new NullPointerException("inet address argument is null.");
|
||||
|
||||
bind0(nativefd, address, port, exclusiveBind);
|
||||
if (port == 0) {
|
||||
localport = localPort0(nativefd);
|
||||
} else {
|
||||
localport = port;
|
||||
}
|
||||
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
void socketListen(int backlog) throws IOException {
|
||||
int nativefd = checkAndReturnNativeFD();
|
||||
|
||||
listen0(nativefd, backlog);
|
||||
}
|
||||
|
||||
void socketAccept(SocketImpl s) throws IOException {
|
||||
int nativefd = checkAndReturnNativeFD();
|
||||
|
||||
if (s == null)
|
||||
throw new NullPointerException("socket is null");
|
||||
|
||||
int newfd = -1;
|
||||
InetSocketAddress[] isaa = new InetSocketAddress[1];
|
||||
if (timeout <= 0) {
|
||||
newfd = accept0(nativefd, isaa);
|
||||
} else {
|
||||
configureBlocking(nativefd, false);
|
||||
try {
|
||||
waitForNewConnection(nativefd, timeout);
|
||||
newfd = accept0(nativefd, isaa);
|
||||
if (newfd != -1) {
|
||||
configureBlocking(newfd, true);
|
||||
}
|
||||
} finally {
|
||||
configureBlocking(nativefd, true);
|
||||
}
|
||||
}
|
||||
/* Update (SocketImpl)s' fd */
|
||||
fdAccess.set(s.fd, newfd);
|
||||
/* Update socketImpls remote port, address and localport */
|
||||
InetSocketAddress isa = isaa[0];
|
||||
s.port = isa.getPort();
|
||||
s.address = isa.getAddress();
|
||||
s.localport = localport;
|
||||
}
|
||||
|
||||
int socketAvailable() throws IOException {
|
||||
int nativefd = checkAndReturnNativeFD();
|
||||
return available0(nativefd);
|
||||
}
|
||||
|
||||
void socketClose0(boolean useDeferredClose/*unused*/) throws IOException {
|
||||
if (fd == null)
|
||||
throw new SocketException("Socket closed");
|
||||
|
||||
if (!fd.valid())
|
||||
return;
|
||||
|
||||
final int nativefd = fdAccess.get(fd);
|
||||
fdAccess.set(fd, -1);
|
||||
close0(nativefd);
|
||||
}
|
||||
|
||||
void socketShutdown(int howto) throws IOException {
|
||||
int nativefd = checkAndReturnNativeFD();
|
||||
shutdown0(nativefd, howto);
|
||||
}
|
||||
|
||||
// Intentional fallthrough after SO_REUSEADDR
|
||||
@SuppressWarnings("fallthrough")
|
||||
void socketSetOption(int opt, boolean on, Object value)
|
||||
throws SocketException {
|
||||
int nativefd = checkAndReturnNativeFD();
|
||||
|
||||
if (opt == SO_TIMEOUT) { // timeout implemented through select.
|
||||
return;
|
||||
}
|
||||
|
||||
int optionValue = 0;
|
||||
|
||||
switch(opt) {
|
||||
case SO_REUSEADDR :
|
||||
if (exclusiveBind) {
|
||||
// SO_REUSEADDR emulated when using exclusive bind
|
||||
isReuseAddress = on;
|
||||
return;
|
||||
}
|
||||
// intentional fallthrough
|
||||
case TCP_NODELAY :
|
||||
case SO_OOBINLINE :
|
||||
case SO_KEEPALIVE :
|
||||
optionValue = on ? 1 : 0;
|
||||
break;
|
||||
case SO_SNDBUF :
|
||||
case SO_RCVBUF :
|
||||
case IP_TOS :
|
||||
optionValue = ((Integer)value).intValue();
|
||||
break;
|
||||
case SO_LINGER :
|
||||
if (on) {
|
||||
optionValue = ((Integer)value).intValue();
|
||||
} else {
|
||||
optionValue = -1;
|
||||
}
|
||||
break;
|
||||
default :/* shouldn't get here */
|
||||
throw new SocketException("Option not supported");
|
||||
}
|
||||
|
||||
setIntOption(nativefd, opt, optionValue);
|
||||
}
|
||||
|
||||
int socketGetOption(int opt, Object iaContainerObj) throws SocketException {
|
||||
int nativefd = checkAndReturnNativeFD();
|
||||
|
||||
// SO_BINDADDR is not a socket option.
|
||||
if (opt == SO_BINDADDR) {
|
||||
localAddress(nativefd, (InetAddressContainer)iaContainerObj);
|
||||
return 0; // return value doesn't matter.
|
||||
}
|
||||
|
||||
// SO_REUSEADDR emulated when using exclusive bind
|
||||
if (opt == SO_REUSEADDR && exclusiveBind)
|
||||
return isReuseAddress? 1 : -1;
|
||||
|
||||
int value = getIntOption(nativefd, opt);
|
||||
|
||||
switch (opt) {
|
||||
case TCP_NODELAY :
|
||||
case SO_OOBINLINE :
|
||||
case SO_KEEPALIVE :
|
||||
case SO_REUSEADDR :
|
||||
return (value == 0) ? -1 : 1;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
void socketSendUrgentData(int data) throws IOException {
|
||||
int nativefd = checkAndReturnNativeFD();
|
||||
sendOOB(nativefd, data);
|
||||
}
|
||||
|
||||
private int checkAndReturnNativeFD() throws SocketException {
|
||||
if (fd == null || !fd.valid())
|
||||
throw new SocketException("Socket closed");
|
||||
|
||||
return fdAccess.get(fd);
|
||||
}
|
||||
|
||||
static final int WOULDBLOCK = -2; // Nothing available (non-blocking)
|
||||
|
||||
static {
|
||||
initIDs();
|
||||
}
|
||||
|
||||
/* Native methods */
|
||||
|
||||
static native void initIDs();
|
||||
|
||||
static native int socket0(boolean stream, boolean v6Only) throws IOException;
|
||||
|
||||
static native void bind0(int fd, InetAddress localAddress, int localport,
|
||||
boolean exclBind)
|
||||
throws IOException;
|
||||
|
||||
static native int connect0(int fd, InetAddress remote, int remotePort)
|
||||
throws IOException;
|
||||
|
||||
static native void waitForConnect(int fd, int timeout) throws IOException;
|
||||
|
||||
static native int localPort0(int fd) throws IOException;
|
||||
|
||||
static native void localAddress(int fd, InetAddressContainer in) throws SocketException;
|
||||
|
||||
static native void listen0(int fd, int backlog) throws IOException;
|
||||
|
||||
static native int accept0(int fd, InetSocketAddress[] isaa) throws IOException;
|
||||
|
||||
static native void waitForNewConnection(int fd, int timeout) throws IOException;
|
||||
|
||||
static native int available0(int fd) throws IOException;
|
||||
|
||||
static native void close0(int fd) throws IOException;
|
||||
|
||||
static native void shutdown0(int fd, int howto) throws IOException;
|
||||
|
||||
static native void setIntOption(int fd, int cmd, int optionValue) throws SocketException;
|
||||
|
||||
static native int getIntOption(int fd, int cmd) throws SocketException;
|
||||
|
||||
static native void sendOOB(int fd, int data) throws IOException;
|
||||
|
||||
static native void configureBlocking(int fd, boolean blocking) throws IOException;
|
||||
}
|
||||
44
jdkSrc/jdk8/java/net/FileNameMap.java
Normal file
44
jdkSrc/jdk8/java/net/FileNameMap.java
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
/**
|
||||
* A simple interface which provides a mechanism to map
|
||||
* between a file name and a MIME type string.
|
||||
*
|
||||
* @author Steven B. Byrne
|
||||
* @since JDK1.1
|
||||
*/
|
||||
public interface FileNameMap {
|
||||
|
||||
/**
|
||||
* Gets the MIME type for the specified file name.
|
||||
* @param fileName the specified file name
|
||||
* @return a {@code String} indicating the MIME
|
||||
* type for the specified file name.
|
||||
*/
|
||||
public String getContentTypeFor(String fileName);
|
||||
}
|
||||
283
jdkSrc/jdk8/java/net/HostPortrange.java
Normal file
283
jdkSrc/jdk8/java/net/HostPortrange.java
Normal file
@@ -0,0 +1,283 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
import java.net.*;
|
||||
import java.util.Formatter;
|
||||
import java.util.Locale;
|
||||
import sun.net.util.IPAddressUtil;
|
||||
|
||||
/**
|
||||
* Parses a string containing a host/domain name and port range
|
||||
*/
|
||||
class HostPortrange {
|
||||
|
||||
String hostname;
|
||||
String scheme;
|
||||
int[] portrange;
|
||||
|
||||
boolean wildcard;
|
||||
boolean literal;
|
||||
boolean ipv6, ipv4;
|
||||
static final int PORT_MIN = 0;
|
||||
static final int PORT_MAX = (1 << 16) -1;
|
||||
|
||||
boolean equals(HostPortrange that) {
|
||||
return this.hostname.equals(that.hostname)
|
||||
&& this.portrange[0] == that.portrange[0]
|
||||
&& this.portrange[1] == that.portrange[1]
|
||||
&& this.wildcard == that.wildcard
|
||||
&& this.literal == that.literal;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return hostname.hashCode() + portrange[0] + portrange[1];
|
||||
}
|
||||
|
||||
HostPortrange(String scheme, String str) {
|
||||
// Parse the host name. A name has up to three components, the
|
||||
// hostname, a port number, or two numbers representing a port
|
||||
// range. "www.sun.com:8080-9090" is a valid host name.
|
||||
|
||||
// With IPv6 an address can be 2010:836B:4179::836B:4179
|
||||
// An IPv6 address needs to be enclose in []
|
||||
// For ex: [2010:836B:4179::836B:4179]:8080-9090
|
||||
// Refer to RFC 2732 for more information.
|
||||
|
||||
// first separate string into two fields: hoststr, portstr
|
||||
String hoststr, portstr = null;
|
||||
this.scheme = scheme;
|
||||
|
||||
// check for IPv6 address
|
||||
if (str.charAt(0) == '[') {
|
||||
ipv6 = literal = true;
|
||||
int rb = str.indexOf(']');
|
||||
if (rb != -1) {
|
||||
hoststr = str.substring(1, rb);
|
||||
} else {
|
||||
throw new IllegalArgumentException("invalid IPv6 address: " + str);
|
||||
}
|
||||
int sep = str.indexOf(':', rb + 1);
|
||||
if (sep != -1 && str.length() > sep) {
|
||||
portstr = str.substring(sep + 1);
|
||||
}
|
||||
// need to normalize hoststr now
|
||||
byte[] ip = IPAddressUtil.textToNumericFormatV6(hoststr);
|
||||
if (ip == null) {
|
||||
throw new IllegalArgumentException("illegal IPv6 address");
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Formatter formatter = new Formatter(sb, Locale.US);
|
||||
formatter.format("%02x%02x:%02x%02x:%02x%02x:%02x"
|
||||
+ "%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
|
||||
ip[0], ip[1], ip[2], ip[3], ip[4], ip[5], ip[6], ip[7], ip[8],
|
||||
ip[9], ip[10], ip[11], ip[12], ip[13], ip[14], ip[15]);
|
||||
hostname = sb.toString();
|
||||
} else {
|
||||
// not IPv6 therefore ':' is the port separator
|
||||
|
||||
int sep = str.indexOf(':');
|
||||
if (sep != -1 && str.length() > sep) {
|
||||
hoststr = str.substring(0, sep);
|
||||
portstr = str.substring(sep + 1);
|
||||
} else {
|
||||
hoststr = sep == -1 ? str : str.substring(0, sep);
|
||||
}
|
||||
// is this a domain wildcard specification?
|
||||
if (hoststr.lastIndexOf('*') > 0) {
|
||||
throw new IllegalArgumentException("invalid host wildcard specification");
|
||||
} else if (hoststr.startsWith("*")) {
|
||||
wildcard = true;
|
||||
if (hoststr.equals("*")) {
|
||||
hoststr = "";
|
||||
} else if (hoststr.startsWith("*.")) {
|
||||
hoststr = toLowerCase(hoststr.substring(1));
|
||||
} else {
|
||||
throw new IllegalArgumentException("invalid host wildcard specification");
|
||||
}
|
||||
} else {
|
||||
// check if ipv4 (if rightmost label a number)
|
||||
// The normal way to specify ipv4 is 4 decimal labels
|
||||
// but actually three, two or single label formats valid also
|
||||
// So, we recognise ipv4 by just testing the rightmost label
|
||||
// being a number.
|
||||
int lastdot = hoststr.lastIndexOf('.');
|
||||
if (lastdot != -1 && (hoststr.length() > 1)) {
|
||||
boolean ipv4 = true;
|
||||
|
||||
for (int i = lastdot + 1, len = hoststr.length(); i < len; i++) {
|
||||
char c = hoststr.charAt(i);
|
||||
if (c < '0' || c > '9') {
|
||||
ipv4 = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.ipv4 = this.literal = ipv4;
|
||||
if (ipv4) {
|
||||
byte[] ip = IPAddressUtil.validateNumericFormatV4(hoststr);
|
||||
if (ip == null) {
|
||||
throw new IllegalArgumentException("illegal IPv4 address");
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Formatter formatter = new Formatter(sb, Locale.US);
|
||||
formatter.format("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
|
||||
hoststr = sb.toString();
|
||||
} else {
|
||||
// regular domain name
|
||||
hoststr = toLowerCase(hoststr);
|
||||
}
|
||||
}
|
||||
}
|
||||
hostname = hoststr;
|
||||
}
|
||||
|
||||
try {
|
||||
portrange = parsePort(portstr);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalArgumentException("invalid port range: " + portstr);
|
||||
}
|
||||
}
|
||||
|
||||
static final int CASE_DIFF = 'A' - 'a';
|
||||
|
||||
/**
|
||||
* Convert to lower case, and check that all chars are ascii
|
||||
* alphanumeric, '-' or '.' only.
|
||||
*/
|
||||
static String toLowerCase(String s) {
|
||||
int len = s.length();
|
||||
StringBuilder sb = null;
|
||||
|
||||
for (int i=0; i<len; i++) {
|
||||
char c = s.charAt(i);
|
||||
if ((c >= 'a' && c <= 'z') || (c == '.')) {
|
||||
if (sb != null)
|
||||
sb.append(c);
|
||||
} else if ((c >= '0' && c <= '9') || (c == '-')) {
|
||||
if (sb != null)
|
||||
sb.append(c);
|
||||
} else if (c >= 'A' && c <= 'Z') {
|
||||
if (sb == null) {
|
||||
sb = new StringBuilder(len);
|
||||
sb.append(s, 0, i);
|
||||
}
|
||||
sb.append((char)(c - CASE_DIFF));
|
||||
} else {
|
||||
throw new IllegalArgumentException("Invalid characters in hostname");
|
||||
}
|
||||
}
|
||||
return sb == null ? s : sb.toString();
|
||||
}
|
||||
|
||||
|
||||
public boolean literal() {
|
||||
return literal;
|
||||
}
|
||||
|
||||
public boolean ipv4Literal() {
|
||||
return ipv4;
|
||||
}
|
||||
|
||||
public boolean ipv6Literal() {
|
||||
return ipv6;
|
||||
}
|
||||
|
||||
public String hostname() {
|
||||
return hostname;
|
||||
}
|
||||
|
||||
public int[] portrange() {
|
||||
return portrange;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true if the hostname part started with *
|
||||
* hostname returns the remaining part of the host component
|
||||
* eg "*.foo.com" -> ".foo.com" or "*" -> ""
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean wildcard() {
|
||||
return wildcard;
|
||||
}
|
||||
|
||||
// these shouldn't leak outside the implementation
|
||||
final static int[] HTTP_PORT = {80, 80};
|
||||
final static int[] HTTPS_PORT = {443, 443};
|
||||
final static int[] NO_PORT = {-1, -1};
|
||||
|
||||
int[] defaultPort() {
|
||||
if (scheme.equals("http")) {
|
||||
return HTTP_PORT;
|
||||
} else if (scheme.equals("https")) {
|
||||
return HTTPS_PORT;
|
||||
}
|
||||
return NO_PORT;
|
||||
}
|
||||
|
||||
int[] parsePort(String port)
|
||||
{
|
||||
|
||||
if (port == null || port.equals("")) {
|
||||
return defaultPort();
|
||||
}
|
||||
|
||||
if (port.equals("*")) {
|
||||
return new int[] {PORT_MIN, PORT_MAX};
|
||||
}
|
||||
|
||||
try {
|
||||
int dash = port.indexOf('-');
|
||||
|
||||
if (dash == -1) {
|
||||
int p = Integer.parseInt(port);
|
||||
return new int[] {p, p};
|
||||
} else {
|
||||
String low = port.substring(0, dash);
|
||||
String high = port.substring(dash+1);
|
||||
int l,h;
|
||||
|
||||
if (low.equals("")) {
|
||||
l = PORT_MIN;
|
||||
} else {
|
||||
l = Integer.parseInt(low);
|
||||
}
|
||||
|
||||
if (high.equals("")) {
|
||||
h = PORT_MAX;
|
||||
} else {
|
||||
h = Integer.parseInt(high);
|
||||
}
|
||||
if (l < 0 || h < 0 || h<l) {
|
||||
return defaultPort();
|
||||
}
|
||||
return new int[] {l, h};
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
return defaultPort();
|
||||
}
|
||||
}
|
||||
}
|
||||
210
jdkSrc/jdk8/java/net/HttpConnectSocketImpl.java
Normal file
210
jdkSrc/jdk8/java/net/HttpConnectSocketImpl.java
Normal file
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Basic SocketImpl that relies on the internal HTTP protocol handler
|
||||
* implementation to perform the HTTP tunneling and authentication. The
|
||||
* sockets impl is swapped out and replaced with the socket from the HTTP
|
||||
* handler after the tunnel is successfully setup.
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
|
||||
/*package*/ class HttpConnectSocketImpl extends PlainSocketImpl {
|
||||
|
||||
private static final String httpURLClazzStr =
|
||||
"sun.net.www.protocol.http.HttpURLConnection";
|
||||
private static final String netClientClazzStr = "sun.net.NetworkClient";
|
||||
private static final String doTunnelingStr = "doTunneling";
|
||||
private static final Field httpField;
|
||||
private static final Field serverSocketField;
|
||||
private static final Method doTunneling;
|
||||
|
||||
private final String server;
|
||||
private InetSocketAddress external_address;
|
||||
private HashMap<Integer, Object> optionsMap = new HashMap<>();
|
||||
|
||||
static {
|
||||
try {
|
||||
Class<?> httpClazz = Class.forName(httpURLClazzStr, true, null);
|
||||
httpField = httpClazz.getDeclaredField("http");
|
||||
doTunneling = httpClazz.getDeclaredMethod(doTunnelingStr);
|
||||
Class<?> netClientClazz = Class.forName(netClientClazzStr, true, null);
|
||||
serverSocketField = netClientClazz.getDeclaredField("serverSocket");
|
||||
|
||||
java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
httpField.setAccessible(true);
|
||||
serverSocketField.setAccessible(true);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
} catch (ReflectiveOperationException x) {
|
||||
throw new InternalError("Should not reach here", x);
|
||||
}
|
||||
}
|
||||
|
||||
HttpConnectSocketImpl(String server, int port) {
|
||||
this.server = server;
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
HttpConnectSocketImpl(Proxy proxy) {
|
||||
SocketAddress a = proxy.address();
|
||||
if ( !(a instanceof InetSocketAddress) )
|
||||
throw new IllegalArgumentException("Unsupported address type");
|
||||
|
||||
InetSocketAddress ad = (InetSocketAddress) a;
|
||||
server = ad.getHostString();
|
||||
port = ad.getPort();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void connect(SocketAddress endpoint, int timeout)
|
||||
throws IOException
|
||||
{
|
||||
if (endpoint == null || !(endpoint instanceof InetSocketAddress))
|
||||
throw new IllegalArgumentException("Unsupported address type");
|
||||
final InetSocketAddress epoint = (InetSocketAddress)endpoint;
|
||||
final String destHost = epoint.isUnresolved() ? epoint.getHostName()
|
||||
: epoint.getAddress().getHostAddress();
|
||||
final int destPort = epoint.getPort();
|
||||
|
||||
SecurityManager security = System.getSecurityManager();
|
||||
if (security != null)
|
||||
security.checkConnect(destHost, destPort);
|
||||
|
||||
// Connect to the HTTP proxy server
|
||||
String urlString = "http://" + destHost + ":" + destPort;
|
||||
Socket httpSocket = privilegedDoTunnel(urlString, timeout);
|
||||
|
||||
// Success!
|
||||
external_address = epoint;
|
||||
|
||||
// close the original socket impl and release its descriptor
|
||||
close();
|
||||
|
||||
// update the Sockets impl to the impl from the http Socket
|
||||
AbstractPlainSocketImpl psi = (AbstractPlainSocketImpl) httpSocket.impl;
|
||||
this.getSocket().impl = psi;
|
||||
|
||||
// best effort is made to try and reset options previously set
|
||||
Set<Map.Entry<Integer,Object>> options = optionsMap.entrySet();
|
||||
try {
|
||||
for(Map.Entry<Integer,Object> entry : options) {
|
||||
psi.setOption(entry.getKey(), entry.getValue());
|
||||
}
|
||||
} catch (IOException x) { /* gulp! */ }
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOption(int opt, Object val) throws SocketException {
|
||||
super.setOption(opt, val);
|
||||
|
||||
if (external_address != null)
|
||||
return; // we're connected, just return
|
||||
|
||||
// store options so that they can be re-applied to the impl after connect
|
||||
optionsMap.put(opt, val);
|
||||
}
|
||||
|
||||
private Socket privilegedDoTunnel(final String urlString,
|
||||
final int timeout)
|
||||
throws IOException
|
||||
{
|
||||
try {
|
||||
return java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedExceptionAction<Socket>() {
|
||||
public Socket run() throws IOException {
|
||||
return doTunnel(urlString, timeout);
|
||||
}
|
||||
});
|
||||
} catch (java.security.PrivilegedActionException pae) {
|
||||
throw (IOException) pae.getException();
|
||||
}
|
||||
}
|
||||
|
||||
private Socket doTunnel(String urlString, int connectTimeout)
|
||||
throws IOException
|
||||
{
|
||||
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(server, port));
|
||||
URL destURL = new URL(urlString);
|
||||
HttpURLConnection conn = (HttpURLConnection) destURL.openConnection(proxy);
|
||||
conn.setConnectTimeout(connectTimeout);
|
||||
conn.setReadTimeout(this.timeout);
|
||||
conn.connect();
|
||||
doTunneling(conn);
|
||||
try {
|
||||
Object httpClient = httpField.get(conn);
|
||||
return (Socket) serverSocketField.get(httpClient);
|
||||
} catch (IllegalAccessException x) {
|
||||
throw new InternalError("Should not reach here", x);
|
||||
}
|
||||
}
|
||||
|
||||
private void doTunneling(HttpURLConnection conn) {
|
||||
try {
|
||||
doTunneling.invoke(conn);
|
||||
} catch (ReflectiveOperationException x) {
|
||||
throw new InternalError("Should not reach here", x);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InetAddress getInetAddress() {
|
||||
if (external_address != null)
|
||||
return external_address.getAddress();
|
||||
else
|
||||
return super.getInetAddress();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getPort() {
|
||||
if (external_address != null)
|
||||
return external_address.getPort();
|
||||
else
|
||||
return super.getPort();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getLocalPort() {
|
||||
if (socket != null)
|
||||
return super.getLocalPort();
|
||||
if (external_address != null)
|
||||
return external_address.getPort();
|
||||
else
|
||||
return super.getLocalPort();
|
||||
}
|
||||
}
|
||||
1146
jdkSrc/jdk8/java/net/HttpCookie.java
Normal file
1146
jdkSrc/jdk8/java/net/HttpCookie.java
Normal file
File diff suppressed because it is too large
Load Diff
99
jdkSrc/jdk8/java/net/HttpRetryException.java
Normal file
99
jdkSrc/jdk8/java/net/HttpRetryException.java
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Thrown to indicate that a HTTP request needs to be retried
|
||||
* but cannot be retried automatically, due to streaming mode
|
||||
* being enabled.
|
||||
*
|
||||
* @author Michael McMahon
|
||||
* @since 1.5
|
||||
*/
|
||||
public
|
||||
class HttpRetryException extends IOException {
|
||||
private static final long serialVersionUID = -9186022286469111381L;
|
||||
|
||||
private int responseCode;
|
||||
private String location;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code HttpRetryException} from the
|
||||
* specified response code and exception detail message
|
||||
*
|
||||
* @param detail the detail message.
|
||||
* @param code the HTTP response code from server.
|
||||
*/
|
||||
public HttpRetryException(String detail, int code) {
|
||||
super(detail);
|
||||
responseCode = code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code HttpRetryException} with detail message
|
||||
* responseCode and the contents of the Location response header field.
|
||||
*
|
||||
* @param detail the detail message.
|
||||
* @param code the HTTP response code from server.
|
||||
* @param location the URL to be redirected to
|
||||
*/
|
||||
public HttpRetryException(String detail, int code, String location) {
|
||||
super (detail);
|
||||
responseCode = code;
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the http response code
|
||||
*
|
||||
* @return The http response code.
|
||||
*/
|
||||
public int responseCode() {
|
||||
return responseCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string explaining why the http request could
|
||||
* not be retried.
|
||||
*
|
||||
* @return The reason string
|
||||
*/
|
||||
public String getReason() {
|
||||
return super.getMessage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the Location header field if the
|
||||
* error resulted from redirection.
|
||||
*
|
||||
* @return The location string
|
||||
*/
|
||||
public String getLocation() {
|
||||
return location;
|
||||
}
|
||||
}
|
||||
817
jdkSrc/jdk8/java/net/HttpURLConnection.java
Normal file
817
jdkSrc/jdk8/java/net/HttpURLConnection.java
Normal file
@@ -0,0 +1,817 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.Permission;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* A URLConnection with support for HTTP-specific features. See
|
||||
* <A HREF="http://www.w3.org/pub/WWW/Protocols/"> the spec </A> for
|
||||
* details.
|
||||
* <p>
|
||||
*
|
||||
* Each HttpURLConnection instance is used to make a single request
|
||||
* but the underlying network connection to the HTTP server may be
|
||||
* transparently shared by other instances. Calling the close() methods
|
||||
* on the InputStream or OutputStream of an HttpURLConnection
|
||||
* after a request may free network resources associated with this
|
||||
* instance but has no effect on any shared persistent connection.
|
||||
* Calling the disconnect() method may close the underlying socket
|
||||
* if a persistent connection is otherwise idle at that time.
|
||||
*
|
||||
* <P>The HTTP protocol handler has a few settings that can be accessed through
|
||||
* System Properties. This covers
|
||||
* <a href="doc-files/net-properties.html#Proxies">Proxy settings</a> as well as
|
||||
* <a href="doc-files/net-properties.html#MiscHTTP"> various other settings</a>.
|
||||
* </P>
|
||||
* <p>
|
||||
* <b>Security permissions</b>
|
||||
* <p>
|
||||
* If a security manager is installed, and if a method is called which results in an
|
||||
* attempt to open a connection, the caller must possess either:-
|
||||
* <ul><li>a "connect" {@link SocketPermission} to the host/port combination of the
|
||||
* destination URL or</li>
|
||||
* <li>a {@link URLPermission} that permits this request.</li>
|
||||
* </ul><p>
|
||||
* If automatic redirection is enabled, and this request is redirected to another
|
||||
* destination, then the caller must also have permission to connect to the
|
||||
* redirected host/URL.
|
||||
*
|
||||
* @see java.net.HttpURLConnection#disconnect()
|
||||
* @since JDK1.1
|
||||
*/
|
||||
abstract public class HttpURLConnection extends URLConnection {
|
||||
/* instance variables */
|
||||
|
||||
/**
|
||||
* The HTTP method (GET,POST,PUT,etc.).
|
||||
*/
|
||||
protected String method = "GET";
|
||||
|
||||
/**
|
||||
* The chunk-length when using chunked encoding streaming mode for output.
|
||||
* A value of {@code -1} means chunked encoding is disabled for output.
|
||||
* @since 1.5
|
||||
*/
|
||||
protected int chunkLength = -1;
|
||||
|
||||
/**
|
||||
* The fixed content-length when using fixed-length streaming mode.
|
||||
* A value of {@code -1} means fixed-length streaming mode is disabled
|
||||
* for output.
|
||||
*
|
||||
* <P> <B>NOTE:</B> {@link #fixedContentLengthLong} is recommended instead
|
||||
* of this field, as it allows larger content lengths to be set.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
protected int fixedContentLength = -1;
|
||||
|
||||
/**
|
||||
* The fixed content-length when using fixed-length streaming mode.
|
||||
* A value of {@code -1} means fixed-length streaming mode is disabled
|
||||
* for output.
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
protected long fixedContentLengthLong = -1;
|
||||
|
||||
/**
|
||||
* Returns the key for the {@code n}<sup>th</sup> header field.
|
||||
* Some implementations may treat the {@code 0}<sup>th</sup>
|
||||
* header field as special, i.e. as the status line returned by the HTTP
|
||||
* server. In this case, {@link #getHeaderField(int) getHeaderField(0)} returns the status
|
||||
* line, but {@code getHeaderFieldKey(0)} returns null.
|
||||
*
|
||||
* @param n an index, where {@code n >=0}.
|
||||
* @return the key for the {@code n}<sup>th</sup> header field,
|
||||
* or {@code null} if the key does not exist.
|
||||
*/
|
||||
public String getHeaderFieldKey (int n) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to enable streaming of a HTTP request body
|
||||
* without internal buffering, when the content length is known in
|
||||
* advance.
|
||||
* <p>
|
||||
* An exception will be thrown if the application
|
||||
* attempts to write more data than the indicated
|
||||
* content-length, or if the application closes the OutputStream
|
||||
* before writing the indicated amount.
|
||||
* <p>
|
||||
* When output streaming is enabled, authentication
|
||||
* and redirection cannot be handled automatically.
|
||||
* A HttpRetryException will be thrown when reading
|
||||
* the response if authentication or redirection are required.
|
||||
* This exception can be queried for the details of the error.
|
||||
* <p>
|
||||
* This method must be called before the URLConnection is connected.
|
||||
* <p>
|
||||
* <B>NOTE:</B> {@link #setFixedLengthStreamingMode(long)} is recommended
|
||||
* instead of this method as it allows larger content lengths to be set.
|
||||
*
|
||||
* @param contentLength The number of bytes which will be written
|
||||
* to the OutputStream.
|
||||
*
|
||||
* @throws IllegalStateException if URLConnection is already connected
|
||||
* or if a different streaming mode is already enabled.
|
||||
*
|
||||
* @throws IllegalArgumentException if a content length less than
|
||||
* zero is specified.
|
||||
*
|
||||
* @see #setChunkedStreamingMode(int)
|
||||
* @since 1.5
|
||||
*/
|
||||
public void setFixedLengthStreamingMode (int contentLength) {
|
||||
if (connected) {
|
||||
throw new IllegalStateException ("Already connected");
|
||||
}
|
||||
if (chunkLength != -1) {
|
||||
throw new IllegalStateException ("Chunked encoding streaming mode set");
|
||||
}
|
||||
if (contentLength < 0) {
|
||||
throw new IllegalArgumentException ("invalid content length");
|
||||
}
|
||||
fixedContentLength = contentLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to enable streaming of a HTTP request body
|
||||
* without internal buffering, when the content length is known in
|
||||
* advance.
|
||||
*
|
||||
* <P> An exception will be thrown if the application attempts to write
|
||||
* more data than the indicated content-length, or if the application
|
||||
* closes the OutputStream before writing the indicated amount.
|
||||
*
|
||||
* <P> When output streaming is enabled, authentication and redirection
|
||||
* cannot be handled automatically. A {@linkplain HttpRetryException} will
|
||||
* be thrown when reading the response if authentication or redirection
|
||||
* are required. This exception can be queried for the details of the
|
||||
* error.
|
||||
*
|
||||
* <P> This method must be called before the URLConnection is connected.
|
||||
*
|
||||
* <P> The content length set by invoking this method takes precedence
|
||||
* over any value set by {@link #setFixedLengthStreamingMode(int)}.
|
||||
*
|
||||
* @param contentLength
|
||||
* The number of bytes which will be written to the OutputStream.
|
||||
*
|
||||
* @throws IllegalStateException
|
||||
* if URLConnection is already connected or if a different
|
||||
* streaming mode is already enabled.
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* if a content length less than zero is specified.
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
public void setFixedLengthStreamingMode(long contentLength) {
|
||||
if (connected) {
|
||||
throw new IllegalStateException("Already connected");
|
||||
}
|
||||
if (chunkLength != -1) {
|
||||
throw new IllegalStateException(
|
||||
"Chunked encoding streaming mode set");
|
||||
}
|
||||
if (contentLength < 0) {
|
||||
throw new IllegalArgumentException("invalid content length");
|
||||
}
|
||||
fixedContentLengthLong = contentLength;
|
||||
}
|
||||
|
||||
/* Default chunk size (including chunk header) if not specified;
|
||||
* we want to keep this in sync with the one defined in
|
||||
* sun.net.www.http.ChunkedOutputStream
|
||||
*/
|
||||
private static final int DEFAULT_CHUNK_SIZE = 4096;
|
||||
|
||||
/**
|
||||
* This method is used to enable streaming of a HTTP request body
|
||||
* without internal buffering, when the content length is <b>not</b>
|
||||
* known in advance. In this mode, chunked transfer encoding
|
||||
* is used to send the request body. Note, not all HTTP servers
|
||||
* support this mode.
|
||||
* <p>
|
||||
* When output streaming is enabled, authentication
|
||||
* and redirection cannot be handled automatically.
|
||||
* A HttpRetryException will be thrown when reading
|
||||
* the response if authentication or redirection are required.
|
||||
* This exception can be queried for the details of the error.
|
||||
* <p>
|
||||
* This method must be called before the URLConnection is connected.
|
||||
*
|
||||
* @param chunklen The number of bytes to write in each chunk.
|
||||
* If chunklen is less than or equal to zero, a default
|
||||
* value will be used.
|
||||
*
|
||||
* @throws IllegalStateException if URLConnection is already connected
|
||||
* or if a different streaming mode is already enabled.
|
||||
*
|
||||
* @see #setFixedLengthStreamingMode(int)
|
||||
* @since 1.5
|
||||
*/
|
||||
public void setChunkedStreamingMode (int chunklen) {
|
||||
if (connected) {
|
||||
throw new IllegalStateException ("Can't set streaming mode: already connected");
|
||||
}
|
||||
if (fixedContentLength != -1 || fixedContentLengthLong != -1) {
|
||||
throw new IllegalStateException ("Fixed length streaming mode set");
|
||||
}
|
||||
chunkLength = chunklen <=0? DEFAULT_CHUNK_SIZE : chunklen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for the {@code n}<sup>th</sup> header field.
|
||||
* Some implementations may treat the {@code 0}<sup>th</sup>
|
||||
* header field as special, i.e. as the status line returned by the HTTP
|
||||
* server.
|
||||
* <p>
|
||||
* This method can be used in conjunction with the
|
||||
* {@link #getHeaderFieldKey getHeaderFieldKey} method to iterate through all
|
||||
* the headers in the message.
|
||||
*
|
||||
* @param n an index, where {@code n>=0}.
|
||||
* @return the value of the {@code n}<sup>th</sup> header field,
|
||||
* or {@code null} if the value does not exist.
|
||||
* @see java.net.HttpURLConnection#getHeaderFieldKey(int)
|
||||
*/
|
||||
public String getHeaderField(int n) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* An {@code int} representing the three digit HTTP Status-Code.
|
||||
* <ul>
|
||||
* <li> 1xx: Informational
|
||||
* <li> 2xx: Success
|
||||
* <li> 3xx: Redirection
|
||||
* <li> 4xx: Client Error
|
||||
* <li> 5xx: Server Error
|
||||
* </ul>
|
||||
*/
|
||||
protected int responseCode = -1;
|
||||
|
||||
/**
|
||||
* The HTTP response message.
|
||||
*/
|
||||
protected String responseMessage = null;
|
||||
|
||||
/* static variables */
|
||||
|
||||
/* do we automatically follow redirects? The default is true. */
|
||||
private static boolean followRedirects = true;
|
||||
|
||||
/**
|
||||
* If {@code true}, the protocol will automatically follow redirects.
|
||||
* If {@code false}, the protocol will not automatically follow
|
||||
* redirects.
|
||||
* <p>
|
||||
* This field is set by the {@code setInstanceFollowRedirects}
|
||||
* method. Its value is returned by the {@code getInstanceFollowRedirects}
|
||||
* method.
|
||||
* <p>
|
||||
* Its default value is based on the value of the static followRedirects
|
||||
* at HttpURLConnection construction time.
|
||||
*
|
||||
* @see java.net.HttpURLConnection#setInstanceFollowRedirects(boolean)
|
||||
* @see java.net.HttpURLConnection#getInstanceFollowRedirects()
|
||||
* @see java.net.HttpURLConnection#setFollowRedirects(boolean)
|
||||
*/
|
||||
protected boolean instanceFollowRedirects = followRedirects;
|
||||
|
||||
/* valid HTTP methods */
|
||||
private static final String[] methods = {
|
||||
"GET", "POST", "HEAD", "OPTIONS", "PUT", "DELETE", "TRACE"
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor for the HttpURLConnection.
|
||||
* @param u the URL
|
||||
*/
|
||||
protected HttpURLConnection (URL u) {
|
||||
super(u);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether HTTP redirects (requests with response code 3xx) should
|
||||
* be automatically followed by this class. True by default. Applets
|
||||
* cannot change this variable.
|
||||
* <p>
|
||||
* If there is a security manager, this method first calls
|
||||
* the security manager's {@code checkSetFactory} method
|
||||
* to ensure the operation is allowed.
|
||||
* This could result in a SecurityException.
|
||||
*
|
||||
* @param set a {@code boolean} indicating whether or not
|
||||
* to follow HTTP redirects.
|
||||
* @exception SecurityException if a security manager exists and its
|
||||
* {@code checkSetFactory} method doesn't
|
||||
* allow the operation.
|
||||
* @see SecurityManager#checkSetFactory
|
||||
* @see #getFollowRedirects()
|
||||
*/
|
||||
public static void setFollowRedirects(boolean set) {
|
||||
SecurityManager sec = System.getSecurityManager();
|
||||
if (sec != null) {
|
||||
// seems to be the best check here...
|
||||
sec.checkSetFactory();
|
||||
}
|
||||
followRedirects = set;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@code boolean} indicating
|
||||
* whether or not HTTP redirects (3xx) should
|
||||
* be automatically followed.
|
||||
*
|
||||
* @return {@code true} if HTTP redirects should
|
||||
* be automatically followed, {@code false} if not.
|
||||
* @see #setFollowRedirects(boolean)
|
||||
*/
|
||||
public static boolean getFollowRedirects() {
|
||||
return followRedirects;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether HTTP redirects (requests with response code 3xx) should
|
||||
* be automatically followed by this {@code HttpURLConnection}
|
||||
* instance.
|
||||
* <p>
|
||||
* The default value comes from followRedirects, which defaults to
|
||||
* true.
|
||||
*
|
||||
* @param followRedirects a {@code boolean} indicating
|
||||
* whether or not to follow HTTP redirects.
|
||||
*
|
||||
* @see java.net.HttpURLConnection#instanceFollowRedirects
|
||||
* @see #getInstanceFollowRedirects
|
||||
* @since 1.3
|
||||
*/
|
||||
public void setInstanceFollowRedirects(boolean followRedirects) {
|
||||
instanceFollowRedirects = followRedirects;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of this {@code HttpURLConnection}'s
|
||||
* {@code instanceFollowRedirects} field.
|
||||
*
|
||||
* @return the value of this {@code HttpURLConnection}'s
|
||||
* {@code instanceFollowRedirects} field.
|
||||
* @see java.net.HttpURLConnection#instanceFollowRedirects
|
||||
* @see #setInstanceFollowRedirects(boolean)
|
||||
* @since 1.3
|
||||
*/
|
||||
public boolean getInstanceFollowRedirects() {
|
||||
return instanceFollowRedirects;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the method for the URL request, one of:
|
||||
* <UL>
|
||||
* <LI>GET
|
||||
* <LI>POST
|
||||
* <LI>HEAD
|
||||
* <LI>OPTIONS
|
||||
* <LI>PUT
|
||||
* <LI>DELETE
|
||||
* <LI>TRACE
|
||||
* </UL> are legal, subject to protocol restrictions. The default
|
||||
* method is GET.
|
||||
*
|
||||
* @param method the HTTP method
|
||||
* @exception ProtocolException if the method cannot be reset or if
|
||||
* the requested method isn't valid for HTTP.
|
||||
* @exception SecurityException if a security manager is set and the
|
||||
* method is "TRACE", but the "allowHttpTrace"
|
||||
* NetPermission is not granted.
|
||||
* @see #getRequestMethod()
|
||||
*/
|
||||
public void setRequestMethod(String method) throws ProtocolException {
|
||||
if (connected) {
|
||||
throw new ProtocolException("Can't reset method: already connected");
|
||||
}
|
||||
// This restriction will prevent people from using this class to
|
||||
// experiment w/ new HTTP methods using java. But it should
|
||||
// be placed for security - the request String could be
|
||||
// arbitrarily long.
|
||||
|
||||
for (int i = 0; i < methods.length; i++) {
|
||||
if (methods[i].equals(method)) {
|
||||
if (method.equals("TRACE")) {
|
||||
SecurityManager s = System.getSecurityManager();
|
||||
if (s != null) {
|
||||
s.checkPermission(new NetPermission("allowHttpTrace"));
|
||||
}
|
||||
}
|
||||
this.method = method;
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new ProtocolException("Invalid HTTP method: " + method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the request method.
|
||||
* @return the HTTP request method
|
||||
* @see #setRequestMethod(java.lang.String)
|
||||
*/
|
||||
public String getRequestMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the status code from an HTTP response message.
|
||||
* For example, in the case of the following status lines:
|
||||
* <PRE>
|
||||
* HTTP/1.0 200 OK
|
||||
* HTTP/1.0 401 Unauthorized
|
||||
* </PRE>
|
||||
* It will return 200 and 401 respectively.
|
||||
* Returns -1 if no code can be discerned
|
||||
* from the response (i.e., the response is not valid HTTP).
|
||||
* @throws IOException if an error occurred connecting to the server.
|
||||
* @return the HTTP Status-Code, or -1
|
||||
*/
|
||||
public int getResponseCode() throws IOException {
|
||||
/*
|
||||
* We're got the response code already
|
||||
*/
|
||||
if (responseCode != -1) {
|
||||
return responseCode;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensure that we have connected to the server. Record
|
||||
* exception as we need to re-throw it if there isn't
|
||||
* a status line.
|
||||
*/
|
||||
Exception exc = null;
|
||||
try {
|
||||
getInputStream();
|
||||
} catch (Exception e) {
|
||||
exc = e;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we can't a status-line then re-throw any exception
|
||||
* that getInputStream threw.
|
||||
*/
|
||||
String statusLine = getHeaderField(0);
|
||||
if (statusLine == null) {
|
||||
if (exc != null) {
|
||||
if (exc instanceof RuntimeException)
|
||||
throw (RuntimeException)exc;
|
||||
else
|
||||
throw (IOException)exc;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Examine the status-line - should be formatted as per
|
||||
* section 6.1 of RFC 2616 :-
|
||||
*
|
||||
* Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase
|
||||
*
|
||||
* If status line can't be parsed return -1.
|
||||
*/
|
||||
if (statusLine.startsWith("HTTP/1.")) {
|
||||
int codePos = statusLine.indexOf(' ');
|
||||
if (codePos > 0) {
|
||||
|
||||
int phrasePos = statusLine.indexOf(' ', codePos+1);
|
||||
if (phrasePos > 0 && phrasePos < statusLine.length()) {
|
||||
responseMessage = statusLine.substring(phrasePos+1);
|
||||
}
|
||||
|
||||
// deviation from RFC 2616 - don't reject status line
|
||||
// if SP Reason-Phrase is not included.
|
||||
if (phrasePos < 0)
|
||||
phrasePos = statusLine.length();
|
||||
|
||||
try {
|
||||
responseCode = Integer.parseInt
|
||||
(statusLine.substring(codePos+1, phrasePos));
|
||||
return responseCode;
|
||||
} catch (NumberFormatException e) { }
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the HTTP response message, if any, returned along with the
|
||||
* response code from a server. From responses like:
|
||||
* <PRE>
|
||||
* HTTP/1.0 200 OK
|
||||
* HTTP/1.0 404 Not Found
|
||||
* </PRE>
|
||||
* Extracts the Strings "OK" and "Not Found" respectively.
|
||||
* Returns null if none could be discerned from the responses
|
||||
* (the result was not valid HTTP).
|
||||
* @throws IOException if an error occurred connecting to the server.
|
||||
* @return the HTTP response message, or {@code null}
|
||||
*/
|
||||
public String getResponseMessage() throws IOException {
|
||||
getResponseCode();
|
||||
return responseMessage;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public long getHeaderFieldDate(String name, long Default) {
|
||||
String dateString = getHeaderField(name);
|
||||
try {
|
||||
if (dateString.indexOf("GMT") == -1) {
|
||||
dateString = dateString+" GMT";
|
||||
}
|
||||
return Date.parse(dateString);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
return Default;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Indicates that other requests to the server
|
||||
* are unlikely in the near future. Calling disconnect()
|
||||
* should not imply that this HttpURLConnection
|
||||
* instance can be reused for other requests.
|
||||
*/
|
||||
public abstract void disconnect();
|
||||
|
||||
/**
|
||||
* Indicates if the connection is going through a proxy.
|
||||
* @return a boolean indicating if the connection is
|
||||
* using a proxy.
|
||||
*/
|
||||
public abstract boolean usingProxy();
|
||||
|
||||
/**
|
||||
* Returns a {@link SocketPermission} object representing the
|
||||
* permission necessary to connect to the destination host and port.
|
||||
*
|
||||
* @exception IOException if an error occurs while computing
|
||||
* the permission.
|
||||
*
|
||||
* @return a {@code SocketPermission} object representing the
|
||||
* permission necessary to connect to the destination
|
||||
* host and port.
|
||||
*/
|
||||
public Permission getPermission() throws IOException {
|
||||
int port = url.getPort();
|
||||
port = port < 0 ? 80 : port;
|
||||
String host = url.getHost() + ":" + port;
|
||||
Permission permission = new SocketPermission(host, "connect");
|
||||
return permission;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the error stream if the connection failed
|
||||
* but the server sent useful data nonetheless. The
|
||||
* typical example is when an HTTP server responds
|
||||
* with a 404, which will cause a FileNotFoundException
|
||||
* to be thrown in connect, but the server sent an HTML
|
||||
* help page with suggestions as to what to do.
|
||||
*
|
||||
* <p>This method will not cause a connection to be initiated. If
|
||||
* the connection was not connected, or if the server did not have
|
||||
* an error while connecting or if the server had an error but
|
||||
* no error data was sent, this method will return null. This is
|
||||
* the default.
|
||||
*
|
||||
* @return an error stream if any, null if there have been no
|
||||
* errors, the connection is not connected or the server sent no
|
||||
* useful data.
|
||||
*/
|
||||
public InputStream getErrorStream() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The response codes for HTTP, as of version 1.1.
|
||||
*/
|
||||
|
||||
// REMIND: do we want all these??
|
||||
// Others not here that we do want??
|
||||
|
||||
/* 2XX: generally "OK" */
|
||||
|
||||
/**
|
||||
* HTTP Status-Code 200: OK.
|
||||
*/
|
||||
public static final int HTTP_OK = 200;
|
||||
|
||||
/**
|
||||
* HTTP Status-Code 201: Created.
|
||||
*/
|
||||
public static final int HTTP_CREATED = 201;
|
||||
|
||||
/**
|
||||
* HTTP Status-Code 202: Accepted.
|
||||
*/
|
||||
public static final int HTTP_ACCEPTED = 202;
|
||||
|
||||
/**
|
||||
* HTTP Status-Code 203: Non-Authoritative Information.
|
||||
*/
|
||||
public static final int HTTP_NOT_AUTHORITATIVE = 203;
|
||||
|
||||
/**
|
||||
* HTTP Status-Code 204: No Content.
|
||||
*/
|
||||
public static final int HTTP_NO_CONTENT = 204;
|
||||
|
||||
/**
|
||||
* HTTP Status-Code 205: Reset Content.
|
||||
*/
|
||||
public static final int HTTP_RESET = 205;
|
||||
|
||||
/**
|
||||
* HTTP Status-Code 206: Partial Content.
|
||||
*/
|
||||
public static final int HTTP_PARTIAL = 206;
|
||||
|
||||
/* 3XX: relocation/redirect */
|
||||
|
||||
/**
|
||||
* HTTP Status-Code 300: Multiple Choices.
|
||||
*/
|
||||
public static final int HTTP_MULT_CHOICE = 300;
|
||||
|
||||
/**
|
||||
* HTTP Status-Code 301: Moved Permanently.
|
||||
*/
|
||||
public static final int HTTP_MOVED_PERM = 301;
|
||||
|
||||
/**
|
||||
* HTTP Status-Code 302: Temporary Redirect.
|
||||
*/
|
||||
public static final int HTTP_MOVED_TEMP = 302;
|
||||
|
||||
/**
|
||||
* HTTP Status-Code 303: See Other.
|
||||
*/
|
||||
public static final int HTTP_SEE_OTHER = 303;
|
||||
|
||||
/**
|
||||
* HTTP Status-Code 304: Not Modified.
|
||||
*/
|
||||
public static final int HTTP_NOT_MODIFIED = 304;
|
||||
|
||||
/**
|
||||
* HTTP Status-Code 305: Use Proxy.
|
||||
*/
|
||||
public static final int HTTP_USE_PROXY = 305;
|
||||
|
||||
/* 4XX: client error */
|
||||
|
||||
/**
|
||||
* HTTP Status-Code 400: Bad Request.
|
||||
*/
|
||||
public static final int HTTP_BAD_REQUEST = 400;
|
||||
|
||||
/**
|
||||
* HTTP Status-Code 401: Unauthorized.
|
||||
*/
|
||||
public static final int HTTP_UNAUTHORIZED = 401;
|
||||
|
||||
/**
|
||||
* HTTP Status-Code 402: Payment Required.
|
||||
*/
|
||||
public static final int HTTP_PAYMENT_REQUIRED = 402;
|
||||
|
||||
/**
|
||||
* HTTP Status-Code 403: Forbidden.
|
||||
*/
|
||||
public static final int HTTP_FORBIDDEN = 403;
|
||||
|
||||
/**
|
||||
* HTTP Status-Code 404: Not Found.
|
||||
*/
|
||||
public static final int HTTP_NOT_FOUND = 404;
|
||||
|
||||
/**
|
||||
* HTTP Status-Code 405: Method Not Allowed.
|
||||
*/
|
||||
public static final int HTTP_BAD_METHOD = 405;
|
||||
|
||||
/**
|
||||
* HTTP Status-Code 406: Not Acceptable.
|
||||
*/
|
||||
public static final int HTTP_NOT_ACCEPTABLE = 406;
|
||||
|
||||
/**
|
||||
* HTTP Status-Code 407: Proxy Authentication Required.
|
||||
*/
|
||||
public static final int HTTP_PROXY_AUTH = 407;
|
||||
|
||||
/**
|
||||
* HTTP Status-Code 408: Request Time-Out.
|
||||
*/
|
||||
public static final int HTTP_CLIENT_TIMEOUT = 408;
|
||||
|
||||
/**
|
||||
* HTTP Status-Code 409: Conflict.
|
||||
*/
|
||||
public static final int HTTP_CONFLICT = 409;
|
||||
|
||||
/**
|
||||
* HTTP Status-Code 410: Gone.
|
||||
*/
|
||||
public static final int HTTP_GONE = 410;
|
||||
|
||||
/**
|
||||
* HTTP Status-Code 411: Length Required.
|
||||
*/
|
||||
public static final int HTTP_LENGTH_REQUIRED = 411;
|
||||
|
||||
/**
|
||||
* HTTP Status-Code 412: Precondition Failed.
|
||||
*/
|
||||
public static final int HTTP_PRECON_FAILED = 412;
|
||||
|
||||
/**
|
||||
* HTTP Status-Code 413: Request Entity Too Large.
|
||||
*/
|
||||
public static final int HTTP_ENTITY_TOO_LARGE = 413;
|
||||
|
||||
/**
|
||||
* HTTP Status-Code 414: Request-URI Too Large.
|
||||
*/
|
||||
public static final int HTTP_REQ_TOO_LONG = 414;
|
||||
|
||||
/**
|
||||
* HTTP Status-Code 415: Unsupported Media Type.
|
||||
*/
|
||||
public static final int HTTP_UNSUPPORTED_TYPE = 415;
|
||||
|
||||
/* 5XX: server error */
|
||||
|
||||
/**
|
||||
* HTTP Status-Code 500: Internal Server Error.
|
||||
* @deprecated it is misplaced and shouldn't have existed.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final int HTTP_SERVER_ERROR = 500;
|
||||
|
||||
/**
|
||||
* HTTP Status-Code 500: Internal Server Error.
|
||||
*/
|
||||
public static final int HTTP_INTERNAL_ERROR = 500;
|
||||
|
||||
/**
|
||||
* HTTP Status-Code 501: Not Implemented.
|
||||
*/
|
||||
public static final int HTTP_NOT_IMPLEMENTED = 501;
|
||||
|
||||
/**
|
||||
* HTTP Status-Code 502: Bad Gateway.
|
||||
*/
|
||||
public static final int HTTP_BAD_GATEWAY = 502;
|
||||
|
||||
/**
|
||||
* HTTP Status-Code 503: Service Unavailable.
|
||||
*/
|
||||
public static final int HTTP_UNAVAILABLE = 503;
|
||||
|
||||
/**
|
||||
* HTTP Status-Code 504: Gateway Timeout.
|
||||
*/
|
||||
public static final int HTTP_GATEWAY_TIMEOUT = 504;
|
||||
|
||||
/**
|
||||
* HTTP Status-Code 505: HTTP Version Not Supported.
|
||||
*/
|
||||
public static final int HTTP_VERSION = 505;
|
||||
|
||||
}
|
||||
499
jdkSrc/jdk8/java/net/IDN.java
Normal file
499
jdkSrc/jdk8/java/net/IDN.java
Normal file
@@ -0,0 +1,499 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package java.net;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
import sun.net.idn.StringPrep;
|
||||
import sun.net.idn.Punycode;
|
||||
import sun.text.normalizer.UCharacterIterator;
|
||||
|
||||
/**
|
||||
* Provides methods to convert internationalized domain names (IDNs) between
|
||||
* a normal Unicode representation and an ASCII Compatible Encoding (ACE) representation.
|
||||
* Internationalized domain names can use characters from the entire range of
|
||||
* Unicode, while traditional domain names are restricted to ASCII characters.
|
||||
* ACE is an encoding of Unicode strings that uses only ASCII characters and
|
||||
* can be used with software (such as the Domain Name System) that only
|
||||
* understands traditional domain names.
|
||||
*
|
||||
* <p>Internationalized domain names are defined in <a href="http://www.ietf.org/rfc/rfc3490.txt">RFC 3490</a>.
|
||||
* RFC 3490 defines two operations: ToASCII and ToUnicode. These 2 operations employ
|
||||
* <a href="http://www.ietf.org/rfc/rfc3491.txt">Nameprep</a> algorithm, which is a
|
||||
* profile of <a href="http://www.ietf.org/rfc/rfc3454.txt">Stringprep</a>, and
|
||||
* <a href="http://www.ietf.org/rfc/rfc3492.txt">Punycode</a> algorithm to convert
|
||||
* domain name string back and forth.
|
||||
*
|
||||
* <p>The behavior of aforementioned conversion process can be adjusted by various flags:
|
||||
* <ul>
|
||||
* <li>If the ALLOW_UNASSIGNED flag is used, the domain name string to be converted
|
||||
* can contain code points that are unassigned in Unicode 3.2, which is the
|
||||
* Unicode version on which IDN conversion is based. If the flag is not used,
|
||||
* the presence of such unassigned code points is treated as an error.
|
||||
* <li>If the USE_STD3_ASCII_RULES flag is used, ASCII strings are checked against <a href="http://www.ietf.org/rfc/rfc1122.txt">RFC 1122</a> and <a href="http://www.ietf.org/rfc/rfc1123.txt">RFC 1123</a>.
|
||||
* It is an error if they don't meet the requirements.
|
||||
* </ul>
|
||||
* These flags can be logically OR'ed together.
|
||||
*
|
||||
* <p>The security consideration is important with respect to internationalization
|
||||
* domain name support. For example, English domain names may be <i>homographed</i>
|
||||
* - maliciously misspelled by substitution of non-Latin letters.
|
||||
* <a href="http://www.unicode.org/reports/tr36/">Unicode Technical Report #36</a>
|
||||
* discusses security issues of IDN support as well as possible solutions.
|
||||
* Applications are responsible for taking adequate security measures when using
|
||||
* international domain names.
|
||||
*
|
||||
* @author Edward Wang
|
||||
* @since 1.6
|
||||
*
|
||||
*/
|
||||
public final class IDN {
|
||||
/**
|
||||
* Flag to allow processing of unassigned code points
|
||||
*/
|
||||
public static final int ALLOW_UNASSIGNED = 0x01;
|
||||
|
||||
/**
|
||||
* Flag to turn on the check against STD-3 ASCII rules
|
||||
*/
|
||||
public static final int USE_STD3_ASCII_RULES = 0x02;
|
||||
|
||||
|
||||
/**
|
||||
* Translates a string from Unicode to ASCII Compatible Encoding (ACE),
|
||||
* as defined by the ToASCII operation of <a href="http://www.ietf.org/rfc/rfc3490.txt">RFC 3490</a>.
|
||||
*
|
||||
* <p>ToASCII operation can fail. ToASCII fails if any step of it fails.
|
||||
* If ToASCII operation fails, an IllegalArgumentException will be thrown.
|
||||
* In this case, the input string should not be used in an internationalized domain name.
|
||||
*
|
||||
* <p> A label is an individual part of a domain name. The original ToASCII operation,
|
||||
* as defined in RFC 3490, only operates on a single label. This method can handle
|
||||
* both label and entire domain name, by assuming that labels in a domain name are
|
||||
* always separated by dots. The following characters are recognized as dots:
|
||||
* \u002E (full stop), \u3002 (ideographic full stop), \uFF0E (fullwidth full stop),
|
||||
* and \uFF61 (halfwidth ideographic full stop). if dots are
|
||||
* used as label separators, this method also changes all of them to \u002E (full stop)
|
||||
* in output translated string.
|
||||
*
|
||||
* @param input the string to be processed
|
||||
* @param flag process flag; can be 0 or any logical OR of possible flags
|
||||
*
|
||||
* @return the translated {@code String}
|
||||
*
|
||||
* @throws IllegalArgumentException if the input string doesn't conform to RFC 3490 specification
|
||||
*/
|
||||
public static String toASCII(String input, int flag)
|
||||
{
|
||||
int p = 0, q = 0;
|
||||
StringBuffer out = new StringBuffer();
|
||||
|
||||
if (isRootLabel(input)) {
|
||||
return ".";
|
||||
}
|
||||
|
||||
while (p < input.length()) {
|
||||
q = searchDots(input, p);
|
||||
out.append(toASCIIInternal(input.substring(p, q), flag));
|
||||
if (q != (input.length())) {
|
||||
// has more labels, or keep the trailing dot as at present
|
||||
out.append('.');
|
||||
}
|
||||
p = q + 1;
|
||||
}
|
||||
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Translates a string from Unicode to ASCII Compatible Encoding (ACE),
|
||||
* as defined by the ToASCII operation of <a href="http://www.ietf.org/rfc/rfc3490.txt">RFC 3490</a>.
|
||||
*
|
||||
* <p> This convenience method works as if by invoking the
|
||||
* two-argument counterpart as follows:
|
||||
* <blockquote>
|
||||
* {@link #toASCII(String, int) toASCII}(input, 0);
|
||||
* </blockquote>
|
||||
*
|
||||
* @param input the string to be processed
|
||||
*
|
||||
* @return the translated {@code String}
|
||||
*
|
||||
* @throws IllegalArgumentException if the input string doesn't conform to RFC 3490 specification
|
||||
*/
|
||||
public static String toASCII(String input) {
|
||||
return toASCII(input, 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Translates a string from ASCII Compatible Encoding (ACE) to Unicode,
|
||||
* as defined by the ToUnicode operation of <a href="http://www.ietf.org/rfc/rfc3490.txt">RFC 3490</a>.
|
||||
*
|
||||
* <p>ToUnicode never fails. In case of any error, the input string is returned unmodified.
|
||||
*
|
||||
* <p> A label is an individual part of a domain name. The original ToUnicode operation,
|
||||
* as defined in RFC 3490, only operates on a single label. This method can handle
|
||||
* both label and entire domain name, by assuming that labels in a domain name are
|
||||
* always separated by dots. The following characters are recognized as dots:
|
||||
* \u002E (full stop), \u3002 (ideographic full stop), \uFF0E (fullwidth full stop),
|
||||
* and \uFF61 (halfwidth ideographic full stop).
|
||||
*
|
||||
* @param input the string to be processed
|
||||
* @param flag process flag; can be 0 or any logical OR of possible flags
|
||||
*
|
||||
* @return the translated {@code String}
|
||||
*/
|
||||
public static String toUnicode(String input, int flag) {
|
||||
int p = 0, q = 0;
|
||||
StringBuffer out = new StringBuffer();
|
||||
|
||||
if (isRootLabel(input)) {
|
||||
return ".";
|
||||
}
|
||||
|
||||
while (p < input.length()) {
|
||||
q = searchDots(input, p);
|
||||
out.append(toUnicodeInternal(input.substring(p, q), flag));
|
||||
if (q != (input.length())) {
|
||||
// has more labels, or keep the trailing dot as at present
|
||||
out.append('.');
|
||||
}
|
||||
p = q + 1;
|
||||
}
|
||||
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Translates a string from ASCII Compatible Encoding (ACE) to Unicode,
|
||||
* as defined by the ToUnicode operation of <a href="http://www.ietf.org/rfc/rfc3490.txt">RFC 3490</a>.
|
||||
*
|
||||
* <p> This convenience method works as if by invoking the
|
||||
* two-argument counterpart as follows:
|
||||
* <blockquote>
|
||||
* {@link #toUnicode(String, int) toUnicode}(input, 0);
|
||||
* </blockquote>
|
||||
*
|
||||
* @param input the string to be processed
|
||||
*
|
||||
* @return the translated {@code String}
|
||||
*/
|
||||
public static String toUnicode(String input) {
|
||||
return toUnicode(input, 0);
|
||||
}
|
||||
|
||||
|
||||
/* ---------------- Private members -------------- */
|
||||
|
||||
// ACE Prefix is "xn--"
|
||||
private static final String ACE_PREFIX = "xn--";
|
||||
private static final int ACE_PREFIX_LENGTH = ACE_PREFIX.length();
|
||||
|
||||
private static final int MAX_LABEL_LENGTH = 63;
|
||||
|
||||
// single instance of nameprep
|
||||
private static StringPrep namePrep = null;
|
||||
|
||||
static {
|
||||
InputStream stream = null;
|
||||
|
||||
try {
|
||||
final String IDN_PROFILE = "uidna.spp";
|
||||
if (System.getSecurityManager() != null) {
|
||||
stream = AccessController.doPrivileged(new PrivilegedAction<InputStream>() {
|
||||
public InputStream run() {
|
||||
return StringPrep.class.getResourceAsStream(IDN_PROFILE);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
stream = StringPrep.class.getResourceAsStream(IDN_PROFILE);
|
||||
}
|
||||
|
||||
namePrep = new StringPrep(stream);
|
||||
stream.close();
|
||||
} catch (IOException e) {
|
||||
// should never reach here
|
||||
assert false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ---------------- Private operations -------------- */
|
||||
|
||||
|
||||
//
|
||||
// to suppress the default zero-argument constructor
|
||||
//
|
||||
private IDN() {}
|
||||
|
||||
//
|
||||
// toASCII operation; should only apply to a single label
|
||||
//
|
||||
private static String toASCIIInternal(String label, int flag)
|
||||
{
|
||||
// step 1
|
||||
// Check if the string contains code points outside the ASCII range 0..0x7c.
|
||||
boolean isASCII = isAllASCII(label);
|
||||
StringBuffer dest;
|
||||
|
||||
// step 2
|
||||
// perform the nameprep operation; flag ALLOW_UNASSIGNED is used here
|
||||
if (!isASCII) {
|
||||
UCharacterIterator iter = UCharacterIterator.getInstance(label);
|
||||
try {
|
||||
dest = namePrep.prepare(iter, flag);
|
||||
} catch (java.text.ParseException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
} else {
|
||||
dest = new StringBuffer(label);
|
||||
}
|
||||
|
||||
// step 8, move forward to check the smallest number of the code points
|
||||
// the length must be inside 1..63
|
||||
if (dest.length() == 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"Empty label is not a legal name");
|
||||
}
|
||||
|
||||
// step 3
|
||||
// Verify the absence of non-LDH ASCII code points
|
||||
// 0..0x2c, 0x2e..0x2f, 0x3a..0x40, 0x5b..0x60, 0x7b..0x7f
|
||||
// Verify the absence of leading and trailing hyphen
|
||||
boolean useSTD3ASCIIRules = ((flag & USE_STD3_ASCII_RULES) != 0);
|
||||
if (useSTD3ASCIIRules) {
|
||||
for (int i = 0; i < dest.length(); i++) {
|
||||
int c = dest.charAt(i);
|
||||
if (isNonLDHAsciiCodePoint(c)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Contains non-LDH ASCII characters");
|
||||
}
|
||||
}
|
||||
|
||||
if (dest.charAt(0) == '-' ||
|
||||
dest.charAt(dest.length() - 1) == '-') {
|
||||
|
||||
throw new IllegalArgumentException(
|
||||
"Has leading or trailing hyphen");
|
||||
}
|
||||
}
|
||||
|
||||
if (!isASCII) {
|
||||
// step 4
|
||||
// If all code points are inside 0..0x7f, skip to step 8
|
||||
if (!isAllASCII(dest.toString())) {
|
||||
// step 5
|
||||
// verify the sequence does not begin with ACE prefix
|
||||
if(!startsWithACEPrefix(dest)){
|
||||
|
||||
// step 6
|
||||
// encode the sequence with punycode
|
||||
try {
|
||||
dest = Punycode.encode(dest, null);
|
||||
} catch (java.text.ParseException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
|
||||
dest = toASCIILower(dest);
|
||||
|
||||
// step 7
|
||||
// prepend the ACE prefix
|
||||
dest.insert(0, ACE_PREFIX);
|
||||
} else {
|
||||
throw new IllegalArgumentException("The input starts with the ACE Prefix");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// step 8
|
||||
// the length must be inside 1..63
|
||||
if (dest.length() > MAX_LABEL_LENGTH) {
|
||||
throw new IllegalArgumentException("The label in the input is too long");
|
||||
}
|
||||
|
||||
return dest.toString();
|
||||
}
|
||||
|
||||
//
|
||||
// toUnicode operation; should only apply to a single label
|
||||
//
|
||||
private static String toUnicodeInternal(String label, int flag) {
|
||||
boolean[] caseFlags = null;
|
||||
StringBuffer dest;
|
||||
|
||||
// step 1
|
||||
// find out if all the codepoints in input are ASCII
|
||||
boolean isASCII = isAllASCII(label);
|
||||
|
||||
if(!isASCII){
|
||||
// step 2
|
||||
// perform the nameprep operation; flag ALLOW_UNASSIGNED is used here
|
||||
try {
|
||||
UCharacterIterator iter = UCharacterIterator.getInstance(label);
|
||||
dest = namePrep.prepare(iter, flag);
|
||||
} catch (Exception e) {
|
||||
// toUnicode never fails; if any step fails, return the input string
|
||||
return label;
|
||||
}
|
||||
} else {
|
||||
dest = new StringBuffer(label);
|
||||
}
|
||||
|
||||
// step 3
|
||||
// verify ACE Prefix
|
||||
if(startsWithACEPrefix(dest)) {
|
||||
|
||||
// step 4
|
||||
// Remove the ACE Prefix
|
||||
String temp = dest.substring(ACE_PREFIX_LENGTH, dest.length());
|
||||
|
||||
try {
|
||||
// step 5
|
||||
// Decode using punycode
|
||||
StringBuffer decodeOut = Punycode.decode(new StringBuffer(temp), null);
|
||||
|
||||
// step 6
|
||||
// Apply toASCII
|
||||
String toASCIIOut = toASCII(decodeOut.toString(), flag);
|
||||
|
||||
// step 7
|
||||
// verify
|
||||
if (toASCIIOut.equalsIgnoreCase(dest.toString())) {
|
||||
// step 8
|
||||
// return output of step 5
|
||||
return decodeOut.toString();
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
|
||||
// just return the input
|
||||
return label;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// LDH stands for "letter/digit/hyphen", with characters restricted to the
|
||||
// 26-letter Latin alphabet <A-Z a-z>, the digits <0-9>, and the hyphen
|
||||
// <->.
|
||||
// Non LDH refers to characters in the ASCII range, but which are not
|
||||
// letters, digits or the hypen.
|
||||
//
|
||||
// non-LDH = 0..0x2C, 0x2E..0x2F, 0x3A..0x40, 0x5B..0x60, 0x7B..0x7F
|
||||
//
|
||||
private static boolean isNonLDHAsciiCodePoint(int ch){
|
||||
return (0x0000 <= ch && ch <= 0x002C) ||
|
||||
(0x002E <= ch && ch <= 0x002F) ||
|
||||
(0x003A <= ch && ch <= 0x0040) ||
|
||||
(0x005B <= ch && ch <= 0x0060) ||
|
||||
(0x007B <= ch && ch <= 0x007F);
|
||||
}
|
||||
|
||||
//
|
||||
// search dots in a string and return the index of that character;
|
||||
// or if there is no dots, return the length of input string
|
||||
// dots might be: \u002E (full stop), \u3002 (ideographic full stop), \uFF0E (fullwidth full stop),
|
||||
// and \uFF61 (halfwidth ideographic full stop).
|
||||
//
|
||||
private static int searchDots(String s, int start) {
|
||||
int i;
|
||||
for (i = start; i < s.length(); i++) {
|
||||
if (isLabelSeparator(s.charAt(i))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
//
|
||||
// to check if a string is a root label, ".".
|
||||
//
|
||||
private static boolean isRootLabel(String s) {
|
||||
return (s.length() == 1 && isLabelSeparator(s.charAt(0)));
|
||||
}
|
||||
|
||||
//
|
||||
// to check if a character is a label separator, i.e. a dot character.
|
||||
//
|
||||
private static boolean isLabelSeparator(char c) {
|
||||
return (c == '.' || c == '\u3002' || c == '\uFF0E' || c == '\uFF61');
|
||||
}
|
||||
|
||||
//
|
||||
// to check if a string only contains US-ASCII code point
|
||||
//
|
||||
private static boolean isAllASCII(String input) {
|
||||
boolean isASCII = true;
|
||||
for (int i = 0; i < input.length(); i++) {
|
||||
int c = input.charAt(i);
|
||||
if (c > 0x7F) {
|
||||
isASCII = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return isASCII;
|
||||
}
|
||||
|
||||
//
|
||||
// to check if a string starts with ACE-prefix
|
||||
//
|
||||
private static boolean startsWithACEPrefix(StringBuffer input){
|
||||
boolean startsWithPrefix = true;
|
||||
|
||||
if(input.length() < ACE_PREFIX_LENGTH){
|
||||
return false;
|
||||
}
|
||||
for(int i = 0; i < ACE_PREFIX_LENGTH; i++){
|
||||
if(toASCIILower(input.charAt(i)) != ACE_PREFIX.charAt(i)){
|
||||
startsWithPrefix = false;
|
||||
}
|
||||
}
|
||||
return startsWithPrefix;
|
||||
}
|
||||
|
||||
private static char toASCIILower(char ch){
|
||||
if('A' <= ch && ch <= 'Z'){
|
||||
return (char)(ch + 'a' - 'A');
|
||||
}
|
||||
return ch;
|
||||
}
|
||||
|
||||
private static StringBuffer toASCIILower(StringBuffer input){
|
||||
StringBuffer dest = new StringBuffer();
|
||||
for(int i = 0; i < input.length();i++){
|
||||
dest.append(toASCIILower(input.charAt(i)));
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
}
|
||||
398
jdkSrc/jdk8/java/net/InMemoryCookieStore.java
Normal file
398
jdkSrc/jdk8/java/net/InMemoryCookieStore.java
Normal file
@@ -0,0 +1,398 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.CookieStore;
|
||||
import java.net.HttpCookie;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
/**
|
||||
* A simple in-memory java.net.CookieStore implementation
|
||||
*
|
||||
* @author Edward Wang
|
||||
* @since 1.6
|
||||
*/
|
||||
class InMemoryCookieStore implements CookieStore {
|
||||
// the in-memory representation of cookies
|
||||
private List<HttpCookie> cookieJar = null;
|
||||
|
||||
// the cookies are indexed by its domain and associated uri (if present)
|
||||
// CAUTION: when a cookie removed from main data structure (i.e. cookieJar),
|
||||
// it won't be cleared in domainIndex & uriIndex. Double-check the
|
||||
// presence of cookie when retrieve one form index store.
|
||||
private Map<String, List<HttpCookie>> domainIndex = null;
|
||||
private Map<URI, List<HttpCookie>> uriIndex = null;
|
||||
|
||||
// use ReentrantLock instead of syncronized for scalability
|
||||
private ReentrantLock lock = null;
|
||||
|
||||
|
||||
/**
|
||||
* The default ctor
|
||||
*/
|
||||
public InMemoryCookieStore() {
|
||||
cookieJar = new ArrayList<HttpCookie>();
|
||||
domainIndex = new HashMap<String, List<HttpCookie>>();
|
||||
uriIndex = new HashMap<URI, List<HttpCookie>>();
|
||||
|
||||
lock = new ReentrantLock(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add one cookie into cookie store.
|
||||
*/
|
||||
public void add(URI uri, HttpCookie cookie) {
|
||||
// pre-condition : argument can't be null
|
||||
if (cookie == null) {
|
||||
throw new NullPointerException("cookie is null");
|
||||
}
|
||||
|
||||
|
||||
lock.lock();
|
||||
try {
|
||||
// remove the ole cookie if there has had one
|
||||
cookieJar.remove(cookie);
|
||||
|
||||
// add new cookie if it has a non-zero max-age
|
||||
if (cookie.getMaxAge() != 0) {
|
||||
cookieJar.add(cookie);
|
||||
// and add it to domain index
|
||||
if (cookie.getDomain() != null) {
|
||||
addIndex(domainIndex, cookie.getDomain(), cookie);
|
||||
}
|
||||
if (uri != null) {
|
||||
// add it to uri index, too
|
||||
addIndex(uriIndex, getEffectiveURI(uri), cookie);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get all cookies, which:
|
||||
* 1) given uri domain-matches with, or, associated with
|
||||
* given uri when added to the cookie store.
|
||||
* 3) not expired.
|
||||
* See RFC 2965 sec. 3.3.4 for more detail.
|
||||
*/
|
||||
public List<HttpCookie> get(URI uri) {
|
||||
// argument can't be null
|
||||
if (uri == null) {
|
||||
throw new NullPointerException("uri is null");
|
||||
}
|
||||
|
||||
List<HttpCookie> cookies = new ArrayList<HttpCookie>();
|
||||
boolean secureLink = "https".equalsIgnoreCase(uri.getScheme());
|
||||
lock.lock();
|
||||
try {
|
||||
// check domainIndex first
|
||||
getInternal1(cookies, domainIndex, uri.getHost(), secureLink);
|
||||
// check uriIndex then
|
||||
getInternal2(cookies, uriIndex, getEffectiveURI(uri), secureLink);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
return cookies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all cookies in cookie store, except those have expired
|
||||
*/
|
||||
public List<HttpCookie> getCookies() {
|
||||
List<HttpCookie> rt;
|
||||
|
||||
lock.lock();
|
||||
try {
|
||||
Iterator<HttpCookie> it = cookieJar.iterator();
|
||||
while (it.hasNext()) {
|
||||
if (it.next().hasExpired()) {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
rt = Collections.unmodifiableList(cookieJar);
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all URIs, which are associated with at least one cookie
|
||||
* of this cookie store.
|
||||
*/
|
||||
public List<URI> getURIs() {
|
||||
List<URI> uris = new ArrayList<URI>();
|
||||
|
||||
lock.lock();
|
||||
try {
|
||||
Iterator<URI> it = uriIndex.keySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
URI uri = it.next();
|
||||
List<HttpCookie> cookies = uriIndex.get(uri);
|
||||
if (cookies == null || cookies.size() == 0) {
|
||||
// no cookies list or an empty list associated with
|
||||
// this uri entry, delete it
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
uris.addAll(uriIndex.keySet());
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
return uris;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove a cookie from store
|
||||
*/
|
||||
public boolean remove(URI uri, HttpCookie ck) {
|
||||
// argument can't be null
|
||||
if (ck == null) {
|
||||
throw new NullPointerException("cookie is null");
|
||||
}
|
||||
|
||||
boolean modified = false;
|
||||
lock.lock();
|
||||
try {
|
||||
modified = cookieJar.remove(ck);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
return modified;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove all cookies in this cookie store.
|
||||
*/
|
||||
public boolean removeAll() {
|
||||
lock.lock();
|
||||
try {
|
||||
if (cookieJar.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
cookieJar.clear();
|
||||
domainIndex.clear();
|
||||
uriIndex.clear();
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* ---------------- Private operations -------------- */
|
||||
|
||||
|
||||
/*
|
||||
* This is almost the same as HttpCookie.domainMatches except for
|
||||
* one difference: It won't reject cookies when the 'H' part of the
|
||||
* domain contains a dot ('.').
|
||||
* I.E.: RFC 2965 section 3.3.2 says that if host is x.y.domain.com
|
||||
* and the cookie domain is .domain.com, then it should be rejected.
|
||||
* However that's not how the real world works. Browsers don't reject and
|
||||
* some sites, like yahoo.com do actually expect these cookies to be
|
||||
* passed along.
|
||||
* And should be used for 'old' style cookies (aka Netscape type of cookies)
|
||||
*/
|
||||
private boolean netscapeDomainMatches(String domain, String host)
|
||||
{
|
||||
if (domain == null || host == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// if there's no embedded dot in domain and domain is not .local
|
||||
boolean isLocalDomain = ".local".equalsIgnoreCase(domain);
|
||||
int embeddedDotInDomain = domain.indexOf('.');
|
||||
if (embeddedDotInDomain == 0) {
|
||||
embeddedDotInDomain = domain.indexOf('.', 1);
|
||||
}
|
||||
if (!isLocalDomain && (embeddedDotInDomain == -1 || embeddedDotInDomain == domain.length() - 1)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// if the host name contains no dot and the domain name is .local
|
||||
int firstDotInHost = host.indexOf('.');
|
||||
if (firstDotInHost == -1 && isLocalDomain) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int domainLength = domain.length();
|
||||
int lengthDiff = host.length() - domainLength;
|
||||
if (lengthDiff == 0) {
|
||||
// if the host name and the domain name are just string-compare euqal
|
||||
return host.equalsIgnoreCase(domain);
|
||||
} else if (lengthDiff > 0) {
|
||||
// need to check H & D component
|
||||
String H = host.substring(0, lengthDiff);
|
||||
String D = host.substring(lengthDiff);
|
||||
|
||||
return (D.equalsIgnoreCase(domain));
|
||||
} else if (lengthDiff == -1) {
|
||||
// if domain is actually .host
|
||||
return (domain.charAt(0) == '.' &&
|
||||
host.equalsIgnoreCase(domain.substring(1)));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void getInternal1(List<HttpCookie> cookies, Map<String, List<HttpCookie>> cookieIndex,
|
||||
String host, boolean secureLink) {
|
||||
// Use a separate list to handle cookies that need to be removed so
|
||||
// that there is no conflict with iterators.
|
||||
ArrayList<HttpCookie> toRemove = new ArrayList<HttpCookie>();
|
||||
for (Map.Entry<String, List<HttpCookie>> entry : cookieIndex.entrySet()) {
|
||||
String domain = entry.getKey();
|
||||
List<HttpCookie> lst = entry.getValue();
|
||||
for (HttpCookie c : lst) {
|
||||
if ((c.getVersion() == 0 && netscapeDomainMatches(domain, host)) ||
|
||||
(c.getVersion() == 1 && HttpCookie.domainMatches(domain, host))) {
|
||||
if ((cookieJar.indexOf(c) != -1)) {
|
||||
// the cookie still in main cookie store
|
||||
if (!c.hasExpired()) {
|
||||
// don't add twice and make sure it's the proper
|
||||
// security level
|
||||
if ((secureLink || !c.getSecure()) &&
|
||||
!cookies.contains(c)) {
|
||||
cookies.add(c);
|
||||
}
|
||||
} else {
|
||||
toRemove.add(c);
|
||||
}
|
||||
} else {
|
||||
// the cookie has beed removed from main store,
|
||||
// so also remove it from domain indexed store
|
||||
toRemove.add(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Clear up the cookies that need to be removed
|
||||
for (HttpCookie c : toRemove) {
|
||||
lst.remove(c);
|
||||
cookieJar.remove(c);
|
||||
|
||||
}
|
||||
toRemove.clear();
|
||||
}
|
||||
}
|
||||
|
||||
// @param cookies [OUT] contains the found cookies
|
||||
// @param cookieIndex the index
|
||||
// @param comparator the prediction to decide whether or not
|
||||
// a cookie in index should be returned
|
||||
private <T> void getInternal2(List<HttpCookie> cookies,
|
||||
Map<T, List<HttpCookie>> cookieIndex,
|
||||
Comparable<T> comparator, boolean secureLink)
|
||||
{
|
||||
for (T index : cookieIndex.keySet()) {
|
||||
if (comparator.compareTo(index) == 0) {
|
||||
List<HttpCookie> indexedCookies = cookieIndex.get(index);
|
||||
// check the list of cookies associated with this domain
|
||||
if (indexedCookies != null) {
|
||||
Iterator<HttpCookie> it = indexedCookies.iterator();
|
||||
while (it.hasNext()) {
|
||||
HttpCookie ck = it.next();
|
||||
if (cookieJar.indexOf(ck) != -1) {
|
||||
// the cookie still in main cookie store
|
||||
if (!ck.hasExpired()) {
|
||||
// don't add twice
|
||||
if ((secureLink || !ck.getSecure()) &&
|
||||
!cookies.contains(ck))
|
||||
cookies.add(ck);
|
||||
} else {
|
||||
it.remove();
|
||||
cookieJar.remove(ck);
|
||||
}
|
||||
} else {
|
||||
// the cookie has beed removed from main store,
|
||||
// so also remove it from domain indexed store
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
} // end of indexedCookies != null
|
||||
} // end of comparator.compareTo(index) == 0
|
||||
} // end of cookieIndex iteration
|
||||
}
|
||||
|
||||
// add 'cookie' indexed by 'index' into 'indexStore'
|
||||
private <T> void addIndex(Map<T, List<HttpCookie>> indexStore,
|
||||
T index,
|
||||
HttpCookie cookie)
|
||||
{
|
||||
if (index != null) {
|
||||
List<HttpCookie> cookies = indexStore.get(index);
|
||||
if (cookies != null) {
|
||||
// there may already have the same cookie, so remove it first
|
||||
cookies.remove(cookie);
|
||||
|
||||
cookies.add(cookie);
|
||||
} else {
|
||||
cookies = new ArrayList<HttpCookie>();
|
||||
cookies.add(cookie);
|
||||
indexStore.put(index, cookies);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// for cookie purpose, the effective uri should only be http://host
|
||||
// the path will be taken into account when path-match algorithm applied
|
||||
//
|
||||
private URI getEffectiveURI(URI uri) {
|
||||
URI effectiveURI = null;
|
||||
try {
|
||||
effectiveURI = new URI("http",
|
||||
uri.getHost(),
|
||||
null, // path component
|
||||
null, // query component
|
||||
null // fragment component
|
||||
);
|
||||
} catch (URISyntaxException ignored) {
|
||||
effectiveURI = uri;
|
||||
}
|
||||
|
||||
return effectiveURI;
|
||||
}
|
||||
}
|
||||
380
jdkSrc/jdk8/java/net/Inet4Address.java
Normal file
380
jdkSrc/jdk8/java/net/Inet4Address.java
Normal file
@@ -0,0 +1,380 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
import java.io.ObjectStreamException;
|
||||
|
||||
/**
|
||||
* This class represents an Internet Protocol version 4 (IPv4) address.
|
||||
* Defined by <a href="http://www.ietf.org/rfc/rfc790.txt">
|
||||
* <i>RFC 790: Assigned Numbers</i></a>,
|
||||
* <a href="http://www.ietf.org/rfc/rfc1918.txt">
|
||||
* <i>RFC 1918: Address Allocation for Private Internets</i></a>,
|
||||
* and <a href="http://www.ietf.org/rfc/rfc2365.txt"><i>RFC 2365:
|
||||
* Administratively Scoped IP Multicast</i></a>
|
||||
*
|
||||
* <h3> <A NAME="format">Textual representation of IP addresses</a> </h3>
|
||||
*
|
||||
* Textual representation of IPv4 address used as input to methods
|
||||
* takes one of the following forms:
|
||||
*
|
||||
* <blockquote><table cellpadding=0 cellspacing=0 summary="layout">
|
||||
* <tr><td>{@code d.d.d.d}</td></tr>
|
||||
* <tr><td>{@code d.d.d}</td></tr>
|
||||
* <tr><td>{@code d.d}</td></tr>
|
||||
* <tr><td>{@code d}</td></tr>
|
||||
* </table></blockquote>
|
||||
*
|
||||
* <p> When four parts are specified, each is interpreted as a byte of
|
||||
* data and assigned, from left to right, to the four bytes of an IPv4
|
||||
* address.
|
||||
|
||||
* <p> When a three part address is specified, the last part is
|
||||
* interpreted as a 16-bit quantity and placed in the right most two
|
||||
* bytes of the network address. This makes the three part address
|
||||
* format convenient for specifying Class B net- work addresses as
|
||||
* 128.net.host.
|
||||
*
|
||||
* <p> When a two part address is supplied, the last part is
|
||||
* interpreted as a 24-bit quantity and placed in the right most three
|
||||
* bytes of the network address. This makes the two part address
|
||||
* format convenient for specifying Class A network addresses as
|
||||
* net.host.
|
||||
*
|
||||
* <p> When only one part is given, the value is stored directly in
|
||||
* the network address without any byte rearrangement.
|
||||
*
|
||||
* <p> For methods that return a textual representation as output
|
||||
* value, the first form, i.e. a dotted-quad string, is used.
|
||||
*
|
||||
* <h4> The Scope of a Multicast Address </h4>
|
||||
*
|
||||
* Historically the IPv4 TTL field in the IP header has doubled as a
|
||||
* multicast scope field: a TTL of 0 means node-local, 1 means
|
||||
* link-local, up through 32 means site-local, up through 64 means
|
||||
* region-local, up through 128 means continent-local, and up through
|
||||
* 255 are global. However, the administrative scoping is preferred.
|
||||
* Please refer to <a href="http://www.ietf.org/rfc/rfc2365.txt">
|
||||
* <i>RFC 2365: Administratively Scoped IP Multicast</i></a>
|
||||
* @since 1.4
|
||||
*/
|
||||
|
||||
public final
|
||||
class Inet4Address extends InetAddress {
|
||||
final static int INADDRSZ = 4;
|
||||
|
||||
/** use serialVersionUID from InetAddress, but Inet4Address instance
|
||||
* is always replaced by an InetAddress instance before being
|
||||
* serialized */
|
||||
private static final long serialVersionUID = 3286316764910316507L;
|
||||
|
||||
/*
|
||||
* Perform initializations.
|
||||
*/
|
||||
static {
|
||||
init();
|
||||
}
|
||||
|
||||
Inet4Address() {
|
||||
super();
|
||||
holder().hostName = null;
|
||||
holder().address = 0;
|
||||
holder().family = IPv4;
|
||||
}
|
||||
|
||||
Inet4Address(String hostName, byte addr[]) {
|
||||
holder().hostName = hostName;
|
||||
holder().family = IPv4;
|
||||
if (addr != null) {
|
||||
if (addr.length == INADDRSZ) {
|
||||
int address = addr[3] & 0xFF;
|
||||
address |= ((addr[2] << 8) & 0xFF00);
|
||||
address |= ((addr[1] << 16) & 0xFF0000);
|
||||
address |= ((addr[0] << 24) & 0xFF000000);
|
||||
holder().address = address;
|
||||
}
|
||||
}
|
||||
holder().originalHostName = hostName;
|
||||
}
|
||||
Inet4Address(String hostName, int address) {
|
||||
holder().hostName = hostName;
|
||||
holder().family = IPv4;
|
||||
holder().address = address;
|
||||
holder().originalHostName = hostName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the object to be serialized with an InetAddress object.
|
||||
*
|
||||
* @return the alternate object to be serialized.
|
||||
*
|
||||
* @throws ObjectStreamException if a new object replacing this
|
||||
* object could not be created
|
||||
*/
|
||||
private Object writeReplace() throws ObjectStreamException {
|
||||
// will replace the to be serialized 'this' object
|
||||
InetAddress inet = new InetAddress();
|
||||
inet.holder().hostName = holder().getHostName();
|
||||
inet.holder().address = holder().getAddress();
|
||||
|
||||
/**
|
||||
* Prior to 1.4 an InetAddress was created with a family
|
||||
* based on the platform AF_INET value (usually 2).
|
||||
* For compatibility reasons we must therefore write the
|
||||
* the InetAddress with this family.
|
||||
*/
|
||||
inet.holder().family = 2;
|
||||
|
||||
return inet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility routine to check if the InetAddress is an
|
||||
* IP multicast address. IP multicast address is a Class D
|
||||
* address i.e first four bits of the address are 1110.
|
||||
* @return a {@code boolean} indicating if the InetAddress is
|
||||
* an IP multicast address
|
||||
* @since JDK1.1
|
||||
*/
|
||||
public boolean isMulticastAddress() {
|
||||
return ((holder().getAddress() & 0xf0000000) == 0xe0000000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility routine to check if the InetAddress in a wildcard address.
|
||||
* @return a {@code boolean} indicating if the Inetaddress is
|
||||
* a wildcard address.
|
||||
* @since 1.4
|
||||
*/
|
||||
public boolean isAnyLocalAddress() {
|
||||
return holder().getAddress() == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility routine to check if the InetAddress is a loopback address.
|
||||
*
|
||||
* @return a {@code boolean} indicating if the InetAddress is
|
||||
* a loopback address; or false otherwise.
|
||||
* @since 1.4
|
||||
*/
|
||||
public boolean isLoopbackAddress() {
|
||||
/* 127.x.x.x */
|
||||
byte[] byteAddr = getAddress();
|
||||
return byteAddr[0] == 127;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility routine to check if the InetAddress is an link local address.
|
||||
*
|
||||
* @return a {@code boolean} indicating if the InetAddress is
|
||||
* a link local address; or false if address is not a link local unicast address.
|
||||
* @since 1.4
|
||||
*/
|
||||
public boolean isLinkLocalAddress() {
|
||||
// link-local unicast in IPv4 (169.254.0.0/16)
|
||||
// defined in "Documenting Special Use IPv4 Address Blocks
|
||||
// that have been Registered with IANA" by Bill Manning
|
||||
// draft-manning-dsua-06.txt
|
||||
int address = holder().getAddress();
|
||||
return (((address >>> 24) & 0xFF) == 169)
|
||||
&& (((address >>> 16) & 0xFF) == 254);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility routine to check if the InetAddress is a site local address.
|
||||
*
|
||||
* @return a {@code boolean} indicating if the InetAddress is
|
||||
* a site local address; or false if address is not a site local unicast address.
|
||||
* @since 1.4
|
||||
*/
|
||||
public boolean isSiteLocalAddress() {
|
||||
// refer to RFC 1918
|
||||
// 10/8 prefix
|
||||
// 172.16/12 prefix
|
||||
// 192.168/16 prefix
|
||||
int address = holder().getAddress();
|
||||
return (((address >>> 24) & 0xFF) == 10)
|
||||
|| ((((address >>> 24) & 0xFF) == 172)
|
||||
&& (((address >>> 16) & 0xF0) == 16))
|
||||
|| ((((address >>> 24) & 0xFF) == 192)
|
||||
&& (((address >>> 16) & 0xFF) == 168));
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility routine to check if the multicast address has global scope.
|
||||
*
|
||||
* @return a {@code boolean} indicating if the address has
|
||||
* is a multicast address of global scope, false if it is not
|
||||
* of global scope or it is not a multicast address
|
||||
* @since 1.4
|
||||
*/
|
||||
public boolean isMCGlobal() {
|
||||
// 224.0.1.0 to 238.255.255.255
|
||||
byte[] byteAddr = getAddress();
|
||||
return ((byteAddr[0] & 0xff) >= 224 && (byteAddr[0] & 0xff) <= 238 ) &&
|
||||
!((byteAddr[0] & 0xff) == 224 && byteAddr[1] == 0 &&
|
||||
byteAddr[2] == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility routine to check if the multicast address has node scope.
|
||||
*
|
||||
* @return a {@code boolean} indicating if the address has
|
||||
* is a multicast address of node-local scope, false if it is not
|
||||
* of node-local scope or it is not a multicast address
|
||||
* @since 1.4
|
||||
*/
|
||||
public boolean isMCNodeLocal() {
|
||||
// unless ttl == 0
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility routine to check if the multicast address has link scope.
|
||||
*
|
||||
* @return a {@code boolean} indicating if the address has
|
||||
* is a multicast address of link-local scope, false if it is not
|
||||
* of link-local scope or it is not a multicast address
|
||||
* @since 1.4
|
||||
*/
|
||||
public boolean isMCLinkLocal() {
|
||||
// 224.0.0/24 prefix and ttl == 1
|
||||
int address = holder().getAddress();
|
||||
return (((address >>> 24) & 0xFF) == 224)
|
||||
&& (((address >>> 16) & 0xFF) == 0)
|
||||
&& (((address >>> 8) & 0xFF) == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility routine to check if the multicast address has site scope.
|
||||
*
|
||||
* @return a {@code boolean} indicating if the address has
|
||||
* is a multicast address of site-local scope, false if it is not
|
||||
* of site-local scope or it is not a multicast address
|
||||
* @since 1.4
|
||||
*/
|
||||
public boolean isMCSiteLocal() {
|
||||
// 239.255/16 prefix or ttl < 32
|
||||
int address = holder().getAddress();
|
||||
return (((address >>> 24) & 0xFF) == 239)
|
||||
&& (((address >>> 16) & 0xFF) == 255);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility routine to check if the multicast address has organization scope.
|
||||
*
|
||||
* @return a {@code boolean} indicating if the address has
|
||||
* is a multicast address of organization-local scope,
|
||||
* false if it is not of organization-local scope
|
||||
* or it is not a multicast address
|
||||
* @since 1.4
|
||||
*/
|
||||
public boolean isMCOrgLocal() {
|
||||
// 239.192 - 239.195
|
||||
int address = holder().getAddress();
|
||||
return (((address >>> 24) & 0xFF) == 239)
|
||||
&& (((address >>> 16) & 0xFF) >= 192)
|
||||
&& (((address >>> 16) & 0xFF) <= 195);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw IP address of this {@code InetAddress}
|
||||
* object. The result is in network byte order: the highest order
|
||||
* byte of the address is in {@code getAddress()[0]}.
|
||||
*
|
||||
* @return the raw IP address of this object.
|
||||
*/
|
||||
public byte[] getAddress() {
|
||||
int address = holder().getAddress();
|
||||
byte[] addr = new byte[INADDRSZ];
|
||||
|
||||
addr[0] = (byte) ((address >>> 24) & 0xFF);
|
||||
addr[1] = (byte) ((address >>> 16) & 0xFF);
|
||||
addr[2] = (byte) ((address >>> 8) & 0xFF);
|
||||
addr[3] = (byte) (address & 0xFF);
|
||||
return addr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the IP address string in textual presentation form.
|
||||
*
|
||||
* @return the raw IP address in a string format.
|
||||
* @since JDK1.0.2
|
||||
*/
|
||||
public String getHostAddress() {
|
||||
return numericToTextFormat(getAddress());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hashcode for this IP address.
|
||||
*
|
||||
* @return a hash code value for this IP address.
|
||||
*/
|
||||
public int hashCode() {
|
||||
return holder().getAddress();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this object against the specified object.
|
||||
* The result is {@code true} if and only if the argument is
|
||||
* not {@code null} and it represents the same IP address as
|
||||
* this object.
|
||||
* <p>
|
||||
* Two instances of {@code InetAddress} represent the same IP
|
||||
* address if the length of the byte arrays returned by
|
||||
* {@code getAddress} is the same for both, and each of the
|
||||
* array components is the same for the byte arrays.
|
||||
*
|
||||
* @param obj the object to compare against.
|
||||
* @return {@code true} if the objects are the same;
|
||||
* {@code false} otherwise.
|
||||
* @see java.net.InetAddress#getAddress()
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
return (obj != null) && (obj instanceof Inet4Address) &&
|
||||
(((InetAddress)obj).holder().getAddress() == holder().getAddress());
|
||||
}
|
||||
|
||||
// Utilities
|
||||
/*
|
||||
* Converts IPv4 binary address into a string suitable for presentation.
|
||||
*
|
||||
* @param src a byte array representing an IPv4 numeric address
|
||||
* @return a String representing the IPv4 address in
|
||||
* textual representation format
|
||||
* @since 1.4
|
||||
*/
|
||||
|
||||
static String numericToTextFormat(byte[] src)
|
||||
{
|
||||
return (src[0] & 0xff) + "." + (src[1] & 0xff) + "." + (src[2] & 0xff) + "." + (src[3] & 0xff);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform class load-time initializations.
|
||||
*/
|
||||
private static native void init();
|
||||
}
|
||||
74
jdkSrc/jdk8/java/net/Inet4AddressImpl.java
Normal file
74
jdkSrc/jdk8/java/net/Inet4AddressImpl.java
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package java.net;
|
||||
import java.io.IOException;
|
||||
|
||||
/*
|
||||
* Package private implementation of InetAddressImpl for IPv4.
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
class Inet4AddressImpl implements InetAddressImpl {
|
||||
public native String getLocalHostName() throws UnknownHostException;
|
||||
public native InetAddress[]
|
||||
lookupAllHostAddr(String hostname) throws UnknownHostException;
|
||||
public native String getHostByAddr(byte[] addr) throws UnknownHostException;
|
||||
private native boolean isReachable0(byte[] addr, int timeout, byte[] ifaddr, int ttl) throws IOException;
|
||||
|
||||
public synchronized InetAddress anyLocalAddress() {
|
||||
if (anyLocalAddress == null) {
|
||||
anyLocalAddress = new Inet4Address(); // {0x00,0x00,0x00,0x00}
|
||||
anyLocalAddress.holder().hostName = "0.0.0.0";
|
||||
}
|
||||
return anyLocalAddress;
|
||||
}
|
||||
|
||||
public synchronized InetAddress loopbackAddress() {
|
||||
if (loopbackAddress == null) {
|
||||
byte[] loopback = {0x7f,0x00,0x00,0x01};
|
||||
loopbackAddress = new Inet4Address("localhost", loopback);
|
||||
}
|
||||
return loopbackAddress;
|
||||
}
|
||||
|
||||
public boolean isReachable(InetAddress addr, int timeout, NetworkInterface netif, int ttl) throws IOException {
|
||||
byte[] ifaddr = null;
|
||||
if (netif != null) {
|
||||
/*
|
||||
* Let's make sure we use an address of the proper family
|
||||
*/
|
||||
java.util.Enumeration<InetAddress> it = netif.getInetAddresses();
|
||||
InetAddress inetaddr = null;
|
||||
while (!(inetaddr instanceof Inet4Address) &&
|
||||
it.hasMoreElements())
|
||||
inetaddr = it.nextElement();
|
||||
if (inetaddr instanceof Inet4Address)
|
||||
ifaddr = inetaddr.getAddress();
|
||||
}
|
||||
return isReachable0(addr.getAddress(), timeout, ifaddr, ttl);
|
||||
}
|
||||
private InetAddress anyLocalAddress;
|
||||
private InetAddress loopbackAddress;
|
||||
}
|
||||
951
jdkSrc/jdk8/java/net/Inet6Address.java
Normal file
951
jdkSrc/jdk8/java/net/Inet6Address.java
Normal file
@@ -0,0 +1,951 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InvalidObjectException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ObjectStreamField;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* This class represents an Internet Protocol version 6 (IPv6) address.
|
||||
* Defined by <a href="http://www.ietf.org/rfc/rfc2373.txt">
|
||||
* <i>RFC 2373: IP Version 6 Addressing Architecture</i></a>.
|
||||
*
|
||||
* <h3> <A NAME="format">Textual representation of IP addresses</a> </h3>
|
||||
*
|
||||
* Textual representation of IPv6 address used as input to methods
|
||||
* takes one of the following forms:
|
||||
*
|
||||
* <ol>
|
||||
* <li><p> <A NAME="lform">The preferred form</a> is x:x:x:x:x:x:x:x,
|
||||
* where the 'x's are
|
||||
* the hexadecimal values of the eight 16-bit pieces of the
|
||||
* address. This is the full form. For example,
|
||||
*
|
||||
* <blockquote><table cellpadding=0 cellspacing=0 summary="layout">
|
||||
* <tr><td>{@code 1080:0:0:0:8:800:200C:417A}<td></tr>
|
||||
* </table></blockquote>
|
||||
*
|
||||
* <p> Note that it is not necessary to write the leading zeros in
|
||||
* an individual field. However, there must be at least one numeral
|
||||
* in every field, except as described below.</li>
|
||||
*
|
||||
* <li><p> Due to some methods of allocating certain styles of IPv6
|
||||
* addresses, it will be common for addresses to contain long
|
||||
* strings of zero bits. In order to make writing addresses
|
||||
* containing zero bits easier, a special syntax is available to
|
||||
* compress the zeros. The use of "::" indicates multiple groups
|
||||
* of 16-bits of zeros. The "::" can only appear once in an address.
|
||||
* The "::" can also be used to compress the leading and/or trailing
|
||||
* zeros in an address. For example,
|
||||
*
|
||||
* <blockquote><table cellpadding=0 cellspacing=0 summary="layout">
|
||||
* <tr><td>{@code 1080::8:800:200C:417A}<td></tr>
|
||||
* </table></blockquote>
|
||||
*
|
||||
* <li><p> An alternative form that is sometimes more convenient
|
||||
* when dealing with a mixed environment of IPv4 and IPv6 nodes is
|
||||
* x:x:x:x:x:x:d.d.d.d, where the 'x's are the hexadecimal values
|
||||
* of the six high-order 16-bit pieces of the address, and the 'd's
|
||||
* are the decimal values of the four low-order 8-bit pieces of the
|
||||
* standard IPv4 representation address, for example,
|
||||
*
|
||||
* <blockquote><table cellpadding=0 cellspacing=0 summary="layout">
|
||||
* <tr><td>{@code ::FFFF:129.144.52.38}<td></tr>
|
||||
* <tr><td>{@code ::129.144.52.38}<td></tr>
|
||||
* </table></blockquote>
|
||||
*
|
||||
* <p> where "::FFFF:d.d.d.d" and "::d.d.d.d" are, respectively, the
|
||||
* general forms of an IPv4-mapped IPv6 address and an
|
||||
* IPv4-compatible IPv6 address. Note that the IPv4 portion must be
|
||||
* in the "d.d.d.d" form. The following forms are invalid:
|
||||
*
|
||||
* <blockquote><table cellpadding=0 cellspacing=0 summary="layout">
|
||||
* <tr><td>{@code ::FFFF:d.d.d}<td></tr>
|
||||
* <tr><td>{@code ::FFFF:d.d}<td></tr>
|
||||
* <tr><td>{@code ::d.d.d}<td></tr>
|
||||
* <tr><td>{@code ::d.d}<td></tr>
|
||||
* </table></blockquote>
|
||||
*
|
||||
* <p> The following form:
|
||||
*
|
||||
* <blockquote><table cellpadding=0 cellspacing=0 summary="layout">
|
||||
* <tr><td>{@code ::FFFF:d}<td></tr>
|
||||
* </table></blockquote>
|
||||
*
|
||||
* <p> is valid, however it is an unconventional representation of
|
||||
* the IPv4-compatible IPv6 address,
|
||||
*
|
||||
* <blockquote><table cellpadding=0 cellspacing=0 summary="layout">
|
||||
* <tr><td>{@code ::255.255.0.d}<td></tr>
|
||||
* </table></blockquote>
|
||||
*
|
||||
* <p> while "::d" corresponds to the general IPv6 address
|
||||
* "0:0:0:0:0:0:0:d".</li>
|
||||
* </ol>
|
||||
*
|
||||
* <p> For methods that return a textual representation as output
|
||||
* value, the full form is used. Inet6Address will return the full
|
||||
* form because it is unambiguous when used in combination with other
|
||||
* textual data.
|
||||
*
|
||||
* <h4> Special IPv6 address </h4>
|
||||
*
|
||||
* <blockquote>
|
||||
* <table cellspacing=2 summary="Description of IPv4-mapped address">
|
||||
* <tr><th valign=top><i>IPv4-mapped address</i></th>
|
||||
* <td>Of the form::ffff:w.x.y.z, this IPv6 address is used to
|
||||
* represent an IPv4 address. It allows the native program to
|
||||
* use the same address data structure and also the same
|
||||
* socket when communicating with both IPv4 and IPv6 nodes.
|
||||
*
|
||||
* <p>In InetAddress and Inet6Address, it is used for internal
|
||||
* representation; it has no functional role. Java will never
|
||||
* return an IPv4-mapped address. These classes can take an
|
||||
* IPv4-mapped address as input, both in byte array and text
|
||||
* representation. However, it will be converted into an IPv4
|
||||
* address.</td></tr>
|
||||
* </table></blockquote>
|
||||
*
|
||||
* <h4><A NAME="scoped">Textual representation of IPv6 scoped addresses</a></h4>
|
||||
*
|
||||
* <p> The textual representation of IPv6 addresses as described above can be
|
||||
* extended to specify IPv6 scoped addresses. This extension to the basic
|
||||
* addressing architecture is described in [draft-ietf-ipngwg-scoping-arch-04.txt].
|
||||
*
|
||||
* <p> Because link-local and site-local addresses are non-global, it is possible
|
||||
* that different hosts may have the same destination address and may be
|
||||
* reachable through different interfaces on the same originating system. In
|
||||
* this case, the originating system is said to be connected to multiple zones
|
||||
* of the same scope. In order to disambiguate which is the intended destination
|
||||
* zone, it is possible to append a zone identifier (or <i>scope_id</i>) to an
|
||||
* IPv6 address.
|
||||
*
|
||||
* <p> The general format for specifying the <i>scope_id</i> is the following:
|
||||
*
|
||||
* <blockquote><i>IPv6-address</i>%<i>scope_id</i></blockquote>
|
||||
* <p> The IPv6-address is a literal IPv6 address as described above.
|
||||
* The <i>scope_id</i> refers to an interface on the local system, and it can be
|
||||
* specified in two ways.
|
||||
* <ol><li><i>As a numeric identifier.</i> This must be a positive integer
|
||||
* that identifies the particular interface and scope as understood by the
|
||||
* system. Usually, the numeric values can be determined through administration
|
||||
* tools on the system. Each interface may have multiple values, one for each
|
||||
* scope. If the scope is unspecified, then the default value used is zero.</li>
|
||||
* <li><i>As a string.</i> This must be the exact string that is returned by
|
||||
* {@link java.net.NetworkInterface#getName()} for the particular interface in
|
||||
* question. When an Inet6Address is created in this way, the numeric scope-id
|
||||
* is determined at the time the object is created by querying the relevant
|
||||
* NetworkInterface.</li></ol>
|
||||
*
|
||||
* <p> Note also, that the numeric <i>scope_id</i> can be retrieved from
|
||||
* Inet6Address instances returned from the NetworkInterface class. This can be
|
||||
* used to find out the current scope ids configured on the system.
|
||||
* @since 1.4
|
||||
*/
|
||||
|
||||
public final
|
||||
class Inet6Address extends InetAddress {
|
||||
final static int INADDRSZ = 16;
|
||||
|
||||
/*
|
||||
* cached scope_id - for link-local address use only.
|
||||
*/
|
||||
private transient int cached_scope_id; // 0
|
||||
|
||||
private class Inet6AddressHolder {
|
||||
|
||||
private Inet6AddressHolder() {
|
||||
ipaddress = new byte[INADDRSZ];
|
||||
}
|
||||
|
||||
private Inet6AddressHolder(
|
||||
byte[] ipaddress, int scope_id, boolean scope_id_set,
|
||||
NetworkInterface ifname, boolean scope_ifname_set)
|
||||
{
|
||||
this.ipaddress = ipaddress;
|
||||
this.scope_id = scope_id;
|
||||
this.scope_id_set = scope_id_set;
|
||||
this.scope_ifname_set = scope_ifname_set;
|
||||
this.scope_ifname = ifname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds a 128-bit (16 bytes) IPv6 address.
|
||||
*/
|
||||
byte[] ipaddress;
|
||||
|
||||
/**
|
||||
* scope_id. The scope specified when the object is created. If the object
|
||||
* is created with an interface name, then the scope_id is not determined
|
||||
* until the time it is needed.
|
||||
*/
|
||||
int scope_id; // 0
|
||||
|
||||
/**
|
||||
* This will be set to true when the scope_id field contains a valid
|
||||
* integer scope_id.
|
||||
*/
|
||||
boolean scope_id_set; // false
|
||||
|
||||
/**
|
||||
* scoped interface. scope_id is derived from this as the scope_id of the first
|
||||
* address whose scope is the same as this address for the named interface.
|
||||
*/
|
||||
NetworkInterface scope_ifname; // null
|
||||
|
||||
/**
|
||||
* set if the object is constructed with a scoped
|
||||
* interface instead of a numeric scope id.
|
||||
*/
|
||||
boolean scope_ifname_set; // false;
|
||||
|
||||
void setAddr(byte addr[]) {
|
||||
if (addr.length == INADDRSZ) { // normal IPv6 address
|
||||
System.arraycopy(addr, 0, ipaddress, 0, INADDRSZ);
|
||||
}
|
||||
}
|
||||
|
||||
void init(byte addr[], int scope_id) {
|
||||
setAddr(addr);
|
||||
|
||||
if (scope_id >= 0) {
|
||||
this.scope_id = scope_id;
|
||||
this.scope_id_set = true;
|
||||
}
|
||||
}
|
||||
|
||||
void init(byte addr[], NetworkInterface nif)
|
||||
throws UnknownHostException
|
||||
{
|
||||
setAddr(addr);
|
||||
|
||||
if (nif != null) {
|
||||
this.scope_id = deriveNumericScope(ipaddress, nif);
|
||||
this.scope_id_set = true;
|
||||
this.scope_ifname = nif;
|
||||
this.scope_ifname_set = true;
|
||||
}
|
||||
}
|
||||
|
||||
String getHostAddress() {
|
||||
String s = numericToTextFormat(ipaddress);
|
||||
if (scope_ifname != null) { /* must check this first */
|
||||
s = s + "%" + scope_ifname.getName();
|
||||
} else if (scope_id_set) {
|
||||
s = s + "%" + scope_id;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (! (o instanceof Inet6AddressHolder)) {
|
||||
return false;
|
||||
}
|
||||
Inet6AddressHolder that = (Inet6AddressHolder)o;
|
||||
|
||||
return Arrays.equals(this.ipaddress, that.ipaddress);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
if (ipaddress != null) {
|
||||
|
||||
int hash = 0;
|
||||
int i=0;
|
||||
while (i<INADDRSZ) {
|
||||
int j=0;
|
||||
int component=0;
|
||||
while (j<4 && i<INADDRSZ) {
|
||||
component = (component << 8) + ipaddress[i];
|
||||
j++;
|
||||
i++;
|
||||
}
|
||||
hash += component;
|
||||
}
|
||||
return hash;
|
||||
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
boolean isIPv4CompatibleAddress() {
|
||||
if ((ipaddress[0] == 0x00) && (ipaddress[1] == 0x00) &&
|
||||
(ipaddress[2] == 0x00) && (ipaddress[3] == 0x00) &&
|
||||
(ipaddress[4] == 0x00) && (ipaddress[5] == 0x00) &&
|
||||
(ipaddress[6] == 0x00) && (ipaddress[7] == 0x00) &&
|
||||
(ipaddress[8] == 0x00) && (ipaddress[9] == 0x00) &&
|
||||
(ipaddress[10] == 0x00) && (ipaddress[11] == 0x00)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isMulticastAddress() {
|
||||
return ((ipaddress[0] & 0xff) == 0xff);
|
||||
}
|
||||
|
||||
boolean isAnyLocalAddress() {
|
||||
byte test = 0x00;
|
||||
for (int i = 0; i < INADDRSZ; i++) {
|
||||
test |= ipaddress[i];
|
||||
}
|
||||
return (test == 0x00);
|
||||
}
|
||||
|
||||
boolean isLoopbackAddress() {
|
||||
byte test = 0x00;
|
||||
for (int i = 0; i < 15; i++) {
|
||||
test |= ipaddress[i];
|
||||
}
|
||||
return (test == 0x00) && (ipaddress[15] == 0x01);
|
||||
}
|
||||
|
||||
boolean isLinkLocalAddress() {
|
||||
return ((ipaddress[0] & 0xff) == 0xfe
|
||||
&& (ipaddress[1] & 0xc0) == 0x80);
|
||||
}
|
||||
|
||||
|
||||
boolean isSiteLocalAddress() {
|
||||
return ((ipaddress[0] & 0xff) == 0xfe
|
||||
&& (ipaddress[1] & 0xc0) == 0xc0);
|
||||
}
|
||||
|
||||
boolean isMCGlobal() {
|
||||
return ((ipaddress[0] & 0xff) == 0xff
|
||||
&& (ipaddress[1] & 0x0f) == 0x0e);
|
||||
}
|
||||
|
||||
boolean isMCNodeLocal() {
|
||||
return ((ipaddress[0] & 0xff) == 0xff
|
||||
&& (ipaddress[1] & 0x0f) == 0x01);
|
||||
}
|
||||
|
||||
boolean isMCLinkLocal() {
|
||||
return ((ipaddress[0] & 0xff) == 0xff
|
||||
&& (ipaddress[1] & 0x0f) == 0x02);
|
||||
}
|
||||
|
||||
boolean isMCSiteLocal() {
|
||||
return ((ipaddress[0] & 0xff) == 0xff
|
||||
&& (ipaddress[1] & 0x0f) == 0x05);
|
||||
}
|
||||
|
||||
boolean isMCOrgLocal() {
|
||||
return ((ipaddress[0] & 0xff) == 0xff
|
||||
&& (ipaddress[1] & 0x0f) == 0x08);
|
||||
}
|
||||
}
|
||||
|
||||
private final transient Inet6AddressHolder holder6;
|
||||
|
||||
private static final long serialVersionUID = 6880410070516793377L;
|
||||
|
||||
// Perform native initialization
|
||||
static { init(); }
|
||||
|
||||
Inet6Address() {
|
||||
super();
|
||||
holder.init(null, IPv6);
|
||||
holder6 = new Inet6AddressHolder();
|
||||
}
|
||||
|
||||
/* checking of value for scope_id should be done by caller
|
||||
* scope_id must be >= 0, or -1 to indicate not being set
|
||||
*/
|
||||
Inet6Address(String hostName, byte addr[], int scope_id) {
|
||||
holder.init(hostName, IPv6);
|
||||
holder6 = new Inet6AddressHolder();
|
||||
holder6.init(addr, scope_id);
|
||||
}
|
||||
|
||||
Inet6Address(String hostName, byte addr[]) {
|
||||
holder6 = new Inet6AddressHolder();
|
||||
try {
|
||||
initif (hostName, addr, null);
|
||||
} catch (UnknownHostException e) {} /* cant happen if ifname is null */
|
||||
}
|
||||
|
||||
Inet6Address (String hostName, byte addr[], NetworkInterface nif)
|
||||
throws UnknownHostException
|
||||
{
|
||||
holder6 = new Inet6AddressHolder();
|
||||
initif (hostName, addr, nif);
|
||||
}
|
||||
|
||||
Inet6Address (String hostName, byte addr[], String ifname)
|
||||
throws UnknownHostException
|
||||
{
|
||||
holder6 = new Inet6AddressHolder();
|
||||
initstr (hostName, addr, ifname);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an Inet6Address in the exact manner of {@link
|
||||
* InetAddress#getByAddress(String,byte[])} except that the IPv6 scope_id is
|
||||
* set to the value corresponding to the given interface for the address
|
||||
* type specified in {@code addr}. The call will fail with an
|
||||
* UnknownHostException if the given interface does not have a numeric
|
||||
* scope_id assigned for the given address type (eg. link-local or site-local).
|
||||
* See <a href="Inet6Address.html#scoped">here</a> for a description of IPv6
|
||||
* scoped addresses.
|
||||
*
|
||||
* @param host the specified host
|
||||
* @param addr the raw IP address in network byte order
|
||||
* @param nif an interface this address must be associated with.
|
||||
* @return an Inet6Address object created from the raw IP address.
|
||||
* @throws UnknownHostException
|
||||
* if IP address is of illegal length, or if the interface does not
|
||||
* have a numeric scope_id assigned for the given address type.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public static Inet6Address getByAddress(String host, byte[] addr,
|
||||
NetworkInterface nif)
|
||||
throws UnknownHostException
|
||||
{
|
||||
if (host != null && host.length() > 0 && host.charAt(0) == '[') {
|
||||
if (host.charAt(host.length()-1) == ']') {
|
||||
host = host.substring(1, host.length() -1);
|
||||
}
|
||||
}
|
||||
if (addr != null) {
|
||||
if (addr.length == Inet6Address.INADDRSZ) {
|
||||
return new Inet6Address(host, addr, nif);
|
||||
}
|
||||
}
|
||||
throw new UnknownHostException("addr is of illegal length");
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an Inet6Address in the exact manner of {@link
|
||||
* InetAddress#getByAddress(String,byte[])} except that the IPv6 scope_id is
|
||||
* set to the given numeric value. The scope_id is not checked to determine
|
||||
* if it corresponds to any interface on the system.
|
||||
* See <a href="Inet6Address.html#scoped">here</a> for a description of IPv6
|
||||
* scoped addresses.
|
||||
*
|
||||
* @param host the specified host
|
||||
* @param addr the raw IP address in network byte order
|
||||
* @param scope_id the numeric scope_id for the address.
|
||||
* @return an Inet6Address object created from the raw IP address.
|
||||
* @throws UnknownHostException if IP address is of illegal length.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public static Inet6Address getByAddress(String host, byte[] addr,
|
||||
int scope_id)
|
||||
throws UnknownHostException
|
||||
{
|
||||
if (host != null && host.length() > 0 && host.charAt(0) == '[') {
|
||||
if (host.charAt(host.length()-1) == ']') {
|
||||
host = host.substring(1, host.length() -1);
|
||||
}
|
||||
}
|
||||
if (addr != null) {
|
||||
if (addr.length == Inet6Address.INADDRSZ) {
|
||||
return new Inet6Address(host, addr, scope_id);
|
||||
}
|
||||
}
|
||||
throw new UnknownHostException("addr is of illegal length");
|
||||
}
|
||||
|
||||
private void initstr(String hostName, byte addr[], String ifname)
|
||||
throws UnknownHostException
|
||||
{
|
||||
try {
|
||||
NetworkInterface nif = NetworkInterface.getByName (ifname);
|
||||
if (nif == null) {
|
||||
throw new UnknownHostException ("no such interface " + ifname);
|
||||
}
|
||||
initif (hostName, addr, nif);
|
||||
} catch (SocketException e) {
|
||||
throw new UnknownHostException ("SocketException thrown" + ifname);
|
||||
}
|
||||
}
|
||||
|
||||
private void initif(String hostName, byte addr[], NetworkInterface nif)
|
||||
throws UnknownHostException
|
||||
{
|
||||
int family = -1;
|
||||
holder6.init(addr, nif);
|
||||
|
||||
if (addr.length == INADDRSZ) { // normal IPv6 address
|
||||
family = IPv6;
|
||||
}
|
||||
holder.init(hostName, family);
|
||||
}
|
||||
|
||||
/* check the two Ipv6 addresses and return false if they are both
|
||||
* non global address types, but not the same.
|
||||
* (ie. one is sitelocal and the other linklocal)
|
||||
* return true otherwise.
|
||||
*/
|
||||
|
||||
private static boolean isDifferentLocalAddressType(
|
||||
byte[] thisAddr, byte[] otherAddr) {
|
||||
|
||||
if (Inet6Address.isLinkLocalAddress(thisAddr) &&
|
||||
!Inet6Address.isLinkLocalAddress(otherAddr)) {
|
||||
return false;
|
||||
}
|
||||
if (Inet6Address.isSiteLocalAddress(thisAddr) &&
|
||||
!Inet6Address.isSiteLocalAddress(otherAddr)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static int deriveNumericScope (byte[] thisAddr, NetworkInterface ifc) throws UnknownHostException {
|
||||
Enumeration<InetAddress> addresses = ifc.getInetAddresses();
|
||||
while (addresses.hasMoreElements()) {
|
||||
InetAddress addr = addresses.nextElement();
|
||||
if (!(addr instanceof Inet6Address)) {
|
||||
continue;
|
||||
}
|
||||
Inet6Address ia6_addr = (Inet6Address)addr;
|
||||
/* check if site or link local prefixes match */
|
||||
if (!isDifferentLocalAddressType(thisAddr, ia6_addr.getAddress())){
|
||||
/* type not the same, so carry on searching */
|
||||
continue;
|
||||
}
|
||||
/* found a matching address - return its scope_id */
|
||||
return ia6_addr.getScopeId();
|
||||
}
|
||||
throw new UnknownHostException ("no scope_id found");
|
||||
}
|
||||
|
||||
private int deriveNumericScope (String ifname) throws UnknownHostException {
|
||||
Enumeration<NetworkInterface> en;
|
||||
try {
|
||||
en = NetworkInterface.getNetworkInterfaces();
|
||||
} catch (SocketException e) {
|
||||
throw new UnknownHostException ("could not enumerate local network interfaces");
|
||||
}
|
||||
while (en.hasMoreElements()) {
|
||||
NetworkInterface ifc = en.nextElement();
|
||||
if (ifc.getName().equals (ifname)) {
|
||||
return deriveNumericScope(holder6.ipaddress, ifc);
|
||||
}
|
||||
}
|
||||
throw new UnknownHostException ("No matching address found for interface : " +ifname);
|
||||
}
|
||||
|
||||
/**
|
||||
* @serialField ipaddress byte[]
|
||||
* @serialField scope_id int
|
||||
* @serialField scope_id_set boolean
|
||||
* @serialField scope_ifname_set boolean
|
||||
* @serialField ifname String
|
||||
*/
|
||||
|
||||
private static final ObjectStreamField[] serialPersistentFields = {
|
||||
new ObjectStreamField("ipaddress", byte[].class),
|
||||
new ObjectStreamField("scope_id", int.class),
|
||||
new ObjectStreamField("scope_id_set", boolean.class),
|
||||
new ObjectStreamField("scope_ifname_set", boolean.class),
|
||||
new ObjectStreamField("ifname", String.class)
|
||||
};
|
||||
|
||||
private static final long FIELDS_OFFSET;
|
||||
private static final sun.misc.Unsafe UNSAFE;
|
||||
|
||||
static {
|
||||
try {
|
||||
sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
|
||||
FIELDS_OFFSET = unsafe.objectFieldOffset(
|
||||
Inet6Address.class.getDeclaredField("holder6"));
|
||||
UNSAFE = unsafe;
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* restore the state of this object from stream
|
||||
* including the scope information, only if the
|
||||
* scoped interface name is valid on this system
|
||||
*/
|
||||
private void readObject(ObjectInputStream s)
|
||||
throws IOException, ClassNotFoundException {
|
||||
NetworkInterface scope_ifname = null;
|
||||
|
||||
if (getClass().getClassLoader() != null) {
|
||||
throw new SecurityException ("invalid address type");
|
||||
}
|
||||
|
||||
ObjectInputStream.GetField gf = s.readFields();
|
||||
byte[] ipaddress = (byte[])gf.get("ipaddress", null);
|
||||
int scope_id = (int)gf.get("scope_id", -1);
|
||||
boolean scope_id_set = (boolean)gf.get("scope_id_set", false);
|
||||
boolean scope_ifname_set = (boolean)gf.get("scope_ifname_set", false);
|
||||
String ifname = (String)gf.get("ifname", null);
|
||||
|
||||
if (ifname != null && !"".equals (ifname)) {
|
||||
try {
|
||||
scope_ifname = NetworkInterface.getByName(ifname);
|
||||
if (scope_ifname == null) {
|
||||
/* the interface does not exist on this system, so we clear
|
||||
* the scope information completely */
|
||||
scope_id_set = false;
|
||||
scope_ifname_set = false;
|
||||
scope_id = 0;
|
||||
} else {
|
||||
scope_ifname_set = true;
|
||||
try {
|
||||
scope_id = deriveNumericScope (ipaddress, scope_ifname);
|
||||
} catch (UnknownHostException e) {
|
||||
// typically should not happen, but it may be that
|
||||
// the machine being used for deserialization has
|
||||
// the same interface name but without IPv6 configured.
|
||||
}
|
||||
}
|
||||
} catch (SocketException e) {}
|
||||
}
|
||||
|
||||
/* if ifname was not supplied, then the numeric info is used */
|
||||
|
||||
ipaddress = ipaddress.clone();
|
||||
|
||||
// Check that our invariants are satisfied
|
||||
if (ipaddress.length != INADDRSZ) {
|
||||
throw new InvalidObjectException("invalid address length: "+
|
||||
ipaddress.length);
|
||||
}
|
||||
|
||||
if (holder.getFamily() != IPv6) {
|
||||
throw new InvalidObjectException("invalid address family type");
|
||||
}
|
||||
|
||||
Inet6AddressHolder h = new Inet6AddressHolder(
|
||||
ipaddress, scope_id, scope_id_set, scope_ifname, scope_ifname_set
|
||||
);
|
||||
|
||||
UNSAFE.putObject(this, FIELDS_OFFSET, h);
|
||||
}
|
||||
|
||||
/**
|
||||
* default behavior is overridden in order to write the
|
||||
* scope_ifname field as a String, rather than a NetworkInterface
|
||||
* which is not serializable
|
||||
*/
|
||||
private synchronized void writeObject(ObjectOutputStream s)
|
||||
throws IOException
|
||||
{
|
||||
String ifname = null;
|
||||
|
||||
if (holder6.scope_ifname != null) {
|
||||
ifname = holder6.scope_ifname.getName();
|
||||
holder6.scope_ifname_set = true;
|
||||
}
|
||||
ObjectOutputStream.PutField pfields = s.putFields();
|
||||
pfields.put("ipaddress", holder6.ipaddress);
|
||||
pfields.put("scope_id", holder6.scope_id);
|
||||
pfields.put("scope_id_set", holder6.scope_id_set);
|
||||
pfields.put("scope_ifname_set", holder6.scope_ifname_set);
|
||||
pfields.put("ifname", ifname);
|
||||
s.writeFields();
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility routine to check if the InetAddress is an IP multicast
|
||||
* address. 11111111 at the start of the address identifies the
|
||||
* address as being a multicast address.
|
||||
*
|
||||
* @return a {@code boolean} indicating if the InetAddress is an IP
|
||||
* multicast address
|
||||
*
|
||||
* @since JDK1.1
|
||||
*/
|
||||
@Override
|
||||
public boolean isMulticastAddress() {
|
||||
return holder6.isMulticastAddress();
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility routine to check if the InetAddress in a wildcard address.
|
||||
*
|
||||
* @return a {@code boolean} indicating if the Inetaddress is
|
||||
* a wildcard address.
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
@Override
|
||||
public boolean isAnyLocalAddress() {
|
||||
return holder6.isAnyLocalAddress();
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility routine to check if the InetAddress is a loopback address.
|
||||
*
|
||||
* @return a {@code boolean} indicating if the InetAddress is a loopback
|
||||
* address; or false otherwise.
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
@Override
|
||||
public boolean isLoopbackAddress() {
|
||||
return holder6.isLoopbackAddress();
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility routine to check if the InetAddress is an link local address.
|
||||
*
|
||||
* @return a {@code boolean} indicating if the InetAddress is a link local
|
||||
* address; or false if address is not a link local unicast address.
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
@Override
|
||||
public boolean isLinkLocalAddress() {
|
||||
return holder6.isLinkLocalAddress();
|
||||
}
|
||||
|
||||
/* static version of above */
|
||||
static boolean isLinkLocalAddress(byte[] ipaddress) {
|
||||
return ((ipaddress[0] & 0xff) == 0xfe
|
||||
&& (ipaddress[1] & 0xc0) == 0x80);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility routine to check if the InetAddress is a site local address.
|
||||
*
|
||||
* @return a {@code boolean} indicating if the InetAddress is a site local
|
||||
* address; or false if address is not a site local unicast address.
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
@Override
|
||||
public boolean isSiteLocalAddress() {
|
||||
return holder6.isSiteLocalAddress();
|
||||
}
|
||||
|
||||
/* static version of above */
|
||||
static boolean isSiteLocalAddress(byte[] ipaddress) {
|
||||
return ((ipaddress[0] & 0xff) == 0xfe
|
||||
&& (ipaddress[1] & 0xc0) == 0xc0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility routine to check if the multicast address has global scope.
|
||||
*
|
||||
* @return a {@code boolean} indicating if the address has is a multicast
|
||||
* address of global scope, false if it is not of global scope or
|
||||
* it is not a multicast address
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
@Override
|
||||
public boolean isMCGlobal() {
|
||||
return holder6.isMCGlobal();
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility routine to check if the multicast address has node scope.
|
||||
*
|
||||
* @return a {@code boolean} indicating if the address has is a multicast
|
||||
* address of node-local scope, false if it is not of node-local
|
||||
* scope or it is not a multicast address
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
@Override
|
||||
public boolean isMCNodeLocal() {
|
||||
return holder6.isMCNodeLocal();
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility routine to check if the multicast address has link scope.
|
||||
*
|
||||
* @return a {@code boolean} indicating if the address has is a multicast
|
||||
* address of link-local scope, false if it is not of link-local
|
||||
* scope or it is not a multicast address
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
@Override
|
||||
public boolean isMCLinkLocal() {
|
||||
return holder6.isMCLinkLocal();
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility routine to check if the multicast address has site scope.
|
||||
*
|
||||
* @return a {@code boolean} indicating if the address has is a multicast
|
||||
* address of site-local scope, false if it is not of site-local
|
||||
* scope or it is not a multicast address
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
@Override
|
||||
public boolean isMCSiteLocal() {
|
||||
return holder6.isMCSiteLocal();
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility routine to check if the multicast address has organization scope.
|
||||
*
|
||||
* @return a {@code boolean} indicating if the address has is a multicast
|
||||
* address of organization-local scope, false if it is not of
|
||||
* organization-local scope or it is not a multicast address
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
@Override
|
||||
public boolean isMCOrgLocal() {
|
||||
return holder6.isMCOrgLocal();
|
||||
}
|
||||
/**
|
||||
* Returns the raw IP address of this {@code InetAddress} object. The result
|
||||
* is in network byte order: the highest order byte of the address is in
|
||||
* {@code getAddress()[0]}.
|
||||
*
|
||||
* @return the raw IP address of this object.
|
||||
*/
|
||||
@Override
|
||||
public byte[] getAddress() {
|
||||
return holder6.ipaddress.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the numeric scopeId, if this instance is associated with
|
||||
* an interface. If no scoped_id is set, the returned value is zero.
|
||||
*
|
||||
* @return the scopeId, or zero if not set.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public int getScopeId() {
|
||||
return holder6.scope_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the scoped interface, if this instance was created with
|
||||
* with a scoped interface.
|
||||
*
|
||||
* @return the scoped interface, or null if not set.
|
||||
* @since 1.5
|
||||
*/
|
||||
public NetworkInterface getScopedInterface() {
|
||||
return holder6.scope_ifname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the IP address string in textual presentation. If the instance
|
||||
* was created specifying a scope identifier then the scope id is appended
|
||||
* to the IP address preceded by a "%" (per-cent) character. This can be
|
||||
* either a numeric value or a string, depending on which was used to create
|
||||
* the instance.
|
||||
*
|
||||
* @return the raw IP address in a string format.
|
||||
*/
|
||||
@Override
|
||||
public String getHostAddress() {
|
||||
return holder6.getHostAddress();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hashcode for this IP address.
|
||||
*
|
||||
* @return a hash code value for this IP address.
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return holder6.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this object against the specified object. The result is {@code
|
||||
* true} if and only if the argument is not {@code null} and it represents
|
||||
* the same IP address as this object.
|
||||
*
|
||||
* <p> Two instances of {@code InetAddress} represent the same IP address
|
||||
* if the length of the byte arrays returned by {@code getAddress} is the
|
||||
* same for both, and each of the array components is the same for the byte
|
||||
* arrays.
|
||||
*
|
||||
* @param obj the object to compare against.
|
||||
*
|
||||
* @return {@code true} if the objects are the same; {@code false} otherwise.
|
||||
*
|
||||
* @see java.net.InetAddress#getAddress()
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null || !(obj instanceof Inet6Address))
|
||||
return false;
|
||||
|
||||
Inet6Address inetAddr = (Inet6Address)obj;
|
||||
|
||||
return holder6.equals(inetAddr.holder6);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility routine to check if the InetAddress is an
|
||||
* IPv4 compatible IPv6 address.
|
||||
*
|
||||
* @return a {@code boolean} indicating if the InetAddress is an IPv4
|
||||
* compatible IPv6 address; or false if address is IPv4 address.
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
public boolean isIPv4CompatibleAddress() {
|
||||
return holder6.isIPv4CompatibleAddress();
|
||||
}
|
||||
|
||||
// Utilities
|
||||
private final static int INT16SZ = 2;
|
||||
|
||||
/*
|
||||
* Convert IPv6 binary address into presentation (printable) format.
|
||||
*
|
||||
* @param src a byte array representing the IPv6 numeric address
|
||||
* @return a String representing an IPv6 address in
|
||||
* textual representation format
|
||||
* @since 1.4
|
||||
*/
|
||||
static String numericToTextFormat(byte[] src) {
|
||||
StringBuilder sb = new StringBuilder(39);
|
||||
for (int i = 0; i < (INADDRSZ / INT16SZ); i++) {
|
||||
sb.append(Integer.toHexString(((src[i<<1]<<8) & 0xff00)
|
||||
| (src[(i<<1)+1] & 0xff)));
|
||||
if (i < (INADDRSZ / INT16SZ) -1 ) {
|
||||
sb.append(":");
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform class load-time initializations.
|
||||
*/
|
||||
private static native void init();
|
||||
}
|
||||
108
jdkSrc/jdk8/java/net/Inet6AddressImpl.java
Normal file
108
jdkSrc/jdk8/java/net/Inet6AddressImpl.java
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package java.net;
|
||||
import java.io.IOException;
|
||||
|
||||
/*
|
||||
* Package private implementation of InetAddressImpl for dual
|
||||
* IPv4/IPv6 stack.
|
||||
* <p>
|
||||
* If InetAddress.preferIPv6Address is true then anyLocalAddress(),
|
||||
* loopbackAddress(), and localHost() will return IPv6 addresses,
|
||||
* otherwise IPv4 addresses.
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
|
||||
class Inet6AddressImpl implements InetAddressImpl {
|
||||
public native String getLocalHostName() throws UnknownHostException;
|
||||
public native InetAddress[]
|
||||
lookupAllHostAddr(String hostname) throws UnknownHostException;
|
||||
public native String getHostByAddr(byte[] addr) throws UnknownHostException;
|
||||
private native boolean isReachable0(byte[] addr, int scope, int timeout, byte[] inf, int ttl, int if_scope) throws IOException;
|
||||
|
||||
public boolean isReachable(InetAddress addr, int timeout, NetworkInterface netif, int ttl) throws IOException {
|
||||
byte[] ifaddr = null;
|
||||
int scope = -1;
|
||||
int netif_scope = -1;
|
||||
if (netif != null) {
|
||||
/*
|
||||
* Let's make sure we bind to an address of the proper family.
|
||||
* Which means same family as addr because at this point it could
|
||||
* be either an IPv6 address or an IPv4 address (case of a dual
|
||||
* stack system).
|
||||
*/
|
||||
java.util.Enumeration<InetAddress> it = netif.getInetAddresses();
|
||||
InetAddress inetaddr = null;
|
||||
while (it.hasMoreElements()) {
|
||||
inetaddr = it.nextElement();
|
||||
if (inetaddr.getClass().isInstance(addr)) {
|
||||
ifaddr = inetaddr.getAddress();
|
||||
if (inetaddr instanceof Inet6Address) {
|
||||
netif_scope = ((Inet6Address) inetaddr).getScopeId();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ifaddr == null) {
|
||||
// Interface doesn't support the address family of
|
||||
// the destination
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (addr instanceof Inet6Address)
|
||||
scope = ((Inet6Address) addr).getScopeId();
|
||||
return isReachable0(addr.getAddress(), scope, timeout, ifaddr, ttl, netif_scope);
|
||||
}
|
||||
|
||||
public synchronized InetAddress anyLocalAddress() {
|
||||
if (anyLocalAddress == null) {
|
||||
if (InetAddress.preferIPv6Address) {
|
||||
anyLocalAddress = new Inet6Address();
|
||||
anyLocalAddress.holder().hostName = "::";
|
||||
} else {
|
||||
anyLocalAddress = (new Inet4AddressImpl()).anyLocalAddress();
|
||||
}
|
||||
}
|
||||
return anyLocalAddress;
|
||||
}
|
||||
|
||||
public synchronized InetAddress loopbackAddress() {
|
||||
if (loopbackAddress == null) {
|
||||
if (InetAddress.preferIPv6Address) {
|
||||
byte[] loopback =
|
||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
|
||||
loopbackAddress = new Inet6Address("localhost", loopback);
|
||||
} else {
|
||||
loopbackAddress = (new Inet4AddressImpl()).loopbackAddress();
|
||||
}
|
||||
}
|
||||
return loopbackAddress;
|
||||
}
|
||||
|
||||
private InetAddress anyLocalAddress;
|
||||
private InetAddress loopbackAddress;
|
||||
}
|
||||
1581
jdkSrc/jdk8/java/net/InetAddress.java
Normal file
1581
jdkSrc/jdk8/java/net/InetAddress.java
Normal file
File diff suppressed because it is too large
Load Diff
30
jdkSrc/jdk8/java/net/InetAddressContainer.java
Normal file
30
jdkSrc/jdk8/java/net/InetAddressContainer.java
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
class InetAddressContainer {
|
||||
InetAddress addr;
|
||||
}
|
||||
48
jdkSrc/jdk8/java/net/InetAddressImpl.java
Normal file
48
jdkSrc/jdk8/java/net/InetAddressImpl.java
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
import java.io.IOException;
|
||||
/*
|
||||
* Package private interface to "implementation" used by
|
||||
* {@link InetAddress}.
|
||||
* <p>
|
||||
* See {@link java.net.Inet4AddressImp} and
|
||||
* {@link java.net.Inet6AddressImp}.
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
interface InetAddressImpl {
|
||||
|
||||
String getLocalHostName() throws UnknownHostException;
|
||||
InetAddress[]
|
||||
lookupAllHostAddr(String hostname) throws UnknownHostException;
|
||||
String getHostByAddr(byte[] addr) throws UnknownHostException;
|
||||
|
||||
InetAddress anyLocalAddress();
|
||||
InetAddress loopbackAddress();
|
||||
boolean isReachable(InetAddress addr, int timeout, NetworkInterface netif,
|
||||
int ttl) throws IOException;
|
||||
}
|
||||
419
jdkSrc/jdk8/java/net/InetSocketAddress.java
Normal file
419
jdkSrc/jdk8/java/net/InetSocketAddress.java
Normal file
@@ -0,0 +1,419 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package java.net;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InvalidObjectException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ObjectStreamException;
|
||||
import java.io.ObjectStreamField;
|
||||
|
||||
/**
|
||||
*
|
||||
* This class implements an IP Socket Address (IP address + port number)
|
||||
* It can also be a pair (hostname + port number), in which case an attempt
|
||||
* will be made to resolve the hostname. If resolution fails then the address
|
||||
* is said to be <I>unresolved</I> but can still be used on some circumstances
|
||||
* like connecting through a proxy.
|
||||
* <p>
|
||||
* It provides an immutable object used by sockets for binding, connecting, or
|
||||
* as returned values.
|
||||
* <p>
|
||||
* The <i>wildcard</i> is a special local IP address. It usually means "any"
|
||||
* and can only be used for {@code bind} operations.
|
||||
*
|
||||
* @see java.net.Socket
|
||||
* @see java.net.ServerSocket
|
||||
* @since 1.4
|
||||
*/
|
||||
public class InetSocketAddress
|
||||
extends SocketAddress
|
||||
{
|
||||
// Private implementation class pointed to by all public methods.
|
||||
private static class InetSocketAddressHolder {
|
||||
// The hostname of the Socket Address
|
||||
private String hostname;
|
||||
// The IP address of the Socket Address
|
||||
private InetAddress addr;
|
||||
// The port number of the Socket Address
|
||||
private int port;
|
||||
|
||||
private InetSocketAddressHolder(String hostname, InetAddress addr, int port) {
|
||||
this.hostname = hostname;
|
||||
this.addr = addr;
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
private int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
private InetAddress getAddress() {
|
||||
return addr;
|
||||
}
|
||||
|
||||
private String getHostName() {
|
||||
if (hostname != null)
|
||||
return hostname;
|
||||
if (addr != null)
|
||||
return addr.getHostName();
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getHostString() {
|
||||
if (hostname != null)
|
||||
return hostname;
|
||||
if (addr != null) {
|
||||
if (addr.holder().getHostName() != null)
|
||||
return addr.holder().getHostName();
|
||||
else
|
||||
return addr.getHostAddress();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean isUnresolved() {
|
||||
return addr == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (isUnresolved()) {
|
||||
return hostname + ":" + port;
|
||||
} else {
|
||||
return addr.toString() + ":" + port;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean equals(Object obj) {
|
||||
if (obj == null || !(obj instanceof InetSocketAddressHolder))
|
||||
return false;
|
||||
InetSocketAddressHolder that = (InetSocketAddressHolder)obj;
|
||||
boolean sameIP;
|
||||
if (addr != null)
|
||||
sameIP = addr.equals(that.addr);
|
||||
else if (hostname != null)
|
||||
sameIP = (that.addr == null) &&
|
||||
hostname.equalsIgnoreCase(that.hostname);
|
||||
else
|
||||
sameIP = (that.addr == null) && (that.hostname == null);
|
||||
return sameIP && (port == that.port);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int hashCode() {
|
||||
if (addr != null)
|
||||
return addr.hashCode() + port;
|
||||
if (hostname != null)
|
||||
return hostname.toLowerCase().hashCode() + port;
|
||||
return port;
|
||||
}
|
||||
}
|
||||
|
||||
private final transient InetSocketAddressHolder holder;
|
||||
|
||||
private static final long serialVersionUID = 5076001401234631237L;
|
||||
|
||||
private static int checkPort(int port) {
|
||||
if (port < 0 || port > 0xFFFF)
|
||||
throw new IllegalArgumentException("port out of range:" + port);
|
||||
return port;
|
||||
}
|
||||
|
||||
private static String checkHost(String hostname) {
|
||||
if (hostname == null)
|
||||
throw new IllegalArgumentException("hostname can't be null");
|
||||
return hostname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a socket address where the IP address is the wildcard address
|
||||
* and the port number a specified value.
|
||||
* <p>
|
||||
* A valid port value is between 0 and 65535.
|
||||
* A port number of {@code zero} will let the system pick up an
|
||||
* ephemeral port in a {@code bind} operation.
|
||||
* <p>
|
||||
* @param port The port number
|
||||
* @throws IllegalArgumentException if the port parameter is outside the specified
|
||||
* range of valid port values.
|
||||
*/
|
||||
public InetSocketAddress(int port) {
|
||||
this(InetAddress.anyLocalAddress(), port);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Creates a socket address from an IP address and a port number.
|
||||
* <p>
|
||||
* A valid port value is between 0 and 65535.
|
||||
* A port number of {@code zero} will let the system pick up an
|
||||
* ephemeral port in a {@code bind} operation.
|
||||
* <P>
|
||||
* A {@code null} address will assign the <i>wildcard</i> address.
|
||||
* <p>
|
||||
* @param addr The IP address
|
||||
* @param port The port number
|
||||
* @throws IllegalArgumentException if the port parameter is outside the specified
|
||||
* range of valid port values.
|
||||
*/
|
||||
public InetSocketAddress(InetAddress addr, int port) {
|
||||
holder = new InetSocketAddressHolder(
|
||||
null,
|
||||
addr == null ? InetAddress.anyLocalAddress() : addr,
|
||||
checkPort(port));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Creates a socket address from a hostname and a port number.
|
||||
* <p>
|
||||
* An attempt will be made to resolve the hostname into an InetAddress.
|
||||
* If that attempt fails, the address will be flagged as <I>unresolved</I>.
|
||||
* <p>
|
||||
* If there is a security manager, its {@code checkConnect} method
|
||||
* is called with the host name as its argument to check the permission
|
||||
* to resolve it. This could result in a SecurityException.
|
||||
* <P>
|
||||
* A valid port value is between 0 and 65535.
|
||||
* A port number of {@code zero} will let the system pick up an
|
||||
* ephemeral port in a {@code bind} operation.
|
||||
* <P>
|
||||
* @param hostname the Host name
|
||||
* @param port The port number
|
||||
* @throws IllegalArgumentException if the port parameter is outside the range
|
||||
* of valid port values, or if the hostname parameter is <TT>null</TT>.
|
||||
* @throws SecurityException if a security manager is present and
|
||||
* permission to resolve the host name is
|
||||
* denied.
|
||||
* @see #isUnresolved()
|
||||
*/
|
||||
public InetSocketAddress(String hostname, int port) {
|
||||
checkHost(hostname);
|
||||
InetAddress addr = null;
|
||||
String host = null;
|
||||
try {
|
||||
addr = InetAddress.getByName(hostname);
|
||||
} catch(UnknownHostException e) {
|
||||
host = hostname;
|
||||
}
|
||||
holder = new InetSocketAddressHolder(host, addr, checkPort(port));
|
||||
}
|
||||
|
||||
// private constructor for creating unresolved instances
|
||||
private InetSocketAddress(int port, String hostname) {
|
||||
holder = new InetSocketAddressHolder(hostname, null, port);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Creates an unresolved socket address from a hostname and a port number.
|
||||
* <p>
|
||||
* No attempt will be made to resolve the hostname into an InetAddress.
|
||||
* The address will be flagged as <I>unresolved</I>.
|
||||
* <p>
|
||||
* A valid port value is between 0 and 65535.
|
||||
* A port number of {@code zero} will let the system pick up an
|
||||
* ephemeral port in a {@code bind} operation.
|
||||
* <P>
|
||||
* @param host the Host name
|
||||
* @param port The port number
|
||||
* @throws IllegalArgumentException if the port parameter is outside
|
||||
* the range of valid port values, or if the hostname
|
||||
* parameter is <TT>null</TT>.
|
||||
* @see #isUnresolved()
|
||||
* @return a {@code InetSocketAddress} representing the unresolved
|
||||
* socket address
|
||||
* @since 1.5
|
||||
*/
|
||||
public static InetSocketAddress createUnresolved(String host, int port) {
|
||||
return new InetSocketAddress(checkPort(port), checkHost(host));
|
||||
}
|
||||
|
||||
/**
|
||||
* @serialField hostname String
|
||||
* @serialField addr InetAddress
|
||||
* @serialField port int
|
||||
*/
|
||||
private static final ObjectStreamField[] serialPersistentFields = {
|
||||
new ObjectStreamField("hostname", String.class),
|
||||
new ObjectStreamField("addr", InetAddress.class),
|
||||
new ObjectStreamField("port", int.class)};
|
||||
|
||||
private void writeObject(ObjectOutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
// Don't call defaultWriteObject()
|
||||
ObjectOutputStream.PutField pfields = out.putFields();
|
||||
pfields.put("hostname", holder.hostname);
|
||||
pfields.put("addr", holder.addr);
|
||||
pfields.put("port", holder.port);
|
||||
out.writeFields();
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream in)
|
||||
throws IOException, ClassNotFoundException
|
||||
{
|
||||
// Don't call defaultReadObject()
|
||||
ObjectInputStream.GetField oisFields = in.readFields();
|
||||
final String oisHostname = (String)oisFields.get("hostname", null);
|
||||
final InetAddress oisAddr = (InetAddress)oisFields.get("addr", null);
|
||||
final int oisPort = oisFields.get("port", -1);
|
||||
|
||||
// Check that our invariants are satisfied
|
||||
checkPort(oisPort);
|
||||
if (oisHostname == null && oisAddr == null)
|
||||
throw new InvalidObjectException("hostname and addr " +
|
||||
"can't both be null");
|
||||
|
||||
InetSocketAddressHolder h = new InetSocketAddressHolder(oisHostname,
|
||||
oisAddr,
|
||||
oisPort);
|
||||
UNSAFE.putObject(this, FIELDS_OFFSET, h);
|
||||
}
|
||||
|
||||
private void readObjectNoData()
|
||||
throws ObjectStreamException
|
||||
{
|
||||
throw new InvalidObjectException("Stream data required");
|
||||
}
|
||||
|
||||
private static final long FIELDS_OFFSET;
|
||||
private static final sun.misc.Unsafe UNSAFE;
|
||||
static {
|
||||
try {
|
||||
sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
|
||||
FIELDS_OFFSET = unsafe.objectFieldOffset(
|
||||
InetSocketAddress.class.getDeclaredField("holder"));
|
||||
UNSAFE = unsafe;
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the port number.
|
||||
*
|
||||
* @return the port number.
|
||||
*/
|
||||
public final int getPort() {
|
||||
return holder.getPort();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Gets the {@code InetAddress}.
|
||||
*
|
||||
* @return the InetAdress or {@code null} if it is unresolved.
|
||||
*/
|
||||
public final InetAddress getAddress() {
|
||||
return holder.getAddress();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@code hostname}.
|
||||
* Note: This method may trigger a name service reverse lookup if the
|
||||
* address was created with a literal IP address.
|
||||
*
|
||||
* @return the hostname part of the address.
|
||||
*/
|
||||
public final String getHostName() {
|
||||
return holder.getHostName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hostname, or the String form of the address if it
|
||||
* doesn't have a hostname (it was created using a literal).
|
||||
* This has the benefit of <b>not</b> attempting a reverse lookup.
|
||||
*
|
||||
* @return the hostname, or String representation of the address.
|
||||
* @since 1.7
|
||||
*/
|
||||
public final String getHostString() {
|
||||
return holder.getHostString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the address has been resolved or not.
|
||||
*
|
||||
* @return {@code true} if the hostname couldn't be resolved into
|
||||
* an {@code InetAddress}.
|
||||
*/
|
||||
public final boolean isUnresolved() {
|
||||
return holder.isUnresolved();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a string representation of this InetSocketAddress.
|
||||
* This String is constructed by calling toString() on the InetAddress
|
||||
* and concatenating the port number (with a colon). If the address
|
||||
* is unresolved then the part before the colon will only contain the hostname.
|
||||
*
|
||||
* @return a string representation of this object.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return holder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this object against the specified object.
|
||||
* The result is {@code true} if and only if the argument is
|
||||
* not {@code null} and it represents the same address as
|
||||
* this object.
|
||||
* <p>
|
||||
* Two instances of {@code InetSocketAddress} represent the same
|
||||
* address if both the InetAddresses (or hostnames if it is unresolved) and port
|
||||
* numbers are equal.
|
||||
* If both addresses are unresolved, then the hostname and the port number
|
||||
* are compared.
|
||||
*
|
||||
* Note: Hostnames are case insensitive. e.g. "FooBar" and "foobar" are
|
||||
* considered equal.
|
||||
*
|
||||
* @param obj the object to compare against.
|
||||
* @return {@code true} if the objects are the same;
|
||||
* {@code false} otherwise.
|
||||
* @see java.net.InetAddress#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public final boolean equals(Object obj) {
|
||||
if (obj == null || !(obj instanceof InetSocketAddress))
|
||||
return false;
|
||||
return holder.equals(((InetSocketAddress) obj).holder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hashcode for this socket address.
|
||||
*
|
||||
* @return a hash code value for this socket address.
|
||||
*/
|
||||
@Override
|
||||
public final int hashCode() {
|
||||
return holder.hashCode();
|
||||
}
|
||||
}
|
||||
134
jdkSrc/jdk8/java/net/InterfaceAddress.java
Normal file
134
jdkSrc/jdk8/java/net/InterfaceAddress.java
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
/**
|
||||
* This class represents a Network Interface address. In short it's an
|
||||
* IP address, a subnet mask and a broadcast address when the address is
|
||||
* an IPv4 one. An IP address and a network prefix length in the case
|
||||
* of IPv6 address.
|
||||
*
|
||||
* @see java.net.NetworkInterface
|
||||
* @since 1.6
|
||||
*/
|
||||
public class InterfaceAddress {
|
||||
private InetAddress address = null;
|
||||
private Inet4Address broadcast = null;
|
||||
private short maskLength = 0;
|
||||
|
||||
/*
|
||||
* Package private constructor. Can't be built directly, instances are
|
||||
* obtained through the NetworkInterface class.
|
||||
*/
|
||||
InterfaceAddress() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an {@code InetAddress} for this address.
|
||||
*
|
||||
* @return the {@code InetAddress} for this address.
|
||||
*/
|
||||
public InetAddress getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an {@code InetAddress} for the broadcast address
|
||||
* for this InterfaceAddress.
|
||||
* <p>
|
||||
* Only IPv4 networks have broadcast address therefore, in the case
|
||||
* of an IPv6 network, {@code null} will be returned.
|
||||
*
|
||||
* @return the {@code InetAddress} representing the broadcast
|
||||
* address or {@code null} if there is no broadcast address.
|
||||
*/
|
||||
public InetAddress getBroadcast() {
|
||||
return broadcast;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the network prefix length for this address. This is also known
|
||||
* as the subnet mask in the context of IPv4 addresses.
|
||||
* Typical IPv4 values would be 8 (255.0.0.0), 16 (255.255.0.0)
|
||||
* or 24 (255.255.255.0). <p>
|
||||
* Typical IPv6 values would be 128 (::1/128) or 10 (fe80::203:baff:fe27:1243/10)
|
||||
*
|
||||
* @return a {@code short} representing the prefix length for the
|
||||
* subnet of that address.
|
||||
*/
|
||||
public short getNetworkPrefixLength() {
|
||||
return maskLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this object against the specified object.
|
||||
* The result is {@code true} if and only if the argument is
|
||||
* not {@code null} and it represents the same interface address as
|
||||
* this object.
|
||||
* <p>
|
||||
* Two instances of {@code InterfaceAddress} represent the same
|
||||
* address if the InetAddress, the prefix length and the broadcast are
|
||||
* the same for both.
|
||||
*
|
||||
* @param obj the object to compare against.
|
||||
* @return {@code true} if the objects are the same;
|
||||
* {@code false} otherwise.
|
||||
* @see java.net.InterfaceAddress#hashCode()
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof InterfaceAddress)) {
|
||||
return false;
|
||||
}
|
||||
InterfaceAddress cmp = (InterfaceAddress) obj;
|
||||
if ( !(address == null ? cmp.address == null : address.equals(cmp.address)) )
|
||||
return false;
|
||||
if ( !(broadcast == null ? cmp.broadcast == null : broadcast.equals(cmp.broadcast)) )
|
||||
return false;
|
||||
if (maskLength != cmp.maskLength)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hashcode for this Interface address.
|
||||
*
|
||||
* @return a hash code value for this Interface address.
|
||||
*/
|
||||
public int hashCode() {
|
||||
return address.hashCode() + ((broadcast != null) ? broadcast.hashCode() : 0) + maskLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts this Interface address to a {@code String}. The
|
||||
* string returned is of the form: InetAddress / prefix length [ broadcast address ].
|
||||
*
|
||||
* @return a string representation of this Interface address.
|
||||
*/
|
||||
public String toString() {
|
||||
return address + "/" + maskLength + " [" + broadcast + "]";
|
||||
}
|
||||
|
||||
}
|
||||
309
jdkSrc/jdk8/java/net/JarURLConnection.java
Normal file
309
jdkSrc/jdk8/java/net/JarURLConnection.java
Normal file
@@ -0,0 +1,309 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.Manifest;
|
||||
import java.security.Permission;
|
||||
import sun.net.www.ParseUtil;
|
||||
|
||||
/**
|
||||
* A URL Connection to a Java ARchive (JAR) file or an entry in a JAR
|
||||
* file.
|
||||
*
|
||||
* <p>The syntax of a JAR URL is:
|
||||
*
|
||||
* <pre>
|
||||
* jar:<url>!/{entry}
|
||||
* </pre>
|
||||
*
|
||||
* <p>for example:
|
||||
*
|
||||
* <p>{@code jar:http://www.foo.com/bar/baz.jar!/COM/foo/Quux.class}
|
||||
*
|
||||
* <p>Jar URLs should be used to refer to a JAR file or entries in
|
||||
* a JAR file. The example above is a JAR URL which refers to a JAR
|
||||
* entry. If the entry name is omitted, the URL refers to the whole
|
||||
* JAR file:
|
||||
*
|
||||
* {@code jar:http://www.foo.com/bar/baz.jar!/}
|
||||
*
|
||||
* <p>Users should cast the generic URLConnection to a
|
||||
* JarURLConnection when they know that the URL they created is a JAR
|
||||
* URL, and they need JAR-specific functionality. For example:
|
||||
*
|
||||
* <pre>
|
||||
* URL url = new URL("jar:file:/home/duke/duke.jar!/");
|
||||
* JarURLConnection jarConnection = (JarURLConnection)url.openConnection();
|
||||
* Manifest manifest = jarConnection.getManifest();
|
||||
* </pre>
|
||||
*
|
||||
* <p>JarURLConnection instances can only be used to read from JAR files.
|
||||
* It is not possible to get a {@link java.io.OutputStream} to modify or write
|
||||
* to the underlying JAR file using this class.
|
||||
* <p>Examples:
|
||||
*
|
||||
* <dl>
|
||||
*
|
||||
* <dt>A Jar entry
|
||||
* <dd>{@code jar:http://www.foo.com/bar/baz.jar!/COM/foo/Quux.class}
|
||||
*
|
||||
* <dt>A Jar file
|
||||
* <dd>{@code jar:http://www.foo.com/bar/baz.jar!/}
|
||||
*
|
||||
* <dt>A Jar directory
|
||||
* <dd>{@code jar:http://www.foo.com/bar/baz.jar!/COM/foo/}
|
||||
*
|
||||
* </dl>
|
||||
*
|
||||
* <p>{@code !/} is referred to as the <em>separator</em>.
|
||||
*
|
||||
* <p>When constructing a JAR url via {@code new URL(context, spec)},
|
||||
* the following rules apply:
|
||||
*
|
||||
* <ul>
|
||||
*
|
||||
* <li>if there is no context URL and the specification passed to the
|
||||
* URL constructor doesn't contain a separator, the URL is considered
|
||||
* to refer to a JarFile.
|
||||
*
|
||||
* <li>if there is a context URL, the context URL is assumed to refer
|
||||
* to a JAR file or a Jar directory.
|
||||
*
|
||||
* <li>if the specification begins with a '/', the Jar directory is
|
||||
* ignored, and the spec is considered to be at the root of the Jar
|
||||
* file.
|
||||
*
|
||||
* <p>Examples:
|
||||
*
|
||||
* <dl>
|
||||
*
|
||||
* <dt>context: <b>jar:http://www.foo.com/bar/jar.jar!/</b>,
|
||||
* spec:<b>baz/entry.txt</b>
|
||||
*
|
||||
* <dd>url:<b>jar:http://www.foo.com/bar/jar.jar!/baz/entry.txt</b>
|
||||
*
|
||||
* <dt>context: <b>jar:http://www.foo.com/bar/jar.jar!/baz</b>,
|
||||
* spec:<b>entry.txt</b>
|
||||
*
|
||||
* <dd>url:<b>jar:http://www.foo.com/bar/jar.jar!/baz/entry.txt</b>
|
||||
*
|
||||
* <dt>context: <b>jar:http://www.foo.com/bar/jar.jar!/baz</b>,
|
||||
* spec:<b>/entry.txt</b>
|
||||
*
|
||||
* <dd>url:<b>jar:http://www.foo.com/bar/jar.jar!/entry.txt</b>
|
||||
*
|
||||
* </dl>
|
||||
*
|
||||
* </ul>
|
||||
*
|
||||
* @see java.net.URL
|
||||
* @see java.net.URLConnection
|
||||
*
|
||||
* @see java.util.jar.JarFile
|
||||
* @see java.util.jar.JarInputStream
|
||||
* @see java.util.jar.Manifest
|
||||
* @see java.util.zip.ZipEntry
|
||||
*
|
||||
* @author Benjamin Renaud
|
||||
* @since 1.2
|
||||
*/
|
||||
public abstract class JarURLConnection extends URLConnection {
|
||||
|
||||
private URL jarFileURL;
|
||||
private String entryName;
|
||||
|
||||
/**
|
||||
* The connection to the JAR file URL, if the connection has been
|
||||
* initiated. This should be set by connect.
|
||||
*/
|
||||
protected URLConnection jarFileURLConnection;
|
||||
|
||||
/**
|
||||
* Creates the new JarURLConnection to the specified URL.
|
||||
* @param url the URL
|
||||
* @throws MalformedURLException if no legal protocol
|
||||
* could be found in a specification string or the
|
||||
* string could not be parsed.
|
||||
*/
|
||||
|
||||
protected JarURLConnection(URL url) throws MalformedURLException {
|
||||
super(url);
|
||||
parseSpecs(url);
|
||||
}
|
||||
|
||||
/* get the specs for a given url out of the cache, and compute and
|
||||
* cache them if they're not there.
|
||||
*/
|
||||
private void parseSpecs(URL url) throws MalformedURLException {
|
||||
String spec = url.getFile();
|
||||
|
||||
int separator = spec.indexOf("!/");
|
||||
/*
|
||||
* REMIND: we don't handle nested JAR URLs
|
||||
*/
|
||||
if (separator == -1) {
|
||||
throw new MalformedURLException("no !/ found in url spec:" + spec);
|
||||
}
|
||||
|
||||
jarFileURL = new URL(spec.substring(0, separator++));
|
||||
entryName = null;
|
||||
|
||||
/* if ! is the last letter of the innerURL, entryName is null */
|
||||
if (++separator != spec.length()) {
|
||||
entryName = spec.substring(separator, spec.length());
|
||||
entryName = ParseUtil.decode (entryName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL for the Jar file for this connection.
|
||||
*
|
||||
* @return the URL for the Jar file for this connection.
|
||||
*/
|
||||
public URL getJarFileURL() {
|
||||
return jarFileURL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the entry name for this connection. This method
|
||||
* returns null if the JAR file URL corresponding to this
|
||||
* connection points to a JAR file and not a JAR file entry.
|
||||
*
|
||||
* @return the entry name for this connection, if any.
|
||||
*/
|
||||
public String getEntryName() {
|
||||
return entryName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the JAR file for this connection.
|
||||
*
|
||||
* @return the JAR file for this connection. If the connection is
|
||||
* a connection to an entry of a JAR file, the JAR file object is
|
||||
* returned
|
||||
*
|
||||
* @exception IOException if an IOException occurs while trying to
|
||||
* connect to the JAR file for this connection.
|
||||
*
|
||||
* @see #connect
|
||||
*/
|
||||
public abstract JarFile getJarFile() throws IOException;
|
||||
|
||||
/**
|
||||
* Returns the Manifest for this connection, or null if none.
|
||||
*
|
||||
* @return the manifest object corresponding to the JAR file object
|
||||
* for this connection.
|
||||
*
|
||||
* @exception IOException if getting the JAR file for this
|
||||
* connection causes an IOException to be thrown.
|
||||
*
|
||||
* @see #getJarFile
|
||||
*/
|
||||
public Manifest getManifest() throws IOException {
|
||||
return getJarFile().getManifest();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the JAR entry object for this connection, if any. This
|
||||
* method returns null if the JAR file URL corresponding to this
|
||||
* connection points to a JAR file and not a JAR file entry.
|
||||
*
|
||||
* @return the JAR entry object for this connection, or null if
|
||||
* the JAR URL for this connection points to a JAR file.
|
||||
*
|
||||
* @exception IOException if getting the JAR file for this
|
||||
* connection causes an IOException to be thrown.
|
||||
*
|
||||
* @see #getJarFile
|
||||
* @see #getJarEntry
|
||||
*/
|
||||
public JarEntry getJarEntry() throws IOException {
|
||||
return getJarFile().getJarEntry(entryName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Attributes object for this connection if the URL
|
||||
* for it points to a JAR file entry, null otherwise.
|
||||
*
|
||||
* @return the Attributes object for this connection if the URL
|
||||
* for it points to a JAR file entry, null otherwise.
|
||||
*
|
||||
* @exception IOException if getting the JAR entry causes an
|
||||
* IOException to be thrown.
|
||||
*
|
||||
* @see #getJarEntry
|
||||
*/
|
||||
public Attributes getAttributes() throws IOException {
|
||||
JarEntry e = getJarEntry();
|
||||
return e != null ? e.getAttributes() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the main Attributes for the JAR file for this
|
||||
* connection.
|
||||
*
|
||||
* @return the main Attributes for the JAR file for this
|
||||
* connection.
|
||||
*
|
||||
* @exception IOException if getting the manifest causes an
|
||||
* IOException to be thrown.
|
||||
*
|
||||
* @see #getJarFile
|
||||
* @see #getManifest
|
||||
*/
|
||||
public Attributes getMainAttributes() throws IOException {
|
||||
Manifest man = getManifest();
|
||||
return man != null ? man.getMainAttributes() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Certificate object for this connection if the URL
|
||||
* for it points to a JAR file entry, null otherwise. This method
|
||||
* can only be called once
|
||||
* the connection has been completely verified by reading
|
||||
* from the input stream until the end of the stream has been
|
||||
* reached. Otherwise, this method will return {@code null}
|
||||
*
|
||||
* @return the Certificate object for this connection if the URL
|
||||
* for it points to a JAR file entry, null otherwise.
|
||||
*
|
||||
* @exception IOException if getting the JAR entry causes an
|
||||
* IOException to be thrown.
|
||||
*
|
||||
* @see #getJarEntry
|
||||
*/
|
||||
public java.security.cert.Certificate[] getCertificates()
|
||||
throws IOException
|
||||
{
|
||||
JarEntry e = getJarEntry();
|
||||
return e != null ? e.getCertificates() : null;
|
||||
}
|
||||
}
|
||||
56
jdkSrc/jdk8/java/net/MalformedURLException.java
Normal file
56
jdkSrc/jdk8/java/net/MalformedURLException.java
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Thrown to indicate that a malformed URL has occurred. Either no
|
||||
* legal protocol could be found in a specification string or the
|
||||
* string could not be parsed.
|
||||
*
|
||||
* @author Arthur van Hoff
|
||||
* @since JDK1.0
|
||||
*/
|
||||
public class MalformedURLException extends IOException {
|
||||
private static final long serialVersionUID = -182787522200415866L;
|
||||
|
||||
/**
|
||||
* Constructs a {@code MalformedURLException} with no detail message.
|
||||
*/
|
||||
public MalformedURLException() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a {@code MalformedURLException} with the
|
||||
* specified detail message.
|
||||
*
|
||||
* @param msg the detail message.
|
||||
*/
|
||||
public MalformedURLException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
709
jdkSrc/jdk8/java/net/MulticastSocket.java
Normal file
709
jdkSrc/jdk8/java/net/MulticastSocket.java
Normal file
@@ -0,0 +1,709 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Enumeration;
|
||||
|
||||
/**
|
||||
* The multicast datagram socket class is useful for sending
|
||||
* and receiving IP multicast packets. A MulticastSocket is
|
||||
* a (UDP) DatagramSocket, with additional capabilities for
|
||||
* joining "groups" of other multicast hosts on the internet.
|
||||
* <P>
|
||||
* A multicast group is specified by a class D IP address
|
||||
* and by a standard UDP port number. Class D IP addresses
|
||||
* are in the range <CODE>224.0.0.0</CODE> to <CODE>239.255.255.255</CODE>,
|
||||
* inclusive. The address 224.0.0.0 is reserved and should not be used.
|
||||
* <P>
|
||||
* One would join a multicast group by first creating a MulticastSocket
|
||||
* with the desired port, then invoking the
|
||||
* <CODE>joinGroup(InetAddress groupAddr)</CODE>
|
||||
* method:
|
||||
* <PRE>
|
||||
* // join a Multicast group and send the group salutations
|
||||
* ...
|
||||
* String msg = "Hello";
|
||||
* InetAddress group = InetAddress.getByName("228.5.6.7");
|
||||
* MulticastSocket s = new MulticastSocket(6789);
|
||||
* s.joinGroup(group);
|
||||
* DatagramPacket hi = new DatagramPacket(msg.getBytes(), msg.length(),
|
||||
* group, 6789);
|
||||
* s.send(hi);
|
||||
* // get their responses!
|
||||
* byte[] buf = new byte[1000];
|
||||
* DatagramPacket recv = new DatagramPacket(buf, buf.length);
|
||||
* s.receive(recv);
|
||||
* ...
|
||||
* // OK, I'm done talking - leave the group...
|
||||
* s.leaveGroup(group);
|
||||
* </PRE>
|
||||
*
|
||||
* When one sends a message to a multicast group, <B>all</B> subscribing
|
||||
* recipients to that host and port receive the message (within the
|
||||
* time-to-live range of the packet, see below). The socket needn't
|
||||
* be a member of the multicast group to send messages to it.
|
||||
* <P>
|
||||
* When a socket subscribes to a multicast group/port, it receives
|
||||
* datagrams sent by other hosts to the group/port, as do all other
|
||||
* members of the group and port. A socket relinquishes membership
|
||||
* in a group by the leaveGroup(InetAddress addr) method. <B>
|
||||
* Multiple MulticastSocket's</B> may subscribe to a multicast group
|
||||
* and port concurrently, and they will all receive group datagrams.
|
||||
* <P>
|
||||
* Currently applets are not allowed to use multicast sockets.
|
||||
*
|
||||
* @author Pavani Diwanji
|
||||
* @since JDK1.1
|
||||
*/
|
||||
public
|
||||
class MulticastSocket extends DatagramSocket {
|
||||
|
||||
/**
|
||||
* Used on some platforms to record if an outgoing interface
|
||||
* has been set for this socket.
|
||||
*/
|
||||
private boolean interfaceSet;
|
||||
|
||||
/**
|
||||
* Create a multicast socket.
|
||||
*
|
||||
* <p>If there is a security manager,
|
||||
* its {@code checkListen} method is first called
|
||||
* with 0 as its argument to ensure the operation is allowed.
|
||||
* This could result in a SecurityException.
|
||||
* <p>
|
||||
* When the socket is created the
|
||||
* {@link DatagramSocket#setReuseAddress(boolean)} method is
|
||||
* called to enable the SO_REUSEADDR socket option.
|
||||
*
|
||||
* @exception IOException if an I/O exception occurs
|
||||
* while creating the MulticastSocket
|
||||
* @exception SecurityException if a security manager exists and its
|
||||
* {@code checkListen} method doesn't allow the operation.
|
||||
* @see SecurityManager#checkListen
|
||||
* @see java.net.DatagramSocket#setReuseAddress(boolean)
|
||||
*/
|
||||
public MulticastSocket() throws IOException {
|
||||
this(new InetSocketAddress(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a multicast socket and bind it to a specific port.
|
||||
*
|
||||
* <p>If there is a security manager,
|
||||
* its {@code checkListen} method is first called
|
||||
* with the {@code port} argument
|
||||
* as its argument to ensure the operation is allowed.
|
||||
* This could result in a SecurityException.
|
||||
* <p>
|
||||
* When the socket is created the
|
||||
* {@link DatagramSocket#setReuseAddress(boolean)} method is
|
||||
* called to enable the SO_REUSEADDR socket option.
|
||||
*
|
||||
* @param port port to use
|
||||
* @exception IOException if an I/O exception occurs
|
||||
* while creating the MulticastSocket
|
||||
* @exception SecurityException if a security manager exists and its
|
||||
* {@code checkListen} method doesn't allow the operation.
|
||||
* @see SecurityManager#checkListen
|
||||
* @see java.net.DatagramSocket#setReuseAddress(boolean)
|
||||
*/
|
||||
public MulticastSocket(int port) throws IOException {
|
||||
this(new InetSocketAddress(port));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a MulticastSocket bound to the specified socket address.
|
||||
* <p>
|
||||
* Or, if the address is {@code null}, create an unbound socket.
|
||||
*
|
||||
* <p>If there is a security manager,
|
||||
* its {@code checkListen} method is first called
|
||||
* with the SocketAddress port as its argument to ensure the operation is allowed.
|
||||
* This could result in a SecurityException.
|
||||
* <p>
|
||||
* When the socket is created the
|
||||
* {@link DatagramSocket#setReuseAddress(boolean)} method is
|
||||
* called to enable the SO_REUSEADDR socket option.
|
||||
*
|
||||
* @param bindaddr Socket address to bind to, or {@code null} for
|
||||
* an unbound socket.
|
||||
* @exception IOException if an I/O exception occurs
|
||||
* while creating the MulticastSocket
|
||||
* @exception SecurityException if a security manager exists and its
|
||||
* {@code checkListen} method doesn't allow the operation.
|
||||
* @see SecurityManager#checkListen
|
||||
* @see java.net.DatagramSocket#setReuseAddress(boolean)
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
public MulticastSocket(SocketAddress bindaddr) throws IOException {
|
||||
super((SocketAddress) null);
|
||||
|
||||
// Enable SO_REUSEADDR before binding
|
||||
setReuseAddress(true);
|
||||
|
||||
if (bindaddr != null) {
|
||||
try {
|
||||
bind(bindaddr);
|
||||
} finally {
|
||||
if (!isBound())
|
||||
close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The lock on the socket's TTL. This is for set/getTTL and
|
||||
* send(packet,ttl).
|
||||
*/
|
||||
private Object ttlLock = new Object();
|
||||
|
||||
/**
|
||||
* The lock on the socket's interface - used by setInterface
|
||||
* and getInterface
|
||||
*/
|
||||
private Object infLock = new Object();
|
||||
|
||||
/**
|
||||
* The "last" interface set by setInterface on this MulticastSocket
|
||||
*/
|
||||
private InetAddress infAddress = null;
|
||||
|
||||
|
||||
/**
|
||||
* Set the default time-to-live for multicast packets sent out
|
||||
* on this {@code MulticastSocket} in order to control the
|
||||
* scope of the multicasts.
|
||||
*
|
||||
* <p>The ttl is an <b>unsigned</b> 8-bit quantity, and so <B>must</B> be
|
||||
* in the range {@code 0 <= ttl <= 0xFF }.
|
||||
*
|
||||
* @param ttl the time-to-live
|
||||
* @exception IOException if an I/O exception occurs
|
||||
* while setting the default time-to-live value
|
||||
* @deprecated use the setTimeToLive method instead, which uses
|
||||
* <b>int</b> instead of <b>byte</b> as the type for ttl.
|
||||
* @see #getTTL()
|
||||
*/
|
||||
@Deprecated
|
||||
public void setTTL(byte ttl) throws IOException {
|
||||
if (isClosed())
|
||||
throw new SocketException("Socket is closed");
|
||||
getImpl().setTTL(ttl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default time-to-live for multicast packets sent out
|
||||
* on this {@code MulticastSocket} in order to control the
|
||||
* scope of the multicasts.
|
||||
*
|
||||
* <P> The ttl <B>must</B> be in the range {@code 0 <= ttl <=
|
||||
* 255} or an {@code IllegalArgumentException} will be thrown.
|
||||
* Multicast packets sent with a TTL of {@code 0} are not transmitted
|
||||
* on the network but may be delivered locally.
|
||||
*
|
||||
* @param ttl
|
||||
* the time-to-live
|
||||
*
|
||||
* @throws IOException
|
||||
* if an I/O exception occurs while setting the
|
||||
* default time-to-live value
|
||||
*
|
||||
* @see #getTimeToLive()
|
||||
*/
|
||||
public void setTimeToLive(int ttl) throws IOException {
|
||||
if (ttl < 0 || ttl > 255) {
|
||||
throw new IllegalArgumentException("ttl out of range");
|
||||
}
|
||||
if (isClosed())
|
||||
throw new SocketException("Socket is closed");
|
||||
getImpl().setTimeToLive(ttl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default time-to-live for multicast packets sent out on
|
||||
* the socket.
|
||||
*
|
||||
* @exception IOException if an I/O exception occurs
|
||||
* while getting the default time-to-live value
|
||||
* @return the default time-to-live value
|
||||
* @deprecated use the getTimeToLive method instead, which returns
|
||||
* an <b>int</b> instead of a <b>byte</b>.
|
||||
* @see #setTTL(byte)
|
||||
*/
|
||||
@Deprecated
|
||||
public byte getTTL() throws IOException {
|
||||
if (isClosed())
|
||||
throw new SocketException("Socket is closed");
|
||||
return getImpl().getTTL();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default time-to-live for multicast packets sent out on
|
||||
* the socket.
|
||||
* @exception IOException if an I/O exception occurs while
|
||||
* getting the default time-to-live value
|
||||
* @return the default time-to-live value
|
||||
* @see #setTimeToLive(int)
|
||||
*/
|
||||
public int getTimeToLive() throws IOException {
|
||||
if (isClosed())
|
||||
throw new SocketException("Socket is closed");
|
||||
return getImpl().getTimeToLive();
|
||||
}
|
||||
|
||||
/**
|
||||
* Joins a multicast group. Its behavior may be affected by
|
||||
* {@code setInterface} or {@code setNetworkInterface}.
|
||||
*
|
||||
* <p>If there is a security manager, this method first
|
||||
* calls its {@code checkMulticast} method
|
||||
* with the {@code mcastaddr} argument
|
||||
* as its argument.
|
||||
*
|
||||
* @param mcastaddr is the multicast address to join
|
||||
*
|
||||
* @exception IOException if there is an error joining
|
||||
* or when the address is not a multicast address.
|
||||
* @exception SecurityException if a security manager exists and its
|
||||
* {@code checkMulticast} method doesn't allow the join.
|
||||
*
|
||||
* @see SecurityManager#checkMulticast(InetAddress)
|
||||
*/
|
||||
public void joinGroup(InetAddress mcastaddr) throws IOException {
|
||||
if (isClosed()) {
|
||||
throw new SocketException("Socket is closed");
|
||||
}
|
||||
|
||||
checkAddress(mcastaddr, "joinGroup");
|
||||
SecurityManager security = System.getSecurityManager();
|
||||
if (security != null) {
|
||||
security.checkMulticast(mcastaddr);
|
||||
}
|
||||
|
||||
if (!mcastaddr.isMulticastAddress()) {
|
||||
throw new SocketException("Not a multicast address");
|
||||
}
|
||||
|
||||
/**
|
||||
* required for some platforms where it's not possible to join
|
||||
* a group without setting the interface first.
|
||||
*/
|
||||
NetworkInterface defaultInterface = NetworkInterface.getDefault();
|
||||
|
||||
if (!interfaceSet && defaultInterface != null) {
|
||||
setNetworkInterface(defaultInterface);
|
||||
}
|
||||
|
||||
getImpl().join(mcastaddr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Leave a multicast group. Its behavior may be affected by
|
||||
* {@code setInterface} or {@code setNetworkInterface}.
|
||||
*
|
||||
* <p>If there is a security manager, this method first
|
||||
* calls its {@code checkMulticast} method
|
||||
* with the {@code mcastaddr} argument
|
||||
* as its argument.
|
||||
*
|
||||
* @param mcastaddr is the multicast address to leave
|
||||
* @exception IOException if there is an error leaving
|
||||
* or when the address is not a multicast address.
|
||||
* @exception SecurityException if a security manager exists and its
|
||||
* {@code checkMulticast} method doesn't allow the operation.
|
||||
*
|
||||
* @see SecurityManager#checkMulticast(InetAddress)
|
||||
*/
|
||||
public void leaveGroup(InetAddress mcastaddr) throws IOException {
|
||||
if (isClosed()) {
|
||||
throw new SocketException("Socket is closed");
|
||||
}
|
||||
|
||||
checkAddress(mcastaddr, "leaveGroup");
|
||||
SecurityManager security = System.getSecurityManager();
|
||||
if (security != null) {
|
||||
security.checkMulticast(mcastaddr);
|
||||
}
|
||||
|
||||
if (!mcastaddr.isMulticastAddress()) {
|
||||
throw new SocketException("Not a multicast address");
|
||||
}
|
||||
|
||||
getImpl().leave(mcastaddr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Joins the specified multicast group at the specified interface.
|
||||
*
|
||||
* <p>If there is a security manager, this method first
|
||||
* calls its {@code checkMulticast} method
|
||||
* with the {@code mcastaddr} argument
|
||||
* as its argument.
|
||||
*
|
||||
* @param mcastaddr is the multicast address to join
|
||||
* @param netIf specifies the local interface to receive multicast
|
||||
* datagram packets, or <i>null</i> to defer to the interface set by
|
||||
* {@link MulticastSocket#setInterface(InetAddress)} or
|
||||
* {@link MulticastSocket#setNetworkInterface(NetworkInterface)}
|
||||
*
|
||||
* @exception IOException if there is an error joining
|
||||
* or when the address is not a multicast address.
|
||||
* @exception SecurityException if a security manager exists and its
|
||||
* {@code checkMulticast} method doesn't allow the join.
|
||||
* @throws IllegalArgumentException if mcastaddr is null or is a
|
||||
* SocketAddress subclass not supported by this socket
|
||||
*
|
||||
* @see SecurityManager#checkMulticast(InetAddress)
|
||||
* @since 1.4
|
||||
*/
|
||||
public void joinGroup(SocketAddress mcastaddr, NetworkInterface netIf)
|
||||
throws IOException {
|
||||
if (isClosed())
|
||||
throw new SocketException("Socket is closed");
|
||||
|
||||
if (mcastaddr == null || !(mcastaddr instanceof InetSocketAddress))
|
||||
throw new IllegalArgumentException("Unsupported address type");
|
||||
|
||||
if (oldImpl)
|
||||
throw new UnsupportedOperationException();
|
||||
|
||||
checkAddress(((InetSocketAddress)mcastaddr).getAddress(), "joinGroup");
|
||||
SecurityManager security = System.getSecurityManager();
|
||||
if (security != null) {
|
||||
security.checkMulticast(((InetSocketAddress)mcastaddr).getAddress());
|
||||
}
|
||||
|
||||
if (!((InetSocketAddress)mcastaddr).getAddress().isMulticastAddress()) {
|
||||
throw new SocketException("Not a multicast address");
|
||||
}
|
||||
|
||||
getImpl().joinGroup(mcastaddr, netIf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Leave a multicast group on a specified local interface.
|
||||
*
|
||||
* <p>If there is a security manager, this method first
|
||||
* calls its {@code checkMulticast} method
|
||||
* with the {@code mcastaddr} argument
|
||||
* as its argument.
|
||||
*
|
||||
* @param mcastaddr is the multicast address to leave
|
||||
* @param netIf specifies the local interface or <i>null</i> to defer
|
||||
* to the interface set by
|
||||
* {@link MulticastSocket#setInterface(InetAddress)} or
|
||||
* {@link MulticastSocket#setNetworkInterface(NetworkInterface)}
|
||||
* @exception IOException if there is an error leaving
|
||||
* or when the address is not a multicast address.
|
||||
* @exception SecurityException if a security manager exists and its
|
||||
* {@code checkMulticast} method doesn't allow the operation.
|
||||
* @throws IllegalArgumentException if mcastaddr is null or is a
|
||||
* SocketAddress subclass not supported by this socket
|
||||
*
|
||||
* @see SecurityManager#checkMulticast(InetAddress)
|
||||
* @since 1.4
|
||||
*/
|
||||
public void leaveGroup(SocketAddress mcastaddr, NetworkInterface netIf)
|
||||
throws IOException {
|
||||
if (isClosed())
|
||||
throw new SocketException("Socket is closed");
|
||||
|
||||
if (mcastaddr == null || !(mcastaddr instanceof InetSocketAddress))
|
||||
throw new IllegalArgumentException("Unsupported address type");
|
||||
|
||||
if (oldImpl)
|
||||
throw new UnsupportedOperationException();
|
||||
|
||||
checkAddress(((InetSocketAddress)mcastaddr).getAddress(), "leaveGroup");
|
||||
SecurityManager security = System.getSecurityManager();
|
||||
if (security != null) {
|
||||
security.checkMulticast(((InetSocketAddress)mcastaddr).getAddress());
|
||||
}
|
||||
|
||||
if (!((InetSocketAddress)mcastaddr).getAddress().isMulticastAddress()) {
|
||||
throw new SocketException("Not a multicast address");
|
||||
}
|
||||
|
||||
getImpl().leaveGroup(mcastaddr, netIf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the multicast network interface used by methods
|
||||
* whose behavior would be affected by the value of the
|
||||
* network interface. Useful for multihomed hosts.
|
||||
* @param inf the InetAddress
|
||||
* @exception SocketException if there is an error in
|
||||
* the underlying protocol, such as a TCP error.
|
||||
* @see #getInterface()
|
||||
*/
|
||||
public void setInterface(InetAddress inf) throws SocketException {
|
||||
if (isClosed()) {
|
||||
throw new SocketException("Socket is closed");
|
||||
}
|
||||
checkAddress(inf, "setInterface");
|
||||
synchronized (infLock) {
|
||||
getImpl().setOption(SocketOptions.IP_MULTICAST_IF, inf);
|
||||
infAddress = inf;
|
||||
interfaceSet = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the address of the network interface used for
|
||||
* multicast packets.
|
||||
*
|
||||
* @return An {@code InetAddress} representing
|
||||
* the address of the network interface used for
|
||||
* multicast packets.
|
||||
*
|
||||
* @exception SocketException if there is an error in
|
||||
* the underlying protocol, such as a TCP error.
|
||||
*
|
||||
* @see #setInterface(java.net.InetAddress)
|
||||
*/
|
||||
public InetAddress getInterface() throws SocketException {
|
||||
if (isClosed()) {
|
||||
throw new SocketException("Socket is closed");
|
||||
}
|
||||
synchronized (infLock) {
|
||||
InetAddress ia =
|
||||
(InetAddress)getImpl().getOption(SocketOptions.IP_MULTICAST_IF);
|
||||
|
||||
/**
|
||||
* No previous setInterface or interface can be
|
||||
* set using setNetworkInterface
|
||||
*/
|
||||
if (infAddress == null) {
|
||||
return ia;
|
||||
}
|
||||
|
||||
/**
|
||||
* Same interface set with setInterface?
|
||||
*/
|
||||
if (ia.equals(infAddress)) {
|
||||
return ia;
|
||||
}
|
||||
|
||||
/**
|
||||
* Different InetAddress from what we set with setInterface
|
||||
* so enumerate the current interface to see if the
|
||||
* address set by setInterface is bound to this interface.
|
||||
*/
|
||||
try {
|
||||
NetworkInterface ni = NetworkInterface.getByInetAddress(ia);
|
||||
Enumeration<InetAddress> addrs = ni.getInetAddresses();
|
||||
while (addrs.hasMoreElements()) {
|
||||
InetAddress addr = addrs.nextElement();
|
||||
if (addr.equals(infAddress)) {
|
||||
return infAddress;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* No match so reset infAddress to indicate that the
|
||||
* interface has changed via means
|
||||
*/
|
||||
infAddress = null;
|
||||
return ia;
|
||||
} catch (Exception e) {
|
||||
return ia;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the network interface for outgoing multicast datagrams
|
||||
* sent on this socket.
|
||||
*
|
||||
* @param netIf the interface
|
||||
* @exception SocketException if there is an error in
|
||||
* the underlying protocol, such as a TCP error.
|
||||
* @see #getNetworkInterface()
|
||||
* @since 1.4
|
||||
*/
|
||||
public void setNetworkInterface(NetworkInterface netIf)
|
||||
throws SocketException {
|
||||
|
||||
synchronized (infLock) {
|
||||
getImpl().setOption(SocketOptions.IP_MULTICAST_IF2, netIf);
|
||||
infAddress = null;
|
||||
interfaceSet = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the multicast network interface set.
|
||||
*
|
||||
* @exception SocketException if there is an error in
|
||||
* the underlying protocol, such as a TCP error.
|
||||
* @return the multicast {@code NetworkInterface} currently set
|
||||
* @see #setNetworkInterface(NetworkInterface)
|
||||
* @since 1.4
|
||||
*/
|
||||
public NetworkInterface getNetworkInterface() throws SocketException {
|
||||
NetworkInterface ni
|
||||
= (NetworkInterface)getImpl().getOption(SocketOptions.IP_MULTICAST_IF2);
|
||||
if ((ni.getIndex() == 0) || (ni.getIndex() == -1)) {
|
||||
InetAddress[] addrs = new InetAddress[1];
|
||||
addrs[0] = InetAddress.anyLocalAddress();
|
||||
return new NetworkInterface(addrs[0].getHostName(), 0, addrs);
|
||||
} else {
|
||||
return ni;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable/Enable local loopback of multicast datagrams
|
||||
* The option is used by the platform's networking code as a hint
|
||||
* for setting whether multicast data will be looped back to
|
||||
* the local socket.
|
||||
*
|
||||
* <p>Because this option is a hint, applications that want to
|
||||
* verify what loopback mode is set to should call
|
||||
* {@link #getLoopbackMode()}
|
||||
* @param disable {@code true} to disable the LoopbackMode
|
||||
* @throws SocketException if an error occurs while setting the value
|
||||
* @since 1.4
|
||||
* @see #getLoopbackMode
|
||||
*/
|
||||
public void setLoopbackMode(boolean disable) throws SocketException {
|
||||
getImpl().setOption(SocketOptions.IP_MULTICAST_LOOP, Boolean.valueOf(disable));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the setting for local loopback of multicast datagrams.
|
||||
*
|
||||
* @throws SocketException if an error occurs while getting the value
|
||||
* @return true if the LoopbackMode has been disabled
|
||||
* @since 1.4
|
||||
* @see #setLoopbackMode
|
||||
*/
|
||||
public boolean getLoopbackMode() throws SocketException {
|
||||
return ((Boolean)getImpl().getOption(SocketOptions.IP_MULTICAST_LOOP)).booleanValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a datagram packet to the destination, with a TTL (time-
|
||||
* to-live) other than the default for the socket. This method
|
||||
* need only be used in instances where a particular TTL is desired;
|
||||
* otherwise it is preferable to set a TTL once on the socket, and
|
||||
* use that default TTL for all packets. This method does <B>not
|
||||
* </B> alter the default TTL for the socket. Its behavior may be
|
||||
* affected by {@code setInterface}.
|
||||
*
|
||||
* <p>If there is a security manager, this method first performs some
|
||||
* security checks. First, if {@code p.getAddress().isMulticastAddress()}
|
||||
* is true, this method calls the
|
||||
* security manager's {@code checkMulticast} method
|
||||
* with {@code p.getAddress()} and {@code ttl} as its arguments.
|
||||
* If the evaluation of that expression is false,
|
||||
* this method instead calls the security manager's
|
||||
* {@code checkConnect} method with arguments
|
||||
* {@code p.getAddress().getHostAddress()} and
|
||||
* {@code p.getPort()}. Each call to a security manager method
|
||||
* could result in a SecurityException if the operation is not allowed.
|
||||
*
|
||||
* @param p is the packet to be sent. The packet should contain
|
||||
* the destination multicast ip address and the data to be sent.
|
||||
* One does not need to be the member of the group to send
|
||||
* packets to a destination multicast address.
|
||||
* @param ttl optional time to live for multicast packet.
|
||||
* default ttl is 1.
|
||||
*
|
||||
* @exception IOException is raised if an error occurs i.e
|
||||
* error while setting ttl.
|
||||
* @exception SecurityException if a security manager exists and its
|
||||
* {@code checkMulticast} or {@code checkConnect}
|
||||
* method doesn't allow the send.
|
||||
*
|
||||
* @deprecated Use the following code or its equivalent instead:
|
||||
* ......
|
||||
* int ttl = mcastSocket.getTimeToLive();
|
||||
* mcastSocket.setTimeToLive(newttl);
|
||||
* mcastSocket.send(p);
|
||||
* mcastSocket.setTimeToLive(ttl);
|
||||
* ......
|
||||
*
|
||||
* @see DatagramSocket#send
|
||||
* @see DatagramSocket#receive
|
||||
* @see SecurityManager#checkMulticast(java.net.InetAddress, byte)
|
||||
* @see SecurityManager#checkConnect
|
||||
*/
|
||||
@Deprecated
|
||||
public void send(DatagramPacket p, byte ttl)
|
||||
throws IOException {
|
||||
if (isClosed())
|
||||
throw new SocketException("Socket is closed");
|
||||
checkAddress(p.getAddress(), "send");
|
||||
synchronized(ttlLock) {
|
||||
synchronized(p) {
|
||||
if (connectState == ST_NOT_CONNECTED) {
|
||||
// Security manager makes sure that the multicast address
|
||||
// is allowed one and that the ttl used is less
|
||||
// than the allowed maxttl.
|
||||
SecurityManager security = System.getSecurityManager();
|
||||
if (security != null) {
|
||||
if (p.getAddress().isMulticastAddress()) {
|
||||
security.checkMulticast(p.getAddress(), ttl);
|
||||
} else {
|
||||
security.checkConnect(p.getAddress().getHostAddress(),
|
||||
p.getPort());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// we're connected
|
||||
InetAddress packetAddress = null;
|
||||
packetAddress = p.getAddress();
|
||||
if (packetAddress == null) {
|
||||
p.setAddress(connectedAddress);
|
||||
p.setPort(connectedPort);
|
||||
} else if ((!packetAddress.equals(connectedAddress)) ||
|
||||
p.getPort() != connectedPort) {
|
||||
throw new SecurityException("connected address and packet address" +
|
||||
" differ");
|
||||
}
|
||||
}
|
||||
byte dttl = getTTL();
|
||||
try {
|
||||
if (ttl != dttl) {
|
||||
// set the ttl
|
||||
getImpl().setTTL(ttl);
|
||||
}
|
||||
// call the datagram method to send
|
||||
getImpl().send(p);
|
||||
} finally {
|
||||
// set it back to default
|
||||
if (ttl != dttl) {
|
||||
getImpl().setTTL(dttl);
|
||||
}
|
||||
}
|
||||
} // synch p
|
||||
} //synch ttl
|
||||
} //method
|
||||
}
|
||||
213
jdkSrc/jdk8/java/net/NetPermission.java
Normal file
213
jdkSrc/jdk8/java/net/NetPermission.java
Normal file
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
import java.security.*;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Hashtable;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
/**
|
||||
* This class is for various network permissions.
|
||||
* A NetPermission contains a name (also referred to as a "target name") but
|
||||
* no actions list; you either have the named permission
|
||||
* or you don't.
|
||||
* <P>
|
||||
* The target name is the name of the network permission (see below). The naming
|
||||
* convention follows the hierarchical property naming convention.
|
||||
* Also, an asterisk
|
||||
* may appear at the end of the name, following a ".", or by itself, to
|
||||
* signify a wildcard match. For example: "foo.*" and "*" signify a wildcard
|
||||
* match, while "*foo" and "a*b" do not.
|
||||
* <P>
|
||||
* The following table lists all the possible NetPermission target names,
|
||||
* and for each provides a description of what the permission allows
|
||||
* and a discussion of the risks of granting code the permission.
|
||||
*
|
||||
* <table border=1 cellpadding=5 summary="Permission target name, what the permission allows, and associated risks">
|
||||
* <tr>
|
||||
* <th>Permission Target Name</th>
|
||||
* <th>What the Permission Allows</th>
|
||||
* <th>Risks of Allowing this Permission</th>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>allowHttpTrace</td>
|
||||
* <td>The ability to use the HTTP TRACE method in HttpURLConnection.</td>
|
||||
* <td>Malicious code using HTTP TRACE could get access to security sensitive
|
||||
* information in the HTTP headers (such as cookies) that it might not
|
||||
* otherwise have access to.</td>
|
||||
* </tr>
|
||||
*
|
||||
* <tr>
|
||||
* <td>getCookieHandler</td>
|
||||
* <td>The ability to get the cookie handler that processes highly
|
||||
* security sensitive cookie information for an Http session.</td>
|
||||
* <td>Malicious code can get a cookie handler to obtain access to
|
||||
* highly security sensitive cookie information. Some web servers
|
||||
* use cookies to save user private information such as access
|
||||
* control information, or to track user browsing habit.</td>
|
||||
* </tr>
|
||||
*
|
||||
* <tr>
|
||||
* <td>getNetworkInformation</td>
|
||||
* <td>The ability to retrieve all information about local network interfaces.</td>
|
||||
* <td>Malicious code can read information about network hardware such as
|
||||
* MAC addresses, which could be used to construct local IPv6 addresses.</td>
|
||||
* </tr>
|
||||
*
|
||||
* <tr>
|
||||
* <td>getProxySelector</td>
|
||||
* <td>The ability to get the proxy selector used to make decisions
|
||||
* on which proxies to use when making network connections.</td>
|
||||
* <td>Malicious code can get a ProxySelector to discover proxy
|
||||
* hosts and ports on internal networks, which could then become
|
||||
* targets for attack.</td>
|
||||
* </tr>
|
||||
*
|
||||
* <tr>
|
||||
* <td>getResponseCache</td>
|
||||
* <td>The ability to get the response cache that provides
|
||||
* access to a local response cache.</td>
|
||||
* <td>Malicious code getting access to the local response cache
|
||||
* could access security sensitive information.</td>
|
||||
* </tr>
|
||||
*
|
||||
* <tr>
|
||||
* <td>requestPasswordAuthentication</td>
|
||||
* <td>The ability
|
||||
* to ask the authenticator registered with the system for
|
||||
* a password</td>
|
||||
* <td>Malicious code may steal this password.</td>
|
||||
* </tr>
|
||||
*
|
||||
* <tr>
|
||||
* <td>setCookieHandler</td>
|
||||
* <td>The ability to set the cookie handler that processes highly
|
||||
* security sensitive cookie information for an Http session.</td>
|
||||
* <td>Malicious code can set a cookie handler to obtain access to
|
||||
* highly security sensitive cookie information. Some web servers
|
||||
* use cookies to save user private information such as access
|
||||
* control information, or to track user browsing habit.</td>
|
||||
* </tr>
|
||||
*
|
||||
* <tr>
|
||||
* <td>setDefaultAuthenticator</td>
|
||||
* <td>The ability to set the
|
||||
* way authentication information is retrieved when
|
||||
* a proxy or HTTP server asks for authentication</td>
|
||||
* <td>Malicious
|
||||
* code can set an authenticator that monitors and steals user
|
||||
* authentication input as it retrieves the input from the user.</td>
|
||||
* </tr>
|
||||
*
|
||||
* <tr>
|
||||
* <td>setProxySelector</td>
|
||||
* <td>The ability to set the proxy selector used to make decisions
|
||||
* on which proxies to use when making network connections.</td>
|
||||
* <td>Malicious code can set a ProxySelector that directs network
|
||||
* traffic to an arbitrary network host.</td>
|
||||
* </tr>
|
||||
*
|
||||
* <tr>
|
||||
* <td>setResponseCache</td>
|
||||
* <td>The ability to set the response cache that provides access to
|
||||
* a local response cache.</td>
|
||||
* <td>Malicious code getting access to the local response cache
|
||||
* could access security sensitive information, or create false
|
||||
* entries in the response cache.</td>
|
||||
* </tr>
|
||||
*
|
||||
* <tr>
|
||||
* <td>specifyStreamHandler</td>
|
||||
* <td>The ability
|
||||
* to specify a stream handler when constructing a URL</td>
|
||||
* <td>Malicious code may create a URL with resources that it would
|
||||
normally not have access to (like file:/foo/fum/), specifying a
|
||||
stream handler that gets the actual bytes from someplace it does
|
||||
have access to. Thus it might be able to trick the system into
|
||||
creating a ProtectionDomain/CodeSource for a class even though
|
||||
that class really didn't come from that location.</td>
|
||||
* </tr>
|
||||
*
|
||||
* <tr>
|
||||
* <th scope="row">setSocketImpl</th>
|
||||
* <td>The ability to create a sub-class of Socket or ServerSocket with a
|
||||
* user specified SocketImpl.</td>
|
||||
* <td>Malicious user-defined SocketImpls can change the behavior of
|
||||
* Socket and ServerSocket in surprising ways, by virtue of their
|
||||
* ability to access the protected fields of SocketImpl.</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* @see java.security.BasicPermission
|
||||
* @see java.security.Permission
|
||||
* @see java.security.Permissions
|
||||
* @see java.security.PermissionCollection
|
||||
* @see java.lang.SecurityManager
|
||||
*
|
||||
*
|
||||
* @author Marianne Mueller
|
||||
* @author Roland Schemers
|
||||
*/
|
||||
|
||||
public final class NetPermission extends BasicPermission {
|
||||
private static final long serialVersionUID = -8343910153355041693L;
|
||||
|
||||
/**
|
||||
* Creates a new NetPermission with the specified name.
|
||||
* The name is the symbolic name of the NetPermission, such as
|
||||
* "setDefaultAuthenticator", etc. An asterisk
|
||||
* may appear at the end of the name, following a ".", or by itself, to
|
||||
* signify a wildcard match.
|
||||
*
|
||||
* @param name the name of the NetPermission.
|
||||
*
|
||||
* @throws NullPointerException if {@code name} is {@code null}.
|
||||
* @throws IllegalArgumentException if {@code name} is empty.
|
||||
*/
|
||||
|
||||
public NetPermission(String name)
|
||||
{
|
||||
super(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new NetPermission object with the specified name.
|
||||
* The name is the symbolic name of the NetPermission, and the
|
||||
* actions String is currently unused and should be null.
|
||||
*
|
||||
* @param name the name of the NetPermission.
|
||||
* @param actions should be null.
|
||||
*
|
||||
* @throws NullPointerException if {@code name} is {@code null}.
|
||||
* @throws IllegalArgumentException if {@code name} is empty.
|
||||
*/
|
||||
|
||||
public NetPermission(String name, String actions)
|
||||
{
|
||||
super(name, actions);
|
||||
}
|
||||
}
|
||||
592
jdkSrc/jdk8/java/net/NetworkInterface.java
Normal file
592
jdkSrc/jdk8/java/net/NetworkInterface.java
Normal file
@@ -0,0 +1,592 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
import java.util.Enumeration;
|
||||
import java.util.NoSuchElementException;
|
||||
import sun.security.action.*;
|
||||
import java.security.AccessController;
|
||||
|
||||
/**
|
||||
* This class represents a Network Interface made up of a name,
|
||||
* and a list of IP addresses assigned to this interface.
|
||||
* It is used to identify the local interface on which a multicast group
|
||||
* is joined.
|
||||
*
|
||||
* Interfaces are normally known by names such as "le0".
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
public final class NetworkInterface {
|
||||
private String name;
|
||||
private String displayName;
|
||||
private int index;
|
||||
private InetAddress addrs[];
|
||||
private InterfaceAddress bindings[];
|
||||
private NetworkInterface childs[];
|
||||
private NetworkInterface parent = null;
|
||||
private boolean virtual = false;
|
||||
private static final NetworkInterface defaultInterface;
|
||||
private static final int defaultIndex; /* index of defaultInterface */
|
||||
|
||||
static {
|
||||
AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
System.loadLibrary("net");
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
init();
|
||||
defaultInterface = DefaultInterface.getDefault();
|
||||
if (defaultInterface != null) {
|
||||
defaultIndex = defaultInterface.getIndex();
|
||||
} else {
|
||||
defaultIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an NetworkInterface object with index set to 0 and name to null.
|
||||
* Setting such an interface on a MulticastSocket will cause the
|
||||
* kernel to choose one interface for sending multicast packets.
|
||||
*
|
||||
*/
|
||||
NetworkInterface() {
|
||||
}
|
||||
|
||||
NetworkInterface(String name, int index, InetAddress[] addrs) {
|
||||
this.name = name;
|
||||
this.index = index;
|
||||
this.addrs = addrs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of this network interface.
|
||||
*
|
||||
* @return the name of this network interface
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to return an Enumeration with all or a
|
||||
* subset of the InetAddresses bound to this network interface.
|
||||
* <p>
|
||||
* If there is a security manager, its {@code checkConnect}
|
||||
* method is called for each InetAddress. Only InetAddresses where
|
||||
* the {@code checkConnect} doesn't throw a SecurityException
|
||||
* will be returned in the Enumeration. However, if the caller has the
|
||||
* {@link NetPermission}("getNetworkInformation") permission, then all
|
||||
* InetAddresses are returned.
|
||||
* @return an Enumeration object with all or a subset of the InetAddresses
|
||||
* bound to this network interface
|
||||
*/
|
||||
public Enumeration<InetAddress> getInetAddresses() {
|
||||
|
||||
class checkedAddresses implements Enumeration<InetAddress> {
|
||||
|
||||
private int i=0, count=0;
|
||||
private InetAddress local_addrs[];
|
||||
|
||||
checkedAddresses() {
|
||||
local_addrs = new InetAddress[addrs.length];
|
||||
boolean trusted = true;
|
||||
|
||||
SecurityManager sec = System.getSecurityManager();
|
||||
if (sec != null) {
|
||||
try {
|
||||
sec.checkPermission(new NetPermission("getNetworkInformation"));
|
||||
} catch (SecurityException e) {
|
||||
trusted = false;
|
||||
}
|
||||
}
|
||||
for (int j=0; j<addrs.length; j++) {
|
||||
try {
|
||||
if (sec != null && !trusted) {
|
||||
sec.checkConnect(addrs[j].getHostAddress(), -1);
|
||||
}
|
||||
local_addrs[count++] = addrs[j];
|
||||
} catch (SecurityException e) { }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public InetAddress nextElement() {
|
||||
if (i < count) {
|
||||
return local_addrs[i++];
|
||||
} else {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasMoreElements() {
|
||||
return (i < count);
|
||||
}
|
||||
}
|
||||
return new checkedAddresses();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a List of all or a subset of the {@code InterfaceAddresses}
|
||||
* of this network interface.
|
||||
* <p>
|
||||
* If there is a security manager, its {@code checkConnect}
|
||||
* method is called with the InetAddress for each InterfaceAddress.
|
||||
* Only InterfaceAddresses where the {@code checkConnect} doesn't throw
|
||||
* a SecurityException will be returned in the List.
|
||||
*
|
||||
* @return a {@code List} object with all or a subset of the
|
||||
* InterfaceAddresss of this network interface
|
||||
* @since 1.6
|
||||
*/
|
||||
public java.util.List<InterfaceAddress> getInterfaceAddresses() {
|
||||
java.util.List<InterfaceAddress> lst = new java.util.ArrayList<InterfaceAddress>(1);
|
||||
SecurityManager sec = System.getSecurityManager();
|
||||
for (int j=0; j<bindings.length; j++) {
|
||||
try {
|
||||
if (sec != null) {
|
||||
sec.checkConnect(bindings[j].getAddress().getHostAddress(), -1);
|
||||
}
|
||||
lst.add(bindings[j]);
|
||||
} catch (SecurityException e) { }
|
||||
}
|
||||
return lst;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an Enumeration with all the subinterfaces (also known as virtual
|
||||
* interfaces) attached to this network interface.
|
||||
* <p>
|
||||
* For instance eth0:1 will be a subinterface to eth0.
|
||||
*
|
||||
* @return an Enumeration object with all of the subinterfaces
|
||||
* of this network interface
|
||||
* @since 1.6
|
||||
*/
|
||||
public Enumeration<NetworkInterface> getSubInterfaces() {
|
||||
class subIFs implements Enumeration<NetworkInterface> {
|
||||
|
||||
private int i=0;
|
||||
|
||||
subIFs() {
|
||||
}
|
||||
|
||||
public NetworkInterface nextElement() {
|
||||
if (i < childs.length) {
|
||||
return childs[i++];
|
||||
} else {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasMoreElements() {
|
||||
return (i < childs.length);
|
||||
}
|
||||
}
|
||||
return new subIFs();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the parent NetworkInterface of this interface if this is
|
||||
* a subinterface, or {@code null} if it is a physical
|
||||
* (non virtual) interface or has no parent.
|
||||
*
|
||||
* @return The {@code NetworkInterface} this interface is attached to.
|
||||
* @since 1.6
|
||||
*/
|
||||
public NetworkInterface getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of this network interface. The index is an integer greater
|
||||
* or equal to zero, or {@code -1} for unknown. This is a system specific value
|
||||
* and interfaces with the same name can have different indexes on different
|
||||
* machines.
|
||||
*
|
||||
* @return the index of this network interface or {@code -1} if the index is
|
||||
* unknown
|
||||
* @see #getByIndex(int)
|
||||
* @since 1.7
|
||||
*/
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the display name of this network interface.
|
||||
* A display name is a human readable String describing the network
|
||||
* device.
|
||||
*
|
||||
* @return a non-empty string representing the display name of this network
|
||||
* interface, or null if no display name is available.
|
||||
*/
|
||||
public String getDisplayName() {
|
||||
/* strict TCK conformance */
|
||||
return "".equals(displayName) ? null : displayName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for the network interface with the specified name.
|
||||
*
|
||||
* @param name
|
||||
* The name of the network interface.
|
||||
*
|
||||
* @return A {@code NetworkInterface} with the specified name,
|
||||
* or {@code null} if there is no network interface
|
||||
* with the specified name.
|
||||
*
|
||||
* @throws SocketException
|
||||
* If an I/O error occurs.
|
||||
*
|
||||
* @throws NullPointerException
|
||||
* If the specified name is {@code null}.
|
||||
*/
|
||||
public static NetworkInterface getByName(String name) throws SocketException {
|
||||
if (name == null)
|
||||
throw new NullPointerException();
|
||||
return getByName0(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a network interface given its index.
|
||||
*
|
||||
* @param index an integer, the index of the interface
|
||||
* @return the NetworkInterface obtained from its index, or {@code null} if
|
||||
* there is no interface with such an index on the system
|
||||
* @throws SocketException if an I/O error occurs.
|
||||
* @throws IllegalArgumentException if index has a negative value
|
||||
* @see #getIndex()
|
||||
* @since 1.7
|
||||
*/
|
||||
public static NetworkInterface getByIndex(int index) throws SocketException {
|
||||
if (index < 0)
|
||||
throw new IllegalArgumentException("Interface index can't be negative");
|
||||
return getByIndex0(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to search for a network interface that
|
||||
* has the specified Internet Protocol (IP) address bound to
|
||||
* it.
|
||||
* <p>
|
||||
* If the specified IP address is bound to multiple network
|
||||
* interfaces it is not defined which network interface is
|
||||
* returned.
|
||||
*
|
||||
* @param addr
|
||||
* The {@code InetAddress} to search with.
|
||||
*
|
||||
* @return A {@code NetworkInterface}
|
||||
* or {@code null} if there is no network interface
|
||||
* with the specified IP address.
|
||||
*
|
||||
* @throws SocketException
|
||||
* If an I/O error occurs.
|
||||
*
|
||||
* @throws NullPointerException
|
||||
* If the specified address is {@code null}.
|
||||
*/
|
||||
public static NetworkInterface getByInetAddress(InetAddress addr) throws SocketException {
|
||||
if (addr == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
if (addr instanceof Inet4Address) {
|
||||
Inet4Address inet4Address = (Inet4Address) addr;
|
||||
if (inet4Address.holder.family != InetAddress.IPv4) {
|
||||
throw new IllegalArgumentException("invalid family type: "
|
||||
+ inet4Address.holder.family);
|
||||
}
|
||||
} else if (addr instanceof Inet6Address) {
|
||||
Inet6Address inet6Address = (Inet6Address) addr;
|
||||
if (inet6Address.holder.family != InetAddress.IPv6) {
|
||||
throw new IllegalArgumentException("invalid family type: "
|
||||
+ inet6Address.holder.family);
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException("invalid address type: " + addr);
|
||||
}
|
||||
return getByInetAddress0(addr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the interfaces on this machine. The {@code Enumeration}
|
||||
* contains at least one element, possibly representing a loopback
|
||||
* interface that only supports communication between entities on
|
||||
* this machine.
|
||||
*
|
||||
* NOTE: can use getNetworkInterfaces()+getInetAddresses()
|
||||
* to obtain all IP addresses for this node
|
||||
*
|
||||
* @return an Enumeration of NetworkInterfaces found on this machine
|
||||
* @exception SocketException if an I/O error occurs.
|
||||
*/
|
||||
|
||||
public static Enumeration<NetworkInterface> getNetworkInterfaces()
|
||||
throws SocketException {
|
||||
final NetworkInterface[] netifs = getAll();
|
||||
|
||||
// specified to return null if no network interfaces
|
||||
if (netifs == null)
|
||||
return null;
|
||||
|
||||
return new Enumeration<NetworkInterface>() {
|
||||
private int i = 0;
|
||||
public NetworkInterface nextElement() {
|
||||
if (netifs != null && i < netifs.length) {
|
||||
NetworkInterface netif = netifs[i++];
|
||||
return netif;
|
||||
} else {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasMoreElements() {
|
||||
return (netifs != null && i < netifs.length);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private native static NetworkInterface[] getAll()
|
||||
throws SocketException;
|
||||
|
||||
private native static NetworkInterface getByName0(String name)
|
||||
throws SocketException;
|
||||
|
||||
private native static NetworkInterface getByIndex0(int index)
|
||||
throws SocketException;
|
||||
|
||||
private native static NetworkInterface getByInetAddress0(InetAddress addr)
|
||||
throws SocketException;
|
||||
|
||||
/**
|
||||
* Returns whether a network interface is up and running.
|
||||
*
|
||||
* @return {@code true} if the interface is up and running.
|
||||
* @exception SocketException if an I/O error occurs.
|
||||
* @since 1.6
|
||||
*/
|
||||
|
||||
public boolean isUp() throws SocketException {
|
||||
return isUp0(name, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether a network interface is a loopback interface.
|
||||
*
|
||||
* @return {@code true} if the interface is a loopback interface.
|
||||
* @exception SocketException if an I/O error occurs.
|
||||
* @since 1.6
|
||||
*/
|
||||
|
||||
public boolean isLoopback() throws SocketException {
|
||||
return isLoopback0(name, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether a network interface is a point to point interface.
|
||||
* A typical point to point interface would be a PPP connection through
|
||||
* a modem.
|
||||
*
|
||||
* @return {@code true} if the interface is a point to point
|
||||
* interface.
|
||||
* @exception SocketException if an I/O error occurs.
|
||||
* @since 1.6
|
||||
*/
|
||||
|
||||
public boolean isPointToPoint() throws SocketException {
|
||||
return isP2P0(name, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether a network interface supports multicasting or not.
|
||||
*
|
||||
* @return {@code true} if the interface supports Multicasting.
|
||||
* @exception SocketException if an I/O error occurs.
|
||||
* @since 1.6
|
||||
*/
|
||||
|
||||
public boolean supportsMulticast() throws SocketException {
|
||||
return supportsMulticast0(name, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hardware address (usually MAC) of the interface if it
|
||||
* has one and if it can be accessed given the current privileges.
|
||||
* If a security manager is set, then the caller must have
|
||||
* the permission {@link NetPermission}("getNetworkInformation").
|
||||
*
|
||||
* @return a byte array containing the address, or {@code null} if
|
||||
* the address doesn't exist, is not accessible or a security
|
||||
* manager is set and the caller does not have the permission
|
||||
* NetPermission("getNetworkInformation")
|
||||
*
|
||||
* @exception SocketException if an I/O error occurs.
|
||||
* @since 1.6
|
||||
*/
|
||||
public byte[] getHardwareAddress() throws SocketException {
|
||||
SecurityManager sec = System.getSecurityManager();
|
||||
if (sec != null) {
|
||||
try {
|
||||
sec.checkPermission(new NetPermission("getNetworkInformation"));
|
||||
} catch (SecurityException e) {
|
||||
if (!getInetAddresses().hasMoreElements()) {
|
||||
// don't have connect permission to any local address
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (InetAddress addr : addrs) {
|
||||
if (addr instanceof Inet4Address) {
|
||||
return getMacAddr0(((Inet4Address)addr).getAddress(), name, index);
|
||||
}
|
||||
}
|
||||
return getMacAddr0(null, name, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Maximum Transmission Unit (MTU) of this interface.
|
||||
*
|
||||
* @return the value of the MTU for that interface.
|
||||
* @exception SocketException if an I/O error occurs.
|
||||
* @since 1.6
|
||||
*/
|
||||
public int getMTU() throws SocketException {
|
||||
return getMTU0(name, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this interface is a virtual interface (also called
|
||||
* subinterface).
|
||||
* Virtual interfaces are, on some systems, interfaces created as a child
|
||||
* of a physical interface and given different settings (like address or
|
||||
* MTU). Usually the name of the interface will the name of the parent
|
||||
* followed by a colon (:) and a number identifying the child since there
|
||||
* can be several virtual interfaces attached to a single physical
|
||||
* interface.
|
||||
*
|
||||
* @return {@code true} if this interface is a virtual interface.
|
||||
* @since 1.6
|
||||
*/
|
||||
public boolean isVirtual() {
|
||||
return virtual;
|
||||
}
|
||||
|
||||
private native static boolean isUp0(String name, int ind) throws SocketException;
|
||||
private native static boolean isLoopback0(String name, int ind) throws SocketException;
|
||||
private native static boolean supportsMulticast0(String name, int ind) throws SocketException;
|
||||
private native static boolean isP2P0(String name, int ind) throws SocketException;
|
||||
private native static byte[] getMacAddr0(byte[] inAddr, String name, int ind) throws SocketException;
|
||||
private native static int getMTU0(String name, int ind) throws SocketException;
|
||||
|
||||
/**
|
||||
* Compares this object against the specified object.
|
||||
* The result is {@code true} if and only if the argument is
|
||||
* not {@code null} and it represents the same NetworkInterface
|
||||
* as this object.
|
||||
* <p>
|
||||
* Two instances of {@code NetworkInterface} represent the same
|
||||
* NetworkInterface if both name and addrs are the same for both.
|
||||
*
|
||||
* @param obj the object to compare against.
|
||||
* @return {@code true} if the objects are the same;
|
||||
* {@code false} otherwise.
|
||||
* @see java.net.InetAddress#getAddress()
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof NetworkInterface)) {
|
||||
return false;
|
||||
}
|
||||
NetworkInterface that = (NetworkInterface)obj;
|
||||
if (this.name != null ) {
|
||||
if (!this.name.equals(that.name)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (that.name != null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.addrs == null) {
|
||||
return that.addrs == null;
|
||||
} else if (that.addrs == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Both addrs not null. Compare number of addresses */
|
||||
|
||||
if (this.addrs.length != that.addrs.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
InetAddress[] thatAddrs = that.addrs;
|
||||
int count = thatAddrs.length;
|
||||
|
||||
for (int i=0; i<count; i++) {
|
||||
boolean found = false;
|
||||
for (int j=0; j<count; j++) {
|
||||
if (addrs[i].equals(thatAddrs[j])) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return name == null? 0: name.hashCode();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
String result = "name:";
|
||||
result += name == null? "null": name;
|
||||
if (displayName != null) {
|
||||
result += " (" + displayName + ")";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static native void init();
|
||||
|
||||
/**
|
||||
* Returns the default network interface of this system
|
||||
*
|
||||
* @return the default interface
|
||||
*/
|
||||
static NetworkInterface getDefault() {
|
||||
return defaultInterface;
|
||||
}
|
||||
}
|
||||
54
jdkSrc/jdk8/java/net/NoRouteToHostException.java
Normal file
54
jdkSrc/jdk8/java/net/NoRouteToHostException.java
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
/**
|
||||
* Signals that an error occurred while attempting to connect a
|
||||
* socket to a remote address and port. Typically, the remote
|
||||
* host cannot be reached because of an intervening firewall, or
|
||||
* if an intermediate router is down.
|
||||
*
|
||||
* @since JDK1.1
|
||||
*/
|
||||
public class NoRouteToHostException extends SocketException {
|
||||
private static final long serialVersionUID = -1897550894873493790L;
|
||||
|
||||
/**
|
||||
* Constructs a new NoRouteToHostException with the specified detail
|
||||
* message as to why the remote host cannot be reached.
|
||||
* A detail message is a String that gives a specific
|
||||
* description of this error.
|
||||
* @param msg the detail message
|
||||
*/
|
||||
public NoRouteToHostException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new NoRouteToHostException with no detailed message.
|
||||
*/
|
||||
public NoRouteToHostException() {}
|
||||
}
|
||||
81
jdkSrc/jdk8/java/net/PasswordAuthentication.java
Normal file
81
jdkSrc/jdk8/java/net/PasswordAuthentication.java
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
|
||||
/**
|
||||
* The class PasswordAuthentication is a data holder that is used by
|
||||
* Authenticator. It is simply a repository for a user name and a password.
|
||||
*
|
||||
* @see java.net.Authenticator
|
||||
* @see java.net.Authenticator#getPasswordAuthentication()
|
||||
*
|
||||
* @author Bill Foote
|
||||
* @since 1.2
|
||||
*/
|
||||
|
||||
public final class PasswordAuthentication {
|
||||
|
||||
private String userName;
|
||||
private char[] password;
|
||||
|
||||
/**
|
||||
* Creates a new {@code PasswordAuthentication} object from the given
|
||||
* user name and password.
|
||||
*
|
||||
* <p> Note that the given user password is cloned before it is stored in
|
||||
* the new {@code PasswordAuthentication} object.
|
||||
*
|
||||
* @param userName the user name
|
||||
* @param password the user's password
|
||||
*/
|
||||
public PasswordAuthentication(String userName, char[] password) {
|
||||
this.userName = userName;
|
||||
this.password = password.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the user name.
|
||||
*
|
||||
* @return the user name
|
||||
*/
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the user password.
|
||||
*
|
||||
* <p> Note that this method returns a reference to the password. It is
|
||||
* the caller's responsibility to zero out the password information after
|
||||
* it is no longer needed.
|
||||
*
|
||||
* @return the password
|
||||
*/
|
||||
public char[] getPassword() {
|
||||
return password;
|
||||
}
|
||||
}
|
||||
345
jdkSrc/jdk8/java/net/PlainSocketImpl.java
Normal file
345
jdkSrc/jdk8/java/net/PlainSocketImpl.java
Normal file
@@ -0,0 +1,345 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package java.net;
|
||||
|
||||
import java.io.*;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
/*
|
||||
* This class PlainSocketImpl simply delegates to the appropriate real
|
||||
* SocketImpl. We do this because PlainSocketImpl is already extended
|
||||
* by SocksSocketImpl.
|
||||
* <p>
|
||||
* There are two possibilities for the real SocketImpl,
|
||||
* TwoStacksPlainSocketImpl or DualStackPlainSocketImpl. We use
|
||||
* DualStackPlainSocketImpl on systems that have a dual stack
|
||||
* TCP implementation. Otherwise we create an instance of
|
||||
* TwoStacksPlainSocketImpl and delegate to it.
|
||||
*
|
||||
* @author Chris Hegarty
|
||||
*/
|
||||
|
||||
class PlainSocketImpl extends AbstractPlainSocketImpl
|
||||
{
|
||||
private AbstractPlainSocketImpl impl;
|
||||
|
||||
/* the windows version. */
|
||||
private static float version;
|
||||
|
||||
/* java.net.preferIPv4Stack */
|
||||
private static boolean preferIPv4Stack = false;
|
||||
|
||||
/* If the version supports a dual stack TCP implementation */
|
||||
private static boolean useDualStackImpl = false;
|
||||
|
||||
/* sun.net.useExclusiveBind */
|
||||
private static String exclBindProp;
|
||||
|
||||
/* True if exclusive binding is on for Windows */
|
||||
private static boolean exclusiveBind = true;
|
||||
|
||||
static {
|
||||
java.security.AccessController.doPrivileged( new PrivilegedAction<Object>() {
|
||||
public Object run() {
|
||||
version = 0;
|
||||
try {
|
||||
version = Float.parseFloat(System.getProperties().getProperty("os.version"));
|
||||
preferIPv4Stack = Boolean.parseBoolean(
|
||||
System.getProperties().getProperty("java.net.preferIPv4Stack"));
|
||||
exclBindProp = System.getProperty("sun.net.useExclusiveBind");
|
||||
} catch (NumberFormatException e ) {
|
||||
assert false : e;
|
||||
}
|
||||
return null; // nothing to return
|
||||
} });
|
||||
|
||||
// (version >= 6.0) implies Vista or greater.
|
||||
if (version >= 6.0 && !preferIPv4Stack) {
|
||||
useDualStackImpl = true;
|
||||
}
|
||||
|
||||
if (exclBindProp != null) {
|
||||
// sun.net.useExclusiveBind is true
|
||||
exclusiveBind = exclBindProp.length() == 0 ? true
|
||||
: Boolean.parseBoolean(exclBindProp);
|
||||
} else if (version < 6.0) {
|
||||
exclusiveBind = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an empty instance.
|
||||
*/
|
||||
PlainSocketImpl() {
|
||||
if (useDualStackImpl) {
|
||||
impl = new DualStackPlainSocketImpl(exclusiveBind);
|
||||
} else {
|
||||
impl = new TwoStacksPlainSocketImpl(exclusiveBind);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an instance with the given file descriptor.
|
||||
*/
|
||||
PlainSocketImpl(FileDescriptor fd) {
|
||||
if (useDualStackImpl) {
|
||||
impl = new DualStackPlainSocketImpl(fd, exclusiveBind);
|
||||
} else {
|
||||
impl = new TwoStacksPlainSocketImpl(fd, exclusiveBind);
|
||||
}
|
||||
}
|
||||
|
||||
// Override methods in SocketImpl that access impl's fields.
|
||||
|
||||
protected FileDescriptor getFileDescriptor() {
|
||||
return impl.getFileDescriptor();
|
||||
}
|
||||
|
||||
protected InetAddress getInetAddress() {
|
||||
return impl.getInetAddress();
|
||||
}
|
||||
|
||||
protected int getPort() {
|
||||
return impl.getPort();
|
||||
}
|
||||
|
||||
protected int getLocalPort() {
|
||||
return impl.getLocalPort();
|
||||
}
|
||||
|
||||
void setSocket(Socket soc) {
|
||||
impl.setSocket(soc);
|
||||
}
|
||||
|
||||
Socket getSocket() {
|
||||
return impl.getSocket();
|
||||
}
|
||||
|
||||
void setServerSocket(ServerSocket soc) {
|
||||
impl.setServerSocket(soc);
|
||||
}
|
||||
|
||||
ServerSocket getServerSocket() {
|
||||
return impl.getServerSocket();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return impl.toString();
|
||||
}
|
||||
|
||||
// Override methods in AbstractPlainSocketImpl that access impl's fields.
|
||||
|
||||
protected synchronized void create(boolean stream) throws IOException {
|
||||
impl.create(stream);
|
||||
|
||||
// set fd to delegate's fd to be compatible with older releases
|
||||
this.fd = impl.fd;
|
||||
}
|
||||
|
||||
protected void connect(String host, int port)
|
||||
throws UnknownHostException, IOException
|
||||
{
|
||||
impl.connect(host, port);
|
||||
}
|
||||
|
||||
protected void connect(InetAddress address, int port) throws IOException {
|
||||
impl.connect(address, port);
|
||||
}
|
||||
|
||||
protected void connect(SocketAddress address, int timeout) throws IOException {
|
||||
impl.connect(address, timeout);
|
||||
}
|
||||
|
||||
public void setOption(int opt, Object val) throws SocketException {
|
||||
impl.setOption(opt, val);
|
||||
}
|
||||
|
||||
public Object getOption(int opt) throws SocketException {
|
||||
return impl.getOption(opt);
|
||||
}
|
||||
|
||||
synchronized void doConnect(InetAddress address, int port, int timeout) throws IOException {
|
||||
impl.doConnect(address, port, timeout);
|
||||
}
|
||||
|
||||
protected synchronized void bind(InetAddress address, int lport)
|
||||
throws IOException
|
||||
{
|
||||
impl.bind(address, lport);
|
||||
}
|
||||
|
||||
protected synchronized void accept(SocketImpl s) throws IOException {
|
||||
if (s instanceof PlainSocketImpl) {
|
||||
// pass in the real impl not the wrapper.
|
||||
SocketImpl delegate = ((PlainSocketImpl)s).impl;
|
||||
delegate.address = new InetAddress();
|
||||
delegate.fd = new FileDescriptor();
|
||||
impl.accept(delegate);
|
||||
// set fd to delegate's fd to be compatible with older releases
|
||||
s.fd = delegate.fd;
|
||||
} else {
|
||||
impl.accept(s);
|
||||
}
|
||||
}
|
||||
|
||||
void setFileDescriptor(FileDescriptor fd) {
|
||||
impl.setFileDescriptor(fd);
|
||||
}
|
||||
|
||||
void setAddress(InetAddress address) {
|
||||
impl.setAddress(address);
|
||||
}
|
||||
|
||||
void setPort(int port) {
|
||||
impl.setPort(port);
|
||||
}
|
||||
|
||||
void setLocalPort(int localPort) {
|
||||
impl.setLocalPort(localPort);
|
||||
}
|
||||
|
||||
protected synchronized InputStream getInputStream() throws IOException {
|
||||
return impl.getInputStream();
|
||||
}
|
||||
|
||||
void setInputStream(SocketInputStream in) {
|
||||
impl.setInputStream(in);
|
||||
}
|
||||
|
||||
protected synchronized OutputStream getOutputStream() throws IOException {
|
||||
return impl.getOutputStream();
|
||||
}
|
||||
|
||||
protected void close() throws IOException {
|
||||
try {
|
||||
impl.close();
|
||||
} finally {
|
||||
// set fd to delegate's fd to be compatible with older releases
|
||||
this.fd = null;
|
||||
}
|
||||
}
|
||||
|
||||
void reset() throws IOException {
|
||||
try {
|
||||
impl.reset();
|
||||
} finally {
|
||||
// set fd to delegate's fd to be compatible with older releases
|
||||
this.fd = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected void shutdownInput() throws IOException {
|
||||
impl.shutdownInput();
|
||||
}
|
||||
|
||||
protected void shutdownOutput() throws IOException {
|
||||
impl.shutdownOutput();
|
||||
}
|
||||
|
||||
protected void sendUrgentData(int data) throws IOException {
|
||||
impl.sendUrgentData(data);
|
||||
}
|
||||
|
||||
FileDescriptor acquireFD() {
|
||||
return impl.acquireFD();
|
||||
}
|
||||
|
||||
void releaseFD() {
|
||||
impl.releaseFD();
|
||||
}
|
||||
|
||||
public boolean isConnectionReset() {
|
||||
return impl.isConnectionReset();
|
||||
}
|
||||
|
||||
public boolean isConnectionResetPending() {
|
||||
return impl.isConnectionResetPending();
|
||||
}
|
||||
|
||||
public void setConnectionReset() {
|
||||
impl.setConnectionReset();
|
||||
}
|
||||
|
||||
public void setConnectionResetPending() {
|
||||
impl.setConnectionResetPending();
|
||||
}
|
||||
|
||||
public boolean isClosedOrPending() {
|
||||
return impl.isClosedOrPending();
|
||||
}
|
||||
|
||||
public int getTimeout() {
|
||||
return impl.getTimeout();
|
||||
}
|
||||
|
||||
// Override methods in AbstractPlainSocketImpl that need to be implemented.
|
||||
|
||||
void socketCreate(boolean isServer) throws IOException {
|
||||
impl.socketCreate(isServer);
|
||||
}
|
||||
|
||||
void socketConnect(InetAddress address, int port, int timeout)
|
||||
throws IOException {
|
||||
impl.socketConnect(address, port, timeout);
|
||||
}
|
||||
|
||||
void socketBind(InetAddress address, int port)
|
||||
throws IOException {
|
||||
impl.socketBind(address, port);
|
||||
}
|
||||
|
||||
void socketListen(int count) throws IOException {
|
||||
impl.socketListen(count);
|
||||
}
|
||||
|
||||
void socketAccept(SocketImpl s) throws IOException {
|
||||
impl.socketAccept(s);
|
||||
}
|
||||
|
||||
int socketAvailable() throws IOException {
|
||||
return impl.socketAvailable();
|
||||
}
|
||||
|
||||
void socketClose0(boolean useDeferredClose) throws IOException {
|
||||
impl.socketClose0(useDeferredClose);
|
||||
}
|
||||
|
||||
void socketShutdown(int howto) throws IOException {
|
||||
impl.socketShutdown(howto);
|
||||
}
|
||||
|
||||
void socketSetOption(int cmd, boolean on, Object value)
|
||||
throws SocketException {
|
||||
impl.socketSetOption(cmd, on, value);
|
||||
}
|
||||
|
||||
int socketGetOption(int opt, Object iaContainerObj) throws SocketException {
|
||||
return impl.socketGetOption(opt, iaContainerObj);
|
||||
}
|
||||
|
||||
void socketSendUrgentData(int data) throws IOException {
|
||||
impl.socketSendUrgentData(data);
|
||||
}
|
||||
}
|
||||
52
jdkSrc/jdk8/java/net/PortUnreachableException.java
Normal file
52
jdkSrc/jdk8/java/net/PortUnreachableException.java
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
/**
|
||||
* Signals that an ICMP Port Unreachable message has been
|
||||
* received on a connected datagram.
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
|
||||
public class PortUnreachableException extends SocketException {
|
||||
private static final long serialVersionUID = 8462541992376507323L;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code PortUnreachableException} with a
|
||||
* detail message.
|
||||
* @param msg the detail message
|
||||
*/
|
||||
public PortUnreachableException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new {@code PortUnreachableException} with no
|
||||
* detailed message.
|
||||
*/
|
||||
public PortUnreachableException() {}
|
||||
}
|
||||
56
jdkSrc/jdk8/java/net/ProtocolException.java
Normal file
56
jdkSrc/jdk8/java/net/ProtocolException.java
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Thrown to indicate that there is an error in the underlying
|
||||
* protocol, such as a TCP error.
|
||||
*
|
||||
* @author Chris Warth
|
||||
* @since JDK1.0
|
||||
*/
|
||||
public
|
||||
class ProtocolException extends IOException {
|
||||
private static final long serialVersionUID = -6098449442062388080L;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ProtocolException} with the
|
||||
* specified detail message.
|
||||
*
|
||||
* @param host the detail message.
|
||||
*/
|
||||
public ProtocolException(String host) {
|
||||
super(host);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ProtocolException} with no detail message.
|
||||
*/
|
||||
public ProtocolException() {
|
||||
}
|
||||
}
|
||||
41
jdkSrc/jdk8/java/net/ProtocolFamily.java
Normal file
41
jdkSrc/jdk8/java/net/ProtocolFamily.java
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
/**
|
||||
* Represents a family of communication protocols.
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
|
||||
public interface ProtocolFamily {
|
||||
/**
|
||||
* Returns the name of the protocol family.
|
||||
*
|
||||
* @return the name of the protocol family
|
||||
*/
|
||||
String name();
|
||||
}
|
||||
171
jdkSrc/jdk8/java/net/Proxy.java
Normal file
171
jdkSrc/jdk8/java/net/Proxy.java
Normal file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
/**
|
||||
* This class represents a proxy setting, typically a type (http, socks) and
|
||||
* a socket address.
|
||||
* A {@code Proxy} is an immutable object.
|
||||
*
|
||||
* @see java.net.ProxySelector
|
||||
* @author Yingxian Wang
|
||||
* @author Jean-Christophe Collet
|
||||
* @since 1.5
|
||||
*/
|
||||
public class Proxy {
|
||||
|
||||
/**
|
||||
* Represents the proxy type.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public enum Type {
|
||||
/**
|
||||
* Represents a direct connection, or the absence of a proxy.
|
||||
*/
|
||||
DIRECT,
|
||||
/**
|
||||
* Represents proxy for high level protocols such as HTTP or FTP.
|
||||
*/
|
||||
HTTP,
|
||||
/**
|
||||
* Represents a SOCKS (V4 or V5) proxy.
|
||||
*/
|
||||
SOCKS
|
||||
};
|
||||
|
||||
private Type type;
|
||||
private SocketAddress sa;
|
||||
|
||||
/**
|
||||
* A proxy setting that represents a {@code DIRECT} connection,
|
||||
* basically telling the protocol handler not to use any proxying.
|
||||
* Used, for instance, to create sockets bypassing any other global
|
||||
* proxy settings (like SOCKS):
|
||||
* <P>
|
||||
* {@code Socket s = new Socket(Proxy.NO_PROXY);}
|
||||
*
|
||||
*/
|
||||
public final static Proxy NO_PROXY = new Proxy();
|
||||
|
||||
// Creates the proxy that represents a {@code DIRECT} connection.
|
||||
private Proxy() {
|
||||
type = Type.DIRECT;
|
||||
sa = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an entry representing a PROXY connection.
|
||||
* Certain combinations are illegal. For instance, for types Http, and
|
||||
* Socks, a SocketAddress <b>must</b> be provided.
|
||||
* <P>
|
||||
* Use the {@code Proxy.NO_PROXY} constant
|
||||
* for representing a direct connection.
|
||||
*
|
||||
* @param type the {@code Type} of the proxy
|
||||
* @param sa the {@code SocketAddress} for that proxy
|
||||
* @throws IllegalArgumentException when the type and the address are
|
||||
* incompatible
|
||||
*/
|
||||
public Proxy(Type type, SocketAddress sa) {
|
||||
if ((type == Type.DIRECT) || !(sa instanceof InetSocketAddress))
|
||||
throw new IllegalArgumentException("type " + type + " is not compatible with address " + sa);
|
||||
this.type = type;
|
||||
this.sa = sa;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the proxy type.
|
||||
*
|
||||
* @return a Type representing the proxy type
|
||||
*/
|
||||
public Type type() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the socket address of the proxy, or
|
||||
* {@code null} if its a direct connection.
|
||||
*
|
||||
* @return a {@code SocketAddress} representing the socket end
|
||||
* point of the proxy
|
||||
*/
|
||||
public SocketAddress address() {
|
||||
return sa;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a string representation of this Proxy.
|
||||
* This String is constructed by calling toString() on its type
|
||||
* and concatenating " @ " and the toString() result from its address
|
||||
* if its type is not {@code DIRECT}.
|
||||
*
|
||||
* @return a string representation of this object.
|
||||
*/
|
||||
public String toString() {
|
||||
if (type() == Type.DIRECT)
|
||||
return "DIRECT";
|
||||
return type() + " @ " + address();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this object against the specified object.
|
||||
* The result is {@code true} if and only if the argument is
|
||||
* not {@code null} and it represents the same proxy as
|
||||
* this object.
|
||||
* <p>
|
||||
* Two instances of {@code Proxy} represent the same
|
||||
* address if both the SocketAddresses and type are equal.
|
||||
*
|
||||
* @param obj the object to compare against.
|
||||
* @return {@code true} if the objects are the same;
|
||||
* {@code false} otherwise.
|
||||
* @see java.net.InetSocketAddress#equals(java.lang.Object)
|
||||
*/
|
||||
public final boolean equals(Object obj) {
|
||||
if (obj == null || !(obj instanceof Proxy))
|
||||
return false;
|
||||
Proxy p = (Proxy) obj;
|
||||
if (p.type() == type()) {
|
||||
if (address() == null) {
|
||||
return (p.address() == null);
|
||||
} else
|
||||
return address().equals(p.address());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hashcode for this Proxy.
|
||||
*
|
||||
* @return a hash code value for this Proxy.
|
||||
*/
|
||||
public final int hashCode() {
|
||||
if (address() == null)
|
||||
return type().hashCode();
|
||||
return type().hashCode() + address().hashCode();
|
||||
}
|
||||
}
|
||||
165
jdkSrc/jdk8/java/net/ProxySelector.java
Normal file
165
jdkSrc/jdk8/java/net/ProxySelector.java
Normal file
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import sun.security.util.SecurityConstants;
|
||||
|
||||
/**
|
||||
* Selects the proxy server to use, if any, when connecting to the
|
||||
* network resource referenced by a URL. A proxy selector is a
|
||||
* concrete sub-class of this class and is registered by invoking the
|
||||
* {@link java.net.ProxySelector#setDefault setDefault} method. The
|
||||
* currently registered proxy selector can be retrieved by calling
|
||||
* {@link java.net.ProxySelector#getDefault getDefault} method.
|
||||
*
|
||||
* <p> When a proxy selector is registered, for instance, a subclass
|
||||
* of URLConnection class should call the {@link #select select}
|
||||
* method for each URL request so that the proxy selector can decide
|
||||
* if a direct, or proxied connection should be used. The {@link
|
||||
* #select select} method returns an iterator over a collection with
|
||||
* the preferred connection approach.
|
||||
*
|
||||
* <p> If a connection cannot be established to a proxy (PROXY or
|
||||
* SOCKS) servers then the caller should call the proxy selector's
|
||||
* {@link #connectFailed connectFailed} method to notify the proxy
|
||||
* selector that the proxy server is unavailable. </p>
|
||||
*
|
||||
* <P>The default proxy selector does enforce a
|
||||
* <a href="doc-files/net-properties.html#Proxies">set of System Properties</a>
|
||||
* related to proxy settings.</P>
|
||||
*
|
||||
* @author Yingxian Wang
|
||||
* @author Jean-Christophe Collet
|
||||
* @since 1.5
|
||||
*/
|
||||
public abstract class ProxySelector {
|
||||
/**
|
||||
* The system wide proxy selector that selects the proxy server to
|
||||
* use, if any, when connecting to a remote object referenced by
|
||||
* an URL.
|
||||
*
|
||||
* @see #setDefault(ProxySelector)
|
||||
*/
|
||||
private static ProxySelector theProxySelector;
|
||||
|
||||
static {
|
||||
try {
|
||||
Class<?> c = Class.forName("sun.net.spi.DefaultProxySelector");
|
||||
if (c != null && ProxySelector.class.isAssignableFrom(c)) {
|
||||
theProxySelector = (ProxySelector) c.newInstance();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
theProxySelector = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the system-wide proxy selector.
|
||||
*
|
||||
* @throws SecurityException
|
||||
* If a security manager has been installed and it denies
|
||||
* {@link NetPermission}{@code ("getProxySelector")}
|
||||
* @see #setDefault(ProxySelector)
|
||||
* @return the system-wide {@code ProxySelector}
|
||||
* @since 1.5
|
||||
*/
|
||||
public static ProxySelector getDefault() {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
sm.checkPermission(SecurityConstants.GET_PROXYSELECTOR_PERMISSION);
|
||||
}
|
||||
return theProxySelector;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets (or unsets) the system-wide proxy selector.
|
||||
*
|
||||
* Note: non-standard protocol handlers may ignore this setting.
|
||||
*
|
||||
* @param ps The HTTP proxy selector, or
|
||||
* {@code null} to unset the proxy selector.
|
||||
*
|
||||
* @throws SecurityException
|
||||
* If a security manager has been installed and it denies
|
||||
* {@link NetPermission}{@code ("setProxySelector")}
|
||||
*
|
||||
* @see #getDefault()
|
||||
* @since 1.5
|
||||
*/
|
||||
public static void setDefault(ProxySelector ps) {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
sm.checkPermission(SecurityConstants.SET_PROXYSELECTOR_PERMISSION);
|
||||
}
|
||||
theProxySelector = ps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Selects all the applicable proxies based on the protocol to
|
||||
* access the resource with and a destination address to access
|
||||
* the resource at.
|
||||
* The format of the URI is defined as follow:
|
||||
* <UL>
|
||||
* <LI>http URI for http connections</LI>
|
||||
* <LI>https URI for https connections
|
||||
* <LI>{@code socket://host:port}<br>
|
||||
* for tcp client sockets connections</LI>
|
||||
* </UL>
|
||||
*
|
||||
* @param uri
|
||||
* The URI that a connection is required to
|
||||
*
|
||||
* @return a List of Proxies. Each element in the
|
||||
* the List is of type
|
||||
* {@link java.net.Proxy Proxy};
|
||||
* when no proxy is available, the list will
|
||||
* contain one element of type
|
||||
* {@link java.net.Proxy Proxy}
|
||||
* that represents a direct connection.
|
||||
* @throws IllegalArgumentException if the argument is null
|
||||
*/
|
||||
public abstract List<Proxy> select(URI uri);
|
||||
|
||||
/**
|
||||
* Called to indicate that a connection could not be established
|
||||
* to a proxy/socks server. An implementation of this method can
|
||||
* temporarily remove the proxies or reorder the sequence of
|
||||
* proxies returned by {@link #select(URI)}, using the address
|
||||
* and the IOException caught when trying to connect.
|
||||
*
|
||||
* @param uri
|
||||
* The URI that the proxy at sa failed to serve.
|
||||
* @param sa
|
||||
* The socket address of the proxy/SOCKS server
|
||||
*
|
||||
* @param ioe
|
||||
* The I/O exception thrown when the connect failed.
|
||||
* @throws IllegalArgumentException if either argument is null
|
||||
*/
|
||||
public abstract void connectFailed(URI uri, SocketAddress sa, IOException ioe);
|
||||
}
|
||||
163
jdkSrc/jdk8/java/net/ResponseCache.java
Normal file
163
jdkSrc/jdk8/java/net/ResponseCache.java
Normal file
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.List;
|
||||
import sun.security.util.SecurityConstants;
|
||||
|
||||
/**
|
||||
* Represents implementations of URLConnection caches. An instance of
|
||||
* such a class can be registered with the system by doing
|
||||
* ResponseCache.setDefault(ResponseCache), and the system will call
|
||||
* this object in order to:
|
||||
*
|
||||
* <ul><li>store resource data which has been retrieved from an
|
||||
* external source into the cache</li>
|
||||
* <li>try to fetch a requested resource that may have been
|
||||
* stored in the cache</li>
|
||||
* </ul>
|
||||
*
|
||||
* The ResponseCache implementation decides which resources
|
||||
* should be cached, and for how long they should be cached. If a
|
||||
* request resource cannot be retrieved from the cache, then the
|
||||
* protocol handlers will fetch the resource from its original
|
||||
* location.
|
||||
*
|
||||
* The settings for URLConnection#useCaches controls whether the
|
||||
* protocol is allowed to use a cached response.
|
||||
*
|
||||
* For more information on HTTP caching, see <a
|
||||
* href="http://www.ietf.org/rfc/rfc2616.txt"><i>RFC 2616: Hypertext
|
||||
* Transfer Protocol -- HTTP/1.1</i></a>
|
||||
*
|
||||
* @author Yingxian Wang
|
||||
* @since 1.5
|
||||
*/
|
||||
public abstract class ResponseCache {
|
||||
|
||||
/**
|
||||
* The system wide cache that provides access to a url
|
||||
* caching mechanism.
|
||||
*
|
||||
* @see #setDefault(ResponseCache)
|
||||
* @see #getDefault()
|
||||
*/
|
||||
private static ResponseCache theResponseCache;
|
||||
|
||||
/**
|
||||
* Gets the system-wide response cache.
|
||||
*
|
||||
* @throws SecurityException
|
||||
* If a security manager has been installed and it denies
|
||||
* {@link NetPermission}{@code ("getResponseCache")}
|
||||
*
|
||||
* @see #setDefault(ResponseCache)
|
||||
* @return the system-wide {@code ResponseCache}
|
||||
* @since 1.5
|
||||
*/
|
||||
public synchronized static ResponseCache getDefault() {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
sm.checkPermission(SecurityConstants.GET_RESPONSECACHE_PERMISSION);
|
||||
}
|
||||
return theResponseCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets (or unsets) the system-wide cache.
|
||||
*
|
||||
* Note: non-standard procotol handlers may ignore this setting.
|
||||
*
|
||||
* @param responseCache The response cache, or
|
||||
* {@code null} to unset the cache.
|
||||
*
|
||||
* @throws SecurityException
|
||||
* If a security manager has been installed and it denies
|
||||
* {@link NetPermission}{@code ("setResponseCache")}
|
||||
*
|
||||
* @see #getDefault()
|
||||
* @since 1.5
|
||||
*/
|
||||
public synchronized static void setDefault(ResponseCache responseCache) {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
sm.checkPermission(SecurityConstants.SET_RESPONSECACHE_PERMISSION);
|
||||
}
|
||||
theResponseCache = responseCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the cached response based on the requesting uri,
|
||||
* request method and request headers. Typically this method is
|
||||
* called by the protocol handler before it sends out the request
|
||||
* to get the network resource. If a cached response is returned,
|
||||
* that resource is used instead.
|
||||
*
|
||||
* @param uri a {@code URI} used to reference the requested
|
||||
* network resource
|
||||
* @param rqstMethod a {@code String} representing the request
|
||||
* method
|
||||
* @param rqstHeaders - a Map from request header
|
||||
* field names to lists of field values representing
|
||||
* the current request headers
|
||||
* @return a {@code CacheResponse} instance if available
|
||||
* from cache, or null otherwise
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws IllegalArgumentException if any one of the arguments is null
|
||||
*
|
||||
* @see java.net.URLConnection#setUseCaches(boolean)
|
||||
* @see java.net.URLConnection#getUseCaches()
|
||||
* @see java.net.URLConnection#setDefaultUseCaches(boolean)
|
||||
* @see java.net.URLConnection#getDefaultUseCaches()
|
||||
*/
|
||||
public abstract CacheResponse
|
||||
get(URI uri, String rqstMethod, Map<String, List<String>> rqstHeaders)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* The protocol handler calls this method after a resource has
|
||||
* been retrieved, and the ResponseCache must decide whether or
|
||||
* not to store the resource in its cache. If the resource is to
|
||||
* be cached, then put() must return a CacheRequest object which
|
||||
* contains an OutputStream that the protocol handler will
|
||||
* use to write the resource into the cache. If the resource is
|
||||
* not to be cached, then put must return null.
|
||||
*
|
||||
* @param uri a {@code URI} used to reference the requested
|
||||
* network resource
|
||||
* @param conn - a URLConnection instance that is used to fetch
|
||||
* the response to be cached
|
||||
* @return a {@code CacheRequest} for recording the
|
||||
* response to be cached. Null return indicates that
|
||||
* the caller does not intend to cache the response.
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws IllegalArgumentException if any one of the arguments is
|
||||
* null
|
||||
*/
|
||||
public abstract CacheRequest put(URI uri, URLConnection conn) throws IOException;
|
||||
}
|
||||
49
jdkSrc/jdk8/java/net/SdpSocketImpl.java
Normal file
49
jdkSrc/jdk8/java/net/SdpSocketImpl.java
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.FileDescriptor;
|
||||
|
||||
import sun.net.sdp.SdpSupport;
|
||||
|
||||
/**
|
||||
* SocketImpl that supports the SDP protocol
|
||||
*/
|
||||
class SdpSocketImpl extends PlainSocketImpl {
|
||||
SdpSocketImpl() { }
|
||||
|
||||
@Override
|
||||
protected void create(boolean stream) throws IOException {
|
||||
if (!stream)
|
||||
throw new UnsupportedOperationException("Must be a stream socket");
|
||||
fd = SdpSupport.createSocket();
|
||||
if (socket != null)
|
||||
socket.setCreated();
|
||||
if (serverSocket != null)
|
||||
serverSocket.setCreated();
|
||||
}
|
||||
}
|
||||
108
jdkSrc/jdk8/java/net/SecureCacheResponse.java
Normal file
108
jdkSrc/jdk8/java/net/SecureCacheResponse.java
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
import java.security.cert.Certificate;
|
||||
import javax.net.ssl.SSLPeerUnverifiedException;
|
||||
import java.security.Principal;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents a cache response originally retrieved through secure
|
||||
* means, such as TLS.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public abstract class SecureCacheResponse extends CacheResponse {
|
||||
/**
|
||||
* Returns the cipher suite in use on the original connection that
|
||||
* retrieved the network resource.
|
||||
*
|
||||
* @return a string representing the cipher suite
|
||||
*/
|
||||
public abstract String getCipherSuite();
|
||||
|
||||
/**
|
||||
* Returns the certificate chain that were sent to the server during
|
||||
* handshaking of the original connection that retrieved the
|
||||
* network resource. Note: This method is useful only
|
||||
* when using certificate-based cipher suites.
|
||||
*
|
||||
* @return an immutable List of Certificate representing the
|
||||
* certificate chain that was sent to the server. If no
|
||||
* certificate chain was sent, null will be returned.
|
||||
* @see #getLocalPrincipal()
|
||||
*/
|
||||
public abstract List<Certificate> getLocalCertificateChain();
|
||||
|
||||
/**
|
||||
* Returns the server's certificate chain, which was established as
|
||||
* part of defining the session in the original connection that
|
||||
* retrieved the network resource, from cache. Note: This method
|
||||
* can be used only when using certificate-based cipher suites;
|
||||
* using it with non-certificate-based cipher suites, such as
|
||||
* Kerberos, will throw an SSLPeerUnverifiedException.
|
||||
*
|
||||
* @return an immutable List of Certificate representing the server's
|
||||
* certificate chain.
|
||||
* @throws SSLPeerUnverifiedException if the peer is not verified.
|
||||
* @see #getPeerPrincipal()
|
||||
*/
|
||||
public abstract List<Certificate> getServerCertificateChain()
|
||||
throws SSLPeerUnverifiedException;
|
||||
|
||||
/**
|
||||
* Returns the server's principal which was established as part of
|
||||
* defining the session during the original connection that
|
||||
* retrieved the network resource.
|
||||
*
|
||||
* @return the server's principal. Returns an X500Principal of the
|
||||
* end-entity certiticate for X509-based cipher suites, and
|
||||
* KerberosPrincipal for Kerberos cipher suites.
|
||||
*
|
||||
* @throws SSLPeerUnverifiedException if the peer was not verified.
|
||||
*
|
||||
* @see #getServerCertificateChain()
|
||||
* @see #getLocalPrincipal()
|
||||
*/
|
||||
public abstract Principal getPeerPrincipal()
|
||||
throws SSLPeerUnverifiedException;
|
||||
|
||||
/**
|
||||
* Returns the principal that was sent to the server during
|
||||
* handshaking in the original connection that retrieved the
|
||||
* network resource.
|
||||
*
|
||||
* @return the principal sent to the server. Returns an X500Principal
|
||||
* of the end-entity certificate for X509-based cipher suites, and
|
||||
* KerberosPrincipal for Kerberos cipher suites. If no principal was
|
||||
* sent, then null is returned.
|
||||
*
|
||||
* @see #getLocalCertificateChain()
|
||||
* @see #getPeerPrincipal()
|
||||
*/
|
||||
public abstract Principal getLocalPrincipal();
|
||||
}
|
||||
938
jdkSrc/jdk8/java/net/ServerSocket.java
Normal file
938
jdkSrc/jdk8/java/net/ServerSocket.java
Normal file
@@ -0,0 +1,938 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.IOException;
|
||||
import java.nio.channels.ServerSocketChannel;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
|
||||
import sun.security.util.SecurityConstants;
|
||||
|
||||
/**
|
||||
* This class implements server sockets. A server socket waits for
|
||||
* requests to come in over the network. It performs some operation
|
||||
* based on that request, and then possibly returns a result to the requester.
|
||||
* <p>
|
||||
* The actual work of the server socket is performed by an instance
|
||||
* of the {@code SocketImpl} class. An application can
|
||||
* change the socket factory that creates the socket
|
||||
* implementation to configure itself to create sockets
|
||||
* appropriate to the local firewall.
|
||||
*
|
||||
* @author unascribed
|
||||
* @see java.net.SocketImpl
|
||||
* @see java.net.ServerSocket#setSocketFactory(java.net.SocketImplFactory)
|
||||
* @see java.nio.channels.ServerSocketChannel
|
||||
* @since JDK1.0
|
||||
*/
|
||||
public
|
||||
class ServerSocket implements java.io.Closeable {
|
||||
/**
|
||||
* Various states of this socket.
|
||||
*/
|
||||
private boolean created = false;
|
||||
private boolean bound = false;
|
||||
private boolean closed = false;
|
||||
private Object closeLock = new Object();
|
||||
|
||||
/**
|
||||
* The implementation of this Socket.
|
||||
*/
|
||||
private SocketImpl impl;
|
||||
|
||||
/**
|
||||
* Are we using an older SocketImpl?
|
||||
*/
|
||||
private boolean oldImpl = false;
|
||||
|
||||
/**
|
||||
* Package-private constructor to create a ServerSocket associated with
|
||||
* the given SocketImpl.
|
||||
*
|
||||
* @throws SecurityException if a security manager is set and
|
||||
* its {@code checkPermission} method doesn't allow
|
||||
* {@code NetPermission("setSocketImpl")}.
|
||||
*/
|
||||
ServerSocket(SocketImpl impl) {
|
||||
checkPermission();
|
||||
this.impl = impl;
|
||||
impl.setServerSocket(this);
|
||||
}
|
||||
|
||||
private static Void checkPermission() {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
sm.checkPermission(SecurityConstants.SET_SOCKETIMPL_PERMISSION);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an unbound server socket.
|
||||
*
|
||||
* @exception IOException IO error when opening the socket.
|
||||
* @revised 1.4
|
||||
*/
|
||||
public ServerSocket() throws IOException {
|
||||
setImpl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a server socket, bound to the specified port. A port number
|
||||
* of {@code 0} means that the port number is automatically
|
||||
* allocated, typically from an ephemeral port range. This port
|
||||
* number can then be retrieved by calling {@link #getLocalPort getLocalPort}.
|
||||
* <p>
|
||||
* The maximum queue length for incoming connection indications (a
|
||||
* request to connect) is set to {@code 50}. If a connection
|
||||
* indication arrives when the queue is full, the connection is refused.
|
||||
* <p>
|
||||
* If the application has specified a server socket factory, that
|
||||
* factory's {@code createSocketImpl} method is called to create
|
||||
* the actual socket implementation. Otherwise a "plain" socket is created.
|
||||
* <p>
|
||||
* If there is a security manager,
|
||||
* its {@code checkListen} method is called
|
||||
* with the {@code port} argument
|
||||
* as its argument to ensure the operation is allowed.
|
||||
* This could result in a SecurityException.
|
||||
*
|
||||
*
|
||||
* @param port the port number, or {@code 0} to use a port
|
||||
* number that is automatically allocated.
|
||||
*
|
||||
* @exception IOException if an I/O error occurs when opening the socket.
|
||||
* @exception SecurityException
|
||||
* if a security manager exists and its {@code checkListen}
|
||||
* method doesn't allow the operation.
|
||||
* @exception IllegalArgumentException if the port parameter is outside
|
||||
* the specified range of valid port values, which is between
|
||||
* 0 and 65535, inclusive.
|
||||
*
|
||||
* @see java.net.SocketImpl
|
||||
* @see java.net.SocketImplFactory#createSocketImpl()
|
||||
* @see java.net.ServerSocket#setSocketFactory(java.net.SocketImplFactory)
|
||||
* @see SecurityManager#checkListen
|
||||
*/
|
||||
public ServerSocket(int port) throws IOException {
|
||||
this(port, 50, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a server socket and binds it to the specified local port
|
||||
* number, with the specified backlog.
|
||||
* A port number of {@code 0} means that the port number is
|
||||
* automatically allocated, typically from an ephemeral port range.
|
||||
* This port number can then be retrieved by calling
|
||||
* {@link #getLocalPort getLocalPort}.
|
||||
* <p>
|
||||
* The maximum queue length for incoming connection indications (a
|
||||
* request to connect) is set to the {@code backlog} parameter. If
|
||||
* a connection indication arrives when the queue is full, the
|
||||
* connection is refused.
|
||||
* <p>
|
||||
* If the application has specified a server socket factory, that
|
||||
* factory's {@code createSocketImpl} method is called to create
|
||||
* the actual socket implementation. Otherwise a "plain" socket is created.
|
||||
* <p>
|
||||
* If there is a security manager,
|
||||
* its {@code checkListen} method is called
|
||||
* with the {@code port} argument
|
||||
* as its argument to ensure the operation is allowed.
|
||||
* This could result in a SecurityException.
|
||||
*
|
||||
* The {@code backlog} argument is the requested maximum number of
|
||||
* pending connections on the socket. Its exact semantics are implementation
|
||||
* specific. In particular, an implementation may impose a maximum length
|
||||
* or may choose to ignore the parameter altogther. The value provided
|
||||
* should be greater than {@code 0}. If it is less than or equal to
|
||||
* {@code 0}, then an implementation specific default will be used.
|
||||
* <P>
|
||||
*
|
||||
* @param port the port number, or {@code 0} to use a port
|
||||
* number that is automatically allocated.
|
||||
* @param backlog requested maximum length of the queue of incoming
|
||||
* connections.
|
||||
*
|
||||
* @exception IOException if an I/O error occurs when opening the socket.
|
||||
* @exception SecurityException
|
||||
* if a security manager exists and its {@code checkListen}
|
||||
* method doesn't allow the operation.
|
||||
* @exception IllegalArgumentException if the port parameter is outside
|
||||
* the specified range of valid port values, which is between
|
||||
* 0 and 65535, inclusive.
|
||||
*
|
||||
* @see java.net.SocketImpl
|
||||
* @see java.net.SocketImplFactory#createSocketImpl()
|
||||
* @see java.net.ServerSocket#setSocketFactory(java.net.SocketImplFactory)
|
||||
* @see SecurityManager#checkListen
|
||||
*/
|
||||
public ServerSocket(int port, int backlog) throws IOException {
|
||||
this(port, backlog, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a server with the specified port, listen backlog, and
|
||||
* local IP address to bind to. The <i>bindAddr</i> argument
|
||||
* can be used on a multi-homed host for a ServerSocket that
|
||||
* will only accept connect requests to one of its addresses.
|
||||
* If <i>bindAddr</i> is null, it will default accepting
|
||||
* connections on any/all local addresses.
|
||||
* The port must be between 0 and 65535, inclusive.
|
||||
* A port number of {@code 0} means that the port number is
|
||||
* automatically allocated, typically from an ephemeral port range.
|
||||
* This port number can then be retrieved by calling
|
||||
* {@link #getLocalPort getLocalPort}.
|
||||
*
|
||||
* <P>If there is a security manager, this method
|
||||
* calls its {@code checkListen} method
|
||||
* with the {@code port} argument
|
||||
* as its argument to ensure the operation is allowed.
|
||||
* This could result in a SecurityException.
|
||||
*
|
||||
* The {@code backlog} argument is the requested maximum number of
|
||||
* pending connections on the socket. Its exact semantics are implementation
|
||||
* specific. In particular, an implementation may impose a maximum length
|
||||
* or may choose to ignore the parameter altogther. The value provided
|
||||
* should be greater than {@code 0}. If it is less than or equal to
|
||||
* {@code 0}, then an implementation specific default will be used.
|
||||
* <P>
|
||||
* @param port the port number, or {@code 0} to use a port
|
||||
* number that is automatically allocated.
|
||||
* @param backlog requested maximum length of the queue of incoming
|
||||
* connections.
|
||||
* @param bindAddr the local InetAddress the server will bind to
|
||||
*
|
||||
* @throws SecurityException if a security manager exists and
|
||||
* its {@code checkListen} method doesn't allow the operation.
|
||||
*
|
||||
* @throws IOException if an I/O error occurs when opening the socket.
|
||||
* @exception IllegalArgumentException if the port parameter is outside
|
||||
* the specified range of valid port values, which is between
|
||||
* 0 and 65535, inclusive.
|
||||
*
|
||||
* @see SocketOptions
|
||||
* @see SocketImpl
|
||||
* @see SecurityManager#checkListen
|
||||
* @since JDK1.1
|
||||
*/
|
||||
public ServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException {
|
||||
setImpl();
|
||||
if (port < 0 || port > 0xFFFF)
|
||||
throw new IllegalArgumentException(
|
||||
"Port value out of range: " + port);
|
||||
if (backlog < 1)
|
||||
backlog = 50;
|
||||
try {
|
||||
bind(new InetSocketAddress(bindAddr, port), backlog);
|
||||
} catch(SecurityException e) {
|
||||
close();
|
||||
throw e;
|
||||
} catch(IOException e) {
|
||||
close();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@code SocketImpl} attached to this socket, creating
|
||||
* it if necessary.
|
||||
*
|
||||
* @return the {@code SocketImpl} attached to that ServerSocket.
|
||||
* @throws SocketException if creation fails.
|
||||
* @since 1.4
|
||||
*/
|
||||
SocketImpl getImpl() throws SocketException {
|
||||
if (!created)
|
||||
createImpl();
|
||||
return impl;
|
||||
}
|
||||
|
||||
private void checkOldImpl() {
|
||||
if (impl == null)
|
||||
return;
|
||||
// SocketImpl.connect() is a protected method, therefore we need to use
|
||||
// getDeclaredMethod, therefore we need permission to access the member
|
||||
try {
|
||||
AccessController.doPrivileged(
|
||||
new PrivilegedExceptionAction<Void>() {
|
||||
public Void run() throws NoSuchMethodException {
|
||||
impl.getClass().getDeclaredMethod("connect",
|
||||
SocketAddress.class,
|
||||
int.class);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
} catch (java.security.PrivilegedActionException e) {
|
||||
oldImpl = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void setImpl() {
|
||||
if (factory != null) {
|
||||
impl = factory.createSocketImpl();
|
||||
checkOldImpl();
|
||||
} else {
|
||||
// No need to do a checkOldImpl() here, we know it's an up to date
|
||||
// SocketImpl!
|
||||
impl = new SocksSocketImpl();
|
||||
}
|
||||
if (impl != null)
|
||||
impl.setServerSocket(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the socket implementation.
|
||||
*
|
||||
* @throws IOException if creation fails
|
||||
* @since 1.4
|
||||
*/
|
||||
void createImpl() throws SocketException {
|
||||
if (impl == null)
|
||||
setImpl();
|
||||
try {
|
||||
impl.create(true);
|
||||
created = true;
|
||||
} catch (IOException e) {
|
||||
throw new SocketException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Binds the {@code ServerSocket} to a specific address
|
||||
* (IP address and port number).
|
||||
* <p>
|
||||
* If the address is {@code null}, then the system will pick up
|
||||
* an ephemeral port and a valid local address to bind the socket.
|
||||
* <p>
|
||||
* @param endpoint The IP address and port number to bind to.
|
||||
* @throws IOException if the bind operation fails, or if the socket
|
||||
* is already bound.
|
||||
* @throws SecurityException if a {@code SecurityManager} is present and
|
||||
* its {@code checkListen} method doesn't allow the operation.
|
||||
* @throws IllegalArgumentException if endpoint is a
|
||||
* SocketAddress subclass not supported by this socket
|
||||
* @since 1.4
|
||||
*/
|
||||
public void bind(SocketAddress endpoint) throws IOException {
|
||||
bind(endpoint, 50);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Binds the {@code ServerSocket} to a specific address
|
||||
* (IP address and port number).
|
||||
* <p>
|
||||
* If the address is {@code null}, then the system will pick up
|
||||
* an ephemeral port and a valid local address to bind the socket.
|
||||
* <P>
|
||||
* The {@code backlog} argument is the requested maximum number of
|
||||
* pending connections on the socket. Its exact semantics are implementation
|
||||
* specific. In particular, an implementation may impose a maximum length
|
||||
* or may choose to ignore the parameter altogther. The value provided
|
||||
* should be greater than {@code 0}. If it is less than or equal to
|
||||
* {@code 0}, then an implementation specific default will be used.
|
||||
* @param endpoint The IP address and port number to bind to.
|
||||
* @param backlog requested maximum length of the queue of
|
||||
* incoming connections.
|
||||
* @throws IOException if the bind operation fails, or if the socket
|
||||
* is already bound.
|
||||
* @throws SecurityException if a {@code SecurityManager} is present and
|
||||
* its {@code checkListen} method doesn't allow the operation.
|
||||
* @throws IllegalArgumentException if endpoint is a
|
||||
* SocketAddress subclass not supported by this socket
|
||||
* @since 1.4
|
||||
*/
|
||||
public void bind(SocketAddress endpoint, int backlog) throws IOException {
|
||||
if (isClosed())
|
||||
throw new SocketException("Socket is closed");
|
||||
if (!oldImpl && isBound())
|
||||
throw new SocketException("Already bound");
|
||||
if (endpoint == null)
|
||||
endpoint = new InetSocketAddress(0);
|
||||
if (!(endpoint instanceof InetSocketAddress))
|
||||
throw new IllegalArgumentException("Unsupported address type");
|
||||
InetSocketAddress epoint = (InetSocketAddress) endpoint;
|
||||
if (epoint.isUnresolved())
|
||||
throw new SocketException("Unresolved address");
|
||||
if (backlog < 1)
|
||||
backlog = 50;
|
||||
try {
|
||||
SecurityManager security = System.getSecurityManager();
|
||||
if (security != null)
|
||||
security.checkListen(epoint.getPort());
|
||||
getImpl().bind(epoint.getAddress(), epoint.getPort());
|
||||
getImpl().listen(backlog);
|
||||
bound = true;
|
||||
} catch(SecurityException e) {
|
||||
bound = false;
|
||||
throw e;
|
||||
} catch(IOException e) {
|
||||
bound = false;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the local address of this server socket.
|
||||
* <p>
|
||||
* If the socket was bound prior to being {@link #close closed},
|
||||
* then this method will continue to return the local address
|
||||
* after the socket is closed.
|
||||
* <p>
|
||||
* If there is a security manager set, its {@code checkConnect} method is
|
||||
* called with the local address and {@code -1} as its arguments to see
|
||||
* if the operation is allowed. If the operation is not allowed,
|
||||
* the {@link InetAddress#getLoopbackAddress loopback} address is returned.
|
||||
*
|
||||
* @return the address to which this socket is bound,
|
||||
* or the loopback address if denied by the security manager,
|
||||
* or {@code null} if the socket is unbound.
|
||||
*
|
||||
* @see SecurityManager#checkConnect
|
||||
*/
|
||||
public InetAddress getInetAddress() {
|
||||
if (!isBound())
|
||||
return null;
|
||||
try {
|
||||
InetAddress in = getImpl().getInetAddress();
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null)
|
||||
sm.checkConnect(in.getHostAddress(), -1);
|
||||
return in;
|
||||
} catch (SecurityException e) {
|
||||
return InetAddress.getLoopbackAddress();
|
||||
} catch (SocketException e) {
|
||||
// nothing
|
||||
// If we're bound, the impl has been created
|
||||
// so we shouldn't get here
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the port number on which this socket is listening.
|
||||
* <p>
|
||||
* If the socket was bound prior to being {@link #close closed},
|
||||
* then this method will continue to return the port number
|
||||
* after the socket is closed.
|
||||
*
|
||||
* @return the port number to which this socket is listening or
|
||||
* -1 if the socket is not bound yet.
|
||||
*/
|
||||
public int getLocalPort() {
|
||||
if (!isBound())
|
||||
return -1;
|
||||
try {
|
||||
return getImpl().getLocalPort();
|
||||
} catch (SocketException e) {
|
||||
// nothing
|
||||
// If we're bound, the impl has been created
|
||||
// so we shouldn't get here
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the address of the endpoint this socket is bound to.
|
||||
* <p>
|
||||
* If the socket was bound prior to being {@link #close closed},
|
||||
* then this method will continue to return the address of the endpoint
|
||||
* after the socket is closed.
|
||||
* <p>
|
||||
* If there is a security manager set, its {@code checkConnect} method is
|
||||
* called with the local address and {@code -1} as its arguments to see
|
||||
* if the operation is allowed. If the operation is not allowed,
|
||||
* a {@code SocketAddress} representing the
|
||||
* {@link InetAddress#getLoopbackAddress loopback} address and the local
|
||||
* port to which the socket is bound is returned.
|
||||
*
|
||||
* @return a {@code SocketAddress} representing the local endpoint of
|
||||
* this socket, or a {@code SocketAddress} representing the
|
||||
* loopback address if denied by the security manager,
|
||||
* or {@code null} if the socket is not bound yet.
|
||||
*
|
||||
* @see #getInetAddress()
|
||||
* @see #getLocalPort()
|
||||
* @see #bind(SocketAddress)
|
||||
* @see SecurityManager#checkConnect
|
||||
* @since 1.4
|
||||
*/
|
||||
|
||||
public SocketAddress getLocalSocketAddress() {
|
||||
if (!isBound())
|
||||
return null;
|
||||
return new InetSocketAddress(getInetAddress(), getLocalPort());
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens for a connection to be made to this socket and accepts
|
||||
* it. The method blocks until a connection is made.
|
||||
*
|
||||
* <p>A new Socket {@code s} is created and, if there
|
||||
* is a security manager,
|
||||
* the security manager's {@code checkAccept} method is called
|
||||
* with {@code s.getInetAddress().getHostAddress()} and
|
||||
* {@code s.getPort()}
|
||||
* as its arguments to ensure the operation is allowed.
|
||||
* This could result in a SecurityException.
|
||||
*
|
||||
* @exception IOException if an I/O error occurs when waiting for a
|
||||
* connection.
|
||||
* @exception SecurityException if a security manager exists and its
|
||||
* {@code checkAccept} method doesn't allow the operation.
|
||||
* @exception SocketTimeoutException if a timeout was previously set with setSoTimeout and
|
||||
* the timeout has been reached.
|
||||
* @exception java.nio.channels.IllegalBlockingModeException
|
||||
* if this socket has an associated channel, the channel is in
|
||||
* non-blocking mode, and there is no connection ready to be
|
||||
* accepted
|
||||
*
|
||||
* @return the new Socket
|
||||
* @see SecurityManager#checkAccept
|
||||
* @revised 1.4
|
||||
* @spec JSR-51
|
||||
*/
|
||||
public Socket accept() throws IOException {
|
||||
if (isClosed())
|
||||
throw new SocketException("Socket is closed");
|
||||
if (!isBound())
|
||||
throw new SocketException("Socket is not bound yet");
|
||||
Socket s = new Socket((SocketImpl) null);
|
||||
implAccept(s);
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses of ServerSocket use this method to override accept()
|
||||
* to return their own subclass of socket. So a FooServerSocket
|
||||
* will typically hand this method an <i>empty</i> FooSocket. On
|
||||
* return from implAccept the FooSocket will be connected to a client.
|
||||
*
|
||||
* @param s the Socket
|
||||
* @throws java.nio.channels.IllegalBlockingModeException
|
||||
* if this socket has an associated channel,
|
||||
* and the channel is in non-blocking mode
|
||||
* @throws IOException if an I/O error occurs when waiting
|
||||
* for a connection.
|
||||
* @since JDK1.1
|
||||
* @revised 1.4
|
||||
* @spec JSR-51
|
||||
*/
|
||||
protected final void implAccept(Socket s) throws IOException {
|
||||
SocketImpl si = null;
|
||||
try {
|
||||
if (s.impl == null)
|
||||
s.setImpl();
|
||||
else {
|
||||
s.impl.reset();
|
||||
}
|
||||
si = s.impl;
|
||||
s.impl = null;
|
||||
si.address = new InetAddress();
|
||||
si.fd = new FileDescriptor();
|
||||
getImpl().accept(si);
|
||||
|
||||
SecurityManager security = System.getSecurityManager();
|
||||
if (security != null) {
|
||||
security.checkAccept(si.getInetAddress().getHostAddress(),
|
||||
si.getPort());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
if (si != null)
|
||||
si.reset();
|
||||
s.impl = si;
|
||||
throw e;
|
||||
} catch (SecurityException e) {
|
||||
if (si != null)
|
||||
si.reset();
|
||||
s.impl = si;
|
||||
throw e;
|
||||
}
|
||||
s.impl = si;
|
||||
s.postAccept();
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes this socket.
|
||||
*
|
||||
* Any thread currently blocked in {@link #accept()} will throw
|
||||
* a {@link SocketException}.
|
||||
*
|
||||
* <p> If this socket has an associated channel then the channel is closed
|
||||
* as well.
|
||||
*
|
||||
* @exception IOException if an I/O error occurs when closing the socket.
|
||||
* @revised 1.4
|
||||
* @spec JSR-51
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
synchronized(closeLock) {
|
||||
if (isClosed())
|
||||
return;
|
||||
if (created)
|
||||
impl.close();
|
||||
closed = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the unique {@link java.nio.channels.ServerSocketChannel} object
|
||||
* associated with this socket, if any.
|
||||
*
|
||||
* <p> A server socket will have a channel if, and only if, the channel
|
||||
* itself was created via the {@link
|
||||
* java.nio.channels.ServerSocketChannel#open ServerSocketChannel.open}
|
||||
* method.
|
||||
*
|
||||
* @return the server-socket channel associated with this socket,
|
||||
* or {@code null} if this socket was not created
|
||||
* for a channel
|
||||
*
|
||||
* @since 1.4
|
||||
* @spec JSR-51
|
||||
*/
|
||||
public ServerSocketChannel getChannel() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the binding state of the ServerSocket.
|
||||
*
|
||||
* @return true if the ServerSocket successfully bound to an address
|
||||
* @since 1.4
|
||||
*/
|
||||
public boolean isBound() {
|
||||
// Before 1.3 ServerSockets were always bound during creation
|
||||
return bound || oldImpl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the closed state of the ServerSocket.
|
||||
*
|
||||
* @return true if the socket has been closed
|
||||
* @since 1.4
|
||||
*/
|
||||
public boolean isClosed() {
|
||||
synchronized(closeLock) {
|
||||
return closed;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable/disable {@link SocketOptions#SO_TIMEOUT SO_TIMEOUT} with the
|
||||
* specified timeout, in milliseconds. With this option set to a non-zero
|
||||
* timeout, a call to accept() for this ServerSocket
|
||||
* will block for only this amount of time. If the timeout expires,
|
||||
* a <B>java.net.SocketTimeoutException</B> is raised, though the
|
||||
* ServerSocket is still valid. The option <B>must</B> be enabled
|
||||
* prior to entering the blocking operation to have effect. The
|
||||
* timeout must be {@code > 0}.
|
||||
* A timeout of zero is interpreted as an infinite timeout.
|
||||
* @param timeout the specified timeout, in milliseconds
|
||||
* @exception SocketException if there is an error in
|
||||
* the underlying protocol, such as a TCP error.
|
||||
* @since JDK1.1
|
||||
* @see #getSoTimeout()
|
||||
*/
|
||||
public synchronized void setSoTimeout(int timeout) throws SocketException {
|
||||
if (isClosed())
|
||||
throw new SocketException("Socket is closed");
|
||||
getImpl().setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve setting for {@link SocketOptions#SO_TIMEOUT SO_TIMEOUT}.
|
||||
* 0 returns implies that the option is disabled (i.e., timeout of infinity).
|
||||
* @return the {@link SocketOptions#SO_TIMEOUT SO_TIMEOUT} value
|
||||
* @exception IOException if an I/O error occurs
|
||||
* @since JDK1.1
|
||||
* @see #setSoTimeout(int)
|
||||
*/
|
||||
public synchronized int getSoTimeout() throws IOException {
|
||||
if (isClosed())
|
||||
throw new SocketException("Socket is closed");
|
||||
Object o = getImpl().getOption(SocketOptions.SO_TIMEOUT);
|
||||
/* extra type safety */
|
||||
if (o instanceof Integer) {
|
||||
return ((Integer) o).intValue();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable/disable the {@link SocketOptions#SO_REUSEADDR SO_REUSEADDR}
|
||||
* socket option.
|
||||
* <p>
|
||||
* When a TCP connection is closed the connection may remain
|
||||
* in a timeout state for a period of time after the connection
|
||||
* is closed (typically known as the {@code TIME_WAIT} state
|
||||
* or {@code 2MSL} wait state).
|
||||
* For applications using a well known socket address or port
|
||||
* it may not be possible to bind a socket to the required
|
||||
* {@code SocketAddress} if there is a connection in the
|
||||
* timeout state involving the socket address or port.
|
||||
* <p>
|
||||
* Enabling {@link SocketOptions#SO_REUSEADDR SO_REUSEADDR} prior to
|
||||
* binding the socket using {@link #bind(SocketAddress)} allows the socket
|
||||
* to be bound even though a previous connection is in a timeout state.
|
||||
* <p>
|
||||
* When a {@code ServerSocket} is created the initial setting
|
||||
* of {@link SocketOptions#SO_REUSEADDR SO_REUSEADDR} is not defined.
|
||||
* Applications can use {@link #getReuseAddress()} to determine the initial
|
||||
* setting of {@link SocketOptions#SO_REUSEADDR SO_REUSEADDR}.
|
||||
* <p>
|
||||
* The behaviour when {@link SocketOptions#SO_REUSEADDR SO_REUSEADDR} is
|
||||
* enabled or disabled after a socket is bound (See {@link #isBound()})
|
||||
* is not defined.
|
||||
*
|
||||
* @param on whether to enable or disable the socket option
|
||||
* @exception SocketException if an error occurs enabling or
|
||||
* disabling the {@link SocketOptions#SO_REUSEADDR SO_REUSEADDR}
|
||||
* socket option, or the socket is closed.
|
||||
* @since 1.4
|
||||
* @see #getReuseAddress()
|
||||
* @see #bind(SocketAddress)
|
||||
* @see #isBound()
|
||||
* @see #isClosed()
|
||||
*/
|
||||
public void setReuseAddress(boolean on) throws SocketException {
|
||||
if (isClosed())
|
||||
throw new SocketException("Socket is closed");
|
||||
getImpl().setOption(SocketOptions.SO_REUSEADDR, Boolean.valueOf(on));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if {@link SocketOptions#SO_REUSEADDR SO_REUSEADDR} is enabled.
|
||||
*
|
||||
* @return a {@code boolean} indicating whether or not
|
||||
* {@link SocketOptions#SO_REUSEADDR SO_REUSEADDR} is enabled.
|
||||
* @exception SocketException if there is an error
|
||||
* in the underlying protocol, such as a TCP error.
|
||||
* @since 1.4
|
||||
* @see #setReuseAddress(boolean)
|
||||
*/
|
||||
public boolean getReuseAddress() throws SocketException {
|
||||
if (isClosed())
|
||||
throw new SocketException("Socket is closed");
|
||||
return ((Boolean) (getImpl().getOption(SocketOptions.SO_REUSEADDR))).booleanValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the implementation address and implementation port of
|
||||
* this socket as a {@code String}.
|
||||
* <p>
|
||||
* If there is a security manager set, its {@code checkConnect} method is
|
||||
* called with the local address and {@code -1} as its arguments to see
|
||||
* if the operation is allowed. If the operation is not allowed,
|
||||
* an {@code InetAddress} representing the
|
||||
* {@link InetAddress#getLoopbackAddress loopback} address is returned as
|
||||
* the implementation address.
|
||||
*
|
||||
* @return a string representation of this socket.
|
||||
*/
|
||||
public String toString() {
|
||||
if (!isBound())
|
||||
return "ServerSocket[unbound]";
|
||||
InetAddress in;
|
||||
if (System.getSecurityManager() != null)
|
||||
in = InetAddress.getLoopbackAddress();
|
||||
else
|
||||
in = impl.getInetAddress();
|
||||
return "ServerSocket[addr=" + in +
|
||||
",localport=" + impl.getLocalPort() + "]";
|
||||
}
|
||||
|
||||
void setBound() {
|
||||
bound = true;
|
||||
}
|
||||
|
||||
void setCreated() {
|
||||
created = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* The factory for all server sockets.
|
||||
*/
|
||||
private static SocketImplFactory factory = null;
|
||||
|
||||
/**
|
||||
* Sets the server socket implementation factory for the
|
||||
* application. The factory can be specified only once.
|
||||
* <p>
|
||||
* When an application creates a new server socket, the socket
|
||||
* implementation factory's {@code createSocketImpl} method is
|
||||
* called to create the actual socket implementation.
|
||||
* <p>
|
||||
* Passing {@code null} to the method is a no-op unless the factory
|
||||
* was already set.
|
||||
* <p>
|
||||
* If there is a security manager, this method first calls
|
||||
* the security manager's {@code checkSetFactory} method
|
||||
* to ensure the operation is allowed.
|
||||
* This could result in a SecurityException.
|
||||
*
|
||||
* @param fac the desired factory.
|
||||
* @exception IOException if an I/O error occurs when setting the
|
||||
* socket factory.
|
||||
* @exception SocketException if the factory has already been defined.
|
||||
* @exception SecurityException if a security manager exists and its
|
||||
* {@code checkSetFactory} method doesn't allow the operation.
|
||||
* @see java.net.SocketImplFactory#createSocketImpl()
|
||||
* @see SecurityManager#checkSetFactory
|
||||
*/
|
||||
public static synchronized void setSocketFactory(SocketImplFactory fac) throws IOException {
|
||||
if (factory != null) {
|
||||
throw new SocketException("factory already defined");
|
||||
}
|
||||
SecurityManager security = System.getSecurityManager();
|
||||
if (security != null) {
|
||||
security.checkSetFactory();
|
||||
}
|
||||
factory = fac;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a default proposed value for the
|
||||
* {@link SocketOptions#SO_RCVBUF SO_RCVBUF} option for sockets
|
||||
* accepted from this {@code ServerSocket}. The value actually set
|
||||
* in the accepted socket must be determined by calling
|
||||
* {@link Socket#getReceiveBufferSize()} after the socket
|
||||
* is returned by {@link #accept()}.
|
||||
* <p>
|
||||
* The value of {@link SocketOptions#SO_RCVBUF SO_RCVBUF} is used both to
|
||||
* set the size of the internal socket receive buffer, and to set the size
|
||||
* of the TCP receive window that is advertized to the remote peer.
|
||||
* <p>
|
||||
* It is possible to change the value subsequently, by calling
|
||||
* {@link Socket#setReceiveBufferSize(int)}. However, if the application
|
||||
* wishes to allow a receive window larger than 64K bytes, as defined by RFC1323
|
||||
* then the proposed value must be set in the ServerSocket <B>before</B>
|
||||
* it is bound to a local address. This implies, that the ServerSocket must be
|
||||
* created with the no-argument constructor, then setReceiveBufferSize() must
|
||||
* be called and lastly the ServerSocket is bound to an address by calling bind().
|
||||
* <p>
|
||||
* Failure to do this will not cause an error, and the buffer size may be set to the
|
||||
* requested value but the TCP receive window in sockets accepted from
|
||||
* this ServerSocket will be no larger than 64K bytes.
|
||||
*
|
||||
* @exception SocketException if there is an error
|
||||
* in the underlying protocol, such as a TCP error.
|
||||
*
|
||||
* @param size the size to which to set the receive buffer
|
||||
* size. This value must be greater than 0.
|
||||
*
|
||||
* @exception IllegalArgumentException if the
|
||||
* value is 0 or is negative.
|
||||
*
|
||||
* @since 1.4
|
||||
* @see #getReceiveBufferSize
|
||||
*/
|
||||
public synchronized void setReceiveBufferSize (int size) throws SocketException {
|
||||
if (!(size > 0)) {
|
||||
throw new IllegalArgumentException("negative receive size");
|
||||
}
|
||||
if (isClosed())
|
||||
throw new SocketException("Socket is closed");
|
||||
getImpl().setOption(SocketOptions.SO_RCVBUF, new Integer(size));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the {@link SocketOptions#SO_RCVBUF SO_RCVBUF} option
|
||||
* for this {@code ServerSocket}, that is the proposed buffer size that
|
||||
* will be used for Sockets accepted from this {@code ServerSocket}.
|
||||
*
|
||||
* <p>Note, the value actually set in the accepted socket is determined by
|
||||
* calling {@link Socket#getReceiveBufferSize()}.
|
||||
* @return the value of the {@link SocketOptions#SO_RCVBUF SO_RCVBUF}
|
||||
* option for this {@code Socket}.
|
||||
* @exception SocketException if there is an error
|
||||
* in the underlying protocol, such as a TCP error.
|
||||
* @see #setReceiveBufferSize(int)
|
||||
* @since 1.4
|
||||
*/
|
||||
public synchronized int getReceiveBufferSize()
|
||||
throws SocketException{
|
||||
if (isClosed())
|
||||
throw new SocketException("Socket is closed");
|
||||
int result = 0;
|
||||
Object o = getImpl().getOption(SocketOptions.SO_RCVBUF);
|
||||
if (o instanceof Integer) {
|
||||
result = ((Integer)o).intValue();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets performance preferences for this ServerSocket.
|
||||
*
|
||||
* <p> Sockets use the TCP/IP protocol by default. Some implementations
|
||||
* may offer alternative protocols which have different performance
|
||||
* characteristics than TCP/IP. This method allows the application to
|
||||
* express its own preferences as to how these tradeoffs should be made
|
||||
* when the implementation chooses from the available protocols.
|
||||
*
|
||||
* <p> Performance preferences are described by three integers
|
||||
* whose values indicate the relative importance of short connection time,
|
||||
* low latency, and high bandwidth. The absolute values of the integers
|
||||
* are irrelevant; in order to choose a protocol the values are simply
|
||||
* compared, with larger values indicating stronger preferences. If the
|
||||
* application prefers short connection time over both low latency and high
|
||||
* bandwidth, for example, then it could invoke this method with the values
|
||||
* {@code (1, 0, 0)}. If the application prefers high bandwidth above low
|
||||
* latency, and low latency above short connection time, then it could
|
||||
* invoke this method with the values {@code (0, 1, 2)}.
|
||||
*
|
||||
* <p> Invoking this method after this socket has been bound
|
||||
* will have no effect. This implies that in order to use this capability
|
||||
* requires the socket to be created with the no-argument constructor.
|
||||
*
|
||||
* @param connectionTime
|
||||
* An {@code int} expressing the relative importance of a short
|
||||
* connection time
|
||||
*
|
||||
* @param latency
|
||||
* An {@code int} expressing the relative importance of low
|
||||
* latency
|
||||
*
|
||||
* @param bandwidth
|
||||
* An {@code int} expressing the relative importance of high
|
||||
* bandwidth
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public void setPerformancePreferences(int connectionTime,
|
||||
int latency,
|
||||
int bandwidth)
|
||||
{
|
||||
/* Not implemented yet */
|
||||
}
|
||||
|
||||
}
|
||||
1748
jdkSrc/jdk8/java/net/Socket.java
Normal file
1748
jdkSrc/jdk8/java/net/Socket.java
Normal file
File diff suppressed because it is too large
Load Diff
45
jdkSrc/jdk8/java/net/SocketAddress.java
Normal file
45
jdkSrc/jdk8/java/net/SocketAddress.java
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package java.net;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* This class represents a Socket Address with no protocol attachment.
|
||||
* As an abstract class, it is meant to be subclassed with a specific,
|
||||
* protocol dependent, implementation.
|
||||
* <p>
|
||||
* It provides an immutable object used by sockets for binding, connecting, or
|
||||
* as returned values.
|
||||
*
|
||||
* @see java.net.Socket
|
||||
* @see java.net.ServerSocket
|
||||
* @since 1.4
|
||||
*/
|
||||
public abstract class SocketAddress implements java.io.Serializable {
|
||||
|
||||
static final long serialVersionUID = 5215720748342549866L;
|
||||
|
||||
}
|
||||
55
jdkSrc/jdk8/java/net/SocketException.java
Normal file
55
jdkSrc/jdk8/java/net/SocketException.java
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Thrown to indicate that there is an error creating or accessing a Socket.
|
||||
*
|
||||
* @author Jonathan Payne
|
||||
* @since JDK1.0
|
||||
*/
|
||||
public
|
||||
class SocketException extends IOException {
|
||||
private static final long serialVersionUID = -5935874303556886934L;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code SocketException} with the
|
||||
* specified detail message.
|
||||
*
|
||||
* @param msg the detail message.
|
||||
*/
|
||||
public SocketException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code SocketException} with no detail message.
|
||||
*/
|
||||
public SocketException() {
|
||||
}
|
||||
}
|
||||
398
jdkSrc/jdk8/java/net/SocketImpl.java
Normal file
398
jdkSrc/jdk8/java/net/SocketImpl.java
Normal file
@@ -0,0 +1,398 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.FileDescriptor;
|
||||
|
||||
/**
|
||||
* The abstract class {@code SocketImpl} is a common superclass
|
||||
* of all classes that actually implement sockets. It is used to
|
||||
* create both client and server sockets.
|
||||
* <p>
|
||||
* A "plain" socket implements these methods exactly as
|
||||
* described, without attempting to go through a firewall or proxy.
|
||||
*
|
||||
* @author unascribed
|
||||
* @since JDK1.0
|
||||
*/
|
||||
public abstract class SocketImpl implements SocketOptions {
|
||||
/**
|
||||
* The actual Socket object.
|
||||
*/
|
||||
Socket socket = null;
|
||||
ServerSocket serverSocket = null;
|
||||
|
||||
/**
|
||||
* The file descriptor object for this socket.
|
||||
*/
|
||||
protected FileDescriptor fd;
|
||||
|
||||
/**
|
||||
* The IP address of the remote end of this socket.
|
||||
*/
|
||||
protected InetAddress address;
|
||||
|
||||
/**
|
||||
* The port number on the remote host to which this socket is connected.
|
||||
*/
|
||||
protected int port;
|
||||
|
||||
/**
|
||||
* The local port number to which this socket is connected.
|
||||
*/
|
||||
protected int localport;
|
||||
|
||||
/**
|
||||
* Creates either a stream or a datagram socket.
|
||||
*
|
||||
* @param stream if {@code true}, create a stream socket;
|
||||
* otherwise, create a datagram socket.
|
||||
* @exception IOException if an I/O error occurs while creating the
|
||||
* socket.
|
||||
*/
|
||||
protected abstract void create(boolean stream) throws IOException;
|
||||
|
||||
/**
|
||||
* Connects this socket to the specified port on the named host.
|
||||
*
|
||||
* @param host the name of the remote host.
|
||||
* @param port the port number.
|
||||
* @exception IOException if an I/O error occurs when connecting to the
|
||||
* remote host.
|
||||
*/
|
||||
protected abstract void connect(String host, int port) throws IOException;
|
||||
|
||||
/**
|
||||
* Connects this socket to the specified port number on the specified host.
|
||||
*
|
||||
* @param address the IP address of the remote host.
|
||||
* @param port the port number.
|
||||
* @exception IOException if an I/O error occurs when attempting a
|
||||
* connection.
|
||||
*/
|
||||
protected abstract void connect(InetAddress address, int port) throws IOException;
|
||||
|
||||
/**
|
||||
* Connects this socket to the specified port number on the specified host.
|
||||
* A timeout of zero is interpreted as an infinite timeout. The connection
|
||||
* will then block until established or an error occurs.
|
||||
*
|
||||
* @param address the Socket address of the remote host.
|
||||
* @param timeout the timeout value, in milliseconds, or zero for no timeout.
|
||||
* @exception IOException if an I/O error occurs when attempting a
|
||||
* connection.
|
||||
* @since 1.4
|
||||
*/
|
||||
protected abstract void connect(SocketAddress address, int timeout) throws IOException;
|
||||
|
||||
/**
|
||||
* Binds this socket to the specified local IP address and port number.
|
||||
*
|
||||
* @param host an IP address that belongs to a local interface.
|
||||
* @param port the port number.
|
||||
* @exception IOException if an I/O error occurs when binding this socket.
|
||||
*/
|
||||
protected abstract void bind(InetAddress host, int port) throws IOException;
|
||||
|
||||
/**
|
||||
* Sets the maximum queue length for incoming connection indications
|
||||
* (a request to connect) to the {@code count} argument. If a
|
||||
* connection indication arrives when the queue is full, the
|
||||
* connection is refused.
|
||||
*
|
||||
* @param backlog the maximum length of the queue.
|
||||
* @exception IOException if an I/O error occurs when creating the queue.
|
||||
*/
|
||||
protected abstract void listen(int backlog) throws IOException;
|
||||
|
||||
/**
|
||||
* Accepts a connection.
|
||||
*
|
||||
* @param s the accepted connection.
|
||||
* @exception IOException if an I/O error occurs when accepting the
|
||||
* connection.
|
||||
*/
|
||||
protected abstract void accept(SocketImpl s) throws IOException;
|
||||
|
||||
/**
|
||||
* Returns an input stream for this socket.
|
||||
*
|
||||
* @return a stream for reading from this socket.
|
||||
* @exception IOException if an I/O error occurs when creating the
|
||||
* input stream.
|
||||
*/
|
||||
protected abstract InputStream getInputStream() throws IOException;
|
||||
|
||||
/**
|
||||
* Returns an output stream for this socket.
|
||||
*
|
||||
* @return an output stream for writing to this socket.
|
||||
* @exception IOException if an I/O error occurs when creating the
|
||||
* output stream.
|
||||
*/
|
||||
protected abstract OutputStream getOutputStream() throws IOException;
|
||||
|
||||
/**
|
||||
* Returns the number of bytes that can be read from this socket
|
||||
* without blocking.
|
||||
*
|
||||
* @return the number of bytes that can be read from this socket
|
||||
* without blocking.
|
||||
* @exception IOException if an I/O error occurs when determining the
|
||||
* number of bytes available.
|
||||
*/
|
||||
protected abstract int available() throws IOException;
|
||||
|
||||
/**
|
||||
* Closes this socket.
|
||||
*
|
||||
* @exception IOException if an I/O error occurs when closing this socket.
|
||||
*/
|
||||
protected abstract void close() throws IOException;
|
||||
|
||||
/**
|
||||
* Places the input stream for this socket at "end of stream".
|
||||
* Any data sent to this socket is acknowledged and then
|
||||
* silently discarded.
|
||||
*
|
||||
* If you read from a socket input stream after invoking this method on the
|
||||
* socket, the stream's {@code available} method will return 0, and its
|
||||
* {@code read} methods will return {@code -1} (end of stream).
|
||||
*
|
||||
* @exception IOException if an I/O error occurs when shutting down this
|
||||
* socket.
|
||||
* @see java.net.Socket#shutdownOutput()
|
||||
* @see java.net.Socket#close()
|
||||
* @see java.net.Socket#setSoLinger(boolean, int)
|
||||
* @since 1.3
|
||||
*/
|
||||
protected void shutdownInput() throws IOException {
|
||||
throw new IOException("Method not implemented!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables the output stream for this socket.
|
||||
* For a TCP socket, any previously written data will be sent
|
||||
* followed by TCP's normal connection termination sequence.
|
||||
*
|
||||
* If you write to a socket output stream after invoking
|
||||
* shutdownOutput() on the socket, the stream will throw
|
||||
* an IOException.
|
||||
*
|
||||
* @exception IOException if an I/O error occurs when shutting down this
|
||||
* socket.
|
||||
* @see java.net.Socket#shutdownInput()
|
||||
* @see java.net.Socket#close()
|
||||
* @see java.net.Socket#setSoLinger(boolean, int)
|
||||
* @since 1.3
|
||||
*/
|
||||
protected void shutdownOutput() throws IOException {
|
||||
throw new IOException("Method not implemented!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of this socket's {@code fd} field.
|
||||
*
|
||||
* @return the value of this socket's {@code fd} field.
|
||||
* @see java.net.SocketImpl#fd
|
||||
*/
|
||||
protected FileDescriptor getFileDescriptor() {
|
||||
return fd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of this socket's {@code address} field.
|
||||
*
|
||||
* @return the value of this socket's {@code address} field.
|
||||
* @see java.net.SocketImpl#address
|
||||
*/
|
||||
protected InetAddress getInetAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of this socket's {@code port} field.
|
||||
*
|
||||
* @return the value of this socket's {@code port} field.
|
||||
* @see java.net.SocketImpl#port
|
||||
*/
|
||||
protected int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not this SocketImpl supports sending
|
||||
* urgent data. By default, false is returned
|
||||
* unless the method is overridden in a sub-class
|
||||
*
|
||||
* @return true if urgent data supported
|
||||
* @see java.net.SocketImpl#address
|
||||
* @since 1.4
|
||||
*/
|
||||
protected boolean supportsUrgentData () {
|
||||
return false; // must be overridden in sub-class
|
||||
}
|
||||
|
||||
/**
|
||||
* Send one byte of urgent data on the socket.
|
||||
* The byte to be sent is the low eight bits of the parameter
|
||||
* @param data The byte of data to send
|
||||
* @exception IOException if there is an error
|
||||
* sending the data.
|
||||
* @since 1.4
|
||||
*/
|
||||
protected abstract void sendUrgentData (int data) throws IOException;
|
||||
|
||||
/**
|
||||
* Returns the value of this socket's {@code localport} field.
|
||||
*
|
||||
* @return the value of this socket's {@code localport} field.
|
||||
* @see java.net.SocketImpl#localport
|
||||
*/
|
||||
protected int getLocalPort() {
|
||||
return localport;
|
||||
}
|
||||
|
||||
void setSocket(Socket soc) {
|
||||
this.socket = soc;
|
||||
}
|
||||
|
||||
Socket getSocket() {
|
||||
return socket;
|
||||
}
|
||||
|
||||
void setServerSocket(ServerSocket soc) {
|
||||
this.serverSocket = soc;
|
||||
}
|
||||
|
||||
ServerSocket getServerSocket() {
|
||||
return serverSocket;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the address and port of this socket as a {@code String}.
|
||||
*
|
||||
* @return a string representation of this socket.
|
||||
*/
|
||||
public String toString() {
|
||||
return "Socket[addr=" + getInetAddress() +
|
||||
",port=" + getPort() + ",localport=" + getLocalPort() + "]";
|
||||
}
|
||||
|
||||
void reset() throws IOException {
|
||||
address = null;
|
||||
port = 0;
|
||||
localport = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets performance preferences for this socket.
|
||||
*
|
||||
* <p> Sockets use the TCP/IP protocol by default. Some implementations
|
||||
* may offer alternative protocols which have different performance
|
||||
* characteristics than TCP/IP. This method allows the application to
|
||||
* express its own preferences as to how these tradeoffs should be made
|
||||
* when the implementation chooses from the available protocols.
|
||||
*
|
||||
* <p> Performance preferences are described by three integers
|
||||
* whose values indicate the relative importance of short connection time,
|
||||
* low latency, and high bandwidth. The absolute values of the integers
|
||||
* are irrelevant; in order to choose a protocol the values are simply
|
||||
* compared, with larger values indicating stronger preferences. Negative
|
||||
* values represent a lower priority than positive values. If the
|
||||
* application prefers short connection time over both low latency and high
|
||||
* bandwidth, for example, then it could invoke this method with the values
|
||||
* {@code (1, 0, 0)}. If the application prefers high bandwidth above low
|
||||
* latency, and low latency above short connection time, then it could
|
||||
* invoke this method with the values {@code (0, 1, 2)}.
|
||||
*
|
||||
* By default, this method does nothing, unless it is overridden in a
|
||||
* a sub-class.
|
||||
*
|
||||
* @param connectionTime
|
||||
* An {@code int} expressing the relative importance of a short
|
||||
* connection time
|
||||
*
|
||||
* @param latency
|
||||
* An {@code int} expressing the relative importance of low
|
||||
* latency
|
||||
*
|
||||
* @param bandwidth
|
||||
* An {@code int} expressing the relative importance of high
|
||||
* bandwidth
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
protected void setPerformancePreferences(int connectionTime,
|
||||
int latency,
|
||||
int bandwidth)
|
||||
{
|
||||
/* Not implemented yet */
|
||||
}
|
||||
|
||||
<T> void setOption(SocketOption<T> name, T value) throws IOException {
|
||||
if (name == StandardSocketOptions.SO_KEEPALIVE) {
|
||||
setOption(SocketOptions.SO_KEEPALIVE, value);
|
||||
} else if (name == StandardSocketOptions.SO_SNDBUF) {
|
||||
setOption(SocketOptions.SO_SNDBUF, value);
|
||||
} else if (name == StandardSocketOptions.SO_RCVBUF) {
|
||||
setOption(SocketOptions.SO_RCVBUF, value);
|
||||
} else if (name == StandardSocketOptions.SO_REUSEADDR) {
|
||||
setOption(SocketOptions.SO_REUSEADDR, value);
|
||||
} else if (name == StandardSocketOptions.SO_LINGER) {
|
||||
setOption(SocketOptions.SO_LINGER, value);
|
||||
} else if (name == StandardSocketOptions.IP_TOS) {
|
||||
setOption(SocketOptions.IP_TOS, value);
|
||||
} else if (name == StandardSocketOptions.TCP_NODELAY) {
|
||||
setOption(SocketOptions.TCP_NODELAY, value);
|
||||
} else {
|
||||
throw new UnsupportedOperationException("unsupported option");
|
||||
}
|
||||
}
|
||||
|
||||
<T> T getOption(SocketOption<T> name) throws IOException {
|
||||
if (name == StandardSocketOptions.SO_KEEPALIVE) {
|
||||
return (T)getOption(SocketOptions.SO_KEEPALIVE);
|
||||
} else if (name == StandardSocketOptions.SO_SNDBUF) {
|
||||
return (T)getOption(SocketOptions.SO_SNDBUF);
|
||||
} else if (name == StandardSocketOptions.SO_RCVBUF) {
|
||||
return (T)getOption(SocketOptions.SO_RCVBUF);
|
||||
} else if (name == StandardSocketOptions.SO_REUSEADDR) {
|
||||
return (T)getOption(SocketOptions.SO_REUSEADDR);
|
||||
} else if (name == StandardSocketOptions.SO_LINGER) {
|
||||
return (T)getOption(SocketOptions.SO_LINGER);
|
||||
} else if (name == StandardSocketOptions.IP_TOS) {
|
||||
return (T)getOption(SocketOptions.IP_TOS);
|
||||
} else if (name == StandardSocketOptions.TCP_NODELAY) {
|
||||
return (T)getOption(SocketOptions.TCP_NODELAY);
|
||||
} else {
|
||||
throw new UnsupportedOperationException("unsupported option");
|
||||
}
|
||||
}
|
||||
}
|
||||
48
jdkSrc/jdk8/java/net/SocketImplFactory.java
Normal file
48
jdkSrc/jdk8/java/net/SocketImplFactory.java
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
/**
|
||||
* This interface defines a factory for socket implementations. It
|
||||
* is used by the classes {@code Socket} and
|
||||
* {@code ServerSocket} to create actual socket
|
||||
* implementations.
|
||||
*
|
||||
* @author Arthur van Hoff
|
||||
* @see java.net.Socket
|
||||
* @see java.net.ServerSocket
|
||||
* @since JDK1.0
|
||||
*/
|
||||
public
|
||||
interface SocketImplFactory {
|
||||
/**
|
||||
* Creates a new {@code SocketImpl} instance.
|
||||
*
|
||||
* @return a new instance of {@code SocketImpl}.
|
||||
* @see java.net.SocketImpl
|
||||
*/
|
||||
SocketImpl createSocketImpl();
|
||||
}
|
||||
292
jdkSrc/jdk8/java/net/SocketInputStream.java
Normal file
292
jdkSrc/jdk8/java/net/SocketInputStream.java
Normal file
@@ -0,0 +1,292 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.channels.FileChannel;
|
||||
|
||||
import sun.net.ConnectionResetException;
|
||||
|
||||
/**
|
||||
* This stream extends FileInputStream to implement a
|
||||
* SocketInputStream. Note that this class should <b>NOT</b> be
|
||||
* public.
|
||||
*
|
||||
* @author Jonathan Payne
|
||||
* @author Arthur van Hoff
|
||||
*/
|
||||
class SocketInputStream extends FileInputStream
|
||||
{
|
||||
static {
|
||||
init();
|
||||
}
|
||||
|
||||
private boolean eof;
|
||||
private AbstractPlainSocketImpl impl = null;
|
||||
private byte temp[];
|
||||
private Socket socket = null;
|
||||
|
||||
/**
|
||||
* Creates a new SocketInputStream. Can only be called
|
||||
* by a Socket. This method needs to hang on to the owner Socket so
|
||||
* that the fd will not be closed.
|
||||
* @param impl the implemented socket input stream
|
||||
*/
|
||||
SocketInputStream(AbstractPlainSocketImpl impl) throws IOException {
|
||||
super(impl.getFileDescriptor());
|
||||
this.impl = impl;
|
||||
socket = impl.getSocket();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the unique {@link java.nio.channels.FileChannel FileChannel}
|
||||
* object associated with this file input stream.</p>
|
||||
*
|
||||
* The {@code getChannel} method of {@code SocketInputStream}
|
||||
* returns {@code null} since it is a socket based stream.</p>
|
||||
*
|
||||
* @return the file channel associated with this file input stream
|
||||
*
|
||||
* @since 1.4
|
||||
* @spec JSR-51
|
||||
*/
|
||||
public final FileChannel getChannel() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads into an array of bytes at the specified offset using
|
||||
* the received socket primitive.
|
||||
* @param fd the FileDescriptor
|
||||
* @param b the buffer into which the data is read
|
||||
* @param off the start offset of the data
|
||||
* @param len the maximum number of bytes read
|
||||
* @param timeout the read timeout in ms
|
||||
* @return the actual number of bytes read, -1 is
|
||||
* returned when the end of the stream is reached.
|
||||
* @exception IOException If an I/O error has occurred.
|
||||
*/
|
||||
private native int socketRead0(FileDescriptor fd,
|
||||
byte b[], int off, int len,
|
||||
int timeout)
|
||||
throws IOException;
|
||||
|
||||
// wrap native call to allow instrumentation
|
||||
/**
|
||||
* Reads into an array of bytes at the specified offset using
|
||||
* the received socket primitive.
|
||||
* @param fd the FileDescriptor
|
||||
* @param b the buffer into which the data is read
|
||||
* @param off the start offset of the data
|
||||
* @param len the maximum number of bytes read
|
||||
* @param timeout the read timeout in ms
|
||||
* @return the actual number of bytes read, -1 is
|
||||
* returned when the end of the stream is reached.
|
||||
* @exception IOException If an I/O error has occurred.
|
||||
*/
|
||||
private int socketRead(FileDescriptor fd,
|
||||
byte b[], int off, int len,
|
||||
int timeout)
|
||||
throws IOException {
|
||||
return socketRead0(fd, b, off, len, timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads into a byte array data from the socket.
|
||||
* @param b the buffer into which the data is read
|
||||
* @return the actual number of bytes read, -1 is
|
||||
* returned when the end of the stream is reached.
|
||||
* @exception IOException If an I/O error has occurred.
|
||||
*/
|
||||
public int read(byte b[]) throws IOException {
|
||||
return read(b, 0, b.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads into a byte array <i>b</i> at offset <i>off</i>,
|
||||
* <i>length</i> bytes of data.
|
||||
* @param b the buffer into which the data is read
|
||||
* @param off the start offset of the data
|
||||
* @param length the maximum number of bytes read
|
||||
* @return the actual number of bytes read, -1 is
|
||||
* returned when the end of the stream is reached.
|
||||
* @exception IOException If an I/O error has occurred.
|
||||
*/
|
||||
public int read(byte b[], int off, int length) throws IOException {
|
||||
return read(b, off, length, impl.getTimeout());
|
||||
}
|
||||
|
||||
int read(byte b[], int off, int length, int timeout) throws IOException {
|
||||
int n;
|
||||
|
||||
// EOF already encountered
|
||||
if (eof) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// connection reset
|
||||
if (impl.isConnectionReset()) {
|
||||
throw new SocketException("Connection reset");
|
||||
}
|
||||
|
||||
// bounds check
|
||||
if (length <= 0 || off < 0 || length > b.length - off) {
|
||||
if (length == 0) {
|
||||
return 0;
|
||||
}
|
||||
throw new ArrayIndexOutOfBoundsException("length == " + length
|
||||
+ " off == " + off + " buffer length == " + b.length);
|
||||
}
|
||||
|
||||
boolean gotReset = false;
|
||||
|
||||
// acquire file descriptor and do the read
|
||||
FileDescriptor fd = impl.acquireFD();
|
||||
try {
|
||||
n = socketRead(fd, b, off, length, timeout);
|
||||
if (n > 0) {
|
||||
return n;
|
||||
}
|
||||
} catch (ConnectionResetException rstExc) {
|
||||
gotReset = true;
|
||||
} finally {
|
||||
impl.releaseFD();
|
||||
}
|
||||
|
||||
/*
|
||||
* We receive a "connection reset" but there may be bytes still
|
||||
* buffered on the socket
|
||||
*/
|
||||
if (gotReset) {
|
||||
impl.setConnectionResetPending();
|
||||
impl.acquireFD();
|
||||
try {
|
||||
n = socketRead(fd, b, off, length, timeout);
|
||||
if (n > 0) {
|
||||
return n;
|
||||
}
|
||||
} catch (ConnectionResetException rstExc) {
|
||||
} finally {
|
||||
impl.releaseFD();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If we get here we are at EOF, the socket has been closed,
|
||||
* or the connection has been reset.
|
||||
*/
|
||||
if (impl.isClosedOrPending()) {
|
||||
throw new SocketException("Socket closed");
|
||||
}
|
||||
if (impl.isConnectionResetPending()) {
|
||||
impl.setConnectionReset();
|
||||
}
|
||||
if (impl.isConnectionReset()) {
|
||||
throw new SocketException("Connection reset");
|
||||
}
|
||||
eof = true;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a single byte from the socket.
|
||||
*/
|
||||
public int read() throws IOException {
|
||||
if (eof) {
|
||||
return -1;
|
||||
}
|
||||
temp = new byte[1];
|
||||
int n = read(temp, 0, 1);
|
||||
if (n <= 0) {
|
||||
return -1;
|
||||
}
|
||||
return temp[0] & 0xff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skips n bytes of input.
|
||||
* @param numbytes the number of bytes to skip
|
||||
* @return the actual number of bytes skipped.
|
||||
* @exception IOException If an I/O error has occurred.
|
||||
*/
|
||||
public long skip(long numbytes) throws IOException {
|
||||
if (numbytes <= 0) {
|
||||
return 0;
|
||||
}
|
||||
long n = numbytes;
|
||||
int buflen = (int) Math.min(1024, n);
|
||||
byte data[] = new byte[buflen];
|
||||
while (n > 0) {
|
||||
int r = read(data, 0, (int) Math.min((long) buflen, n));
|
||||
if (r < 0) {
|
||||
break;
|
||||
}
|
||||
n -= r;
|
||||
}
|
||||
return numbytes - n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of bytes that can be read without blocking.
|
||||
* @return the number of immediately available bytes
|
||||
*/
|
||||
public int available() throws IOException {
|
||||
return impl.available();
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the stream.
|
||||
*/
|
||||
private boolean closing = false;
|
||||
public void close() throws IOException {
|
||||
// Prevent recursion. See BugId 4484411
|
||||
if (closing)
|
||||
return;
|
||||
closing = true;
|
||||
if (socket != null) {
|
||||
if (!socket.isClosed())
|
||||
socket.close();
|
||||
} else
|
||||
impl.close();
|
||||
closing = false;
|
||||
}
|
||||
|
||||
void setEOF(boolean eof) {
|
||||
this.eof = eof;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides finalize, the fd is closed by the Socket.
|
||||
*/
|
||||
protected void finalize() {}
|
||||
|
||||
/**
|
||||
* Perform class load-time initializations.
|
||||
*/
|
||||
private native static void init();
|
||||
}
|
||||
59
jdkSrc/jdk8/java/net/SocketOption.java
Normal file
59
jdkSrc/jdk8/java/net/SocketOption.java
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
/**
|
||||
* A socket option associated with a socket.
|
||||
*
|
||||
* <p> In the {@link java.nio.channels channels} package, the {@link
|
||||
* java.nio.channels.NetworkChannel} interface defines the {@link
|
||||
* java.nio.channels.NetworkChannel#setOption(SocketOption,Object) setOption}
|
||||
* and {@link java.nio.channels.NetworkChannel#getOption(SocketOption) getOption}
|
||||
* methods to set and query the channel's socket options.
|
||||
*
|
||||
* @param <T> The type of the socket option value.
|
||||
*
|
||||
* @since 1.7
|
||||
*
|
||||
* @see StandardSocketOptions
|
||||
*/
|
||||
|
||||
public interface SocketOption<T> {
|
||||
|
||||
/**
|
||||
* Returns the name of the socket option.
|
||||
*
|
||||
* @return the name of the socket option
|
||||
*/
|
||||
String name();
|
||||
|
||||
/**
|
||||
* Returns the type of the socket option value.
|
||||
*
|
||||
* @return the type of the socket option value
|
||||
*/
|
||||
Class<T> type();
|
||||
}
|
||||
331
jdkSrc/jdk8/java/net/SocketOptions.java
Normal file
331
jdkSrc/jdk8/java/net/SocketOptions.java
Normal file
@@ -0,0 +1,331 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
import java.lang.annotation.Native;
|
||||
|
||||
/**
|
||||
* Interface of methods to get/set socket options. This interface is
|
||||
* implemented by: <B>SocketImpl</B> and <B>DatagramSocketImpl</B>.
|
||||
* Subclasses of these should override the methods
|
||||
* of this interface in order to support their own options.
|
||||
* <P>
|
||||
* The methods and constants which specify options in this interface are
|
||||
* for implementation only. If you're not subclassing SocketImpl or
|
||||
* DatagramSocketImpl, <B>you won't use these directly.</B> There are
|
||||
* type-safe methods to get/set each of these options in Socket, ServerSocket,
|
||||
* DatagramSocket and MulticastSocket.
|
||||
* <P>
|
||||
* @author David Brown
|
||||
*/
|
||||
|
||||
|
||||
public interface SocketOptions {
|
||||
|
||||
/**
|
||||
* Enable/disable the option specified by <I>optID</I>. If the option
|
||||
* is to be enabled, and it takes an option-specific "value", this is
|
||||
* passed in <I>value</I>. The actual type of value is option-specific,
|
||||
* and it is an error to pass something that isn't of the expected type:
|
||||
* <BR><PRE>
|
||||
* SocketImpl s;
|
||||
* ...
|
||||
* s.setOption(SO_LINGER, new Integer(10));
|
||||
* // OK - set SO_LINGER w/ timeout of 10 sec.
|
||||
* s.setOption(SO_LINGER, new Double(10));
|
||||
* // ERROR - expects java.lang.Integer
|
||||
*</PRE>
|
||||
* If the requested option is binary, it can be set using this method by
|
||||
* a java.lang.Boolean:
|
||||
* <BR><PRE>
|
||||
* s.setOption(TCP_NODELAY, new Boolean(true));
|
||||
* // OK - enables TCP_NODELAY, a binary option
|
||||
* </PRE>
|
||||
* <BR>
|
||||
* Any option can be disabled using this method with a Boolean(false):
|
||||
* <BR><PRE>
|
||||
* s.setOption(TCP_NODELAY, new Boolean(false));
|
||||
* // OK - disables TCP_NODELAY
|
||||
* s.setOption(SO_LINGER, new Boolean(false));
|
||||
* // OK - disables SO_LINGER
|
||||
* </PRE>
|
||||
* <BR>
|
||||
* For an option that has a notion of on and off, and requires
|
||||
* a non-boolean parameter, setting its value to anything other than
|
||||
* <I>Boolean(false)</I> implicitly enables it.
|
||||
* <BR>
|
||||
* Throws SocketException if the option is unrecognized,
|
||||
* the socket is closed, or some low-level error occurred
|
||||
* <BR>
|
||||
* @param optID identifies the option
|
||||
* @param value the parameter of the socket option
|
||||
* @throws SocketException if the option is unrecognized,
|
||||
* the socket is closed, or some low-level error occurred
|
||||
* @see #getOption(int)
|
||||
*/
|
||||
public void
|
||||
setOption(int optID, Object value) throws SocketException;
|
||||
|
||||
/**
|
||||
* Fetch the value of an option.
|
||||
* Binary options will return java.lang.Boolean(true)
|
||||
* if enabled, java.lang.Boolean(false) if disabled, e.g.:
|
||||
* <BR><PRE>
|
||||
* SocketImpl s;
|
||||
* ...
|
||||
* Boolean noDelay = (Boolean)(s.getOption(TCP_NODELAY));
|
||||
* if (noDelay.booleanValue()) {
|
||||
* // true if TCP_NODELAY is enabled...
|
||||
* ...
|
||||
* }
|
||||
* </PRE>
|
||||
* <P>
|
||||
* For options that take a particular type as a parameter,
|
||||
* getOption(int) will return the parameter's value, else
|
||||
* it will return java.lang.Boolean(false):
|
||||
* <PRE>
|
||||
* Object o = s.getOption(SO_LINGER);
|
||||
* if (o instanceof Integer) {
|
||||
* System.out.print("Linger time is " + ((Integer)o).intValue());
|
||||
* } else {
|
||||
* // the true type of o is java.lang.Boolean(false);
|
||||
* }
|
||||
* </PRE>
|
||||
*
|
||||
* @param optID an {@code int} identifying the option to fetch
|
||||
* @return the value of the option
|
||||
* @throws SocketException if the socket is closed
|
||||
* @throws SocketException if <I>optID</I> is unknown along the
|
||||
* protocol stack (including the SocketImpl)
|
||||
* @see #setOption(int, java.lang.Object)
|
||||
*/
|
||||
public Object getOption(int optID) throws SocketException;
|
||||
|
||||
/**
|
||||
* The java-supported BSD-style options.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Disable Nagle's algorithm for this connection. Written data
|
||||
* to the network is not buffered pending acknowledgement of
|
||||
* previously written data.
|
||||
*<P>
|
||||
* Valid for TCP only: SocketImpl.
|
||||
*
|
||||
* @see Socket#setTcpNoDelay
|
||||
* @see Socket#getTcpNoDelay
|
||||
*/
|
||||
|
||||
@Native public final static int TCP_NODELAY = 0x0001;
|
||||
|
||||
/**
|
||||
* Fetch the local address binding of a socket (this option cannot
|
||||
* be "set" only "gotten", since sockets are bound at creation time,
|
||||
* and so the locally bound address cannot be changed). The default local
|
||||
* address of a socket is INADDR_ANY, meaning any local address on a
|
||||
* multi-homed host. A multi-homed host can use this option to accept
|
||||
* connections to only one of its addresses (in the case of a
|
||||
* ServerSocket or DatagramSocket), or to specify its return address
|
||||
* to the peer (for a Socket or DatagramSocket). The parameter of
|
||||
* this option is an InetAddress.
|
||||
* <P>
|
||||
* This option <B>must</B> be specified in the constructor.
|
||||
* <P>
|
||||
* Valid for: SocketImpl, DatagramSocketImpl
|
||||
*
|
||||
* @see Socket#getLocalAddress
|
||||
* @see DatagramSocket#getLocalAddress
|
||||
*/
|
||||
|
||||
@Native public final static int SO_BINDADDR = 0x000F;
|
||||
|
||||
/** Sets SO_REUSEADDR for a socket. This is used only for MulticastSockets
|
||||
* in java, and it is set by default for MulticastSockets.
|
||||
* <P>
|
||||
* Valid for: DatagramSocketImpl
|
||||
*/
|
||||
|
||||
@Native public final static int SO_REUSEADDR = 0x04;
|
||||
|
||||
/**
|
||||
* Sets SO_BROADCAST for a socket. This option enables and disables
|
||||
* the ability of the process to send broadcast messages. It is supported
|
||||
* for only datagram sockets and only on networks that support
|
||||
* the concept of a broadcast message (e.g. Ethernet, token ring, etc.),
|
||||
* and it is set by default for DatagramSockets.
|
||||
* @since 1.4
|
||||
*/
|
||||
|
||||
@Native public final static int SO_BROADCAST = 0x0020;
|
||||
|
||||
/** Set which outgoing interface on which to send multicast packets.
|
||||
* Useful on hosts with multiple network interfaces, where applications
|
||||
* want to use other than the system default. Takes/returns an InetAddress.
|
||||
* <P>
|
||||
* Valid for Multicast: DatagramSocketImpl
|
||||
*
|
||||
* @see MulticastSocket#setInterface(InetAddress)
|
||||
* @see MulticastSocket#getInterface()
|
||||
*/
|
||||
|
||||
@Native public final static int IP_MULTICAST_IF = 0x10;
|
||||
|
||||
/** Same as above. This option is introduced so that the behaviour
|
||||
* with IP_MULTICAST_IF will be kept the same as before, while
|
||||
* this new option can support setting outgoing interfaces with either
|
||||
* IPv4 and IPv6 addresses.
|
||||
*
|
||||
* NOTE: make sure there is no conflict with this
|
||||
* @see MulticastSocket#setNetworkInterface(NetworkInterface)
|
||||
* @see MulticastSocket#getNetworkInterface()
|
||||
* @since 1.4
|
||||
*/
|
||||
@Native public final static int IP_MULTICAST_IF2 = 0x1f;
|
||||
|
||||
/**
|
||||
* This option enables or disables local loopback of multicast datagrams.
|
||||
* This option is enabled by default for Multicast Sockets.
|
||||
* @since 1.4
|
||||
*/
|
||||
|
||||
@Native public final static int IP_MULTICAST_LOOP = 0x12;
|
||||
|
||||
/**
|
||||
* This option sets the type-of-service or traffic class field
|
||||
* in the IP header for a TCP or UDP socket.
|
||||
* @since 1.4
|
||||
*/
|
||||
|
||||
@Native public final static int IP_TOS = 0x3;
|
||||
|
||||
/**
|
||||
* Specify a linger-on-close timeout. This option disables/enables
|
||||
* immediate return from a <B>close()</B> of a TCP Socket. Enabling
|
||||
* this option with a non-zero Integer <I>timeout</I> means that a
|
||||
* <B>close()</B> will block pending the transmission and acknowledgement
|
||||
* of all data written to the peer, at which point the socket is closed
|
||||
* <I>gracefully</I>. Upon reaching the linger timeout, the socket is
|
||||
* closed <I>forcefully</I>, with a TCP RST. Enabling the option with a
|
||||
* timeout of zero does a forceful close immediately. If the specified
|
||||
* timeout value exceeds 65,535 it will be reduced to 65,535.
|
||||
* <P>
|
||||
* Valid only for TCP: SocketImpl
|
||||
*
|
||||
* @see Socket#setSoLinger
|
||||
* @see Socket#getSoLinger
|
||||
*/
|
||||
@Native public final static int SO_LINGER = 0x0080;
|
||||
|
||||
/** Set a timeout on blocking Socket operations:
|
||||
* <PRE>
|
||||
* ServerSocket.accept();
|
||||
* SocketInputStream.read();
|
||||
* DatagramSocket.receive();
|
||||
* </PRE>
|
||||
*
|
||||
* <P> The option must be set prior to entering a blocking
|
||||
* operation to take effect. If the timeout expires and the
|
||||
* operation would continue to block,
|
||||
* <B>java.io.InterruptedIOException</B> is raised. The Socket is
|
||||
* not closed in this case.
|
||||
*
|
||||
* <P> Valid for all sockets: SocketImpl, DatagramSocketImpl
|
||||
*
|
||||
* @see Socket#setSoTimeout
|
||||
* @see ServerSocket#setSoTimeout
|
||||
* @see DatagramSocket#setSoTimeout
|
||||
*/
|
||||
@Native public final static int SO_TIMEOUT = 0x1006;
|
||||
|
||||
/**
|
||||
* Set a hint the size of the underlying buffers used by the
|
||||
* platform for outgoing network I/O. When used in set, this is a
|
||||
* suggestion to the kernel from the application about the size of
|
||||
* buffers to use for the data to be sent over the socket. When
|
||||
* used in get, this must return the size of the buffer actually
|
||||
* used by the platform when sending out data on this socket.
|
||||
*
|
||||
* Valid for all sockets: SocketImpl, DatagramSocketImpl
|
||||
*
|
||||
* @see Socket#setSendBufferSize
|
||||
* @see Socket#getSendBufferSize
|
||||
* @see DatagramSocket#setSendBufferSize
|
||||
* @see DatagramSocket#getSendBufferSize
|
||||
*/
|
||||
@Native public final static int SO_SNDBUF = 0x1001;
|
||||
|
||||
/**
|
||||
* Set a hint the size of the underlying buffers used by the
|
||||
* platform for incoming network I/O. When used in set, this is a
|
||||
* suggestion to the kernel from the application about the size of
|
||||
* buffers to use for the data to be received over the
|
||||
* socket. When used in get, this must return the size of the
|
||||
* buffer actually used by the platform when receiving in data on
|
||||
* this socket.
|
||||
*
|
||||
* Valid for all sockets: SocketImpl, DatagramSocketImpl
|
||||
*
|
||||
* @see Socket#setReceiveBufferSize
|
||||
* @see Socket#getReceiveBufferSize
|
||||
* @see DatagramSocket#setReceiveBufferSize
|
||||
* @see DatagramSocket#getReceiveBufferSize
|
||||
*/
|
||||
@Native public final static int SO_RCVBUF = 0x1002;
|
||||
|
||||
/**
|
||||
* When the keepalive option is set for a TCP socket and no data
|
||||
* has been exchanged across the socket in either direction for
|
||||
* 2 hours (NOTE: the actual value is implementation dependent),
|
||||
* TCP automatically sends a keepalive probe to the peer. This probe is a
|
||||
* TCP segment to which the peer must respond.
|
||||
* One of three responses is expected:
|
||||
* 1. The peer responds with the expected ACK. The application is not
|
||||
* notified (since everything is OK). TCP will send another probe
|
||||
* following another 2 hours of inactivity.
|
||||
* 2. The peer responds with an RST, which tells the local TCP that
|
||||
* the peer host has crashed and rebooted. The socket is closed.
|
||||
* 3. There is no response from the peer. The socket is closed.
|
||||
*
|
||||
* The purpose of this option is to detect if the peer host crashes.
|
||||
*
|
||||
* Valid only for TCP socket: SocketImpl
|
||||
*
|
||||
* @see Socket#setKeepAlive
|
||||
* @see Socket#getKeepAlive
|
||||
*/
|
||||
@Native public final static int SO_KEEPALIVE = 0x0008;
|
||||
|
||||
/**
|
||||
* When the OOBINLINE option is set, any TCP urgent data received on
|
||||
* the socket will be received through the socket input stream.
|
||||
* When the option is disabled (which is the default) urgent data
|
||||
* is silently discarded.
|
||||
*
|
||||
* @see Socket#setOOBInline
|
||||
* @see Socket#getOOBInline
|
||||
*/
|
||||
@Native public final static int SO_OOBINLINE = 0x1003;
|
||||
}
|
||||
185
jdkSrc/jdk8/java/net/SocketOutputStream.java
Normal file
185
jdkSrc/jdk8/java/net/SocketOutputStream.java
Normal file
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.channels.FileChannel;
|
||||
|
||||
/**
|
||||
* This stream extends FileOutputStream to implement a
|
||||
* SocketOutputStream. Note that this class should <b>NOT</b> be
|
||||
* public.
|
||||
*
|
||||
* @author Jonathan Payne
|
||||
* @author Arthur van Hoff
|
||||
*/
|
||||
class SocketOutputStream extends FileOutputStream
|
||||
{
|
||||
static {
|
||||
init();
|
||||
}
|
||||
|
||||
private AbstractPlainSocketImpl impl = null;
|
||||
private byte temp[] = new byte[1];
|
||||
private Socket socket = null;
|
||||
|
||||
/**
|
||||
* Creates a new SocketOutputStream. Can only be called
|
||||
* by a Socket. This method needs to hang on to the owner Socket so
|
||||
* that the fd will not be closed.
|
||||
* @param impl the socket output stream inplemented
|
||||
*/
|
||||
SocketOutputStream(AbstractPlainSocketImpl impl) throws IOException {
|
||||
super(impl.getFileDescriptor());
|
||||
this.impl = impl;
|
||||
socket = impl.getSocket();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the unique {@link java.nio.channels.FileChannel FileChannel}
|
||||
* object associated with this file output stream. </p>
|
||||
*
|
||||
* The {@code getChannel} method of {@code SocketOutputStream}
|
||||
* returns {@code null} since it is a socket based stream.</p>
|
||||
*
|
||||
* @return the file channel associated with this file output stream
|
||||
*
|
||||
* @since 1.4
|
||||
* @spec JSR-51
|
||||
*/
|
||||
public final FileChannel getChannel() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes to the socket.
|
||||
* @param fd the FileDescriptor
|
||||
* @param b the data to be written
|
||||
* @param off the start offset in the data
|
||||
* @param len the number of bytes that are written
|
||||
* @exception IOException If an I/O error has occurred.
|
||||
*/
|
||||
private native void socketWrite0(FileDescriptor fd, byte[] b, int off,
|
||||
int len) throws IOException;
|
||||
|
||||
/**
|
||||
* Writes to the socket with appropriate locking of the
|
||||
* FileDescriptor.
|
||||
* @param b the data to be written
|
||||
* @param off the start offset in the data
|
||||
* @param len the number of bytes that are written
|
||||
* @exception IOException If an I/O error has occurred.
|
||||
*/
|
||||
private void socketWrite(byte b[], int off, int len) throws IOException {
|
||||
|
||||
|
||||
if (len <= 0 || off < 0 || len > b.length - off) {
|
||||
if (len == 0) {
|
||||
return;
|
||||
}
|
||||
throw new ArrayIndexOutOfBoundsException("len == " + len
|
||||
+ " off == " + off + " buffer length == " + b.length);
|
||||
}
|
||||
|
||||
FileDescriptor fd = impl.acquireFD();
|
||||
try {
|
||||
socketWrite0(fd, b, off, len);
|
||||
} catch (SocketException se) {
|
||||
if (se instanceof sun.net.ConnectionResetException) {
|
||||
impl.setConnectionResetPending();
|
||||
se = new SocketException("Connection reset");
|
||||
}
|
||||
if (impl.isClosedOrPending()) {
|
||||
throw new SocketException("Socket closed");
|
||||
} else {
|
||||
throw se;
|
||||
}
|
||||
} finally {
|
||||
impl.releaseFD();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a byte to the socket.
|
||||
* @param b the data to be written
|
||||
* @exception IOException If an I/O error has occurred.
|
||||
*/
|
||||
public void write(int b) throws IOException {
|
||||
temp[0] = (byte)b;
|
||||
socketWrite(temp, 0, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the contents of the buffer <i>b</i> to the socket.
|
||||
* @param b the data to be written
|
||||
* @exception SocketException If an I/O error has occurred.
|
||||
*/
|
||||
public void write(byte b[]) throws IOException {
|
||||
socketWrite(b, 0, b.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes <i>length</i> bytes from buffer <i>b</i> starting at
|
||||
* offset <i>len</i>.
|
||||
* @param b the data to be written
|
||||
* @param off the start offset in the data
|
||||
* @param len the number of bytes that are written
|
||||
* @exception SocketException If an I/O error has occurred.
|
||||
*/
|
||||
public void write(byte b[], int off, int len) throws IOException {
|
||||
socketWrite(b, off, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the stream.
|
||||
*/
|
||||
private boolean closing = false;
|
||||
public void close() throws IOException {
|
||||
// Prevent recursion. See BugId 4484411
|
||||
if (closing)
|
||||
return;
|
||||
closing = true;
|
||||
if (socket != null) {
|
||||
if (!socket.isClosed())
|
||||
socket.close();
|
||||
} else
|
||||
impl.close();
|
||||
closing = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides finalize, the fd is closed by the Socket.
|
||||
*/
|
||||
protected void finalize() {}
|
||||
|
||||
/**
|
||||
* Perform class load-time initializations.
|
||||
*/
|
||||
private native static void init();
|
||||
|
||||
}
|
||||
1491
jdkSrc/jdk8/java/net/SocketPermission.java
Normal file
1491
jdkSrc/jdk8/java/net/SocketPermission.java
Normal file
File diff suppressed because it is too large
Load Diff
70
jdkSrc/jdk8/java/net/SocketSecrets.java
Normal file
70
jdkSrc/jdk8/java/net/SocketSecrets.java
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
class SocketSecrets {
|
||||
|
||||
/* accessed by reflection from jdk.net.Sockets */
|
||||
|
||||
/* obj must be a Socket or ServerSocket */
|
||||
|
||||
private static <T> void setOption(Object obj, SocketOption<T> name, T value) throws IOException {
|
||||
SocketImpl impl;
|
||||
|
||||
if (obj instanceof Socket) {
|
||||
impl = ((Socket)obj).getImpl();
|
||||
} else if (obj instanceof ServerSocket) {
|
||||
impl = ((ServerSocket)obj).getImpl();
|
||||
} else {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
impl.setOption(name, value);
|
||||
}
|
||||
|
||||
private static <T> T getOption(Object obj, SocketOption<T> name) throws IOException {
|
||||
SocketImpl impl;
|
||||
|
||||
if (obj instanceof Socket) {
|
||||
impl = ((Socket)obj).getImpl();
|
||||
} else if (obj instanceof ServerSocket) {
|
||||
impl = ((ServerSocket)obj).getImpl();
|
||||
} else {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
return impl.getOption(name);
|
||||
}
|
||||
|
||||
private static <T> void setOption(DatagramSocket s, SocketOption<T> name, T value) throws IOException {
|
||||
s.getImpl().setOption(name, value);
|
||||
}
|
||||
|
||||
private static <T> T getOption(DatagramSocket s, SocketOption<T> name) throws IOException {
|
||||
return s.getImpl().getOption(name);
|
||||
}
|
||||
|
||||
}
|
||||
50
jdkSrc/jdk8/java/net/SocketTimeoutException.java
Normal file
50
jdkSrc/jdk8/java/net/SocketTimeoutException.java
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
/**
|
||||
* Signals that a timeout has occurred on a socket read or accept.
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
|
||||
public class SocketTimeoutException extends java.io.InterruptedIOException {
|
||||
private static final long serialVersionUID = -8846654841826352300L;
|
||||
|
||||
/**
|
||||
* Constructs a new SocketTimeoutException with a detail
|
||||
* message.
|
||||
* @param msg the detail message
|
||||
*/
|
||||
public SocketTimeoutException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new SocketTimeoutException with no detailed message.
|
||||
*/
|
||||
public SocketTimeoutException() {}
|
||||
}
|
||||
58
jdkSrc/jdk8/java/net/SocksConsts.java
Normal file
58
jdkSrc/jdk8/java/net/SocksConsts.java
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package java.net;
|
||||
|
||||
/**
|
||||
* Constants used by the SOCKS protocol implementation.
|
||||
*/
|
||||
|
||||
interface SocksConsts {
|
||||
static final int PROTO_VERS4 = 4;
|
||||
static final int PROTO_VERS = 5;
|
||||
static final int DEFAULT_PORT = 1080;
|
||||
|
||||
static final int NO_AUTH = 0;
|
||||
static final int GSSAPI = 1;
|
||||
static final int USER_PASSW = 2;
|
||||
static final int NO_METHODS = -1;
|
||||
|
||||
static final int CONNECT = 1;
|
||||
static final int BIND = 2;
|
||||
static final int UDP_ASSOC = 3;
|
||||
|
||||
static final int IPV4 = 1;
|
||||
static final int DOMAIN_NAME = 3;
|
||||
static final int IPV6 = 4;
|
||||
|
||||
static final int REQUEST_OK = 0;
|
||||
static final int GENERAL_FAILURE = 1;
|
||||
static final int NOT_ALLOWED = 2;
|
||||
static final int NET_UNREACHABLE = 3;
|
||||
static final int HOST_UNREACHABLE = 4;
|
||||
static final int CONN_REFUSED = 5;
|
||||
static final int TTL_EXPIRED = 6;
|
||||
static final int CMD_NOT_SUPPORTED = 7;
|
||||
static final int ADDR_TYPE_NOT_SUP = 8;
|
||||
}
|
||||
1094
jdkSrc/jdk8/java/net/SocksSocketImpl.java
Normal file
1094
jdkSrc/jdk8/java/net/SocksSocketImpl.java
Normal file
File diff suppressed because it is too large
Load Diff
45
jdkSrc/jdk8/java/net/StandardProtocolFamily.java
Normal file
45
jdkSrc/jdk8/java/net/StandardProtocolFamily.java
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
/**
|
||||
* Defines the standard families of communication protocols.
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
|
||||
public enum StandardProtocolFamily implements ProtocolFamily {
|
||||
|
||||
/**
|
||||
* Internet Protocol Version 4 (IPv4)
|
||||
*/
|
||||
INET,
|
||||
|
||||
/**
|
||||
* Internet Protocol Version 6 (IPv6)
|
||||
*/
|
||||
INET6
|
||||
}
|
||||
367
jdkSrc/jdk8/java/net/StandardSocketOptions.java
Normal file
367
jdkSrc/jdk8/java/net/StandardSocketOptions.java
Normal file
@@ -0,0 +1,367 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
/**
|
||||
* Defines the <em>standard</em> socket options.
|
||||
*
|
||||
* <p> The {@link SocketOption#name name} of each socket option defined by this
|
||||
* class is its field name.
|
||||
*
|
||||
* <p> In this release, the socket options defined here are used by {@link
|
||||
* java.nio.channels.NetworkChannel network} channels in the {@link
|
||||
* java.nio.channels channels} package.
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
|
||||
public final class StandardSocketOptions {
|
||||
private StandardSocketOptions() { }
|
||||
|
||||
// -- SOL_SOCKET --
|
||||
|
||||
/**
|
||||
* Allow transmission of broadcast datagrams.
|
||||
*
|
||||
* <p> The value of this socket option is a {@code Boolean} that represents
|
||||
* whether the option is enabled or disabled. The option is specific to
|
||||
* datagram-oriented sockets sending to {@link java.net.Inet4Address IPv4}
|
||||
* broadcast addresses. When the socket option is enabled then the socket
|
||||
* can be used to send <em>broadcast datagrams</em>.
|
||||
*
|
||||
* <p> The initial value of this socket option is {@code FALSE}. The socket
|
||||
* option may be enabled or disabled at any time. Some operating systems may
|
||||
* require that the Java virtual machine be started with implementation
|
||||
* specific privileges to enable this option or send broadcast datagrams.
|
||||
*
|
||||
* @see <a href="http://www.ietf.org/rfc/rfc919.txt">RFC 929:
|
||||
* Broadcasting Internet Datagrams</a>
|
||||
* @see DatagramSocket#setBroadcast
|
||||
*/
|
||||
public static final SocketOption<Boolean> SO_BROADCAST =
|
||||
new StdSocketOption<Boolean>("SO_BROADCAST", Boolean.class);
|
||||
|
||||
/**
|
||||
* Keep connection alive.
|
||||
*
|
||||
* <p> The value of this socket option is a {@code Boolean} that represents
|
||||
* whether the option is enabled or disabled. When the {@code SO_KEEPALIVE}
|
||||
* option is enabled the operating system may use a <em>keep-alive</em>
|
||||
* mechanism to periodically probe the other end of a connection when the
|
||||
* connection is otherwise idle. The exact semantics of the keep alive
|
||||
* mechanism is system dependent and therefore unspecified.
|
||||
*
|
||||
* <p> The initial value of this socket option is {@code FALSE}. The socket
|
||||
* option may be enabled or disabled at any time.
|
||||
*
|
||||
* @see <a href="http://www.ietf.org/rfc/rfc1122.txt">RFC 1122
|
||||
* Requirements for Internet Hosts -- Communication Layers</a>
|
||||
* @see Socket#setKeepAlive
|
||||
*/
|
||||
public static final SocketOption<Boolean> SO_KEEPALIVE =
|
||||
new StdSocketOption<Boolean>("SO_KEEPALIVE", Boolean.class);
|
||||
|
||||
/**
|
||||
* The size of the socket send buffer.
|
||||
*
|
||||
* <p> The value of this socket option is an {@code Integer} that is the
|
||||
* size of the socket send buffer in bytes. The socket send buffer is an
|
||||
* output buffer used by the networking implementation. It may need to be
|
||||
* increased for high-volume connections. The value of the socket option is
|
||||
* a <em>hint</em> to the implementation to size the buffer and the actual
|
||||
* size may differ. The socket option can be queried to retrieve the actual
|
||||
* size.
|
||||
*
|
||||
* <p> For datagram-oriented sockets, the size of the send buffer may limit
|
||||
* the size of the datagrams that may be sent by the socket. Whether
|
||||
* datagrams larger than the buffer size are sent or discarded is system
|
||||
* dependent.
|
||||
*
|
||||
* <p> The initial/default size of the socket send buffer and the range of
|
||||
* allowable values is system dependent although a negative size is not
|
||||
* allowed. An attempt to set the socket send buffer to larger than its
|
||||
* maximum size causes it to be set to its maximum size.
|
||||
*
|
||||
* <p> An implementation allows this socket option to be set before the
|
||||
* socket is bound or connected. Whether an implementation allows the
|
||||
* socket send buffer to be changed after the socket is bound is system
|
||||
* dependent.
|
||||
*
|
||||
* @see Socket#setSendBufferSize
|
||||
*/
|
||||
public static final SocketOption<Integer> SO_SNDBUF =
|
||||
new StdSocketOption<Integer>("SO_SNDBUF", Integer.class);
|
||||
|
||||
|
||||
/**
|
||||
* The size of the socket receive buffer.
|
||||
*
|
||||
* <p> The value of this socket option is an {@code Integer} that is the
|
||||
* size of the socket receive buffer in bytes. The socket receive buffer is
|
||||
* an input buffer used by the networking implementation. It may need to be
|
||||
* increased for high-volume connections or decreased to limit the possible
|
||||
* backlog of incoming data. The value of the socket option is a
|
||||
* <em>hint</em> to the implementation to size the buffer and the actual
|
||||
* size may differ.
|
||||
*
|
||||
* <p> For datagram-oriented sockets, the size of the receive buffer may
|
||||
* limit the size of the datagrams that can be received. Whether datagrams
|
||||
* larger than the buffer size can be received is system dependent.
|
||||
* Increasing the socket receive buffer may be important for cases where
|
||||
* datagrams arrive in bursts faster than they can be processed.
|
||||
*
|
||||
* <p> In the case of stream-oriented sockets and the TCP/IP protocol, the
|
||||
* size of the socket receive buffer may be used when advertising the size
|
||||
* of the TCP receive window to the remote peer.
|
||||
*
|
||||
* <p> The initial/default size of the socket receive buffer and the range
|
||||
* of allowable values is system dependent although a negative size is not
|
||||
* allowed. An attempt to set the socket receive buffer to larger than its
|
||||
* maximum size causes it to be set to its maximum size.
|
||||
*
|
||||
* <p> An implementation allows this socket option to be set before the
|
||||
* socket is bound or connected. Whether an implementation allows the
|
||||
* socket receive buffer to be changed after the socket is bound is system
|
||||
* dependent.
|
||||
*
|
||||
* @see <a href="http://www.ietf.org/rfc/rfc1323.txt">RFC 1323: TCP
|
||||
* Extensions for High Performance</a>
|
||||
* @see Socket#setReceiveBufferSize
|
||||
* @see ServerSocket#setReceiveBufferSize
|
||||
*/
|
||||
public static final SocketOption<Integer> SO_RCVBUF =
|
||||
new StdSocketOption<Integer>("SO_RCVBUF", Integer.class);
|
||||
|
||||
/**
|
||||
* Re-use address.
|
||||
*
|
||||
* <p> The value of this socket option is a {@code Boolean} that represents
|
||||
* whether the option is enabled or disabled. The exact semantics of this
|
||||
* socket option are socket type and system dependent.
|
||||
*
|
||||
* <p> In the case of stream-oriented sockets, this socket option will
|
||||
* usually determine whether the socket can be bound to a socket address
|
||||
* when a previous connection involving that socket address is in the
|
||||
* <em>TIME_WAIT</em> state. On implementations where the semantics differ,
|
||||
* and the socket option is not required to be enabled in order to bind the
|
||||
* socket when a previous connection is in this state, then the
|
||||
* implementation may choose to ignore this option.
|
||||
*
|
||||
* <p> For datagram-oriented sockets the socket option is used to allow
|
||||
* multiple programs bind to the same address. This option should be enabled
|
||||
* when the socket is to be used for Internet Protocol (IP) multicasting.
|
||||
*
|
||||
* <p> An implementation allows this socket option to be set before the
|
||||
* socket is bound or connected. Changing the value of this socket option
|
||||
* after the socket is bound has no effect. The default value of this
|
||||
* socket option is system dependent.
|
||||
*
|
||||
* @see <a href="http://www.ietf.org/rfc/rfc793.txt">RFC 793: Transmission
|
||||
* Control Protocol</a>
|
||||
* @see ServerSocket#setReuseAddress
|
||||
*/
|
||||
public static final SocketOption<Boolean> SO_REUSEADDR =
|
||||
new StdSocketOption<Boolean>("SO_REUSEADDR", Boolean.class);
|
||||
|
||||
/**
|
||||
* Linger on close if data is present.
|
||||
*
|
||||
* <p> The value of this socket option is an {@code Integer} that controls
|
||||
* the action taken when unsent data is queued on the socket and a method
|
||||
* to close the socket is invoked. If the value of the socket option is zero
|
||||
* or greater, then it represents a timeout value, in seconds, known as the
|
||||
* <em>linger interval</em>. The linger interval is the timeout for the
|
||||
* {@code close} method to block while the operating system attempts to
|
||||
* transmit the unsent data or it decides that it is unable to transmit the
|
||||
* data. If the value of the socket option is less than zero then the option
|
||||
* is disabled. In that case the {@code close} method does not wait until
|
||||
* unsent data is transmitted; if possible the operating system will transmit
|
||||
* any unsent data before the connection is closed.
|
||||
*
|
||||
* <p> This socket option is intended for use with sockets that are configured
|
||||
* in {@link java.nio.channels.SelectableChannel#isBlocking() blocking} mode
|
||||
* only. The behavior of the {@code close} method when this option is
|
||||
* enabled on a non-blocking socket is not defined.
|
||||
*
|
||||
* <p> The initial value of this socket option is a negative value, meaning
|
||||
* that the option is disabled. The option may be enabled, or the linger
|
||||
* interval changed, at any time. The maximum value of the linger interval
|
||||
* is system dependent. Setting the linger interval to a value that is
|
||||
* greater than its maximum value causes the linger interval to be set to
|
||||
* its maximum value.
|
||||
*
|
||||
* @see Socket#setSoLinger
|
||||
*/
|
||||
public static final SocketOption<Integer> SO_LINGER =
|
||||
new StdSocketOption<Integer>("SO_LINGER", Integer.class);
|
||||
|
||||
|
||||
// -- IPPROTO_IP --
|
||||
|
||||
/**
|
||||
* The Type of Service (ToS) octet in the Internet Protocol (IP) header.
|
||||
*
|
||||
* <p> The value of this socket option is an {@code Integer} representing
|
||||
* the value of the ToS octet in IP packets sent by sockets to an {@link
|
||||
* StandardProtocolFamily#INET IPv4} socket. The interpretation of the ToS
|
||||
* octet is network specific and is not defined by this class. Further
|
||||
* information on the ToS octet can be found in <a
|
||||
* href="http://www.ietf.org/rfc/rfc1349.txt">RFC 1349</a> and <a
|
||||
* href="http://www.ietf.org/rfc/rfc2474.txt">RFC 2474</a>. The value
|
||||
* of the socket option is a <em>hint</em>. An implementation may ignore the
|
||||
* value, or ignore specific values.
|
||||
*
|
||||
* <p> The initial/default value of the TOS field in the ToS octet is
|
||||
* implementation specific but will typically be {@code 0}. For
|
||||
* datagram-oriented sockets the option may be configured at any time after
|
||||
* the socket has been bound. The new value of the octet is used when sending
|
||||
* subsequent datagrams. It is system dependent whether this option can be
|
||||
* queried or changed prior to binding the socket.
|
||||
*
|
||||
* <p> The behavior of this socket option on a stream-oriented socket, or an
|
||||
* {@link StandardProtocolFamily#INET6 IPv6} socket, is not defined in this
|
||||
* release.
|
||||
*
|
||||
* @see DatagramSocket#setTrafficClass
|
||||
*/
|
||||
public static final SocketOption<Integer> IP_TOS =
|
||||
new StdSocketOption<Integer>("IP_TOS", Integer.class);
|
||||
|
||||
/**
|
||||
* The network interface for Internet Protocol (IP) multicast datagrams.
|
||||
*
|
||||
* <p> The value of this socket option is a {@link NetworkInterface} that
|
||||
* represents the outgoing interface for multicast datagrams sent by the
|
||||
* datagram-oriented socket. For {@link StandardProtocolFamily#INET6 IPv6}
|
||||
* sockets then it is system dependent whether setting this option also
|
||||
* sets the outgoing interface for multicast datagrams sent to IPv4
|
||||
* addresses.
|
||||
*
|
||||
* <p> The initial/default value of this socket option may be {@code null}
|
||||
* to indicate that outgoing interface will be selected by the operating
|
||||
* system, typically based on the network routing tables. An implementation
|
||||
* allows this socket option to be set after the socket is bound. Whether
|
||||
* the socket option can be queried or changed prior to binding the socket
|
||||
* is system dependent.
|
||||
*
|
||||
* @see java.nio.channels.MulticastChannel
|
||||
* @see MulticastSocket#setInterface
|
||||
*/
|
||||
public static final SocketOption<NetworkInterface> IP_MULTICAST_IF =
|
||||
new StdSocketOption<NetworkInterface>("IP_MULTICAST_IF", NetworkInterface.class);
|
||||
|
||||
/**
|
||||
* The <em>time-to-live</em> for Internet Protocol (IP) multicast datagrams.
|
||||
*
|
||||
* <p> The value of this socket option is an {@code Integer} in the range
|
||||
* {@code 0 <= value <= 255}. It is used to control the scope of multicast
|
||||
* datagrams sent by the datagram-oriented socket.
|
||||
* In the case of an {@link StandardProtocolFamily#INET IPv4} socket
|
||||
* the option is the time-to-live (TTL) on multicast datagrams sent by the
|
||||
* socket. Datagrams with a TTL of zero are not transmitted on the network
|
||||
* but may be delivered locally. In the case of an {@link
|
||||
* StandardProtocolFamily#INET6 IPv6} socket the option is the
|
||||
* <em>hop limit</em> which is number of <em>hops</em> that the datagram can
|
||||
* pass through before expiring on the network. For IPv6 sockets it is
|
||||
* system dependent whether the option also sets the <em>time-to-live</em>
|
||||
* on multicast datagrams sent to IPv4 addresses.
|
||||
*
|
||||
* <p> The initial/default value of the time-to-live setting is typically
|
||||
* {@code 1}. An implementation allows this socket option to be set after
|
||||
* the socket is bound. Whether the socket option can be queried or changed
|
||||
* prior to binding the socket is system dependent.
|
||||
*
|
||||
* @see java.nio.channels.MulticastChannel
|
||||
* @see MulticastSocket#setTimeToLive
|
||||
*/
|
||||
public static final SocketOption<Integer> IP_MULTICAST_TTL =
|
||||
new StdSocketOption<Integer>("IP_MULTICAST_TTL", Integer.class);
|
||||
|
||||
/**
|
||||
* Loopback for Internet Protocol (IP) multicast datagrams.
|
||||
*
|
||||
* <p> The value of this socket option is a {@code Boolean} that controls
|
||||
* the <em>loopback</em> of multicast datagrams. The value of the socket
|
||||
* option represents if the option is enabled or disabled.
|
||||
*
|
||||
* <p> The exact semantics of this socket options are system dependent.
|
||||
* In particular, it is system dependent whether the loopback applies to
|
||||
* multicast datagrams sent from the socket or received by the socket.
|
||||
* For {@link StandardProtocolFamily#INET6 IPv6} sockets then it is
|
||||
* system dependent whether the option also applies to multicast datagrams
|
||||
* sent to IPv4 addresses.
|
||||
*
|
||||
* <p> The initial/default value of this socket option is {@code TRUE}. An
|
||||
* implementation allows this socket option to be set after the socket is
|
||||
* bound. Whether the socket option can be queried or changed prior to
|
||||
* binding the socket is system dependent.
|
||||
*
|
||||
* @see java.nio.channels.MulticastChannel
|
||||
* @see MulticastSocket#setLoopbackMode
|
||||
*/
|
||||
public static final SocketOption<Boolean> IP_MULTICAST_LOOP =
|
||||
new StdSocketOption<Boolean>("IP_MULTICAST_LOOP", Boolean.class);
|
||||
|
||||
|
||||
// -- IPPROTO_TCP --
|
||||
|
||||
/**
|
||||
* Disable the Nagle algorithm.
|
||||
*
|
||||
* <p> The value of this socket option is a {@code Boolean} that represents
|
||||
* whether the option is enabled or disabled. The socket option is specific to
|
||||
* stream-oriented sockets using the TCP/IP protocol. TCP/IP uses an algorithm
|
||||
* known as <em>The Nagle Algorithm</em> to coalesce short segments and
|
||||
* improve network efficiency.
|
||||
*
|
||||
* <p> The default value of this socket option is {@code FALSE}. The
|
||||
* socket option should only be enabled in cases where it is known that the
|
||||
* coalescing impacts performance. The socket option may be enabled at any
|
||||
* time. In other words, the Nagle Algorithm can be disabled. Once the option
|
||||
* is enabled, it is system dependent whether it can be subsequently
|
||||
* disabled. If it cannot, then invoking the {@code setOption} method to
|
||||
* disable the option has no effect.
|
||||
*
|
||||
* @see <a href="http://www.ietf.org/rfc/rfc1122.txt">RFC 1122:
|
||||
* Requirements for Internet Hosts -- Communication Layers</a>
|
||||
* @see Socket#setTcpNoDelay
|
||||
*/
|
||||
public static final SocketOption<Boolean> TCP_NODELAY =
|
||||
new StdSocketOption<Boolean>("TCP_NODELAY", Boolean.class);
|
||||
|
||||
|
||||
private static class StdSocketOption<T> implements SocketOption<T> {
|
||||
private final String name;
|
||||
private final Class<T> type;
|
||||
StdSocketOption(String name, Class<T> type) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
}
|
||||
@Override public String name() { return name; }
|
||||
@Override public Class<T> type() { return type; }
|
||||
@Override public String toString() { return name; }
|
||||
}
|
||||
}
|
||||
216
jdkSrc/jdk8/java/net/TwoStacksPlainDatagramSocketImpl.java
Normal file
216
jdkSrc/jdk8/java/net/TwoStacksPlainDatagramSocketImpl.java
Normal file
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package java.net;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.FileDescriptor;
|
||||
import sun.net.ResourceManager;
|
||||
|
||||
/**
|
||||
* This class defines the plain DatagramSocketImpl that is used for all
|
||||
* Windows versions lower than Vista. It adds support for IPv6 on
|
||||
* these platforms where available.
|
||||
*
|
||||
* For backward compatibility windows platforms that do not have IPv6
|
||||
* support also use this implementation, and fd1 gets set to null
|
||||
* during socket creation.
|
||||
*
|
||||
* @author Chris Hegarty
|
||||
*/
|
||||
|
||||
class TwoStacksPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
|
||||
{
|
||||
/* Used for IPv6 on Windows only */
|
||||
private FileDescriptor fd1;
|
||||
|
||||
/*
|
||||
* Needed for ipv6 on windows because we need to know
|
||||
* if the socket was bound to ::0 or 0.0.0.0, when a caller
|
||||
* asks for it. In this case, both sockets are used, but we
|
||||
* don't know whether the caller requested ::0 or 0.0.0.0
|
||||
* and need to remember it here.
|
||||
*/
|
||||
private InetAddress anyLocalBoundAddr=null;
|
||||
|
||||
private int fduse=-1; /* saved between peek() and receive() calls */
|
||||
|
||||
/* saved between successive calls to receive, if data is detected
|
||||
* on both sockets at same time. To ensure that one socket is not
|
||||
* starved, they rotate using this field
|
||||
*/
|
||||
private int lastfd=-1;
|
||||
|
||||
static {
|
||||
init();
|
||||
}
|
||||
|
||||
// true if this socket is exclusively bound
|
||||
private final boolean exclusiveBind;
|
||||
|
||||
/*
|
||||
* Set to true if SO_REUSEADDR is set after the socket is bound to
|
||||
* indicate SO_REUSEADDR is being emulated
|
||||
*/
|
||||
private boolean reuseAddressEmulated;
|
||||
|
||||
// emulates SO_REUSEADDR when exclusiveBind is true and socket is bound
|
||||
private boolean isReuseAddress;
|
||||
|
||||
TwoStacksPlainDatagramSocketImpl(boolean exclBind) {
|
||||
exclusiveBind = exclBind;
|
||||
}
|
||||
|
||||
protected synchronized void create() throws SocketException {
|
||||
fd1 = new FileDescriptor();
|
||||
try {
|
||||
super.create();
|
||||
} catch (SocketException e) {
|
||||
fd1 = null;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
protected synchronized void bind(int lport, InetAddress laddr)
|
||||
throws SocketException {
|
||||
super.bind(lport, laddr);
|
||||
if (laddr.isAnyLocalAddress()) {
|
||||
anyLocalBoundAddr = laddr;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected synchronized void bind0(int lport, InetAddress laddr)
|
||||
throws SocketException
|
||||
{
|
||||
bind0(lport, laddr, exclusiveBind);
|
||||
|
||||
}
|
||||
|
||||
protected synchronized void receive(DatagramPacket p)
|
||||
throws IOException {
|
||||
try {
|
||||
receive0(p);
|
||||
} finally {
|
||||
fduse = -1;
|
||||
}
|
||||
}
|
||||
|
||||
public Object getOption(int optID) throws SocketException {
|
||||
if (isClosed()) {
|
||||
throw new SocketException("Socket Closed");
|
||||
}
|
||||
|
||||
if (optID == SO_BINDADDR) {
|
||||
if ((fd != null && fd1 != null) && !connected) {
|
||||
return anyLocalBoundAddr;
|
||||
}
|
||||
int family = connectedAddress == null ? -1 : connectedAddress.holder().getFamily();
|
||||
return socketLocalAddress(family);
|
||||
} else if (optID == SO_REUSEADDR && reuseAddressEmulated) {
|
||||
return isReuseAddress;
|
||||
} else {
|
||||
return super.getOption(optID);
|
||||
}
|
||||
}
|
||||
|
||||
protected void socketSetOption(int opt, Object val)
|
||||
throws SocketException
|
||||
{
|
||||
if (opt == SO_REUSEADDR && exclusiveBind && localPort != 0) {
|
||||
// socket already bound, emulate
|
||||
reuseAddressEmulated = true;
|
||||
isReuseAddress = (Boolean)val;
|
||||
} else {
|
||||
socketNativeSetOption(opt, val);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected boolean isClosed() {
|
||||
return (fd == null && fd1 == null) ? true : false;
|
||||
}
|
||||
|
||||
protected void close() {
|
||||
if (fd != null || fd1 != null) {
|
||||
datagramSocketClose();
|
||||
ResourceManager.afterUdpClose();
|
||||
fd = null;
|
||||
fd1 = null;
|
||||
}
|
||||
}
|
||||
|
||||
/* Native methods */
|
||||
|
||||
protected synchronized native void bind0(int lport, InetAddress laddr,
|
||||
boolean exclBind)
|
||||
throws SocketException;
|
||||
|
||||
protected native void send(DatagramPacket p) throws IOException;
|
||||
|
||||
protected synchronized native int peek(InetAddress i) throws IOException;
|
||||
|
||||
protected synchronized native int peekData(DatagramPacket p) throws IOException;
|
||||
|
||||
protected synchronized native void receive0(DatagramPacket p)
|
||||
throws IOException;
|
||||
|
||||
protected native void setTimeToLive(int ttl) throws IOException;
|
||||
|
||||
protected native int getTimeToLive() throws IOException;
|
||||
|
||||
@Deprecated
|
||||
protected native void setTTL(byte ttl) throws IOException;
|
||||
|
||||
@Deprecated
|
||||
protected native byte getTTL() throws IOException;
|
||||
|
||||
protected native void join(InetAddress inetaddr, NetworkInterface netIf)
|
||||
throws IOException;
|
||||
|
||||
protected native void leave(InetAddress inetaddr, NetworkInterface netIf)
|
||||
throws IOException;
|
||||
|
||||
protected native void datagramSocketCreate() throws SocketException;
|
||||
|
||||
protected native void datagramSocketClose();
|
||||
|
||||
protected native void socketNativeSetOption(int opt, Object val)
|
||||
throws SocketException;
|
||||
|
||||
protected native Object socketGetOption(int opt) throws SocketException;
|
||||
|
||||
protected native void connect0(InetAddress address, int port) throws SocketException;
|
||||
|
||||
protected native Object socketLocalAddress(int family) throws SocketException;
|
||||
|
||||
protected native void disconnect0(int family);
|
||||
|
||||
native int dataAvailable();
|
||||
|
||||
/**
|
||||
* Perform class load-time initializations.
|
||||
*/
|
||||
private native static void init();
|
||||
}
|
||||
243
jdkSrc/jdk8/java/net/TwoStacksPlainSocketImpl.java
Normal file
243
jdkSrc/jdk8/java/net/TwoStacksPlainSocketImpl.java
Normal file
@@ -0,0 +1,243 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package java.net;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.FileDescriptor;
|
||||
import sun.net.ResourceManager;
|
||||
|
||||
/*
|
||||
* This class defines the plain SocketImpl that is used for all
|
||||
* Windows version lower than Vista. It adds support for IPv6 on
|
||||
* these platforms where available.
|
||||
*
|
||||
* For backward compatibility Windows platforms that do not have IPv6
|
||||
* support also use this implementation, and fd1 gets set to null
|
||||
* during socket creation.
|
||||
*
|
||||
* @author Chris Hegarty
|
||||
*/
|
||||
|
||||
class TwoStacksPlainSocketImpl extends AbstractPlainSocketImpl
|
||||
{
|
||||
/* second fd, used for ipv6 on windows only.
|
||||
* fd1 is used for listeners and for client sockets at initialization
|
||||
* until the socket is connected. Up to this point fd always refers
|
||||
* to the ipv4 socket and fd1 to the ipv6 socket. After the socket
|
||||
* becomes connected, fd always refers to the connected socket
|
||||
* (either v4 or v6) and fd1 is closed.
|
||||
*
|
||||
* For ServerSockets, fd always refers to the v4 listener and
|
||||
* fd1 the v6 listener.
|
||||
*/
|
||||
private FileDescriptor fd1;
|
||||
|
||||
/*
|
||||
* Needed for ipv6 on windows because we need to know
|
||||
* if the socket is bound to ::0 or 0.0.0.0, when a caller
|
||||
* asks for it. Otherwise we don't know which socket to ask.
|
||||
*/
|
||||
private InetAddress anyLocalBoundAddr = null;
|
||||
|
||||
/* to prevent starvation when listening on two sockets, this is
|
||||
* is used to hold the id of the last socket we accepted on.
|
||||
*/
|
||||
private int lastfd = -1;
|
||||
|
||||
// true if this socket is exclusively bound
|
||||
private final boolean exclusiveBind;
|
||||
|
||||
// emulates SO_REUSEADDR when exclusiveBind is true
|
||||
private boolean isReuseAddress;
|
||||
|
||||
static {
|
||||
initProto();
|
||||
}
|
||||
|
||||
public TwoStacksPlainSocketImpl(boolean exclBind) {
|
||||
exclusiveBind = exclBind;
|
||||
}
|
||||
|
||||
public TwoStacksPlainSocketImpl(FileDescriptor fd, boolean exclBind) {
|
||||
this.fd = fd;
|
||||
exclusiveBind = exclBind;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a socket with a boolean that specifies whether this
|
||||
* is a stream socket (true) or an unconnected UDP socket (false).
|
||||
*/
|
||||
protected synchronized void create(boolean stream) throws IOException {
|
||||
fd1 = new FileDescriptor();
|
||||
try {
|
||||
super.create(stream);
|
||||
} catch (IOException e) {
|
||||
fd1 = null;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds the socket to the specified address of the specified local port.
|
||||
* @param address the address
|
||||
* @param port the port
|
||||
*/
|
||||
protected synchronized void bind(InetAddress address, int lport)
|
||||
throws IOException
|
||||
{
|
||||
super.bind(address, lport);
|
||||
if (address.isAnyLocalAddress()) {
|
||||
anyLocalBoundAddr = address;
|
||||
}
|
||||
}
|
||||
|
||||
public Object getOption(int opt) throws SocketException {
|
||||
if (isClosedOrPending()) {
|
||||
throw new SocketException("Socket Closed");
|
||||
}
|
||||
if (opt == SO_BINDADDR) {
|
||||
if (fd != null && fd1 != null ) {
|
||||
/* must be unbound or else bound to anyLocal */
|
||||
return anyLocalBoundAddr;
|
||||
}
|
||||
InetAddressContainer in = new InetAddressContainer();
|
||||
socketGetOption(opt, in);
|
||||
return in.addr;
|
||||
} else if (opt == SO_REUSEADDR && exclusiveBind) {
|
||||
// SO_REUSEADDR emulated when using exclusive bind
|
||||
return isReuseAddress;
|
||||
} else
|
||||
return super.getOption(opt);
|
||||
}
|
||||
|
||||
@Override
|
||||
void socketBind(InetAddress address, int port) throws IOException {
|
||||
socketBind(address, port, exclusiveBind);
|
||||
}
|
||||
|
||||
@Override
|
||||
void socketSetOption(int opt, boolean on, Object value)
|
||||
throws SocketException
|
||||
{
|
||||
// SO_REUSEADDR emulated when using exclusive bind
|
||||
if (opt == SO_REUSEADDR && exclusiveBind)
|
||||
isReuseAddress = on;
|
||||
else
|
||||
socketNativeSetOption(opt, on, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the socket.
|
||||
*/
|
||||
@Override
|
||||
protected void close() throws IOException {
|
||||
synchronized(fdLock) {
|
||||
if (fd != null || fd1 != null) {
|
||||
if (!stream) {
|
||||
ResourceManager.afterUdpClose();
|
||||
}
|
||||
if (fdUseCount == 0) {
|
||||
if (closePending) {
|
||||
return;
|
||||
}
|
||||
closePending = true;
|
||||
socketClose();
|
||||
fd = null;
|
||||
fd1 = null;
|
||||
return;
|
||||
} else {
|
||||
/*
|
||||
* If a thread has acquired the fd and a close
|
||||
* isn't pending then use a deferred close.
|
||||
* Also decrement fdUseCount to signal the last
|
||||
* thread that releases the fd to close it.
|
||||
*/
|
||||
if (!closePending) {
|
||||
closePending = true;
|
||||
fdUseCount--;
|
||||
socketClose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void reset() throws IOException {
|
||||
if (fd != null || fd1 != null) {
|
||||
socketClose();
|
||||
}
|
||||
fd = null;
|
||||
fd1 = null;
|
||||
super.reset();
|
||||
}
|
||||
|
||||
/*
|
||||
* Return true if already closed or close is pending
|
||||
*/
|
||||
@Override
|
||||
public boolean isClosedOrPending() {
|
||||
/*
|
||||
* Lock on fdLock to ensure that we wait if a
|
||||
* close is in progress.
|
||||
*/
|
||||
synchronized (fdLock) {
|
||||
if (closePending || (fd == null && fd1 == null)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Native methods */
|
||||
|
||||
static native void initProto();
|
||||
|
||||
native void socketCreate(boolean isServer) throws IOException;
|
||||
|
||||
native void socketConnect(InetAddress address, int port, int timeout)
|
||||
throws IOException;
|
||||
|
||||
native void socketBind(InetAddress address, int port, boolean exclBind)
|
||||
throws IOException;
|
||||
|
||||
native void socketListen(int count) throws IOException;
|
||||
|
||||
native void socketAccept(SocketImpl s) throws IOException;
|
||||
|
||||
native int socketAvailable() throws IOException;
|
||||
|
||||
native void socketClose0(boolean useDeferredClose) throws IOException;
|
||||
|
||||
native void socketShutdown(int howto) throws IOException;
|
||||
|
||||
native void socketNativeSetOption(int cmd, boolean on, Object value)
|
||||
throws SocketException;
|
||||
|
||||
native int socketGetOption(int opt, Object iaContainerObj) throws SocketException;
|
||||
|
||||
native void socketSendUrgentData(int data) throws IOException;
|
||||
}
|
||||
3544
jdkSrc/jdk8/java/net/URI.java
Normal file
3544
jdkSrc/jdk8/java/net/URI.java
Normal file
File diff suppressed because it is too large
Load Diff
135
jdkSrc/jdk8/java/net/URISyntaxException.java
Normal file
135
jdkSrc/jdk8/java/net/URISyntaxException.java
Normal file
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
|
||||
/**
|
||||
* Checked exception thrown to indicate that a string could not be parsed as a
|
||||
* URI reference.
|
||||
*
|
||||
* @author Mark Reinhold
|
||||
* @see URI
|
||||
* @since 1.4
|
||||
*/
|
||||
|
||||
public class URISyntaxException
|
||||
extends Exception
|
||||
{
|
||||
private static final long serialVersionUID = 2137979680897488891L;
|
||||
|
||||
private String input;
|
||||
private int index;
|
||||
|
||||
/**
|
||||
* Constructs an instance from the given input string, reason, and error
|
||||
* index.
|
||||
*
|
||||
* @param input The input string
|
||||
* @param reason A string explaining why the input could not be parsed
|
||||
* @param index The index at which the parse error occurred,
|
||||
* or {@code -1} if the index is not known
|
||||
*
|
||||
* @throws NullPointerException
|
||||
* If either the input or reason strings are {@code null}
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* If the error index is less than {@code -1}
|
||||
*/
|
||||
public URISyntaxException(String input, String reason, int index) {
|
||||
super(reason);
|
||||
if ((input == null) || (reason == null))
|
||||
throw new NullPointerException();
|
||||
if (index < -1)
|
||||
throw new IllegalArgumentException();
|
||||
this.input = input;
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an instance from the given input string and reason. The
|
||||
* resulting object will have an error index of {@code -1}.
|
||||
*
|
||||
* @param input The input string
|
||||
* @param reason A string explaining why the input could not be parsed
|
||||
*
|
||||
* @throws NullPointerException
|
||||
* If either the input or reason strings are {@code null}
|
||||
*/
|
||||
public URISyntaxException(String input, String reason) {
|
||||
this(input, reason, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the input string.
|
||||
*
|
||||
* @return The input string
|
||||
*/
|
||||
public String getInput() {
|
||||
return input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string explaining why the input string could not be parsed.
|
||||
*
|
||||
* @return The reason string
|
||||
*/
|
||||
public String getReason() {
|
||||
return super.getMessage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an index into the input string of the position at which the
|
||||
* parse error occurred, or {@code -1} if this position is not known.
|
||||
*
|
||||
* @return The error index
|
||||
*/
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string describing the parse error. The resulting string
|
||||
* consists of the reason string followed by a colon character
|
||||
* ({@code ':'}), a space, and the input string. If the error index is
|
||||
* defined then the string {@code " at index "} followed by the index, in
|
||||
* decimal, is inserted after the reason string and before the colon
|
||||
* character.
|
||||
*
|
||||
* @return A string describing the parse error
|
||||
*/
|
||||
public String getMessage() {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append(getReason());
|
||||
if (index > -1) {
|
||||
sb.append(" at index ");
|
||||
sb.append(index);
|
||||
}
|
||||
sb.append(": ");
|
||||
sb.append(input);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
1587
jdkSrc/jdk8/java/net/URL.java
Normal file
1587
jdkSrc/jdk8/java/net/URL.java
Normal file
File diff suppressed because it is too large
Load Diff
824
jdkSrc/jdk8/java/net/URLClassLoader.java
Normal file
824
jdkSrc/jdk8/java/net/URLClassLoader.java
Normal file
@@ -0,0 +1,824 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.File;
|
||||
import java.io.FilePermission;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.AccessController;
|
||||
import java.security.CodeSigner;
|
||||
import java.security.CodeSource;
|
||||
import java.security.Permission;
|
||||
import java.security.PermissionCollection;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.security.SecureClassLoader;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.Attributes.Name;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.jar.Manifest;
|
||||
import sun.misc.Resource;
|
||||
import sun.misc.SharedSecrets;
|
||||
import sun.misc.URLClassPath;
|
||||
import sun.net.www.ParseUtil;
|
||||
import sun.security.util.SecurityConstants;
|
||||
|
||||
/**
|
||||
* This class loader is used to load classes and resources from a search
|
||||
* path of URLs referring to both JAR files and directories. Any URL that
|
||||
* ends with a '/' is assumed to refer to a directory. Otherwise, the URL
|
||||
* is assumed to refer to a JAR file which will be opened as needed.
|
||||
* <p>
|
||||
* The AccessControlContext of the thread that created the instance of
|
||||
* URLClassLoader will be used when subsequently loading classes and
|
||||
* resources.
|
||||
* <p>
|
||||
* The classes that are loaded are by default granted permission only to
|
||||
* access the URLs specified when the URLClassLoader was created.
|
||||
*
|
||||
* @author David Connelly
|
||||
* @since 1.2
|
||||
*/
|
||||
public class URLClassLoader extends SecureClassLoader implements Closeable {
|
||||
/* The search path for classes and resources */
|
||||
private final URLClassPath ucp;
|
||||
|
||||
/* The context to be used when loading classes and resources */
|
||||
private final AccessControlContext acc;
|
||||
|
||||
/**
|
||||
* Constructs a new URLClassLoader for the given URLs. The URLs will be
|
||||
* searched in the order specified for classes and resources after first
|
||||
* searching in the specified parent class loader. Any URL that ends with
|
||||
* a '/' is assumed to refer to a directory. Otherwise, the URL is assumed
|
||||
* to refer to a JAR file which will be downloaded and opened as needed.
|
||||
*
|
||||
* <p>If there is a security manager, this method first
|
||||
* calls the security manager's {@code checkCreateClassLoader} method
|
||||
* to ensure creation of a class loader is allowed.
|
||||
*
|
||||
* @param urls the URLs from which to load classes and resources
|
||||
* @param parent the parent class loader for delegation
|
||||
* @exception SecurityException if a security manager exists and its
|
||||
* {@code checkCreateClassLoader} method doesn't allow
|
||||
* creation of a class loader.
|
||||
* @exception NullPointerException if {@code urls} is {@code null}.
|
||||
* @see SecurityManager#checkCreateClassLoader
|
||||
*/
|
||||
public URLClassLoader(URL[] urls, ClassLoader parent) {
|
||||
super(parent);
|
||||
// this is to make the stack depth consistent with 1.1
|
||||
SecurityManager security = System.getSecurityManager();
|
||||
if (security != null) {
|
||||
security.checkCreateClassLoader();
|
||||
}
|
||||
this.acc = AccessController.getContext();
|
||||
ucp = new URLClassPath(urls, acc);
|
||||
}
|
||||
|
||||
URLClassLoader(URL[] urls, ClassLoader parent,
|
||||
AccessControlContext acc) {
|
||||
super(parent);
|
||||
// this is to make the stack depth consistent with 1.1
|
||||
SecurityManager security = System.getSecurityManager();
|
||||
if (security != null) {
|
||||
security.checkCreateClassLoader();
|
||||
}
|
||||
this.acc = acc;
|
||||
ucp = new URLClassPath(urls, acc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new URLClassLoader for the specified URLs using the
|
||||
* default delegation parent {@code ClassLoader}. The URLs will
|
||||
* be searched in the order specified for classes and resources after
|
||||
* first searching in the parent class loader. Any URL that ends with
|
||||
* a '/' is assumed to refer to a directory. Otherwise, the URL is
|
||||
* assumed to refer to a JAR file which will be downloaded and opened
|
||||
* as needed.
|
||||
*
|
||||
* <p>If there is a security manager, this method first
|
||||
* calls the security manager's {@code checkCreateClassLoader} method
|
||||
* to ensure creation of a class loader is allowed.
|
||||
*
|
||||
* @param urls the URLs from which to load classes and resources
|
||||
*
|
||||
* @exception SecurityException if a security manager exists and its
|
||||
* {@code checkCreateClassLoader} method doesn't allow
|
||||
* creation of a class loader.
|
||||
* @exception NullPointerException if {@code urls} is {@code null}.
|
||||
* @see SecurityManager#checkCreateClassLoader
|
||||
*/
|
||||
public URLClassLoader(URL[] urls) {
|
||||
super();
|
||||
// this is to make the stack depth consistent with 1.1
|
||||
SecurityManager security = System.getSecurityManager();
|
||||
if (security != null) {
|
||||
security.checkCreateClassLoader();
|
||||
}
|
||||
this.acc = AccessController.getContext();
|
||||
ucp = new URLClassPath(urls, acc);
|
||||
}
|
||||
|
||||
URLClassLoader(URL[] urls, AccessControlContext acc) {
|
||||
super();
|
||||
// this is to make the stack depth consistent with 1.1
|
||||
SecurityManager security = System.getSecurityManager();
|
||||
if (security != null) {
|
||||
security.checkCreateClassLoader();
|
||||
}
|
||||
this.acc = acc;
|
||||
ucp = new URLClassPath(urls, acc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new URLClassLoader for the specified URLs, parent
|
||||
* class loader, and URLStreamHandlerFactory. The parent argument
|
||||
* will be used as the parent class loader for delegation. The
|
||||
* factory argument will be used as the stream handler factory to
|
||||
* obtain protocol handlers when creating new jar URLs.
|
||||
*
|
||||
* <p>If there is a security manager, this method first
|
||||
* calls the security manager's {@code checkCreateClassLoader} method
|
||||
* to ensure creation of a class loader is allowed.
|
||||
*
|
||||
* @param urls the URLs from which to load classes and resources
|
||||
* @param parent the parent class loader for delegation
|
||||
* @param factory the URLStreamHandlerFactory to use when creating URLs
|
||||
*
|
||||
* @exception SecurityException if a security manager exists and its
|
||||
* {@code checkCreateClassLoader} method doesn't allow
|
||||
* creation of a class loader.
|
||||
* @exception NullPointerException if {@code urls} is {@code null}.
|
||||
* @see SecurityManager#checkCreateClassLoader
|
||||
*/
|
||||
public URLClassLoader(URL[] urls, ClassLoader parent,
|
||||
URLStreamHandlerFactory factory) {
|
||||
super(parent);
|
||||
// this is to make the stack depth consistent with 1.1
|
||||
SecurityManager security = System.getSecurityManager();
|
||||
if (security != null) {
|
||||
security.checkCreateClassLoader();
|
||||
}
|
||||
acc = AccessController.getContext();
|
||||
ucp = new URLClassPath(urls, factory, acc);
|
||||
}
|
||||
|
||||
/* A map (used as a set) to keep track of closeable local resources
|
||||
* (either JarFiles or FileInputStreams). We don't care about
|
||||
* Http resources since they don't need to be closed.
|
||||
*
|
||||
* If the resource is coming from a jar file
|
||||
* we keep a (weak) reference to the JarFile object which can
|
||||
* be closed if URLClassLoader.close() called. Due to jar file
|
||||
* caching there will typically be only one JarFile object
|
||||
* per underlying jar file.
|
||||
*
|
||||
* For file resources, which is probably a less common situation
|
||||
* we have to keep a weak reference to each stream.
|
||||
*/
|
||||
|
||||
private WeakHashMap<Closeable,Void>
|
||||
closeables = new WeakHashMap<>();
|
||||
|
||||
/**
|
||||
* Returns an input stream for reading the specified resource.
|
||||
* If this loader is closed, then any resources opened by this method
|
||||
* will be closed.
|
||||
*
|
||||
* <p> The search order is described in the documentation for {@link
|
||||
* #getResource(String)}. </p>
|
||||
*
|
||||
* @param name
|
||||
* The resource name
|
||||
*
|
||||
* @return An input stream for reading the resource, or {@code null}
|
||||
* if the resource could not be found
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
public InputStream getResourceAsStream(String name) {
|
||||
URL url = getResource(name);
|
||||
try {
|
||||
if (url == null) {
|
||||
return null;
|
||||
}
|
||||
URLConnection urlc = url.openConnection();
|
||||
InputStream is = urlc.getInputStream();
|
||||
if (urlc instanceof JarURLConnection) {
|
||||
JarURLConnection juc = (JarURLConnection)urlc;
|
||||
JarFile jar = juc.getJarFile();
|
||||
synchronized (closeables) {
|
||||
if (!closeables.containsKey(jar)) {
|
||||
closeables.put(jar, null);
|
||||
}
|
||||
}
|
||||
} else if (urlc instanceof sun.net.www.protocol.file.FileURLConnection) {
|
||||
synchronized (closeables) {
|
||||
closeables.put(is, null);
|
||||
}
|
||||
}
|
||||
return is;
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes this URLClassLoader, so that it can no longer be used to load
|
||||
* new classes or resources that are defined by this loader.
|
||||
* Classes and resources defined by any of this loader's parents in the
|
||||
* delegation hierarchy are still accessible. Also, any classes or resources
|
||||
* that are already loaded, are still accessible.
|
||||
* <p>
|
||||
* In the case of jar: and file: URLs, it also closes any files
|
||||
* that were opened by it. If another thread is loading a
|
||||
* class when the {@code close} method is invoked, then the result of
|
||||
* that load is undefined.
|
||||
* <p>
|
||||
* The method makes a best effort attempt to close all opened files,
|
||||
* by catching {@link IOException}s internally. Unchecked exceptions
|
||||
* and errors are not caught. Calling close on an already closed
|
||||
* loader has no effect.
|
||||
* <p>
|
||||
* @exception IOException if closing any file opened by this class loader
|
||||
* resulted in an IOException. Any such exceptions are caught internally.
|
||||
* If only one is caught, then it is re-thrown. If more than one exception
|
||||
* is caught, then the second and following exceptions are added
|
||||
* as suppressed exceptions of the first one caught, which is then re-thrown.
|
||||
*
|
||||
* @exception SecurityException if a security manager is set, and it denies
|
||||
* {@link RuntimePermission}{@code ("closeClassLoader")}
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
SecurityManager security = System.getSecurityManager();
|
||||
if (security != null) {
|
||||
security.checkPermission(new RuntimePermission("closeClassLoader"));
|
||||
}
|
||||
List<IOException> errors = ucp.closeLoaders();
|
||||
|
||||
// now close any remaining streams.
|
||||
|
||||
synchronized (closeables) {
|
||||
Set<Closeable> keys = closeables.keySet();
|
||||
for (Closeable c : keys) {
|
||||
try {
|
||||
c.close();
|
||||
} catch (IOException ioex) {
|
||||
errors.add(ioex);
|
||||
}
|
||||
}
|
||||
closeables.clear();
|
||||
}
|
||||
|
||||
if (errors.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
IOException firstex = errors.remove(0);
|
||||
|
||||
// Suppress any remaining exceptions
|
||||
|
||||
for (IOException error: errors) {
|
||||
firstex.addSuppressed(error);
|
||||
}
|
||||
throw firstex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the specified URL to the list of URLs to search for
|
||||
* classes and resources.
|
||||
* <p>
|
||||
* If the URL specified is {@code null} or is already in the
|
||||
* list of URLs, or if this loader is closed, then invoking this
|
||||
* method has no effect.
|
||||
*
|
||||
* @param url the URL to be added to the search path of URLs
|
||||
*/
|
||||
protected void addURL(URL url) {
|
||||
ucp.addURL(url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the search path of URLs for loading classes and resources.
|
||||
* This includes the original list of URLs specified to the constructor,
|
||||
* along with any URLs subsequently appended by the addURL() method.
|
||||
* @return the search path of URLs for loading classes and resources.
|
||||
*/
|
||||
public URL[] getURLs() {
|
||||
return ucp.getURLs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds and loads the class with the specified name from the URL search
|
||||
* path. Any URLs referring to JAR files are loaded and opened as needed
|
||||
* until the class is found.
|
||||
*
|
||||
* @param name the name of the class
|
||||
* @return the resulting class
|
||||
* @exception ClassNotFoundException if the class could not be found,
|
||||
* or if the loader is closed.
|
||||
* @exception NullPointerException if {@code name} is {@code null}.
|
||||
*/
|
||||
protected Class<?> findClass(final String name)
|
||||
throws ClassNotFoundException
|
||||
{
|
||||
final Class<?> result;
|
||||
try {
|
||||
result = AccessController.doPrivileged(
|
||||
new PrivilegedExceptionAction<Class<?>>() {
|
||||
public Class<?> run() throws ClassNotFoundException {
|
||||
String path = name.replace('.', '/').concat(".class");
|
||||
Resource res = ucp.getResource(path, false);
|
||||
if (res != null) {
|
||||
try {
|
||||
return defineClass(name, res);
|
||||
} catch (IOException e) {
|
||||
throw new ClassNotFoundException(name, e);
|
||||
} catch (ClassFormatError e2) {
|
||||
if (res.getDataError() != null) {
|
||||
e2.addSuppressed(res.getDataError());
|
||||
}
|
||||
throw e2;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}, acc);
|
||||
} catch (java.security.PrivilegedActionException pae) {
|
||||
throw (ClassNotFoundException) pae.getException();
|
||||
}
|
||||
if (result == null) {
|
||||
throw new ClassNotFoundException(name);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Retrieve the package using the specified package name.
|
||||
* If non-null, verify the package using the specified code
|
||||
* source and manifest.
|
||||
*/
|
||||
private Package getAndVerifyPackage(String pkgname,
|
||||
Manifest man, URL url) {
|
||||
Package pkg = getPackage(pkgname);
|
||||
if (pkg != null) {
|
||||
// Package found, so check package sealing.
|
||||
if (pkg.isSealed()) {
|
||||
// Verify that code source URL is the same.
|
||||
if (!pkg.isSealed(url)) {
|
||||
throw new SecurityException(
|
||||
"sealing violation: package " + pkgname + " is sealed");
|
||||
}
|
||||
} else {
|
||||
// Make sure we are not attempting to seal the package
|
||||
// at this code source URL.
|
||||
if ((man != null) && isSealed(pkgname, man)) {
|
||||
throw new SecurityException(
|
||||
"sealing violation: can't seal package " + pkgname +
|
||||
": already loaded");
|
||||
}
|
||||
}
|
||||
}
|
||||
return pkg;
|
||||
}
|
||||
|
||||
// Also called by VM to define Package for classes loaded from the CDS
|
||||
// archive
|
||||
private void definePackageInternal(String pkgname, Manifest man, URL url)
|
||||
{
|
||||
if (getAndVerifyPackage(pkgname, man, url) == null) {
|
||||
try {
|
||||
if (man != null) {
|
||||
definePackage(pkgname, man, url);
|
||||
} else {
|
||||
definePackage(pkgname, null, null, null, null, null, null, null);
|
||||
}
|
||||
} catch (IllegalArgumentException iae) {
|
||||
// parallel-capable class loaders: re-verify in case of a
|
||||
// race condition
|
||||
if (getAndVerifyPackage(pkgname, man, url) == null) {
|
||||
// Should never happen
|
||||
throw new AssertionError("Cannot find package " +
|
||||
pkgname);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Defines a Class using the class bytes obtained from the specified
|
||||
* Resource. The resulting Class must be resolved before it can be
|
||||
* used.
|
||||
*/
|
||||
private Class<?> defineClass(String name, Resource res) throws IOException {
|
||||
long t0 = System.nanoTime();
|
||||
int i = name.lastIndexOf('.');
|
||||
URL url = res.getCodeSourceURL();
|
||||
if (i != -1) {
|
||||
String pkgname = name.substring(0, i);
|
||||
// Check if package already loaded.
|
||||
Manifest man = res.getManifest();
|
||||
definePackageInternal(pkgname, man, url);
|
||||
}
|
||||
// Now read the class bytes and define the class
|
||||
java.nio.ByteBuffer bb = res.getByteBuffer();
|
||||
if (bb != null) {
|
||||
// Use (direct) ByteBuffer:
|
||||
CodeSigner[] signers = res.getCodeSigners();
|
||||
CodeSource cs = new CodeSource(url, signers);
|
||||
sun.misc.PerfCounter.getReadClassBytesTime().addElapsedTimeFrom(t0);
|
||||
return defineClass(name, bb, cs);
|
||||
} else {
|
||||
byte[] b = res.getBytes();
|
||||
// must read certificates AFTER reading bytes.
|
||||
CodeSigner[] signers = res.getCodeSigners();
|
||||
CodeSource cs = new CodeSource(url, signers);
|
||||
sun.misc.PerfCounter.getReadClassBytesTime().addElapsedTimeFrom(t0);
|
||||
return defineClass(name, b, 0, b.length, cs);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines a new package by name in this ClassLoader. The attributes
|
||||
* contained in the specified Manifest will be used to obtain package
|
||||
* version and sealing information. For sealed packages, the additional
|
||||
* URL specifies the code source URL from which the package was loaded.
|
||||
*
|
||||
* @param name the package name
|
||||
* @param man the Manifest containing package version and sealing
|
||||
* information
|
||||
* @param url the code source url for the package, or null if none
|
||||
* @exception IllegalArgumentException if the package name duplicates
|
||||
* an existing package either in this class loader or one
|
||||
* of its ancestors
|
||||
* @return the newly defined Package object
|
||||
*/
|
||||
protected Package definePackage(String name, Manifest man, URL url)
|
||||
throws IllegalArgumentException
|
||||
{
|
||||
String specTitle = null, specVersion = null, specVendor = null;
|
||||
String implTitle = null, implVersion = null, implVendor = null;
|
||||
String sealed = null;
|
||||
URL sealBase = null;
|
||||
|
||||
Attributes attr = SharedSecrets.javaUtilJarAccess()
|
||||
.getTrustedAttributes(man, name.replace('.', '/').concat("/"));
|
||||
if (attr != null) {
|
||||
specTitle = attr.getValue(Name.SPECIFICATION_TITLE);
|
||||
specVersion = attr.getValue(Name.SPECIFICATION_VERSION);
|
||||
specVendor = attr.getValue(Name.SPECIFICATION_VENDOR);
|
||||
implTitle = attr.getValue(Name.IMPLEMENTATION_TITLE);
|
||||
implVersion = attr.getValue(Name.IMPLEMENTATION_VERSION);
|
||||
implVendor = attr.getValue(Name.IMPLEMENTATION_VENDOR);
|
||||
sealed = attr.getValue(Name.SEALED);
|
||||
}
|
||||
attr = man.getMainAttributes();
|
||||
if (attr != null) {
|
||||
if (specTitle == null) {
|
||||
specTitle = attr.getValue(Name.SPECIFICATION_TITLE);
|
||||
}
|
||||
if (specVersion == null) {
|
||||
specVersion = attr.getValue(Name.SPECIFICATION_VERSION);
|
||||
}
|
||||
if (specVendor == null) {
|
||||
specVendor = attr.getValue(Name.SPECIFICATION_VENDOR);
|
||||
}
|
||||
if (implTitle == null) {
|
||||
implTitle = attr.getValue(Name.IMPLEMENTATION_TITLE);
|
||||
}
|
||||
if (implVersion == null) {
|
||||
implVersion = attr.getValue(Name.IMPLEMENTATION_VERSION);
|
||||
}
|
||||
if (implVendor == null) {
|
||||
implVendor = attr.getValue(Name.IMPLEMENTATION_VENDOR);
|
||||
}
|
||||
if (sealed == null) {
|
||||
sealed = attr.getValue(Name.SEALED);
|
||||
}
|
||||
}
|
||||
if ("true".equalsIgnoreCase(sealed)) {
|
||||
sealBase = url;
|
||||
}
|
||||
return definePackage(name, specTitle, specVersion, specVendor,
|
||||
implTitle, implVersion, implVendor, sealBase);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns true if the specified package name is sealed according to the
|
||||
* given manifest.
|
||||
*
|
||||
* @throws SecurityException if the package name is untrusted in the manifest
|
||||
*/
|
||||
private boolean isSealed(String name, Manifest man) {
|
||||
Attributes attr = SharedSecrets.javaUtilJarAccess()
|
||||
.getTrustedAttributes(man, name.replace('.', '/').concat("/"));
|
||||
String sealed = null;
|
||||
if (attr != null) {
|
||||
sealed = attr.getValue(Name.SEALED);
|
||||
}
|
||||
if (sealed == null) {
|
||||
if ((attr = man.getMainAttributes()) != null) {
|
||||
sealed = attr.getValue(Name.SEALED);
|
||||
}
|
||||
}
|
||||
return "true".equalsIgnoreCase(sealed);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the resource with the specified name on the URL search path.
|
||||
*
|
||||
* @param name the name of the resource
|
||||
* @return a {@code URL} for the resource, or {@code null}
|
||||
* if the resource could not be found, or if the loader is closed.
|
||||
*/
|
||||
public URL findResource(final String name) {
|
||||
/*
|
||||
* The same restriction to finding classes applies to resources
|
||||
*/
|
||||
URL url = AccessController.doPrivileged(
|
||||
new PrivilegedAction<URL>() {
|
||||
public URL run() {
|
||||
return ucp.findResource(name, true);
|
||||
}
|
||||
}, acc);
|
||||
|
||||
return url != null ? ucp.checkURL(url) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an Enumeration of URLs representing all of the resources
|
||||
* on the URL search path having the specified name.
|
||||
*
|
||||
* @param name the resource name
|
||||
* @exception IOException if an I/O exception occurs
|
||||
* @return an {@code Enumeration} of {@code URL}s
|
||||
* If the loader is closed, the Enumeration will be empty.
|
||||
*/
|
||||
public Enumeration<URL> findResources(final String name)
|
||||
throws IOException
|
||||
{
|
||||
final Enumeration<URL> e = ucp.findResources(name, true);
|
||||
|
||||
return new Enumeration<URL>() {
|
||||
private URL url = null;
|
||||
|
||||
private boolean next() {
|
||||
if (url != null) {
|
||||
return true;
|
||||
}
|
||||
do {
|
||||
URL u = AccessController.doPrivileged(
|
||||
new PrivilegedAction<URL>() {
|
||||
public URL run() {
|
||||
if (!e.hasMoreElements())
|
||||
return null;
|
||||
return e.nextElement();
|
||||
}
|
||||
}, acc);
|
||||
if (u == null)
|
||||
break;
|
||||
url = ucp.checkURL(u);
|
||||
} while (url == null);
|
||||
return url != null;
|
||||
}
|
||||
|
||||
public URL nextElement() {
|
||||
if (!next()) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
URL u = url;
|
||||
url = null;
|
||||
return u;
|
||||
}
|
||||
|
||||
public boolean hasMoreElements() {
|
||||
return next();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the permissions for the given codesource object.
|
||||
* The implementation of this method first calls super.getPermissions
|
||||
* and then adds permissions based on the URL of the codesource.
|
||||
* <p>
|
||||
* If the protocol of this URL is "jar", then the permission granted
|
||||
* is based on the permission that is required by the URL of the Jar
|
||||
* file.
|
||||
* <p>
|
||||
* If the protocol is "file" and there is an authority component, then
|
||||
* permission to connect to and accept connections from that authority
|
||||
* may be granted. If the protocol is "file"
|
||||
* and the path specifies a file, then permission to read that
|
||||
* file is granted. If protocol is "file" and the path is
|
||||
* a directory, permission is granted to read all files
|
||||
* and (recursively) all files and subdirectories contained in
|
||||
* that directory.
|
||||
* <p>
|
||||
* If the protocol is not "file", then permission
|
||||
* to connect to and accept connections from the URL's host is granted.
|
||||
* @param codesource the codesource
|
||||
* @exception NullPointerException if {@code codesource} is {@code null}.
|
||||
* @return the permissions granted to the codesource
|
||||
*/
|
||||
protected PermissionCollection getPermissions(CodeSource codesource)
|
||||
{
|
||||
PermissionCollection perms = super.getPermissions(codesource);
|
||||
|
||||
URL url = codesource.getLocation();
|
||||
|
||||
Permission p;
|
||||
URLConnection urlConnection;
|
||||
|
||||
try {
|
||||
urlConnection = url.openConnection();
|
||||
p = urlConnection.getPermission();
|
||||
} catch (java.io.IOException ioe) {
|
||||
p = null;
|
||||
urlConnection = null;
|
||||
}
|
||||
|
||||
if (p instanceof FilePermission) {
|
||||
// if the permission has a separator char on the end,
|
||||
// it means the codebase is a directory, and we need
|
||||
// to add an additional permission to read recursively
|
||||
String path = p.getName();
|
||||
if (path.endsWith(File.separator)) {
|
||||
path += "-";
|
||||
p = new FilePermission(path, SecurityConstants.FILE_READ_ACTION);
|
||||
}
|
||||
} else if ((p == null) && (url.getProtocol().equals("file"))) {
|
||||
String path = url.getFile().replace('/', File.separatorChar);
|
||||
path = ParseUtil.decode(path);
|
||||
if (path.endsWith(File.separator))
|
||||
path += "-";
|
||||
p = new FilePermission(path, SecurityConstants.FILE_READ_ACTION);
|
||||
} else {
|
||||
/**
|
||||
* Not loading from a 'file:' URL so we want to give the class
|
||||
* permission to connect to and accept from the remote host
|
||||
* after we've made sure the host is the correct one and is valid.
|
||||
*/
|
||||
URL locUrl = url;
|
||||
if (urlConnection instanceof JarURLConnection) {
|
||||
locUrl = ((JarURLConnection)urlConnection).getJarFileURL();
|
||||
}
|
||||
String host = locUrl.getHost();
|
||||
if (host != null && (host.length() > 0))
|
||||
p = new SocketPermission(host,
|
||||
SecurityConstants.SOCKET_CONNECT_ACCEPT_ACTION);
|
||||
}
|
||||
|
||||
// make sure the person that created this class loader
|
||||
// would have this permission
|
||||
|
||||
if (p != null) {
|
||||
final SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
final Permission fp = p;
|
||||
AccessController.doPrivileged(new PrivilegedAction<Void>() {
|
||||
public Void run() throws SecurityException {
|
||||
sm.checkPermission(fp);
|
||||
return null;
|
||||
}
|
||||
}, acc);
|
||||
}
|
||||
perms.add(p);
|
||||
}
|
||||
return perms;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of URLClassLoader for the specified
|
||||
* URLs and parent class loader. If a security manager is
|
||||
* installed, the {@code loadClass} method of the URLClassLoader
|
||||
* returned by this method will invoke the
|
||||
* {@code SecurityManager.checkPackageAccess} method before
|
||||
* loading the class.
|
||||
*
|
||||
* @param urls the URLs to search for classes and resources
|
||||
* @param parent the parent class loader for delegation
|
||||
* @exception NullPointerException if {@code urls} is {@code null}.
|
||||
* @return the resulting class loader
|
||||
*/
|
||||
public static URLClassLoader newInstance(final URL[] urls,
|
||||
final ClassLoader parent) {
|
||||
// Save the caller's context
|
||||
final AccessControlContext acc = AccessController.getContext();
|
||||
// Need a privileged block to create the class loader
|
||||
URLClassLoader ucl = AccessController.doPrivileged(
|
||||
new PrivilegedAction<URLClassLoader>() {
|
||||
public URLClassLoader run() {
|
||||
return new FactoryURLClassLoader(urls, parent, acc);
|
||||
}
|
||||
});
|
||||
return ucl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of URLClassLoader for the specified
|
||||
* URLs and default parent class loader. If a security manager is
|
||||
* installed, the {@code loadClass} method of the URLClassLoader
|
||||
* returned by this method will invoke the
|
||||
* {@code SecurityManager.checkPackageAccess} before
|
||||
* loading the class.
|
||||
*
|
||||
* @param urls the URLs to search for classes and resources
|
||||
* @exception NullPointerException if {@code urls} is {@code null}.
|
||||
* @return the resulting class loader
|
||||
*/
|
||||
public static URLClassLoader newInstance(final URL[] urls) {
|
||||
// Save the caller's context
|
||||
final AccessControlContext acc = AccessController.getContext();
|
||||
// Need a privileged block to create the class loader
|
||||
URLClassLoader ucl = AccessController.doPrivileged(
|
||||
new PrivilegedAction<URLClassLoader>() {
|
||||
public URLClassLoader run() {
|
||||
return new FactoryURLClassLoader(urls, acc);
|
||||
}
|
||||
});
|
||||
return ucl;
|
||||
}
|
||||
|
||||
static {
|
||||
sun.misc.SharedSecrets.setJavaNetAccess (
|
||||
new sun.misc.JavaNetAccess() {
|
||||
public URLClassPath getURLClassPath (URLClassLoader u) {
|
||||
return u.ucp;
|
||||
}
|
||||
|
||||
public String getOriginalHostName(InetAddress ia) {
|
||||
return ia.holder.getOriginalHostName();
|
||||
}
|
||||
}
|
||||
);
|
||||
ClassLoader.registerAsParallelCapable();
|
||||
}
|
||||
}
|
||||
|
||||
final class FactoryURLClassLoader extends URLClassLoader {
|
||||
|
||||
static {
|
||||
ClassLoader.registerAsParallelCapable();
|
||||
}
|
||||
|
||||
FactoryURLClassLoader(URL[] urls, ClassLoader parent,
|
||||
AccessControlContext acc) {
|
||||
super(urls, parent, acc);
|
||||
}
|
||||
|
||||
FactoryURLClassLoader(URL[] urls, AccessControlContext acc) {
|
||||
super(urls, acc);
|
||||
}
|
||||
|
||||
public final Class<?> loadClass(String name, boolean resolve)
|
||||
throws ClassNotFoundException
|
||||
{
|
||||
// First check if we have permission to access the package. This
|
||||
// should go away once we've added support for exported packages.
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
int i = name.lastIndexOf('.');
|
||||
if (i != -1) {
|
||||
sm.checkPackageAccess(name.substring(0, i));
|
||||
}
|
||||
}
|
||||
return super.loadClass(name, resolve);
|
||||
}
|
||||
}
|
||||
1783
jdkSrc/jdk8/java/net/URLConnection.java
Normal file
1783
jdkSrc/jdk8/java/net/URLConnection.java
Normal file
File diff suppressed because it is too large
Load Diff
207
jdkSrc/jdk8/java/net/URLDecoder.java
Normal file
207
jdkSrc/jdk8/java/net/URLDecoder.java
Normal file
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* Utility class for HTML form decoding. This class contains static methods
|
||||
* for decoding a String from the <CODE>application/x-www-form-urlencoded</CODE>
|
||||
* MIME format.
|
||||
* <p>
|
||||
* The conversion process is the reverse of that used by the URLEncoder class. It is assumed
|
||||
* that all characters in the encoded string are one of the following:
|
||||
* "{@code a}" through "{@code z}",
|
||||
* "{@code A}" through "{@code Z}",
|
||||
* "{@code 0}" through "{@code 9}", and
|
||||
* "{@code -}", "{@code _}",
|
||||
* "{@code .}", and "{@code *}". The
|
||||
* character "{@code %}" is allowed but is interpreted
|
||||
* as the start of a special escaped sequence.
|
||||
* <p>
|
||||
* The following rules are applied in the conversion:
|
||||
*
|
||||
* <ul>
|
||||
* <li>The alphanumeric characters "{@code a}" through
|
||||
* "{@code z}", "{@code A}" through
|
||||
* "{@code Z}" and "{@code 0}"
|
||||
* through "{@code 9}" remain the same.
|
||||
* <li>The special characters "{@code .}",
|
||||
* "{@code -}", "{@code *}", and
|
||||
* "{@code _}" remain the same.
|
||||
* <li>The plus sign "{@code +}" is converted into a
|
||||
* space character " " .
|
||||
* <li>A sequence of the form "<i>{@code %xy}</i>" will be
|
||||
* treated as representing a byte where <i>xy</i> is the two-digit
|
||||
* hexadecimal representation of the 8 bits. Then, all substrings
|
||||
* that contain one or more of these byte sequences consecutively
|
||||
* will be replaced by the character(s) whose encoding would result
|
||||
* in those consecutive bytes.
|
||||
* The encoding scheme used to decode these characters may be specified,
|
||||
* or if unspecified, the default encoding of the platform will be used.
|
||||
* </ul>
|
||||
* <p>
|
||||
* There are two possible ways in which this decoder could deal with
|
||||
* illegal strings. It could either leave illegal characters alone or
|
||||
* it could throw an {@link java.lang.IllegalArgumentException}.
|
||||
* Which approach the decoder takes is left to the
|
||||
* implementation.
|
||||
*
|
||||
* @author Mark Chamness
|
||||
* @author Michael McCloskey
|
||||
* @since 1.2
|
||||
*/
|
||||
|
||||
public class URLDecoder {
|
||||
|
||||
// The platform default encoding
|
||||
static String dfltEncName = URLEncoder.dfltEncName;
|
||||
|
||||
/**
|
||||
* Decodes a {@code x-www-form-urlencoded} string.
|
||||
* The platform's default encoding is used to determine what characters
|
||||
* are represented by any consecutive sequences of the form
|
||||
* "<i>{@code %xy}</i>".
|
||||
* @param s the {@code String} to decode
|
||||
* @deprecated The resulting string may vary depending on the platform's
|
||||
* default encoding. Instead, use the decode(String,String) method
|
||||
* to specify the encoding.
|
||||
* @return the newly decoded {@code String}
|
||||
*/
|
||||
@Deprecated
|
||||
public static String decode(String s) {
|
||||
|
||||
String str = null;
|
||||
|
||||
try {
|
||||
str = decode(s, dfltEncName);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
// The system should always have the platform default
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes a {@code application/x-www-form-urlencoded} string using a specific
|
||||
* encoding scheme.
|
||||
* The supplied encoding is used to determine
|
||||
* what characters are represented by any consecutive sequences of the
|
||||
* form "<i>{@code %xy}</i>".
|
||||
* <p>
|
||||
* <em><strong>Note:</strong> The <a href=
|
||||
* "http://www.w3.org/TR/html40/appendix/notes.html#non-ascii-chars">
|
||||
* World Wide Web Consortium Recommendation</a> states that
|
||||
* UTF-8 should be used. Not doing so may introduce
|
||||
* incompatibilities.</em>
|
||||
*
|
||||
* @param s the {@code String} to decode
|
||||
* @param enc The name of a supported
|
||||
* <a href="../lang/package-summary.html#charenc">character
|
||||
* encoding</a>.
|
||||
* @return the newly decoded {@code String}
|
||||
* @exception UnsupportedEncodingException
|
||||
* If character encoding needs to be consulted, but
|
||||
* named character encoding is not supported
|
||||
* @see URLEncoder#encode(java.lang.String, java.lang.String)
|
||||
* @since 1.4
|
||||
*/
|
||||
public static String decode(String s, String enc)
|
||||
throws UnsupportedEncodingException{
|
||||
|
||||
boolean needToChange = false;
|
||||
int numChars = s.length();
|
||||
StringBuffer sb = new StringBuffer(numChars > 500 ? numChars / 2 : numChars);
|
||||
int i = 0;
|
||||
|
||||
if (enc.length() == 0) {
|
||||
throw new UnsupportedEncodingException ("URLDecoder: empty string enc parameter");
|
||||
}
|
||||
|
||||
char c;
|
||||
byte[] bytes = null;
|
||||
while (i < numChars) {
|
||||
c = s.charAt(i);
|
||||
switch (c) {
|
||||
case '+':
|
||||
sb.append(' ');
|
||||
i++;
|
||||
needToChange = true;
|
||||
break;
|
||||
case '%':
|
||||
/*
|
||||
* Starting with this instance of %, process all
|
||||
* consecutive substrings of the form %xy. Each
|
||||
* substring %xy will yield a byte. Convert all
|
||||
* consecutive bytes obtained this way to whatever
|
||||
* character(s) they represent in the provided
|
||||
* encoding.
|
||||
*/
|
||||
|
||||
try {
|
||||
|
||||
// (numChars-i)/3 is an upper bound for the number
|
||||
// of remaining bytes
|
||||
if (bytes == null)
|
||||
bytes = new byte[(numChars-i)/3];
|
||||
int pos = 0;
|
||||
|
||||
while ( ((i+2) < numChars) &&
|
||||
(c=='%')) {
|
||||
int v = Integer.parseInt(s.substring(i+1,i+3),16);
|
||||
if (v < 0)
|
||||
throw new IllegalArgumentException("URLDecoder: Illegal hex characters in escape (%) pattern - negative value");
|
||||
bytes[pos++] = (byte) v;
|
||||
i+= 3;
|
||||
if (i < numChars)
|
||||
c = s.charAt(i);
|
||||
}
|
||||
|
||||
// A trailing, incomplete byte encoding such as
|
||||
// "%x" will cause an exception to be thrown
|
||||
|
||||
if ((i < numChars) && (c=='%'))
|
||||
throw new IllegalArgumentException(
|
||||
"URLDecoder: Incomplete trailing escape (%) pattern");
|
||||
|
||||
sb.append(new String(bytes, 0, pos, enc));
|
||||
} catch (NumberFormatException e) {
|
||||
throw new IllegalArgumentException(
|
||||
"URLDecoder: Illegal hex characters in escape (%) pattern - "
|
||||
+ e.getMessage());
|
||||
}
|
||||
needToChange = true;
|
||||
break;
|
||||
default:
|
||||
sb.append(c);
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (needToChange? sb.toString() : s);
|
||||
}
|
||||
}
|
||||
292
jdkSrc/jdk8/java/net/URLEncoder.java
Normal file
292
jdkSrc/jdk8/java/net/URLEncoder.java
Normal file
@@ -0,0 +1,292 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.io.CharArrayWriter;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.IllegalCharsetNameException;
|
||||
import java.nio.charset.UnsupportedCharsetException ;
|
||||
import java.util.BitSet;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import sun.security.action.GetBooleanAction;
|
||||
import sun.security.action.GetPropertyAction;
|
||||
|
||||
/**
|
||||
* Utility class for HTML form encoding. This class contains static methods
|
||||
* for converting a String to the <CODE>application/x-www-form-urlencoded</CODE> MIME
|
||||
* format. For more information about HTML form encoding, consult the HTML
|
||||
* <A HREF="http://www.w3.org/TR/html4/">specification</A>.
|
||||
*
|
||||
* <p>
|
||||
* When encoding a String, the following rules apply:
|
||||
*
|
||||
* <ul>
|
||||
* <li>The alphanumeric characters "{@code a}" through
|
||||
* "{@code z}", "{@code A}" through
|
||||
* "{@code Z}" and "{@code 0}"
|
||||
* through "{@code 9}" remain the same.
|
||||
* <li>The special characters "{@code .}",
|
||||
* "{@code -}", "{@code *}", and
|
||||
* "{@code _}" remain the same.
|
||||
* <li>The space character " " is
|
||||
* converted into a plus sign "{@code +}".
|
||||
* <li>All other characters are unsafe and are first converted into
|
||||
* one or more bytes using some encoding scheme. Then each byte is
|
||||
* represented by the 3-character string
|
||||
* "<i>{@code %xy}</i>", where <i>xy</i> is the
|
||||
* two-digit hexadecimal representation of the byte.
|
||||
* The recommended encoding scheme to use is UTF-8. However,
|
||||
* for compatibility reasons, if an encoding is not specified,
|
||||
* then the default encoding of the platform is used.
|
||||
* </ul>
|
||||
*
|
||||
* <p>
|
||||
* For example using UTF-8 as the encoding scheme the string "The
|
||||
* string ü@foo-bar" would get converted to
|
||||
* "The+string+%C3%BC%40foo-bar" because in UTF-8 the character
|
||||
* ü is encoded as two bytes C3 (hex) and BC (hex), and the
|
||||
* character @ is encoded as one byte 40 (hex).
|
||||
*
|
||||
* @author Herb Jellinek
|
||||
* @since JDK1.0
|
||||
*/
|
||||
public class URLEncoder {
|
||||
static BitSet dontNeedEncoding;
|
||||
static final int caseDiff = ('a' - 'A');
|
||||
static String dfltEncName = null;
|
||||
|
||||
static {
|
||||
|
||||
/* The list of characters that are not encoded has been
|
||||
* determined as follows:
|
||||
*
|
||||
* RFC 2396 states:
|
||||
* -----
|
||||
* Data characters that are allowed in a URI but do not have a
|
||||
* reserved purpose are called unreserved. These include upper
|
||||
* and lower case letters, decimal digits, and a limited set of
|
||||
* punctuation marks and symbols.
|
||||
*
|
||||
* unreserved = alphanum | mark
|
||||
*
|
||||
* mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"
|
||||
*
|
||||
* Unreserved characters can be escaped without changing the
|
||||
* semantics of the URI, but this should not be done unless the
|
||||
* URI is being used in a context that does not allow the
|
||||
* unescaped character to appear.
|
||||
* -----
|
||||
*
|
||||
* It appears that both Netscape and Internet Explorer escape
|
||||
* all special characters from this list with the exception
|
||||
* of "-", "_", ".", "*". While it is not clear why they are
|
||||
* escaping the other characters, perhaps it is safest to
|
||||
* assume that there might be contexts in which the others
|
||||
* are unsafe if not escaped. Therefore, we will use the same
|
||||
* list. It is also noteworthy that this is consistent with
|
||||
* O'Reilly's "HTML: The Definitive Guide" (page 164).
|
||||
*
|
||||
* As a last note, Intenet Explorer does not encode the "@"
|
||||
* character which is clearly not unreserved according to the
|
||||
* RFC. We are being consistent with the RFC in this matter,
|
||||
* as is Netscape.
|
||||
*
|
||||
*/
|
||||
|
||||
dontNeedEncoding = new BitSet(256);
|
||||
int i;
|
||||
for (i = 'a'; i <= 'z'; i++) {
|
||||
dontNeedEncoding.set(i);
|
||||
}
|
||||
for (i = 'A'; i <= 'Z'; i++) {
|
||||
dontNeedEncoding.set(i);
|
||||
}
|
||||
for (i = '0'; i <= '9'; i++) {
|
||||
dontNeedEncoding.set(i);
|
||||
}
|
||||
dontNeedEncoding.set(' '); /* encoding a space to a + is done
|
||||
* in the encode() method */
|
||||
dontNeedEncoding.set('-');
|
||||
dontNeedEncoding.set('_');
|
||||
dontNeedEncoding.set('.');
|
||||
dontNeedEncoding.set('*');
|
||||
|
||||
dfltEncName = AccessController.doPrivileged(
|
||||
new GetPropertyAction("file.encoding")
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* You can't call the constructor.
|
||||
*/
|
||||
private URLEncoder() { }
|
||||
|
||||
/**
|
||||
* Translates a string into {@code x-www-form-urlencoded}
|
||||
* format. This method uses the platform's default encoding
|
||||
* as the encoding scheme to obtain the bytes for unsafe characters.
|
||||
*
|
||||
* @param s {@code String} to be translated.
|
||||
* @deprecated The resulting string may vary depending on the platform's
|
||||
* default encoding. Instead, use the encode(String,String)
|
||||
* method to specify the encoding.
|
||||
* @return the translated {@code String}.
|
||||
*/
|
||||
@Deprecated
|
||||
public static String encode(String s) {
|
||||
|
||||
String str = null;
|
||||
|
||||
try {
|
||||
str = encode(s, dfltEncName);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
// The system should always have the platform default
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates a string into {@code application/x-www-form-urlencoded}
|
||||
* format using a specific encoding scheme. This method uses the
|
||||
* supplied encoding scheme to obtain the bytes for unsafe
|
||||
* characters.
|
||||
* <p>
|
||||
* <em><strong>Note:</strong> The <a href=
|
||||
* "http://www.w3.org/TR/html40/appendix/notes.html#non-ascii-chars">
|
||||
* World Wide Web Consortium Recommendation</a> states that
|
||||
* UTF-8 should be used. Not doing so may introduce
|
||||
* incompatibilities.</em>
|
||||
*
|
||||
* @param s {@code String} to be translated.
|
||||
* @param enc The name of a supported
|
||||
* <a href="../lang/package-summary.html#charenc">character
|
||||
* encoding</a>.
|
||||
* @return the translated {@code String}.
|
||||
* @exception UnsupportedEncodingException
|
||||
* If the named encoding is not supported
|
||||
* @see URLDecoder#decode(java.lang.String, java.lang.String)
|
||||
* @since 1.4
|
||||
*/
|
||||
public static String encode(String s, String enc)
|
||||
throws UnsupportedEncodingException {
|
||||
|
||||
boolean needToChange = false;
|
||||
StringBuffer out = new StringBuffer(s.length());
|
||||
Charset charset;
|
||||
CharArrayWriter charArrayWriter = new CharArrayWriter();
|
||||
|
||||
if (enc == null)
|
||||
throw new NullPointerException("charsetName");
|
||||
|
||||
try {
|
||||
charset = Charset.forName(enc);
|
||||
} catch (IllegalCharsetNameException e) {
|
||||
throw new UnsupportedEncodingException(enc);
|
||||
} catch (UnsupportedCharsetException e) {
|
||||
throw new UnsupportedEncodingException(enc);
|
||||
}
|
||||
|
||||
for (int i = 0; i < s.length();) {
|
||||
int c = (int) s.charAt(i);
|
||||
//System.out.println("Examining character: " + c);
|
||||
if (dontNeedEncoding.get(c)) {
|
||||
if (c == ' ') {
|
||||
c = '+';
|
||||
needToChange = true;
|
||||
}
|
||||
//System.out.println("Storing: " + c);
|
||||
out.append((char)c);
|
||||
i++;
|
||||
} else {
|
||||
// convert to external encoding before hex conversion
|
||||
do {
|
||||
charArrayWriter.write(c);
|
||||
/*
|
||||
* If this character represents the start of a Unicode
|
||||
* surrogate pair, then pass in two characters. It's not
|
||||
* clear what should be done if a bytes reserved in the
|
||||
* surrogate pairs range occurs outside of a legal
|
||||
* surrogate pair. For now, just treat it as if it were
|
||||
* any other character.
|
||||
*/
|
||||
if (c >= 0xD800 && c <= 0xDBFF) {
|
||||
/*
|
||||
System.out.println(Integer.toHexString(c)
|
||||
+ " is high surrogate");
|
||||
*/
|
||||
if ( (i+1) < s.length()) {
|
||||
int d = (int) s.charAt(i+1);
|
||||
/*
|
||||
System.out.println("\tExamining "
|
||||
+ Integer.toHexString(d));
|
||||
*/
|
||||
if (d >= 0xDC00 && d <= 0xDFFF) {
|
||||
/*
|
||||
System.out.println("\t"
|
||||
+ Integer.toHexString(d)
|
||||
+ " is low surrogate");
|
||||
*/
|
||||
charArrayWriter.write(d);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
i++;
|
||||
} while (i < s.length() && !dontNeedEncoding.get((c = (int) s.charAt(i))));
|
||||
|
||||
charArrayWriter.flush();
|
||||
String str = new String(charArrayWriter.toCharArray());
|
||||
byte[] ba = str.getBytes(charset);
|
||||
for (int j = 0; j < ba.length; j++) {
|
||||
out.append('%');
|
||||
char ch = Character.forDigit((ba[j] >> 4) & 0xF, 16);
|
||||
// converting to use uppercase letter as part of
|
||||
// the hex value if ch is a letter.
|
||||
if (Character.isLetter(ch)) {
|
||||
ch -= caseDiff;
|
||||
}
|
||||
out.append(ch);
|
||||
ch = Character.forDigit(ba[j] & 0xF, 16);
|
||||
if (Character.isLetter(ch)) {
|
||||
ch -= caseDiff;
|
||||
}
|
||||
out.append(ch);
|
||||
}
|
||||
charArrayWriter.reset();
|
||||
needToChange = true;
|
||||
}
|
||||
}
|
||||
|
||||
return (needToChange? out.toString() : s);
|
||||
}
|
||||
}
|
||||
539
jdkSrc/jdk8/java/net/URLPermission.java
Normal file
539
jdkSrc/jdk8/java/net/URLPermission.java
Normal file
@@ -0,0 +1,539 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.security.Permission;
|
||||
|
||||
/**
|
||||
* Represents permission to access a resource or set of resources defined by a
|
||||
* given url, and for a given set of user-settable request methods
|
||||
* and request headers. The <i>name</i> of the permission is the url string.
|
||||
* The <i>actions</i> string is a concatenation of the request methods and headers.
|
||||
* The range of method and header names is not restricted by this class.
|
||||
* <p><b>The url</b><p>
|
||||
* The url string has the following expected structure.
|
||||
* <pre>
|
||||
* scheme : // authority [ / path ]
|
||||
* </pre>
|
||||
* <i>scheme</i> will typically be http or https, but is not restricted by this
|
||||
* class.
|
||||
* <i>authority</i> is specified as:
|
||||
* <pre>
|
||||
* authority = [ userinfo @ ] hostrange [ : portrange ]
|
||||
* portrange = portnumber | -portnumber | portnumber-[portnumber] | *
|
||||
* hostrange = ([*.] dnsname) | IPv4address | IPv6address
|
||||
* </pre>
|
||||
* <i>dnsname</i> is a standard DNS host or domain name, ie. one or more labels
|
||||
* separated by ".". <i>IPv4address</i> is a standard literal IPv4 address and
|
||||
* <i>IPv6address</i> is as defined in <a href="http://www.ietf.org/rfc/rfc2732.txt">
|
||||
* RFC 2732</a>. Literal IPv6 addresses must however, be enclosed in '[]' characters.
|
||||
* The <i>dnsname</i> specification can be preceded by "*." which means
|
||||
* the name will match any hostname whose right-most domain labels are the same as
|
||||
* this name. For example, "*.oracle.com" matches "foo.bar.oracle.com"
|
||||
* <p>
|
||||
* <i>portrange</i> is used to specify a port number, or a bounded or unbounded range of ports
|
||||
* that this permission applies to. If portrange is absent or invalid, then a default
|
||||
* port number is assumed if the scheme is {@code http} (default 80) or {@code https}
|
||||
* (default 443). No default is assumed for other schemes. A wildcard may be specified
|
||||
* which means all ports.
|
||||
* <p>
|
||||
* <i>userinfo</i> is optional. A userinfo component if present, is ignored when
|
||||
* creating a URLPermission, and has no effect on any other methods defined by this class.
|
||||
* <p>
|
||||
* The <i>path</i> component comprises a sequence of path segments,
|
||||
* separated by '/' characters. <i>path</i> may also be empty. The path is specified
|
||||
* in a similar way to the path in {@link java.io.FilePermission}. There are
|
||||
* three different ways as the following examples show:
|
||||
* <table border>
|
||||
* <caption>URL Examples</caption>
|
||||
* <tr><th>Example url</th><th>Description</th></tr>
|
||||
* <tr><td style="white-space:nowrap;">http://www.oracle.com/a/b/c.html</td>
|
||||
* <td>A url which identifies a specific (single) resource</td>
|
||||
* </tr>
|
||||
* <tr><td>http://www.oracle.com/a/b/*</td>
|
||||
* <td>The '*' character refers to all resources in the same "directory" - in
|
||||
* other words all resources with the same number of path components, and
|
||||
* which only differ in the final path component, represented by the '*'.
|
||||
* </td>
|
||||
* </tr>
|
||||
* <tr><td>http://www.oracle.com/a/b/-</td>
|
||||
* <td>The '-' character refers to all resources recursively below the
|
||||
* preceding path (eg. http://www.oracle.com/a/b/c/d/e.html matches this
|
||||
* example).
|
||||
* </td>
|
||||
* </tr>
|
||||
* </table>
|
||||
* <p>
|
||||
* The '*' and '-' may only be specified in the final segment of a path and must be
|
||||
* the only character in that segment. Any query or fragment components of the
|
||||
* url are ignored when constructing URLPermissions.
|
||||
* <p>
|
||||
* As a special case, urls of the form, "scheme:*" are accepted to
|
||||
* mean any url of the given scheme.
|
||||
* <p>
|
||||
* The <i>scheme</i> and <i>authority</i> components of the url string are handled
|
||||
* without regard to case. This means {@link #equals(Object)},
|
||||
* {@link #hashCode()} and {@link #implies(Permission)} are case insensitive with respect
|
||||
* to these components. If the <i>authority</i> contains a literal IP address,
|
||||
* then the address is normalized for comparison. The path component is case sensitive.
|
||||
* <p><b>The actions string</b><p>
|
||||
* The actions string of a URLPermission is a concatenation of the <i>method list</i>
|
||||
* and the <i>request headers list</i>. These are lists of the permitted request
|
||||
* methods and permitted request headers of the permission (respectively). The two lists
|
||||
* are separated by a colon ':' character and elements of each list are comma separated.
|
||||
* Some examples are:
|
||||
* <pre>
|
||||
* "POST,GET,DELETE"
|
||||
* "GET:X-Foo-Request,X-Bar-Request"
|
||||
* "POST,GET:Header1,Header2"
|
||||
* </pre>
|
||||
* The first example specifies the methods: POST, GET and DELETE, but no request headers.
|
||||
* The second example specifies one request method and two headers. The third
|
||||
* example specifies two request methods, and two headers.
|
||||
* <p>
|
||||
* The colon separator need not be present if the request headers list is empty.
|
||||
* No white-space is permitted in the actions string. The action strings supplied to
|
||||
* the URLPermission constructors are case-insensitive and are normalized by converting
|
||||
* method names to upper-case and header names to the form defines in RFC2616 (lower case
|
||||
* with initial letter of each word capitalized). Either list can contain a wild-card '*'
|
||||
* character which signifies all request methods or headers respectively.
|
||||
* <p>
|
||||
* Note. Depending on the context of use, some request methods and headers may be permitted
|
||||
* at all times, and others may not be permitted at any time. For example, the
|
||||
* HTTP protocol handler might disallow certain headers such as Content-Length
|
||||
* from being set by application code, regardless of whether the security policy
|
||||
* in force, permits it.
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
public final class URLPermission extends Permission {
|
||||
|
||||
private static final long serialVersionUID = -2702463814894478682L;
|
||||
|
||||
private transient String scheme;
|
||||
private transient String ssp; // scheme specific part
|
||||
private transient String path;
|
||||
private transient List<String> methods;
|
||||
private transient List<String> requestHeaders;
|
||||
private transient Authority authority;
|
||||
|
||||
// serialized field
|
||||
private String actions;
|
||||
|
||||
/**
|
||||
* Creates a new URLPermission from a url string and which permits the given
|
||||
* request methods and user-settable request headers.
|
||||
* The name of the permission is the url string it was created with. Only the scheme,
|
||||
* authority and path components of the url are used internally. Any fragment or query
|
||||
* components are ignored. The permissions action string is as specified above.
|
||||
*
|
||||
* @param url the url string
|
||||
*
|
||||
* @param actions the actions string
|
||||
*
|
||||
* @exception IllegalArgumentException if url is invalid or if actions contains white-space.
|
||||
*/
|
||||
public URLPermission(String url, String actions) {
|
||||
super(url);
|
||||
init(actions);
|
||||
}
|
||||
|
||||
private void init(String actions) {
|
||||
parseURI(getName());
|
||||
int colon = actions.indexOf(':');
|
||||
if (actions.lastIndexOf(':') != colon) {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid actions string: \"" + actions + "\"");
|
||||
}
|
||||
|
||||
String methods, headers;
|
||||
if (colon == -1) {
|
||||
methods = actions;
|
||||
headers = "";
|
||||
} else {
|
||||
methods = actions.substring(0, colon);
|
||||
headers = actions.substring(colon+1);
|
||||
}
|
||||
|
||||
List<String> l = normalizeMethods(methods);
|
||||
Collections.sort(l);
|
||||
this.methods = Collections.unmodifiableList(l);
|
||||
|
||||
l = normalizeHeaders(headers);
|
||||
Collections.sort(l);
|
||||
this.requestHeaders = Collections.unmodifiableList(l);
|
||||
|
||||
this.actions = actions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a URLPermission with the given url string and unrestricted
|
||||
* methods and request headers by invoking the two argument
|
||||
* constructor as follows: URLPermission(url, "*:*")
|
||||
*
|
||||
* @param url the url string
|
||||
*
|
||||
* @throws IllegalArgumentException if url does not result in a valid {@link URI}
|
||||
*/
|
||||
public URLPermission(String url) {
|
||||
this(url, "*:*");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the normalized method list and request
|
||||
* header list, in the form:
|
||||
* <pre>
|
||||
* "method-names : header-names"
|
||||
* </pre>
|
||||
* <p>
|
||||
* where method-names is the list of methods separated by commas
|
||||
* and header-names is the list of permitted headers separated by commas.
|
||||
* There is no white space in the returned String. If header-names is empty
|
||||
* then the colon separator will not be present.
|
||||
*/
|
||||
public String getActions() {
|
||||
return actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this URLPermission implies the given permission.
|
||||
* Specifically, the following checks are done as if in the
|
||||
* following sequence:
|
||||
* <ul>
|
||||
* <li>if 'p' is not an instance of URLPermission return false</li>
|
||||
* <li>if any of p's methods are not in this's method list, and if
|
||||
* this's method list is not equal to "*", then return false.</li>
|
||||
* <li>if any of p's headers are not in this's request header list, and if
|
||||
* this's request header list is not equal to "*", then return false.</li>
|
||||
* <li>if this's url scheme is not equal to p's url scheme return false</li>
|
||||
* <li>if the scheme specific part of this's url is '*' return true</li>
|
||||
* <li>if the set of hosts defined by p's url hostrange is not a subset of
|
||||
* this's url hostrange then return false. For example, "*.foo.oracle.com"
|
||||
* is a subset of "*.oracle.com". "foo.bar.oracle.com" is not
|
||||
* a subset of "*.foo.oracle.com"</li>
|
||||
* <li>if the portrange defined by p's url is not a subset of the
|
||||
* portrange defined by this's url then return false.
|
||||
* <li>if the path or paths specified by p's url are contained in the
|
||||
* set of paths specified by this's url, then return true
|
||||
* <li>otherwise, return false</li>
|
||||
* </ul>
|
||||
* <p>Some examples of how paths are matched are shown below:
|
||||
* <table border>
|
||||
* <caption>Examples of Path Matching</caption>
|
||||
* <tr><th>this's path</th><th>p's path</th><th>match</th></tr>
|
||||
* <tr><td>/a/b</td><td>/a/b</td><td>yes</td></tr>
|
||||
* <tr><td>/a/b/*</td><td>/a/b/c</td><td>yes</td></tr>
|
||||
* <tr><td>/a/b/*</td><td>/a/b/c/d</td><td>no</td></tr>
|
||||
* <tr><td>/a/b/-</td><td>/a/b/c/d</td><td>yes</td></tr>
|
||||
* <tr><td>/a/b/-</td><td>/a/b/c/d/e</td><td>yes</td></tr>
|
||||
* <tr><td>/a/b/-</td><td>/a/b/c/*</td><td>yes</td></tr>
|
||||
* <tr><td>/a/b/*</td><td>/a/b/c/-</td><td>no</td></tr>
|
||||
* </table>
|
||||
*/
|
||||
public boolean implies(Permission p) {
|
||||
if (! (p instanceof URLPermission)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
URLPermission that = (URLPermission)p;
|
||||
|
||||
if (!this.methods.get(0).equals("*") &&
|
||||
Collections.indexOfSubList(this.methods, that.methods) == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.requestHeaders.isEmpty() && !that.requestHeaders.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.requestHeaders.isEmpty() &&
|
||||
!this.requestHeaders.get(0).equals("*") &&
|
||||
Collections.indexOfSubList(this.requestHeaders,
|
||||
that.requestHeaders) == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.scheme.equals(that.scheme)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.ssp.equals("*")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!this.authority.implies(that.authority)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.path == null) {
|
||||
return that.path == null;
|
||||
}
|
||||
if (that.path == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.path.endsWith("/-")) {
|
||||
String thisprefix = this.path.substring(0, this.path.length() - 1);
|
||||
return that.path.startsWith(thisprefix);
|
||||
}
|
||||
|
||||
if (this.path.endsWith("/*")) {
|
||||
String thisprefix = this.path.substring(0, this.path.length() - 1);
|
||||
if (!that.path.startsWith(thisprefix)) {
|
||||
return false;
|
||||
}
|
||||
String thatsuffix = that.path.substring(thisprefix.length());
|
||||
// suffix must not contain '/' chars
|
||||
if (thatsuffix.indexOf('/') != -1) {
|
||||
return false;
|
||||
}
|
||||
if (thatsuffix.equals("-")) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return this.path.equals(that.path);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if, this.getActions().equals(p.getActions())
|
||||
* and p's url equals this's url. Returns false otherwise.
|
||||
*/
|
||||
public boolean equals(Object p) {
|
||||
if (!(p instanceof URLPermission)) {
|
||||
return false;
|
||||
}
|
||||
URLPermission that = (URLPermission)p;
|
||||
if (!this.scheme.equals(that.scheme)) {
|
||||
return false;
|
||||
}
|
||||
if (!this.getActions().equals(that.getActions())) {
|
||||
return false;
|
||||
}
|
||||
if (!this.authority.equals(that.authority)) {
|
||||
return false;
|
||||
}
|
||||
if (this.path != null) {
|
||||
return this.path.equals(that.path);
|
||||
} else {
|
||||
return that.path == null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hashcode calculated from the hashcode of the
|
||||
* actions String and the url string.
|
||||
*/
|
||||
public int hashCode() {
|
||||
return getActions().hashCode()
|
||||
+ scheme.hashCode()
|
||||
+ authority.hashCode()
|
||||
+ (path == null ? 0 : path.hashCode());
|
||||
}
|
||||
|
||||
|
||||
private List<String> normalizeMethods(String methods) {
|
||||
List<String> l = new ArrayList<>();
|
||||
StringBuilder b = new StringBuilder();
|
||||
for (int i=0; i<methods.length(); i++) {
|
||||
char c = methods.charAt(i);
|
||||
if (c == ',') {
|
||||
String s = b.toString();
|
||||
if (s.length() > 0)
|
||||
l.add(s);
|
||||
b = new StringBuilder();
|
||||
} else if (c == ' ' || c == '\t') {
|
||||
throw new IllegalArgumentException(
|
||||
"White space not allowed in methods: \"" + methods + "\"");
|
||||
} else {
|
||||
if (c >= 'a' && c <= 'z') {
|
||||
c += 'A' - 'a';
|
||||
}
|
||||
b.append(c);
|
||||
}
|
||||
}
|
||||
String s = b.toString();
|
||||
if (s.length() > 0)
|
||||
l.add(s);
|
||||
return l;
|
||||
}
|
||||
|
||||
private List<String> normalizeHeaders(String headers) {
|
||||
List<String> l = new ArrayList<>();
|
||||
StringBuilder b = new StringBuilder();
|
||||
boolean capitalizeNext = true;
|
||||
for (int i=0; i<headers.length(); i++) {
|
||||
char c = headers.charAt(i);
|
||||
if (c >= 'a' && c <= 'z') {
|
||||
if (capitalizeNext) {
|
||||
c += 'A' - 'a';
|
||||
capitalizeNext = false;
|
||||
}
|
||||
b.append(c);
|
||||
} else if (c == ' ' || c == '\t') {
|
||||
throw new IllegalArgumentException(
|
||||
"White space not allowed in headers: \"" + headers + "\"");
|
||||
} else if (c == '-') {
|
||||
capitalizeNext = true;
|
||||
b.append(c);
|
||||
} else if (c == ',') {
|
||||
String s = b.toString();
|
||||
if (s.length() > 0)
|
||||
l.add(s);
|
||||
b = new StringBuilder();
|
||||
capitalizeNext = true;
|
||||
} else {
|
||||
capitalizeNext = false;
|
||||
b.append(c);
|
||||
}
|
||||
}
|
||||
String s = b.toString();
|
||||
if (s.length() > 0)
|
||||
l.add(s);
|
||||
return l;
|
||||
}
|
||||
|
||||
private void parseURI(String url) {
|
||||
int len = url.length();
|
||||
int delim = url.indexOf(':');
|
||||
if (delim == -1 || delim + 1 == len) {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid URL string: \"" + url + "\"");
|
||||
}
|
||||
scheme = url.substring(0, delim).toLowerCase();
|
||||
this.ssp = url.substring(delim + 1);
|
||||
|
||||
if (!ssp.startsWith("//")) {
|
||||
if (!ssp.equals("*")) {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid URL string: \"" + url + "\"");
|
||||
}
|
||||
this.authority = new Authority(scheme, "*");
|
||||
return;
|
||||
}
|
||||
String authpath = ssp.substring(2);
|
||||
|
||||
delim = authpath.indexOf('/');
|
||||
String auth;
|
||||
if (delim == -1) {
|
||||
this.path = "";
|
||||
auth = authpath;
|
||||
} else {
|
||||
auth = authpath.substring(0, delim);
|
||||
this.path = authpath.substring(delim);
|
||||
}
|
||||
this.authority = new Authority(scheme, auth.toLowerCase());
|
||||
}
|
||||
|
||||
private String actions() {
|
||||
StringBuilder b = new StringBuilder();
|
||||
for (String s : methods) {
|
||||
b.append(s);
|
||||
}
|
||||
b.append(":");
|
||||
for (String s : requestHeaders) {
|
||||
b.append(s);
|
||||
}
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* restore the state of this object from stream
|
||||
*/
|
||||
private void readObject(ObjectInputStream s)
|
||||
throws IOException, ClassNotFoundException {
|
||||
ObjectInputStream.GetField fields = s.readFields();
|
||||
String actions = (String)fields.get("actions", null);
|
||||
|
||||
init(actions);
|
||||
}
|
||||
|
||||
static class Authority {
|
||||
HostPortrange p;
|
||||
|
||||
Authority(String scheme, String authority) {
|
||||
int at = authority.indexOf('@');
|
||||
if (at == -1) {
|
||||
p = new HostPortrange(scheme, authority);
|
||||
} else {
|
||||
p = new HostPortrange(scheme, authority.substring(at+1));
|
||||
}
|
||||
}
|
||||
|
||||
boolean implies(Authority other) {
|
||||
return impliesHostrange(other) && impliesPortrange(other);
|
||||
}
|
||||
|
||||
private boolean impliesHostrange(Authority that) {
|
||||
String thishost = this.p.hostname();
|
||||
String thathost = that.p.hostname();
|
||||
|
||||
if (p.wildcard() && thishost.equals("")) {
|
||||
// this "*" implies all others
|
||||
return true;
|
||||
}
|
||||
if (that.p.wildcard() && thathost.equals("")) {
|
||||
// that "*" can only be implied by this "*"
|
||||
return false;
|
||||
}
|
||||
if (thishost.equals(thathost)) {
|
||||
// covers all cases of literal IP addresses and fixed
|
||||
// domain names.
|
||||
return true;
|
||||
}
|
||||
if (this.p.wildcard()) {
|
||||
// this "*.foo.com" implies "bub.bar.foo.com"
|
||||
return thathost.endsWith(thishost);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean impliesPortrange(Authority that) {
|
||||
int[] thisrange = this.p.portrange();
|
||||
int[] thatrange = that.p.portrange();
|
||||
if (thisrange[0] == -1) {
|
||||
/* port not specified non http/s URL */
|
||||
return true;
|
||||
}
|
||||
return thisrange[0] <= thatrange[0] &&
|
||||
thisrange[1] >= thatrange[1];
|
||||
}
|
||||
|
||||
boolean equals(Authority that) {
|
||||
return this.p.equals(that.p);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return p.hashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
583
jdkSrc/jdk8/java/net/URLStreamHandler.java
Normal file
583
jdkSrc/jdk8/java/net/URLStreamHandler.java
Normal file
@@ -0,0 +1,583 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.File;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Hashtable;
|
||||
import sun.net.util.IPAddressUtil;
|
||||
import sun.net.www.ParseUtil;
|
||||
|
||||
/**
|
||||
* The abstract class {@code URLStreamHandler} is the common
|
||||
* superclass for all stream protocol handlers. A stream protocol
|
||||
* handler knows how to make a connection for a particular protocol
|
||||
* type, such as {@code http} or {@code https}.
|
||||
* <p>
|
||||
* In most cases, an instance of a {@code URLStreamHandler}
|
||||
* subclass is not created directly by an application. Rather, the
|
||||
* first time a protocol name is encountered when constructing a
|
||||
* {@code URL}, the appropriate stream protocol handler is
|
||||
* automatically loaded.
|
||||
*
|
||||
* @author James Gosling
|
||||
* @see java.net.URL#URL(java.lang.String, java.lang.String, int, java.lang.String)
|
||||
* @since JDK1.0
|
||||
*/
|
||||
public abstract class URLStreamHandler {
|
||||
/**
|
||||
* Opens a connection to the object referenced by the
|
||||
* {@code URL} argument.
|
||||
* This method should be overridden by a subclass.
|
||||
*
|
||||
* <p>If for the handler's protocol (such as HTTP or JAR), there
|
||||
* exists a public, specialized URLConnection subclass belonging
|
||||
* to one of the following packages or one of their subpackages:
|
||||
* java.lang, java.io, java.util, java.net, the connection
|
||||
* returned will be of that subclass. For example, for HTTP an
|
||||
* HttpURLConnection will be returned, and for JAR a
|
||||
* JarURLConnection will be returned.
|
||||
*
|
||||
* @param u the URL that this connects to.
|
||||
* @return a {@code URLConnection} object for the {@code URL}.
|
||||
* @exception IOException if an I/O error occurs while opening the
|
||||
* connection.
|
||||
*/
|
||||
abstract protected URLConnection openConnection(URL u) throws IOException;
|
||||
|
||||
/**
|
||||
* Same as openConnection(URL), except that the connection will be
|
||||
* made through the specified proxy; Protocol handlers that do not
|
||||
* support proxying will ignore the proxy parameter and make a
|
||||
* normal connection.
|
||||
*
|
||||
* Calling this method preempts the system's default ProxySelector
|
||||
* settings.
|
||||
*
|
||||
* @param u the URL that this connects to.
|
||||
* @param p the proxy through which the connection will be made.
|
||||
* If direct connection is desired, Proxy.NO_PROXY
|
||||
* should be specified.
|
||||
* @return a {@code URLConnection} object for the {@code URL}.
|
||||
* @exception IOException if an I/O error occurs while opening the
|
||||
* connection.
|
||||
* @exception IllegalArgumentException if either u or p is null,
|
||||
* or p has the wrong type.
|
||||
* @exception UnsupportedOperationException if the subclass that
|
||||
* implements the protocol doesn't support this method.
|
||||
* @since 1.5
|
||||
*/
|
||||
protected URLConnection openConnection(URL u, Proxy p) throws IOException {
|
||||
throw new UnsupportedOperationException("Method not implemented.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the string representation of a {@code URL} into a
|
||||
* {@code URL} object.
|
||||
* <p>
|
||||
* If there is any inherited context, then it has already been
|
||||
* copied into the {@code URL} argument.
|
||||
* <p>
|
||||
* The {@code parseURL} method of {@code URLStreamHandler}
|
||||
* parses the string representation as if it were an
|
||||
* {@code http} specification. Most URL protocol families have a
|
||||
* similar parsing. A stream protocol handler for a protocol that has
|
||||
* a different syntax must override this routine.
|
||||
*
|
||||
* @param u the {@code URL} to receive the result of parsing
|
||||
* the spec.
|
||||
* @param spec the {@code String} representing the URL that
|
||||
* must be parsed.
|
||||
* @param start the character index at which to begin parsing. This is
|
||||
* just past the '{@code :}' (if there is one) that
|
||||
* specifies the determination of the protocol name.
|
||||
* @param limit the character position to stop parsing at. This is the
|
||||
* end of the string or the position of the
|
||||
* "{@code #}" character, if present. All information
|
||||
* after the sharp sign indicates an anchor.
|
||||
*/
|
||||
protected void parseURL(URL u, String spec, int start, int limit) {
|
||||
// These fields may receive context content if this was relative URL
|
||||
String protocol = u.getProtocol();
|
||||
String authority = u.getAuthority();
|
||||
String userInfo = u.getUserInfo();
|
||||
String host = u.getHost();
|
||||
int port = u.getPort();
|
||||
String path = u.getPath();
|
||||
String query = u.getQuery();
|
||||
|
||||
// This field has already been parsed
|
||||
String ref = u.getRef();
|
||||
|
||||
boolean isRelPath = false;
|
||||
boolean queryOnly = false;
|
||||
|
||||
// FIX: should not assume query if opaque
|
||||
// Strip off the query part
|
||||
if (start < limit) {
|
||||
int queryStart = spec.indexOf('?');
|
||||
queryOnly = queryStart == start;
|
||||
if ((queryStart != -1) && (queryStart < limit)) {
|
||||
query = spec.substring(queryStart+1, limit);
|
||||
if (limit > queryStart)
|
||||
limit = queryStart;
|
||||
spec = spec.substring(0, queryStart);
|
||||
}
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
// Parse the authority part if any
|
||||
boolean isUNCName = (start <= limit - 4) &&
|
||||
(spec.charAt(start) == '/') &&
|
||||
(spec.charAt(start + 1) == '/') &&
|
||||
(spec.charAt(start + 2) == '/') &&
|
||||
(spec.charAt(start + 3) == '/');
|
||||
if (!isUNCName && (start <= limit - 2) && (spec.charAt(start) == '/') &&
|
||||
(spec.charAt(start + 1) == '/')) {
|
||||
start += 2;
|
||||
i = spec.indexOf('/', start);
|
||||
if (i < 0 || i > limit) {
|
||||
i = spec.indexOf('?', start);
|
||||
if (i < 0 || i > limit)
|
||||
i = limit;
|
||||
}
|
||||
|
||||
host = authority = spec.substring(start, i);
|
||||
|
||||
int ind = authority.indexOf('@');
|
||||
if (ind != -1) {
|
||||
if (ind != authority.lastIndexOf('@')) {
|
||||
// more than one '@' in authority. This is not server based
|
||||
userInfo = null;
|
||||
host = null;
|
||||
} else {
|
||||
userInfo = authority.substring(0, ind);
|
||||
host = authority.substring(ind+1);
|
||||
}
|
||||
} else {
|
||||
userInfo = null;
|
||||
}
|
||||
if (host != null) {
|
||||
// If the host is surrounded by [ and ] then its an IPv6
|
||||
// literal address as specified in RFC2732
|
||||
if (host.length()>0 && (host.charAt(0) == '[')) {
|
||||
if ((ind = host.indexOf(']')) > 2) {
|
||||
|
||||
String nhost = host ;
|
||||
host = nhost.substring(0,ind+1);
|
||||
if (!IPAddressUtil.
|
||||
isIPv6LiteralAddress(host.substring(1, ind))) {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid host: "+ host);
|
||||
}
|
||||
|
||||
port = -1 ;
|
||||
if (nhost.length() > ind+1) {
|
||||
if (nhost.charAt(ind+1) == ':') {
|
||||
++ind ;
|
||||
// port can be null according to RFC2396
|
||||
if (nhost.length() > (ind + 1)) {
|
||||
port = Integer.parseInt(nhost.substring(ind+1));
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid authority field: " + authority);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid authority field: " + authority);
|
||||
}
|
||||
} else {
|
||||
ind = host.indexOf(':');
|
||||
port = -1;
|
||||
if (ind >= 0) {
|
||||
// port can be null according to RFC2396
|
||||
if (host.length() > (ind + 1)) {
|
||||
port = Integer.parseInt(host.substring(ind + 1));
|
||||
}
|
||||
host = host.substring(0, ind);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
host = "";
|
||||
}
|
||||
if (port < -1)
|
||||
throw new IllegalArgumentException("Invalid port number :" +
|
||||
port);
|
||||
start = i;
|
||||
// If the authority is defined then the path is defined by the
|
||||
// spec only; See RFC 2396 Section 5.2.4.
|
||||
if (authority != null && authority.length() > 0)
|
||||
path = "";
|
||||
}
|
||||
|
||||
if (host == null) {
|
||||
host = "";
|
||||
}
|
||||
|
||||
// Parse the file path if any
|
||||
if (start < limit) {
|
||||
if (spec.charAt(start) == '/') {
|
||||
path = spec.substring(start, limit);
|
||||
} else if (path != null && path.length() > 0) {
|
||||
isRelPath = true;
|
||||
int ind = path.lastIndexOf('/');
|
||||
String seperator = "";
|
||||
if (ind == -1 && authority != null)
|
||||
seperator = "/";
|
||||
path = path.substring(0, ind + 1) + seperator +
|
||||
spec.substring(start, limit);
|
||||
|
||||
} else {
|
||||
String seperator = (authority != null) ? "/" : "";
|
||||
path = seperator + spec.substring(start, limit);
|
||||
}
|
||||
} else if (queryOnly && path != null) {
|
||||
int ind = path.lastIndexOf('/');
|
||||
if (ind < 0)
|
||||
ind = 0;
|
||||
path = path.substring(0, ind) + "/";
|
||||
}
|
||||
if (path == null)
|
||||
path = "";
|
||||
|
||||
if (isRelPath) {
|
||||
// Remove embedded /./
|
||||
while ((i = path.indexOf("/./")) >= 0) {
|
||||
path = path.substring(0, i) + path.substring(i + 2);
|
||||
}
|
||||
// Remove embedded /../ if possible
|
||||
i = 0;
|
||||
while ((i = path.indexOf("/../", i)) >= 0) {
|
||||
/*
|
||||
* A "/../" will cancel the previous segment and itself,
|
||||
* unless that segment is a "/../" itself
|
||||
* i.e. "/a/b/../c" becomes "/a/c"
|
||||
* but "/../../a" should stay unchanged
|
||||
*/
|
||||
if (i > 0 && (limit = path.lastIndexOf('/', i - 1)) >= 0 &&
|
||||
(path.indexOf("/../", limit) != 0)) {
|
||||
path = path.substring(0, limit) + path.substring(i + 3);
|
||||
i = 0;
|
||||
} else {
|
||||
i = i + 3;
|
||||
}
|
||||
}
|
||||
// Remove trailing .. if possible
|
||||
while (path.endsWith("/..")) {
|
||||
i = path.indexOf("/..");
|
||||
if ((limit = path.lastIndexOf('/', i - 1)) >= 0) {
|
||||
path = path.substring(0, limit+1);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Remove starting .
|
||||
if (path.startsWith("./") && path.length() > 2)
|
||||
path = path.substring(2);
|
||||
|
||||
// Remove trailing .
|
||||
if (path.endsWith("/."))
|
||||
path = path.substring(0, path.length() -1);
|
||||
}
|
||||
|
||||
setURL(u, protocol, host, port, authority, userInfo, path, query, ref);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default port for a URL parsed by this handler. This method
|
||||
* is meant to be overidden by handlers with default port numbers.
|
||||
* @return the default port for a {@code URL} parsed by this handler.
|
||||
* @since 1.3
|
||||
*/
|
||||
protected int getDefaultPort() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the default equals calculation. May be overidden by handlers
|
||||
* for other protocols that have different requirements for equals().
|
||||
* This method requires that none of its arguments is null. This is
|
||||
* guaranteed by the fact that it is only called by java.net.URL class.
|
||||
* @param u1 a URL object
|
||||
* @param u2 a URL object
|
||||
* @return {@code true} if the two urls are
|
||||
* considered equal, ie. they refer to the same
|
||||
* fragment in the same file.
|
||||
* @since 1.3
|
||||
*/
|
||||
protected boolean equals(URL u1, URL u2) {
|
||||
String ref1 = u1.getRef();
|
||||
String ref2 = u2.getRef();
|
||||
return (ref1 == ref2 || (ref1 != null && ref1.equals(ref2))) &&
|
||||
sameFile(u1, u2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the default hash calculation. May be overidden by handlers for
|
||||
* other protocols that have different requirements for hashCode
|
||||
* calculation.
|
||||
* @param u a URL object
|
||||
* @return an {@code int} suitable for hash table indexing
|
||||
* @since 1.3
|
||||
*/
|
||||
protected int hashCode(URL u) {
|
||||
int h = 0;
|
||||
|
||||
// Generate the protocol part.
|
||||
String protocol = u.getProtocol();
|
||||
if (protocol != null)
|
||||
h += protocol.hashCode();
|
||||
|
||||
// Generate the host part.
|
||||
InetAddress addr = getHostAddress(u);
|
||||
if (addr != null) {
|
||||
h += addr.hashCode();
|
||||
} else {
|
||||
String host = u.getHost();
|
||||
if (host != null)
|
||||
h += host.toLowerCase().hashCode();
|
||||
}
|
||||
|
||||
// Generate the file part.
|
||||
String file = u.getFile();
|
||||
if (file != null)
|
||||
h += file.hashCode();
|
||||
|
||||
// Generate the port part.
|
||||
if (u.getPort() == -1)
|
||||
h += getDefaultPort();
|
||||
else
|
||||
h += u.getPort();
|
||||
|
||||
// Generate the ref part.
|
||||
String ref = u.getRef();
|
||||
if (ref != null)
|
||||
h += ref.hashCode();
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two urls to see whether they refer to the same file,
|
||||
* i.e., having the same protocol, host, port, and path.
|
||||
* This method requires that none of its arguments is null. This is
|
||||
* guaranteed by the fact that it is only called indirectly
|
||||
* by java.net.URL class.
|
||||
* @param u1 a URL object
|
||||
* @param u2 a URL object
|
||||
* @return true if u1 and u2 refer to the same file
|
||||
* @since 1.3
|
||||
*/
|
||||
protected boolean sameFile(URL u1, URL u2) {
|
||||
// Compare the protocols.
|
||||
if (!((u1.getProtocol() == u2.getProtocol()) ||
|
||||
(u1.getProtocol() != null &&
|
||||
u1.getProtocol().equalsIgnoreCase(u2.getProtocol()))))
|
||||
return false;
|
||||
|
||||
// Compare the files.
|
||||
if (!(u1.getFile() == u2.getFile() ||
|
||||
(u1.getFile() != null && u1.getFile().equals(u2.getFile()))))
|
||||
return false;
|
||||
|
||||
// Compare the ports.
|
||||
int port1, port2;
|
||||
port1 = (u1.getPort() != -1) ? u1.getPort() : u1.handler.getDefaultPort();
|
||||
port2 = (u2.getPort() != -1) ? u2.getPort() : u2.handler.getDefaultPort();
|
||||
if (port1 != port2)
|
||||
return false;
|
||||
|
||||
// Compare the hosts.
|
||||
if (!hostsEqual(u1, u2))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the IP address of our host. An empty host field or a DNS failure
|
||||
* will result in a null return.
|
||||
*
|
||||
* @param u a URL object
|
||||
* @return an {@code InetAddress} representing the host
|
||||
* IP address.
|
||||
* @since 1.3
|
||||
*/
|
||||
protected InetAddress getHostAddress(URL u) {
|
||||
return u.getHostAddress();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the host components of two URLs.
|
||||
* @param u1 the URL of the first host to compare
|
||||
* @param u2 the URL of the second host to compare
|
||||
* @return {@code true} if and only if they
|
||||
* are equal, {@code false} otherwise.
|
||||
* @since 1.3
|
||||
*/
|
||||
protected boolean hostsEqual(URL u1, URL u2) {
|
||||
InetAddress a1 = getHostAddress(u1);
|
||||
InetAddress a2 = getHostAddress(u2);
|
||||
// if we have internet address for both, compare them
|
||||
if (a1 != null && a2 != null) {
|
||||
return a1.equals(a2);
|
||||
// else, if both have host names, compare them
|
||||
} else if (u1.getHost() != null && u2.getHost() != null)
|
||||
return u1.getHost().equalsIgnoreCase(u2.getHost());
|
||||
else
|
||||
return u1.getHost() == null && u2.getHost() == null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a {@code URL} of a specific protocol to a
|
||||
* {@code String}.
|
||||
*
|
||||
* @param u the URL.
|
||||
* @return a string representation of the {@code URL} argument.
|
||||
*/
|
||||
protected String toExternalForm(URL u) {
|
||||
|
||||
// pre-compute length of StringBuffer
|
||||
int len = u.getProtocol().length() + 1;
|
||||
if (u.getAuthority() != null && u.getAuthority().length() > 0)
|
||||
len += 2 + u.getAuthority().length();
|
||||
if (u.getPath() != null) {
|
||||
len += u.getPath().length();
|
||||
}
|
||||
if (u.getQuery() != null) {
|
||||
len += 1 + u.getQuery().length();
|
||||
}
|
||||
if (u.getRef() != null)
|
||||
len += 1 + u.getRef().length();
|
||||
|
||||
StringBuffer result = new StringBuffer(len);
|
||||
result.append(u.getProtocol());
|
||||
result.append(":");
|
||||
if (u.getAuthority() != null && u.getAuthority().length() > 0) {
|
||||
result.append("//");
|
||||
result.append(u.getAuthority());
|
||||
}
|
||||
if (u.getPath() != null) {
|
||||
result.append(u.getPath());
|
||||
}
|
||||
if (u.getQuery() != null) {
|
||||
result.append('?');
|
||||
result.append(u.getQuery());
|
||||
}
|
||||
if (u.getRef() != null) {
|
||||
result.append("#");
|
||||
result.append(u.getRef());
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the fields of the {@code URL} argument to the indicated values.
|
||||
* Only classes derived from URLStreamHandler are able
|
||||
* to use this method to set the values of the URL fields.
|
||||
*
|
||||
* @param u the URL to modify.
|
||||
* @param protocol the protocol name.
|
||||
* @param host the remote host value for the URL.
|
||||
* @param port the port on the remote machine.
|
||||
* @param authority the authority part for the URL.
|
||||
* @param userInfo the userInfo part of the URL.
|
||||
* @param path the path component of the URL.
|
||||
* @param query the query part for the URL.
|
||||
* @param ref the reference.
|
||||
* @exception SecurityException if the protocol handler of the URL is
|
||||
* different from this one
|
||||
* @see java.net.URL#set(java.lang.String, java.lang.String, int, java.lang.String, java.lang.String)
|
||||
* @since 1.3
|
||||
*/
|
||||
protected void setURL(URL u, String protocol, String host, int port,
|
||||
String authority, String userInfo, String path,
|
||||
String query, String ref) {
|
||||
if (this != u.handler) {
|
||||
throw new SecurityException("handler for url different from " +
|
||||
"this handler");
|
||||
} else if (host != null && u.isBuiltinStreamHandler(this)) {
|
||||
String s = IPAddressUtil.checkHostString(host);
|
||||
if (s != null) throw new IllegalArgumentException(s);
|
||||
}
|
||||
// ensure that no one can reset the protocol on a given URL.
|
||||
u.set(u.getProtocol(), host, port, authority, userInfo, path, query, ref);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the fields of the {@code URL} argument to the indicated values.
|
||||
* Only classes derived from URLStreamHandler are able
|
||||
* to use this method to set the values of the URL fields.
|
||||
*
|
||||
* @param u the URL to modify.
|
||||
* @param protocol the protocol name. This value is ignored since 1.2.
|
||||
* @param host the remote host value for the URL.
|
||||
* @param port the port on the remote machine.
|
||||
* @param file the file.
|
||||
* @param ref the reference.
|
||||
* @exception SecurityException if the protocol handler of the URL is
|
||||
* different from this one
|
||||
* @deprecated Use setURL(URL, String, String, int, String, String, String,
|
||||
* String);
|
||||
*/
|
||||
@Deprecated
|
||||
protected void setURL(URL u, String protocol, String host, int port,
|
||||
String file, String ref) {
|
||||
/*
|
||||
* Only old URL handlers call this, so assume that the host
|
||||
* field might contain "user:passwd@host". Fix as necessary.
|
||||
*/
|
||||
String authority = null;
|
||||
String userInfo = null;
|
||||
if (host != null && host.length() != 0) {
|
||||
authority = (port == -1) ? host : host + ":" + port;
|
||||
int at = host.lastIndexOf('@');
|
||||
if (at != -1) {
|
||||
userInfo = host.substring(0, at);
|
||||
host = host.substring(at+1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Assume file might contain query part. Fix as necessary.
|
||||
*/
|
||||
String path = null;
|
||||
String query = null;
|
||||
if (file != null) {
|
||||
int q = file.lastIndexOf('?');
|
||||
if (q != -1) {
|
||||
query = file.substring(q+1);
|
||||
path = file.substring(0, q);
|
||||
} else
|
||||
path = file;
|
||||
}
|
||||
setURL(u, protocol, host, port, authority, userInfo, path, query, ref);
|
||||
}
|
||||
}
|
||||
51
jdkSrc/jdk8/java/net/URLStreamHandlerFactory.java
Normal file
51
jdkSrc/jdk8/java/net/URLStreamHandlerFactory.java
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
/**
|
||||
* This interface defines a factory for {@code URL} stream
|
||||
* protocol handlers.
|
||||
* <p>
|
||||
* It is used by the {@code URL} class to create a
|
||||
* {@code URLStreamHandler} for a specific protocol.
|
||||
*
|
||||
* @author Arthur van Hoff
|
||||
* @see java.net.URL
|
||||
* @see java.net.URLStreamHandler
|
||||
* @since JDK1.0
|
||||
*/
|
||||
public interface URLStreamHandlerFactory {
|
||||
/**
|
||||
* Creates a new {@code URLStreamHandler} instance with the specified
|
||||
* protocol.
|
||||
*
|
||||
* @param protocol the protocol ("{@code ftp}",
|
||||
* "{@code http}", "{@code nntp}", etc.).
|
||||
* @return a {@code URLStreamHandler} for the specific protocol.
|
||||
* @see java.net.URLStreamHandler
|
||||
*/
|
||||
URLStreamHandler createURLStreamHandler(String protocol);
|
||||
}
|
||||
56
jdkSrc/jdk8/java/net/UnknownHostException.java
Normal file
56
jdkSrc/jdk8/java/net/UnknownHostException.java
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Thrown to indicate that the IP address of a host could not be determined.
|
||||
*
|
||||
* @author Jonathan Payne
|
||||
* @since JDK1.0
|
||||
*/
|
||||
public
|
||||
class UnknownHostException extends IOException {
|
||||
private static final long serialVersionUID = -4639126076052875403L;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code UnknownHostException} with the
|
||||
* specified detail message.
|
||||
*
|
||||
* @param host the detail message.
|
||||
*/
|
||||
public UnknownHostException(String host) {
|
||||
super(host);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code UnknownHostException} with no detail
|
||||
* message.
|
||||
*/
|
||||
public UnknownHostException() {
|
||||
}
|
||||
}
|
||||
58
jdkSrc/jdk8/java/net/UnknownServiceException.java
Normal file
58
jdkSrc/jdk8/java/net/UnknownServiceException.java
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.net;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Thrown to indicate that an unknown service exception has
|
||||
* occurred. Either the MIME type returned by a URL connection does
|
||||
* not make sense, or the application is attempting to write to a
|
||||
* read-only URL connection.
|
||||
*
|
||||
* @author unascribed
|
||||
* @since JDK1.0
|
||||
*/
|
||||
public class UnknownServiceException extends IOException {
|
||||
private static final long serialVersionUID = -4169033248853639508L;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code UnknownServiceException} with no
|
||||
* detail message.
|
||||
*/
|
||||
public UnknownServiceException() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code UnknownServiceException} with the
|
||||
* specified detail message.
|
||||
*
|
||||
* @param msg the detail message.
|
||||
*/
|
||||
public UnknownServiceException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
161
jdkSrc/jdk8/java/net/package-info.java
Normal file
161
jdkSrc/jdk8/java/net/package-info.java
Normal file
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provides the classes for implementing networking applications.
|
||||
*
|
||||
* <p> The java.net package can be roughly divided in two sections:</p>
|
||||
* <ul>
|
||||
* <li><p><i>A Low Level API</i>, which deals with the
|
||||
* following abstractions:</p>
|
||||
* <ul>
|
||||
* <li><p><i>Addresses</i>, which are networking identifiers,
|
||||
* like IP addresses.</p></li>
|
||||
* <li><p><i>Sockets</i>, which are basic bidirectional data communication
|
||||
* mechanisms.</p></li>
|
||||
* <li><p><i>Interfaces</i>, which describe network interfaces. </p></li>
|
||||
* </ul></li>
|
||||
* <li> <p><i>A High Level API</i>, which deals with the following
|
||||
* abstractions:</p>
|
||||
* <ul>
|
||||
* <li><p><i>URIs</i>, which represent
|
||||
* Universal Resource Identifiers.</p></li>
|
||||
* <li><p><i>URLs</i>, which represent
|
||||
* Universal Resource Locators.</p></li>
|
||||
* <li><p><i>Connections</i>, which represents connections to the resource
|
||||
* pointed to by <i>URLs</i>.</p></li>
|
||||
* </ul></li>
|
||||
* </ul>
|
||||
* <h2>Addresses</h2>
|
||||
* <p>Addresses are used throughout the java.net APIs as either host
|
||||
* identifiers, or socket endpoint identifiers.</p>
|
||||
* <p>The {@link java.net.InetAddress} class is the abstraction representing an
|
||||
* IP (Internet Protocol) address. It has two subclasses:
|
||||
* <ul>
|
||||
* <li>{@link java.net.Inet4Address} for IPv4 addresses.</li>
|
||||
* <li>{@link java.net.Inet6Address} for IPv6 addresses.</li>
|
||||
* </ul>
|
||||
* <p>But, in most cases, there is no need to deal directly with the subclasses,
|
||||
* as the InetAddress abstraction should cover most of the needed
|
||||
* functionality.</p>
|
||||
* <h3><b>About IPv6</b></h3>
|
||||
* <p>Not all systems have support for the IPv6 protocol, and while the Java
|
||||
* networking stack will attempt to detect it and use it transparently when
|
||||
* available, it is also possible to disable its use with a system property.
|
||||
* In the case where IPv6 is not available, or explicitly disabled,
|
||||
* Inet6Address are not valid arguments for most networking operations any
|
||||
* more. While methods like {@link java.net.InetAddress#getByName} are
|
||||
* guaranteed not to return an Inet6Address when looking up host names, it
|
||||
* is possible, by passing literals, to create such an object. In which
|
||||
* case, most methods, when called with an Inet6Address will throw an
|
||||
* Exception.</p>
|
||||
* <h2>Sockets</h2>
|
||||
* <p>Sockets are means to establish a communication link between machines over
|
||||
* the network. The java.net package provides 4 kinds of Sockets:</p>
|
||||
* <ul>
|
||||
* <li>{@link java.net.Socket} is a TCP client API, and will typically
|
||||
* be used to {@linkplain java.net.Socket#connect(SocketAddress)
|
||||
* connect} to a remote host.</li>
|
||||
* <li>{@link java.net.ServerSocket} is a TCP server API, and will
|
||||
* typically {@linkplain java.net.ServerSocket#accept accept}
|
||||
* connections from client sockets.</li>
|
||||
* <li>{@link java.net.DatagramSocket} is a UDP endpoint API and is used
|
||||
* to {@linkplain java.net.DatagramSocket#send send} and
|
||||
* {@linkplain java.net.DatagramSocket#receive receive}
|
||||
* {@linkplain java.net.DatagramPacket datagram packets}.</li>
|
||||
* <li>{@link java.net.MulticastSocket} is a subclass of
|
||||
* {@code DatagramSocket} used when dealing with multicast
|
||||
* groups.</li>
|
||||
* </ul>
|
||||
* <p>Sending and receiving with TCP sockets is done through InputStreams and
|
||||
* OutputStreams which can be obtained via the
|
||||
* {@link java.net.Socket#getInputStream} and
|
||||
* {@link java.net.Socket#getOutputStream} methods.</p>
|
||||
* <h2>Interfaces</h2>
|
||||
* <p>The {@link java.net.NetworkInterface} class provides APIs to browse and
|
||||
* query all the networking interfaces (e.g. ethernet connection or PPP
|
||||
* endpoint) of the local machine. It is through that class that you can
|
||||
* check if any of the local interfaces is configured to support IPv6.</p>
|
||||
* <p>Note, all conforming implementations must support at least one
|
||||
* {@code NetworkInterface} object, which must either be connected to a
|
||||
* network, or be a "loopback" interface that can only communicate with
|
||||
* entities on the same machine.</p>
|
||||
*
|
||||
* <h2>High level API</h2>
|
||||
* <p>A number of classes in the java.net package do provide for a much higher
|
||||
* level of abstraction and allow for easy access to resources on the
|
||||
* network. The classes are:
|
||||
* <ul>
|
||||
* <li>{@link java.net.URI} is the class representing a
|
||||
* Universal Resource Identifier, as specified in RFC 2396.
|
||||
* As the name indicates, this is just an Identifier and doesn't
|
||||
* provide directly the means to access the resource.</li>
|
||||
* <li>{@link java.net.URL} is the class representing a
|
||||
* Universal Resource Locator, which is both an older concept for
|
||||
* URIs and a means to access the resources.</li>
|
||||
* <li>{@link java.net.URLConnection} is created from a URL and is the
|
||||
* communication link used to access the resource pointed by the
|
||||
* URL. This abstract class will delegate most of the work to the
|
||||
* underlying protocol handlers like http or https.</li>
|
||||
* <li>{@link java.net.HttpURLConnection} is a subclass of URLConnection
|
||||
* and provides some additional functionalities specific to the
|
||||
* HTTP protocol.</li>
|
||||
* </ul>
|
||||
* <p>The recommended usage is to use {@link java.net.URI} to identify
|
||||
* resources, then convert it into a {@link java.net.URL} when it is time to
|
||||
* access the resource. From that URL, you can either get the
|
||||
* {@link java.net.URLConnection} for fine control, or get directly the
|
||||
* InputStream.
|
||||
* <p>Here is an example:</p>
|
||||
* <pre>
|
||||
* URI uri = new URI("http://java.sun.com/");
|
||||
* URL url = uri.toURL();
|
||||
* InputStream in = url.openStream();
|
||||
* </pre>
|
||||
* <h2>Protocol Handlers</h2>
|
||||
* As mentioned, URL and URLConnection rely on protocol handlers which must be
|
||||
* present, otherwise an Exception is thrown. This is the major difference with
|
||||
* URIs which only identify resources, and therefore don't need to have access
|
||||
* to the protocol handler. So, while it is possible to create an URI with any
|
||||
* kind of protocol scheme (e.g. {@code myproto://myhost.mydomain/resource/}),
|
||||
* a similar URL will try to instantiate the handler for the specified protocol;
|
||||
* if it doesn't exist an exception will be thrown.
|
||||
* <p>By default the protocol handlers are loaded dynamically from the default
|
||||
* location. It is, however, possible to add to the search path by setting
|
||||
* the {@code java.protocol.handler.pkgs} system property. For instance if
|
||||
* it is set to {@code myapp.protocols}, then the URL code will try, in the
|
||||
* case of http, first to load {@code myapp.protocols.http.Handler}, then,
|
||||
* if this fails, {@code http.Handler} from the default location.
|
||||
* <p>Note that the Handler class <b>has to</b> be a subclass of the abstract
|
||||
* class {@link java.net.URLStreamHandler}.</p>
|
||||
* <h2>Additional Specification</h2>
|
||||
* <ul>
|
||||
* <li><a href="doc-files/net-properties.html">
|
||||
* Networking System Properties</a></li>
|
||||
* </ul>
|
||||
*
|
||||
* @since JDK1.0
|
||||
*/
|
||||
package java.net;
|
||||
Reference in New Issue
Block a user