feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
43
jdkSrc/jdk8/sun/net/ApplicationProxy.java
Normal file
43
jdkSrc/jdk8/sun/net/ApplicationProxy.java
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 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 sun.net;
|
||||
|
||||
import java.net.Proxy;
|
||||
import java.net.SocketAddress;
|
||||
|
||||
/**
|
||||
* Proxy wrapper class so that we can determine application set
|
||||
* proxies by type.
|
||||
*/
|
||||
public final class ApplicationProxy extends Proxy {
|
||||
private ApplicationProxy(Proxy proxy) {
|
||||
super(proxy.type(), proxy.address());
|
||||
}
|
||||
|
||||
public static ApplicationProxy create(Proxy proxy) {
|
||||
return new ApplicationProxy(proxy);
|
||||
}
|
||||
}
|
||||
45
jdkSrc/jdk8/sun/net/ConnectionResetException.java
Normal file
45
jdkSrc/jdk8/sun/net/ConnectionResetException.java
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 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 sun.net;
|
||||
|
||||
import java.net.SocketException;
|
||||
|
||||
/**
|
||||
* Thrown to indicate a connection reset.
|
||||
*
|
||||
* @since 1.4.1
|
||||
*/
|
||||
public
|
||||
class ConnectionResetException extends SocketException {
|
||||
private static final long serialVersionUID = -7633185991801851556L;
|
||||
|
||||
public ConnectionResetException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public ConnectionResetException() {
|
||||
}
|
||||
}
|
||||
54
jdkSrc/jdk8/sun/net/ExtendedOptionsHelper.java
Normal file
54
jdkSrc/jdk8/sun/net/ExtendedOptionsHelper.java
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Red Hat, Inc.
|
||||
* 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 sun.net;
|
||||
|
||||
import java.net.SocketOption;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import static jdk.net.ExtendedSocketOptions.TCP_KEEPCOUNT;
|
||||
import static jdk.net.ExtendedSocketOptions.TCP_KEEPIDLE;
|
||||
import static jdk.net.ExtendedSocketOptions.TCP_KEEPINTERVAL;
|
||||
|
||||
public class ExtendedOptionsHelper {
|
||||
|
||||
private static final boolean keepAliveOptSupported =
|
||||
ExtendedOptionsImpl.keepAliveOptionsSupported();
|
||||
private static final Set<SocketOption<?>> extendedOptions = options();
|
||||
|
||||
private static Set<SocketOption<?>> options() {
|
||||
Set<SocketOption<?>> options = new HashSet<>();
|
||||
if (keepAliveOptSupported) {
|
||||
options.add(TCP_KEEPCOUNT);
|
||||
options.add(TCP_KEEPIDLE);
|
||||
options.add(TCP_KEEPINTERVAL);
|
||||
}
|
||||
return Collections.unmodifiableSet(options);
|
||||
}
|
||||
|
||||
public static Set<SocketOption<?>> keepAliveOptions() {
|
||||
return extendedOptions;
|
||||
}
|
||||
}
|
||||
100
jdkSrc/jdk8/sun/net/ExtendedOptionsImpl.java
Normal file
100
jdkSrc/jdk8/sun/net/ExtendedOptionsImpl.java
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* 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 sun.net;
|
||||
|
||||
import java.net.*;
|
||||
import jdk.net.*;
|
||||
import java.io.IOException;
|
||||
import java.io.FileDescriptor;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.AccessController;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* Contains the native implementation for extended socket options
|
||||
* together with some other static utilities
|
||||
*/
|
||||
public class ExtendedOptionsImpl {
|
||||
|
||||
static {
|
||||
AccessController.doPrivileged((PrivilegedAction<Void>)() -> {
|
||||
System.loadLibrary("net");
|
||||
return null;
|
||||
});
|
||||
init();
|
||||
}
|
||||
|
||||
private ExtendedOptionsImpl() {}
|
||||
|
||||
public static void checkSetOptionPermission(SocketOption<?> option) {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm == null) {
|
||||
return;
|
||||
}
|
||||
String check = "setOption." + option.name();
|
||||
sm.checkPermission(new NetworkPermission(check));
|
||||
}
|
||||
|
||||
public static void checkGetOptionPermission(SocketOption<?> option) {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm == null) {
|
||||
return;
|
||||
}
|
||||
String check = "getOption." + option.name();
|
||||
sm.checkPermission(new NetworkPermission(check));
|
||||
}
|
||||
|
||||
public static void checkValueType(Object value, Class<?> type) {
|
||||
if (!type.isAssignableFrom(value.getClass())) {
|
||||
String s = "Found: " + value.getClass().toString() + " Expected: "
|
||||
+ type.toString();
|
||||
throw new IllegalArgumentException(s);
|
||||
}
|
||||
}
|
||||
|
||||
private static native void init();
|
||||
|
||||
/*
|
||||
* Extension native implementations
|
||||
*
|
||||
* SO_FLOW_SLA
|
||||
*/
|
||||
public static native void setFlowOption(FileDescriptor fd, SocketFlow f);
|
||||
public static native void getFlowOption(FileDescriptor fd, SocketFlow f);
|
||||
public static native boolean flowSupported();
|
||||
|
||||
public static native void setTcpKeepAliveProbes(FileDescriptor fd, int value) throws SocketException;
|
||||
public static native void setTcpKeepAliveTime(FileDescriptor fd, int value) throws SocketException;
|
||||
public static native void setTcpKeepAliveIntvl(FileDescriptor fd, int value) throws SocketException;
|
||||
public static native int getTcpKeepAliveProbes(FileDescriptor fd) throws SocketException;
|
||||
public static native int getTcpKeepAliveTime(FileDescriptor fd) throws SocketException;
|
||||
public static native int getTcpKeepAliveIntvl(FileDescriptor fd) throws SocketException;
|
||||
public static native boolean keepAliveOptionsSupported();
|
||||
}
|
||||
219
jdkSrc/jdk8/sun/net/InetAddressCachePolicy.java
Normal file
219
jdkSrc/jdk8/sun/net/InetAddressCachePolicy.java
Normal file
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 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 sun.net;
|
||||
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.Security;
|
||||
|
||||
public final class InetAddressCachePolicy {
|
||||
|
||||
// Controls the cache policy for successful lookups only
|
||||
private static final String cachePolicyProp = "networkaddress.cache.ttl";
|
||||
private static final String cachePolicyPropFallback =
|
||||
"sun.net.inetaddr.ttl";
|
||||
|
||||
// Controls the cache policy for negative lookups only
|
||||
private static final String negativeCachePolicyProp =
|
||||
"networkaddress.cache.negative.ttl";
|
||||
private static final String negativeCachePolicyPropFallback =
|
||||
"sun.net.inetaddr.negative.ttl";
|
||||
|
||||
public static final int FOREVER = -1;
|
||||
public static final int NEVER = 0;
|
||||
|
||||
/* default value for positive lookups */
|
||||
public static final int DEFAULT_POSITIVE = 30;
|
||||
|
||||
/* The Java-level namelookup cache policy for successful lookups:
|
||||
*
|
||||
* -1: caching forever
|
||||
* any positive value: the number of seconds to cache an address for
|
||||
*
|
||||
* default value is forever (FOREVER), as we let the platform do the
|
||||
* caching. For security reasons, this caching is made forever when
|
||||
* a security manager is set.
|
||||
*/
|
||||
private static volatile int cachePolicy = FOREVER;
|
||||
|
||||
/* The Java-level namelookup cache policy for negative lookups:
|
||||
*
|
||||
* -1: caching forever
|
||||
* any positive value: the number of seconds to cache an address for
|
||||
*
|
||||
* default value is 0. It can be set to some other value for
|
||||
* performance reasons.
|
||||
*/
|
||||
private static volatile int negativeCachePolicy = NEVER;
|
||||
|
||||
/*
|
||||
* Whether or not the cache policy for successful lookups was set
|
||||
* using a property (cmd line).
|
||||
*/
|
||||
private static boolean propertySet;
|
||||
|
||||
/*
|
||||
* Whether or not the cache policy for negative lookups was set
|
||||
* using a property (cmd line).
|
||||
*/
|
||||
private static boolean propertyNegativeSet;
|
||||
|
||||
/*
|
||||
* Initialize
|
||||
*/
|
||||
static {
|
||||
|
||||
Integer tmp = java.security.AccessController.doPrivileged(
|
||||
new PrivilegedAction<Integer>() {
|
||||
public Integer run() {
|
||||
try {
|
||||
String tmpString = Security.getProperty(cachePolicyProp);
|
||||
if (tmpString != null) {
|
||||
return Integer.valueOf(tmpString);
|
||||
}
|
||||
} catch (NumberFormatException ignored) {
|
||||
// Ignore
|
||||
}
|
||||
|
||||
try {
|
||||
String tmpString = System.getProperty(cachePolicyPropFallback);
|
||||
if (tmpString != null) {
|
||||
return Integer.decode(tmpString);
|
||||
}
|
||||
} catch (NumberFormatException ignored) {
|
||||
// Ignore
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
if (tmp != null) {
|
||||
cachePolicy = tmp < 0 ? FOREVER : tmp;
|
||||
propertySet = true;
|
||||
} else {
|
||||
/* No properties defined for positive caching. If there is no
|
||||
* security manager then use the default positive cache value.
|
||||
*/
|
||||
if (System.getSecurityManager() == null) {
|
||||
cachePolicy = DEFAULT_POSITIVE;
|
||||
}
|
||||
}
|
||||
tmp = java.security.AccessController.doPrivileged (
|
||||
new PrivilegedAction<Integer>() {
|
||||
public Integer run() {
|
||||
try {
|
||||
String tmpString = Security.getProperty(negativeCachePolicyProp);
|
||||
if (tmpString != null) {
|
||||
return Integer.valueOf(tmpString);
|
||||
}
|
||||
} catch (NumberFormatException ignored) {
|
||||
// Ignore
|
||||
}
|
||||
|
||||
try {
|
||||
String tmpString = System.getProperty(negativeCachePolicyPropFallback);
|
||||
if (tmpString != null) {
|
||||
return Integer.decode(tmpString);
|
||||
}
|
||||
} catch (NumberFormatException ignored) {
|
||||
// Ignore
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
if (tmp != null) {
|
||||
negativeCachePolicy = tmp < 0 ? FOREVER : tmp;
|
||||
propertyNegativeSet = true;
|
||||
}
|
||||
}
|
||||
|
||||
public static int get() {
|
||||
return cachePolicy;
|
||||
}
|
||||
|
||||
public static int getNegative() {
|
||||
return negativeCachePolicy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the cache policy for successful lookups if the user has not
|
||||
* already specified a cache policy for it using a
|
||||
* command-property.
|
||||
* @param newPolicy the value in seconds for how long the lookup
|
||||
* should be cached
|
||||
*/
|
||||
public static synchronized void setIfNotSet(int newPolicy) {
|
||||
/*
|
||||
* When setting the new value we may want to signal that the
|
||||
* cache should be flushed, though this doesn't seem strictly
|
||||
* necessary.
|
||||
*/
|
||||
if (!propertySet) {
|
||||
checkValue(newPolicy, cachePolicy);
|
||||
cachePolicy = newPolicy;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the cache policy for negative lookups if the user has not
|
||||
* already specified a cache policy for it using a
|
||||
* command-property.
|
||||
* @param newPolicy the value in seconds for how long the lookup
|
||||
* should be cached
|
||||
*/
|
||||
public static void setNegativeIfNotSet(int newPolicy) {
|
||||
/*
|
||||
* When setting the new value we may want to signal that the
|
||||
* cache should be flushed, though this doesn't seem strictly
|
||||
* necessary.
|
||||
*/
|
||||
if (!propertyNegativeSet) {
|
||||
// Negative caching does not seem to have any security
|
||||
// implications.
|
||||
// checkValue(newPolicy, negativeCachePolicy);
|
||||
// but we should normalize negative policy
|
||||
negativeCachePolicy = newPolicy < 0 ? FOREVER : newPolicy;
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkValue(int newPolicy, int oldPolicy) {
|
||||
/*
|
||||
* If malicious code gets a hold of this method, prevent
|
||||
* setting the cache policy to something laxer or some
|
||||
* invalid negative value.
|
||||
*/
|
||||
if (newPolicy == FOREVER)
|
||||
return;
|
||||
|
||||
if ((oldPolicy == FOREVER) ||
|
||||
(newPolicy < oldPolicy) ||
|
||||
(newPolicy < FOREVER)) {
|
||||
|
||||
throw new
|
||||
SecurityException("can't make InetAddress cache more lax");
|
||||
}
|
||||
}
|
||||
}
|
||||
59
jdkSrc/jdk8/sun/net/NetHooks.java
Normal file
59
jdkSrc/jdk8/sun/net/NetHooks.java
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 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 sun.net;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Defines static methods to ensure that any installed net hooks are invoked
|
||||
* prior to binding or connecting TCP sockets.
|
||||
*/
|
||||
|
||||
public final class NetHooks {
|
||||
|
||||
/**
|
||||
* Invoke prior to binding a TCP socket.
|
||||
*/
|
||||
public static void beforeTcpBind(FileDescriptor fdObj,
|
||||
InetAddress address,
|
||||
int port)
|
||||
throws IOException
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke prior to connecting an unbound TCP socket.
|
||||
*/
|
||||
public static void beforeTcpConnect(FileDescriptor fdObj,
|
||||
InetAddress address,
|
||||
int port)
|
||||
throws IOException
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
}
|
||||
158
jdkSrc/jdk8/sun/net/NetProperties.java
Normal file
158
jdkSrc/jdk8/sun/net/NetProperties.java
Normal file
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 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 sun.net;
|
||||
|
||||
import java.io.*;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.Properties;
|
||||
|
||||
/*
|
||||
* This class allows for centralized access to Networking properties.
|
||||
* Default values are loaded from the file jre/lib/net.properties
|
||||
*
|
||||
*
|
||||
* @author Jean-Christophe Collet
|
||||
*
|
||||
*/
|
||||
|
||||
public class NetProperties {
|
||||
static private Properties props = new Properties();
|
||||
static {
|
||||
AccessController.doPrivileged(
|
||||
new PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
loadDefaultProperties();
|
||||
return null;
|
||||
}});
|
||||
}
|
||||
|
||||
private NetProperties() { };
|
||||
|
||||
|
||||
/*
|
||||
* Loads the default networking system properties
|
||||
* the file is in jre/lib/net.properties
|
||||
*/
|
||||
static private void loadDefaultProperties() {
|
||||
String fname = System.getProperty("java.home");
|
||||
if (fname == null) {
|
||||
throw new Error("Can't find java.home ??");
|
||||
}
|
||||
try {
|
||||
File f = new File(fname, "lib");
|
||||
f = new File(f, "net.properties");
|
||||
fname = f.getCanonicalPath();
|
||||
InputStream in = new FileInputStream(fname);
|
||||
BufferedInputStream bin = new BufferedInputStream(in);
|
||||
props.load(bin);
|
||||
bin.close();
|
||||
} catch (Exception e) {
|
||||
// Do nothing. We couldn't find or access the file
|
||||
// so we won't have default properties...
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a networking system property. If no system property was defined
|
||||
* returns the default value, if it exists, otherwise returns
|
||||
* <code>null</code>.
|
||||
* @param key the property name.
|
||||
* @throws SecurityException if a security manager exists and its
|
||||
* <code>checkPropertiesAccess</code> method doesn't allow access
|
||||
* to the system properties.
|
||||
* @return the <code>String</code> value for the property,
|
||||
* or <code>null</code>
|
||||
*/
|
||||
static public String get(String key) {
|
||||
String def = props.getProperty(key);
|
||||
try {
|
||||
return System.getProperty(key, def);
|
||||
} catch (IllegalArgumentException e) {
|
||||
} catch (NullPointerException e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an Integer networking system property. If no system property was
|
||||
* defined returns the default value, if it exists, otherwise returns
|
||||
* <code>null</code>.
|
||||
* @param key the property name.
|
||||
* @param defval the default value to use if the property is not found
|
||||
* @throws SecurityException if a security manager exists and its
|
||||
* <code>checkPropertiesAccess</code> method doesn't allow access
|
||||
* to the system properties.
|
||||
* @return the <code>Integer</code> value for the property,
|
||||
* or <code>null</code>
|
||||
*/
|
||||
static public Integer getInteger(String key, int defval) {
|
||||
String val = null;
|
||||
|
||||
try {
|
||||
val = System.getProperty(key, props.getProperty(key));
|
||||
} catch (IllegalArgumentException e) {
|
||||
} catch (NullPointerException e) {
|
||||
}
|
||||
|
||||
if (val != null) {
|
||||
try {
|
||||
return Integer.decode(val);
|
||||
} catch (NumberFormatException ex) {
|
||||
}
|
||||
}
|
||||
return new Integer(defval);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a Boolean networking system property. If no system property was
|
||||
* defined returns the default value, if it exists, otherwise returns
|
||||
* <code>null</code>.
|
||||
* @param key the property name.
|
||||
* @throws SecurityException if a security manager exists and its
|
||||
* <code>checkPropertiesAccess</code> method doesn't allow access
|
||||
* to the system properties.
|
||||
* @return the <code>Boolean</code> value for the property,
|
||||
* or <code>null</code>
|
||||
*/
|
||||
static public Boolean getBoolean(String key) {
|
||||
String val = null;
|
||||
|
||||
try {
|
||||
val = System.getProperty(key, props.getProperty(key));
|
||||
} catch (IllegalArgumentException e) {
|
||||
} catch (NullPointerException e) {
|
||||
}
|
||||
|
||||
if (val != null) {
|
||||
try {
|
||||
return Boolean.valueOf(val);
|
||||
} catch (NumberFormatException ex) {
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
273
jdkSrc/jdk8/sun/net/NetworkClient.java
Normal file
273
jdkSrc/jdk8/sun/net/NetworkClient.java
Normal file
@@ -0,0 +1,273 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 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 sun.net;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.Socket;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.net.Proxy;
|
||||
import java.util.Arrays;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
/**
|
||||
* This is the base class for network clients.
|
||||
*
|
||||
* @author Jonathan Payne
|
||||
*/
|
||||
public class NetworkClient {
|
||||
/* Default value of read timeout, if not specified (infinity) */
|
||||
public static final int DEFAULT_READ_TIMEOUT = -1;
|
||||
|
||||
/* Default value of connect timeout, if not specified (infinity) */
|
||||
public static final int DEFAULT_CONNECT_TIMEOUT = -1;
|
||||
|
||||
protected Proxy proxy = Proxy.NO_PROXY;
|
||||
/** Socket for communicating with server. */
|
||||
protected Socket serverSocket = null;
|
||||
|
||||
/** Stream for printing to the server. */
|
||||
public PrintStream serverOutput;
|
||||
|
||||
/** Buffered stream for reading replies from server. */
|
||||
public InputStream serverInput;
|
||||
|
||||
protected static int defaultSoTimeout;
|
||||
protected static int defaultConnectTimeout;
|
||||
|
||||
protected int readTimeout = DEFAULT_READ_TIMEOUT;
|
||||
protected int connectTimeout = DEFAULT_CONNECT_TIMEOUT;
|
||||
/* Name of encoding to use for output */
|
||||
protected static String encoding;
|
||||
|
||||
static {
|
||||
final int vals[] = {0, 0};
|
||||
final String encs[] = { null };
|
||||
|
||||
AccessController.doPrivileged(
|
||||
new PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
vals[0] = Integer.getInteger("sun.net.client.defaultReadTimeout", 0).intValue();
|
||||
vals[1] = Integer.getInteger("sun.net.client.defaultConnectTimeout", 0).intValue();
|
||||
encs[0] = System.getProperty("file.encoding", "ISO8859_1");
|
||||
return null;
|
||||
}
|
||||
});
|
||||
if (vals[0] != 0) {
|
||||
defaultSoTimeout = vals[0];
|
||||
}
|
||||
if (vals[1] != 0) {
|
||||
defaultConnectTimeout = vals[1];
|
||||
}
|
||||
|
||||
encoding = encs[0];
|
||||
try {
|
||||
if (!isASCIISuperset (encoding)) {
|
||||
encoding = "ISO8859_1";
|
||||
}
|
||||
} catch (Exception e) {
|
||||
encoding = "ISO8859_1";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test the named character encoding to verify that it converts ASCII
|
||||
* characters correctly. We have to use an ASCII based encoding, or else
|
||||
* the NetworkClients will not work correctly in EBCDIC based systems.
|
||||
* However, we cannot just use ASCII or ISO8859_1 universally, because in
|
||||
* Asian locales, non-ASCII characters may be embedded in otherwise
|
||||
* ASCII based protocols (eg. HTTP). The specifications (RFC2616, 2398)
|
||||
* are a little ambiguous in this matter. For instance, RFC2398 [part 2.1]
|
||||
* says that the HTTP request URI should be escaped using a defined
|
||||
* mechanism, but there is no way to specify in the escaped string what
|
||||
* the original character set is. It is not correct to assume that
|
||||
* UTF-8 is always used (as in URLs in HTML 4.0). For this reason,
|
||||
* until the specifications are updated to deal with this issue more
|
||||
* comprehensively, and more importantly, HTTP servers are known to
|
||||
* support these mechanisms, we will maintain the current behavior
|
||||
* where it is possible to send non-ASCII characters in their original
|
||||
* unescaped form.
|
||||
*/
|
||||
private static boolean isASCIISuperset (String encoding) throws Exception {
|
||||
String chkS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"+
|
||||
"abcdefghijklmnopqrstuvwxyz-_.!~*'();/?:@&=+$,";
|
||||
|
||||
// Expected byte sequence for string above
|
||||
byte[] chkB = { 48,49,50,51,52,53,54,55,56,57,65,66,67,68,69,70,71,72,
|
||||
73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,97,98,99,
|
||||
100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,
|
||||
115,116,117,118,119,120,121,122,45,95,46,33,126,42,39,40,41,59,
|
||||
47,63,58,64,38,61,43,36,44};
|
||||
|
||||
byte[] b = chkS.getBytes (encoding);
|
||||
return Arrays.equals (b, chkB);
|
||||
}
|
||||
|
||||
/** Open a connection to the server. */
|
||||
public void openServer(String server, int port)
|
||||
throws IOException, UnknownHostException {
|
||||
if (serverSocket != null)
|
||||
closeServer();
|
||||
serverSocket = doConnect (server, port);
|
||||
try {
|
||||
serverOutput = new PrintStream(new BufferedOutputStream(
|
||||
serverSocket.getOutputStream()),
|
||||
true, encoding);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new InternalError(encoding +"encoding not found", e);
|
||||
}
|
||||
serverInput = new BufferedInputStream(serverSocket.getInputStream());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a socket connected to the server, with any
|
||||
* appropriate options pre-established
|
||||
*/
|
||||
protected Socket doConnect (String server, int port)
|
||||
throws IOException, UnknownHostException {
|
||||
Socket s;
|
||||
if (proxy != null) {
|
||||
if (proxy.type() == Proxy.Type.SOCKS) {
|
||||
s = AccessController.doPrivileged(
|
||||
new PrivilegedAction<Socket>() {
|
||||
public Socket run() {
|
||||
return new Socket(proxy);
|
||||
}});
|
||||
} else if (proxy.type() == Proxy.Type.DIRECT) {
|
||||
s = createSocket();
|
||||
} else {
|
||||
// Still connecting through a proxy
|
||||
// server & port will be the proxy address and port
|
||||
s = new Socket(Proxy.NO_PROXY);
|
||||
}
|
||||
} else
|
||||
s = createSocket();
|
||||
// Instance specific timeouts do have priority, that means
|
||||
// connectTimeout & readTimeout (-1 means not set)
|
||||
// Then global default timeouts
|
||||
// Then no timeout.
|
||||
if (connectTimeout >= 0) {
|
||||
s.connect(new InetSocketAddress(server, port), connectTimeout);
|
||||
} else {
|
||||
if (defaultConnectTimeout > 0) {
|
||||
s.connect(new InetSocketAddress(server, port), defaultConnectTimeout);
|
||||
} else {
|
||||
s.connect(new InetSocketAddress(server, port));
|
||||
}
|
||||
}
|
||||
if (readTimeout >= 0)
|
||||
s.setSoTimeout(readTimeout);
|
||||
else if (defaultSoTimeout > 0) {
|
||||
s.setSoTimeout(defaultSoTimeout);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* The following method, createSocket, is provided to allow the
|
||||
* https client to override it so that it may use its socket factory
|
||||
* to create the socket.
|
||||
*/
|
||||
protected Socket createSocket() throws IOException {
|
||||
return new java.net.Socket();
|
||||
}
|
||||
|
||||
protected InetAddress getLocalAddress() throws IOException {
|
||||
if (serverSocket == null)
|
||||
throw new IOException("not connected");
|
||||
return AccessController.doPrivileged(
|
||||
new PrivilegedAction<InetAddress>() {
|
||||
public InetAddress run() {
|
||||
return serverSocket.getLocalAddress();
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** Close an open connection to the server. */
|
||||
public void closeServer() throws IOException {
|
||||
if (! serverIsOpen()) {
|
||||
return;
|
||||
}
|
||||
serverSocket.close();
|
||||
serverSocket = null;
|
||||
serverInput = null;
|
||||
serverOutput = null;
|
||||
}
|
||||
|
||||
/** Return server connection status */
|
||||
public boolean serverIsOpen() {
|
||||
return serverSocket != null;
|
||||
}
|
||||
|
||||
/** Create connection with host <i>host</i> on port <i>port</i> */
|
||||
public NetworkClient(String host, int port) throws IOException {
|
||||
openServer(host, port);
|
||||
}
|
||||
|
||||
public NetworkClient() {}
|
||||
|
||||
public void setConnectTimeout(int timeout) {
|
||||
connectTimeout = timeout;
|
||||
}
|
||||
|
||||
public int getConnectTimeout() {
|
||||
return connectTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the read timeout.
|
||||
*
|
||||
* Note: Public URLConnection (and protocol specific implementations)
|
||||
* protect against negative timeout values being set. This implementation,
|
||||
* and protocol specific implementations, use -1 to represent the default
|
||||
* read timeout.
|
||||
*
|
||||
* This method may be invoked with the default timeout value when the
|
||||
* protocol handler is trying to reset the timeout after doing a
|
||||
* potentially blocking internal operation, e.g. cleaning up unread
|
||||
* response data, buffering error stream response data, etc
|
||||
*/
|
||||
public void setReadTimeout(int timeout) {
|
||||
if (timeout == DEFAULT_READ_TIMEOUT)
|
||||
timeout = defaultSoTimeout;
|
||||
|
||||
if (serverSocket != null && timeout >= 0) {
|
||||
try {
|
||||
serverSocket.setSoTimeout(timeout);
|
||||
} catch(IOException e) {
|
||||
// We tried...
|
||||
}
|
||||
}
|
||||
readTimeout = timeout;
|
||||
}
|
||||
|
||||
public int getReadTimeout() {
|
||||
return readTimeout;
|
||||
}
|
||||
}
|
||||
151
jdkSrc/jdk8/sun/net/NetworkServer.java
Normal file
151
jdkSrc/jdk8/sun/net/NetworkServer.java
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2011, 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 sun.net;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.Socket;
|
||||
import java.net.ServerSocket;
|
||||
|
||||
/**
|
||||
* This is the base class for network servers. To define a new type
|
||||
* of server define a new subclass of NetworkServer with a serviceRequest
|
||||
* method that services one request. Start the server by executing:
|
||||
* <pre>
|
||||
* new MyServerClass().startServer(port);
|
||||
* </pre>
|
||||
*/
|
||||
public class NetworkServer implements Runnable, Cloneable {
|
||||
/** Socket for communicating with client. */
|
||||
public Socket clientSocket = null;
|
||||
private Thread serverInstance;
|
||||
private ServerSocket serverSocket;
|
||||
|
||||
/** Stream for printing to the client. */
|
||||
public PrintStream clientOutput;
|
||||
|
||||
/** Buffered stream for reading replies from client. */
|
||||
public InputStream clientInput;
|
||||
|
||||
/** Close an open connection to the client. */
|
||||
public void close() throws IOException {
|
||||
clientSocket.close();
|
||||
clientSocket = null;
|
||||
clientInput = null;
|
||||
clientOutput = null;
|
||||
}
|
||||
|
||||
/** Return client connection status */
|
||||
public boolean clientIsOpen() {
|
||||
return clientSocket != null;
|
||||
}
|
||||
|
||||
final public void run() {
|
||||
if (serverSocket != null) {
|
||||
Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
|
||||
// System.out.print("Server starts " + serverSocket + "\n");
|
||||
while (true) {
|
||||
try {
|
||||
Socket ns = serverSocket.accept();
|
||||
// System.out.print("New connection " + ns + "\n");
|
||||
NetworkServer n = (NetworkServer)clone();
|
||||
n.serverSocket = null;
|
||||
n.clientSocket = ns;
|
||||
new Thread(n).start();
|
||||
} catch(Exception e) {
|
||||
System.out.print("Server failure\n");
|
||||
e.printStackTrace();
|
||||
try {
|
||||
serverSocket.close();
|
||||
} catch(IOException e2) {}
|
||||
System.out.print("cs="+serverSocket+"\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
// close();
|
||||
} else {
|
||||
try {
|
||||
clientOutput = new PrintStream(
|
||||
new BufferedOutputStream(clientSocket.getOutputStream()),
|
||||
false, "ISO8859_1");
|
||||
clientInput = new BufferedInputStream(clientSocket.getInputStream());
|
||||
serviceRequest();
|
||||
// System.out.print("Service handler exits
|
||||
// "+clientSocket+"\n");
|
||||
} catch(Exception e) {
|
||||
// System.out.print("Service handler failure\n");
|
||||
// e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
close();
|
||||
} catch(IOException e2) {}
|
||||
}
|
||||
}
|
||||
|
||||
/** Start a server on port <i>port</i>. It will call serviceRequest()
|
||||
for each new connection. */
|
||||
final public void startServer(int port) throws IOException {
|
||||
serverSocket = new ServerSocket(port, 50);
|
||||
serverInstance = new Thread(this);
|
||||
serverInstance.start();
|
||||
}
|
||||
|
||||
/** Service one request. It is invoked with the clientInput and
|
||||
clientOutput streams initialized. This method handles one client
|
||||
connection. When it is done, it can simply exit. The default
|
||||
server just echoes it's input. It is invoked in it's own private
|
||||
thread. */
|
||||
public void serviceRequest() throws IOException {
|
||||
byte buf[] = new byte[300];
|
||||
int n;
|
||||
clientOutput.print("Echo server " + getClass().getName() + "\n");
|
||||
clientOutput.flush();
|
||||
while ((n = clientInput.read(buf, 0, buf.length)) >= 0) {
|
||||
clientOutput.write(buf, 0, n);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String argv[]) {
|
||||
try {
|
||||
new NetworkServer ().startServer(8888);
|
||||
} catch (IOException e) {
|
||||
System.out.print("Server failed: "+e+"\n");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone this object;
|
||||
*/
|
||||
public Object clone() {
|
||||
try {
|
||||
return super.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
// this shouldn't happen, since we are Cloneable
|
||||
throw new InternalError(e);
|
||||
}
|
||||
}
|
||||
|
||||
public NetworkServer () {
|
||||
}
|
||||
}
|
||||
73
jdkSrc/jdk8/sun/net/PortConfig.java
Normal file
73
jdkSrc/jdk8/sun/net/PortConfig.java
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* 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 sun.net;
|
||||
|
||||
import java.security.AccessController;
|
||||
|
||||
/**
|
||||
* Determines the ephemeral port range in use on this system.
|
||||
* If this cannot be determined, then the default settings
|
||||
* of the OS are returned.
|
||||
*/
|
||||
|
||||
public final class PortConfig {
|
||||
|
||||
private static int defaultUpper, defaultLower;
|
||||
private final static int upper, lower;
|
||||
|
||||
static {
|
||||
AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
System.loadLibrary("net");
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
int v = getLower0();
|
||||
if (v == -1) {
|
||||
v = defaultLower;
|
||||
}
|
||||
lower = v;
|
||||
|
||||
v = getUpper0();
|
||||
if (v == -1) {
|
||||
v = defaultUpper;
|
||||
}
|
||||
upper = v;
|
||||
}
|
||||
|
||||
static native int getLower0();
|
||||
static native int getUpper0();
|
||||
|
||||
public static int getLower() {
|
||||
return lower;
|
||||
}
|
||||
|
||||
public static int getUpper() {
|
||||
return upper;
|
||||
}
|
||||
}
|
||||
113
jdkSrc/jdk8/sun/net/ProgressEvent.java
Normal file
113
jdkSrc/jdk8/sun/net/ProgressEvent.java
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 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 sun.net;
|
||||
|
||||
import java.util.EventObject;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* ProgressEvent represents an progress event in monitering network input stream.
|
||||
*
|
||||
* @author Stanley Man-Kit Ho
|
||||
*/
|
||||
@SuppressWarnings("serial") // never serialized
|
||||
public class ProgressEvent extends EventObject {
|
||||
// URL of the stream
|
||||
private URL url;
|
||||
// content type of the stream
|
||||
private String contentType;
|
||||
// method associated with URL
|
||||
private String method;
|
||||
// bytes read
|
||||
private long progress;
|
||||
// bytes expected
|
||||
private long expected;
|
||||
// the last thing to happen
|
||||
private ProgressSource.State state;
|
||||
|
||||
/**
|
||||
* Construct a ProgressEvent object.
|
||||
*/
|
||||
public ProgressEvent(ProgressSource source, URL url, String method, String contentType, ProgressSource.State state, long progress, long expected) {
|
||||
super(source);
|
||||
this.url = url;
|
||||
this.method = method;
|
||||
this.contentType = contentType;
|
||||
this.progress = progress;
|
||||
this.expected = expected;
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return URL related to the progress.
|
||||
*/
|
||||
public URL getURL()
|
||||
{
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return method associated with URL.
|
||||
*/
|
||||
public String getMethod()
|
||||
{
|
||||
return method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return content type of the URL.
|
||||
*/
|
||||
public String getContentType()
|
||||
{
|
||||
return contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return current progress value.
|
||||
*/
|
||||
public long getProgress()
|
||||
{
|
||||
return progress;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return expected maximum progress value; -1 if expected is unknown.
|
||||
*/
|
||||
public long getExpected() {
|
||||
return expected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return state.
|
||||
*/
|
||||
public ProgressSource.State getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return getClass().getName() + "[url=" + url + ", method=" + method + ", state=" + state
|
||||
+ ", content-type=" + contentType + ", progress=" + progress + ", expected=" + expected + "]";
|
||||
}
|
||||
}
|
||||
51
jdkSrc/jdk8/sun/net/ProgressListener.java
Normal file
51
jdkSrc/jdk8/sun/net/ProgressListener.java
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 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 sun.net;
|
||||
|
||||
import java.util.EventListener;
|
||||
|
||||
/**
|
||||
* ProgressListener is an interface to be implemented by parties
|
||||
* interested to be notified of progress in network input stream.
|
||||
*
|
||||
* @author Stanley Man-Kit Ho
|
||||
*/
|
||||
public interface ProgressListener extends EventListener
|
||||
{
|
||||
/**
|
||||
* Start progress.
|
||||
*/
|
||||
public void progressStart(ProgressEvent evt);
|
||||
|
||||
/**
|
||||
* Update progress.
|
||||
*/
|
||||
public void progressUpdate(ProgressEvent evt);
|
||||
|
||||
/**
|
||||
* Finish progress.
|
||||
*/
|
||||
public void progressFinish(ProgressEvent evt);
|
||||
}
|
||||
45
jdkSrc/jdk8/sun/net/ProgressMeteringPolicy.java
Normal file
45
jdkSrc/jdk8/sun/net/ProgressMeteringPolicy.java
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 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 sun.net;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* ProgressMeteringPolicy is an interface for determining progress metering policy.
|
||||
*
|
||||
* @author Stanley Man-Kit Ho
|
||||
*/
|
||||
public interface ProgressMeteringPolicy
|
||||
{
|
||||
/**
|
||||
* Return true if metering should be turned on for a particular network input stream.
|
||||
*/
|
||||
public boolean shouldMeterInput(URL url, String method);
|
||||
|
||||
/**
|
||||
* Return update notification threshold.
|
||||
*/
|
||||
public int getProgressUpdateThreshold();
|
||||
}
|
||||
257
jdkSrc/jdk8/sun/net/ProgressMonitor.java
Normal file
257
jdkSrc/jdk8/sun/net/ProgressMonitor.java
Normal file
@@ -0,0 +1,257 @@
|
||||
/*
|
||||
* Copyright (c) 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 sun.net;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* ProgressMonitor is a class for monitoring progress in network input stream.
|
||||
*
|
||||
* @author Stanley Man-Kit Ho
|
||||
*/
|
||||
public class ProgressMonitor
|
||||
{
|
||||
/**
|
||||
* Return default ProgressMonitor.
|
||||
*/
|
||||
public static synchronized ProgressMonitor getDefault() {
|
||||
return pm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change default ProgressMonitor implementation.
|
||||
*/
|
||||
public static synchronized void setDefault(ProgressMonitor m) {
|
||||
if (m != null)
|
||||
pm = m;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change progress metering policy.
|
||||
*/
|
||||
public static synchronized void setMeteringPolicy(ProgressMeteringPolicy policy) {
|
||||
if (policy != null)
|
||||
meteringPolicy = policy;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a snapshot of the ProgressSource list
|
||||
*/
|
||||
public ArrayList<ProgressSource> getProgressSources() {
|
||||
ArrayList<ProgressSource> snapshot = new ArrayList<ProgressSource>();
|
||||
|
||||
try {
|
||||
synchronized(progressSourceList) {
|
||||
for (Iterator<ProgressSource> iter = progressSourceList.iterator(); iter.hasNext();) {
|
||||
ProgressSource pi = iter.next();
|
||||
|
||||
// Clone ProgressSource and add to snapshot
|
||||
snapshot.add((ProgressSource)pi.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(CloneNotSupportedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return update notification threshold
|
||||
*/
|
||||
public synchronized int getProgressUpdateThreshold() {
|
||||
return meteringPolicy.getProgressUpdateThreshold();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if metering should be turned on
|
||||
* for a particular URL input stream.
|
||||
*/
|
||||
public boolean shouldMeterInput(URL url, String method) {
|
||||
return meteringPolicy.shouldMeterInput(url, method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register progress source when progress is began.
|
||||
*/
|
||||
public void registerSource(ProgressSource pi) {
|
||||
|
||||
synchronized(progressSourceList) {
|
||||
if (progressSourceList.contains(pi))
|
||||
return;
|
||||
|
||||
progressSourceList.add(pi);
|
||||
}
|
||||
|
||||
// Notify only if there is at least one listener
|
||||
if (progressListenerList.size() > 0)
|
||||
{
|
||||
// Notify progress listener if there is progress change
|
||||
ArrayList<ProgressListener> listeners = new ArrayList<ProgressListener>();
|
||||
|
||||
// Copy progress listeners to another list to avoid holding locks
|
||||
synchronized(progressListenerList) {
|
||||
for (Iterator<ProgressListener> iter = progressListenerList.iterator(); iter.hasNext();) {
|
||||
listeners.add(iter.next());
|
||||
}
|
||||
}
|
||||
|
||||
// Fire event on each progress listener
|
||||
for (Iterator<ProgressListener> iter = listeners.iterator(); iter.hasNext();) {
|
||||
ProgressListener pl = iter.next();
|
||||
ProgressEvent pe = new ProgressEvent(pi, pi.getURL(), pi.getMethod(), pi.getContentType(), pi.getState(), pi.getProgress(), pi.getExpected());
|
||||
pl.progressStart(pe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister progress source when progress is finished.
|
||||
*/
|
||||
public void unregisterSource(ProgressSource pi) {
|
||||
|
||||
synchronized(progressSourceList) {
|
||||
// Return if ProgressEvent does not exist
|
||||
if (progressSourceList.contains(pi) == false)
|
||||
return;
|
||||
|
||||
// Close entry and remove from map
|
||||
pi.close();
|
||||
progressSourceList.remove(pi);
|
||||
}
|
||||
|
||||
// Notify only if there is at least one listener
|
||||
if (progressListenerList.size() > 0)
|
||||
{
|
||||
// Notify progress listener if there is progress change
|
||||
ArrayList<ProgressListener> listeners = new ArrayList<ProgressListener>();
|
||||
|
||||
// Copy progress listeners to another list to avoid holding locks
|
||||
synchronized(progressListenerList) {
|
||||
for (Iterator<ProgressListener> iter = progressListenerList.iterator(); iter.hasNext();) {
|
||||
listeners.add(iter.next());
|
||||
}
|
||||
}
|
||||
|
||||
// Fire event on each progress listener
|
||||
for (Iterator<ProgressListener> iter = listeners.iterator(); iter.hasNext();) {
|
||||
ProgressListener pl = iter.next();
|
||||
ProgressEvent pe = new ProgressEvent(pi, pi.getURL(), pi.getMethod(), pi.getContentType(), pi.getState(), pi.getProgress(), pi.getExpected());
|
||||
pl.progressFinish(pe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Progress source is updated.
|
||||
*/
|
||||
public void updateProgress(ProgressSource pi) {
|
||||
|
||||
synchronized (progressSourceList) {
|
||||
if (progressSourceList.contains(pi) == false)
|
||||
return;
|
||||
}
|
||||
|
||||
// Notify only if there is at least one listener
|
||||
if (progressListenerList.size() > 0)
|
||||
{
|
||||
// Notify progress listener if there is progress change
|
||||
ArrayList<ProgressListener> listeners = new ArrayList<ProgressListener>();
|
||||
|
||||
// Copy progress listeners to another list to avoid holding locks
|
||||
synchronized(progressListenerList) {
|
||||
for (Iterator<ProgressListener> iter = progressListenerList.iterator(); iter.hasNext();) {
|
||||
listeners.add(iter.next());
|
||||
}
|
||||
}
|
||||
|
||||
// Fire event on each progress listener
|
||||
for (Iterator<ProgressListener> iter = listeners.iterator(); iter.hasNext();) {
|
||||
ProgressListener pl = iter.next();
|
||||
ProgressEvent pe = new ProgressEvent(pi, pi.getURL(), pi.getMethod(), pi.getContentType(), pi.getState(), pi.getProgress(), pi.getExpected());
|
||||
pl.progressUpdate(pe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add progress listener in progress monitor.
|
||||
*/
|
||||
public void addProgressListener(ProgressListener l) {
|
||||
synchronized(progressListenerList) {
|
||||
progressListenerList.add(l);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove progress listener from progress monitor.
|
||||
*/
|
||||
public void removeProgressListener(ProgressListener l) {
|
||||
synchronized(progressListenerList) {
|
||||
progressListenerList.remove(l);
|
||||
}
|
||||
}
|
||||
|
||||
// Metering policy
|
||||
private static ProgressMeteringPolicy meteringPolicy = new DefaultProgressMeteringPolicy();
|
||||
|
||||
// Default implementation
|
||||
private static ProgressMonitor pm = new ProgressMonitor();
|
||||
|
||||
// ArrayList for outstanding progress sources
|
||||
private ArrayList<ProgressSource> progressSourceList = new ArrayList<ProgressSource>();
|
||||
|
||||
// ArrayList for progress listeners
|
||||
private ArrayList<ProgressListener> progressListenerList = new ArrayList<ProgressListener>();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Default progress metering policy.
|
||||
*/
|
||||
class DefaultProgressMeteringPolicy implements ProgressMeteringPolicy {
|
||||
/**
|
||||
* Return true if metering should be turned on for a particular network input stream.
|
||||
*/
|
||||
public boolean shouldMeterInput(URL url, String method)
|
||||
{
|
||||
// By default, no URL input stream is metered for
|
||||
// performance reason.
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return update notification threshold.
|
||||
*/
|
||||
public int getProgressUpdateThreshold() {
|
||||
// 8K - same as default I/O buffer size
|
||||
return 8192;
|
||||
}
|
||||
}
|
||||
210
jdkSrc/jdk8/sun/net/ProgressSource.java
Normal file
210
jdkSrc/jdk8/sun/net/ProgressSource.java
Normal file
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* Copyright (c) 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 sun.net;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* ProgressSource represents the source of progress changes.
|
||||
*
|
||||
* @author Stanley Man-Kit Ho
|
||||
*/
|
||||
public class ProgressSource
|
||||
{
|
||||
public enum State { NEW, CONNECTED, UPDATE, DELETE };
|
||||
|
||||
// URL
|
||||
private URL url;
|
||||
// URL method
|
||||
private String method;
|
||||
// Content type
|
||||
private String contentType;
|
||||
// bytes read
|
||||
private long progress = 0;
|
||||
// last bytes read
|
||||
private long lastProgress = 0;
|
||||
//bytes expected
|
||||
private long expected = -1;
|
||||
// the last thing to happen with this source
|
||||
private State state;
|
||||
// connect flag
|
||||
private boolean connected = false;
|
||||
// threshold for notification
|
||||
private int threshold = 8192;
|
||||
// progress monitor
|
||||
private ProgressMonitor progressMonitor;
|
||||
|
||||
/**
|
||||
* Construct progress source object.
|
||||
*/
|
||||
public ProgressSource(URL url, String method) {
|
||||
this(url, method, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct progress source object.
|
||||
*/
|
||||
public ProgressSource(URL url, String method, long expected) {
|
||||
this.url = url;
|
||||
this.method = method;
|
||||
this.contentType = "content/unknown";
|
||||
this.progress = 0;
|
||||
this.lastProgress = 0;
|
||||
this.expected = expected;
|
||||
this.state = State.NEW;
|
||||
this.progressMonitor = ProgressMonitor.getDefault();
|
||||
this.threshold = progressMonitor.getProgressUpdateThreshold();
|
||||
}
|
||||
|
||||
public boolean connected() {
|
||||
if (!connected) {
|
||||
connected = true;
|
||||
state = State.CONNECTED;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close progress source.
|
||||
*/
|
||||
public void close() {
|
||||
state = State.DELETE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return URL of progress source.
|
||||
*/
|
||||
public URL getURL() {
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return method of URL.
|
||||
*/
|
||||
public String getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return content type of URL.
|
||||
*/
|
||||
public String getContentType() {
|
||||
return contentType;
|
||||
}
|
||||
|
||||
// Change content type
|
||||
public void setContentType(String ct) {
|
||||
contentType = ct;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return current progress.
|
||||
*/
|
||||
public long getProgress() {
|
||||
return progress;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return expected maximum progress; -1 if expected is unknown.
|
||||
*/
|
||||
public long getExpected() {
|
||||
return expected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return state.
|
||||
*/
|
||||
public State getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Begin progress tracking.
|
||||
*/
|
||||
public void beginTracking() {
|
||||
progressMonitor.registerSource(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finish progress tracking.
|
||||
*/
|
||||
public void finishTracking() {
|
||||
progressMonitor.unregisterSource(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update progress.
|
||||
*/
|
||||
public void updateProgress(long latestProgress, long expectedProgress) {
|
||||
lastProgress = progress;
|
||||
progress = latestProgress;
|
||||
expected = expectedProgress;
|
||||
|
||||
if (connected() == false)
|
||||
state = State.CONNECTED;
|
||||
else
|
||||
state = State.UPDATE;
|
||||
|
||||
// The threshold effectively divides the progress into
|
||||
// different set of ranges:
|
||||
//
|
||||
// Range 0: 0..threshold-1,
|
||||
// Range 1: threshold .. 2*threshold-1
|
||||
// ....
|
||||
// Range n: n*threshold .. (n+1)*threshold-1
|
||||
//
|
||||
// To determine which range the progress belongs to, it
|
||||
// would be calculated as follow:
|
||||
//
|
||||
// range number = progress / threshold
|
||||
//
|
||||
// Notification should only be triggered when the current
|
||||
// progress and the last progress are in different ranges,
|
||||
// i.e. they have different range numbers.
|
||||
//
|
||||
// Using this range scheme, notification will be generated
|
||||
// only once when the progress reaches each range.
|
||||
//
|
||||
if (lastProgress / threshold != progress / threshold) {
|
||||
progressMonitor.updateProgress(this);
|
||||
}
|
||||
|
||||
// Detect read overrun
|
||||
if (expected != -1) {
|
||||
if (progress >= expected && progress != 0)
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
public Object clone() throws CloneNotSupportedException {
|
||||
return super.clone();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return getClass().getName() + "[url=" + url + ", method=" + method + ", state=" + state
|
||||
+ ", content-type=" + contentType + ", progress=" + progress + ", expected=" + expected + "]";
|
||||
}
|
||||
}
|
||||
913
jdkSrc/jdk8/sun/net/RegisteredDomain.java
Normal file
913
jdkSrc/jdk8/sun/net/RegisteredDomain.java
Normal file
@@ -0,0 +1,913 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2017, 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 sun.net;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/*
|
||||
* WARNING: This class may contain out-of-date information. It should be
|
||||
* updated or replaced with an appropriate implementation. See
|
||||
* sun.security.util.RegisteredDomain for more information.
|
||||
*
|
||||
* The naming tables listed below were gathered from publicly available data such as
|
||||
* the subdomain registration websites listed for each top-level domain by the Internet
|
||||
* Assigned Numbers Authority and the website of the Internet Corporation for Assigned Names
|
||||
* and Numbers as well as Wikipedia.
|
||||
*/
|
||||
|
||||
public class RegisteredDomain {
|
||||
|
||||
// XX.AA
|
||||
private static Set<String> top1Set = new HashSet<String>(Arrays.asList("asia", "biz", "cat", "coop",
|
||||
"edu", "info", "gov", "jobs", "travel", "am", "aq", "ax", "cc", "cf", "cg", "ch", "cv", "cz",
|
||||
"de", "dj", "dk", "fm", "fo", "ga", "gd", "gf", "gl", "gm", "gq", "gs", "gw", "hm",
|
||||
"li", "lu", "md", "mh", "mil", "mobi", "mq", "ms", "ms", "ne", "nl", "nu", "si",
|
||||
"sm", "sr", "su", "tc", "td", "tf", "tg", "tk", "tm", "tv", "va", "vg",
|
||||
/* ae */ "xn--mgbaam7a8h", /* cn s */ "xn--fiqs8s", /* cn t */ "xn--fiqz9s",
|
||||
/* eg */ "xn--wgbh1c", /* hk */ "xn--j6w193g", /* jo */ "xn--mgbayh7gpa",
|
||||
/* lk */ "xn--fzc2c9e2c", /* ps */ "xn--ygbi2ammx", /* ru */ "xn--p1ai",
|
||||
/* qa */ "xn--wgbl6a", /* sa */ "xn--mgberp4a5d4ar", /* sg */ "xn--yfro4i67o",
|
||||
/* th */ "xn--o3cw4h", /* tn */ "xn--pgbs0dh", /* tw s */ "xn--kpry57d",
|
||||
/* tw */ "xn--kprw13d", /* sg tamil */ "xn--clchc0ea0b2g2a9gcd"));
|
||||
|
||||
// common pattern: XX.AA or XX.GOV.AA
|
||||
private static Set<String> top2Set = new HashSet<String>(Arrays.asList("as", "bf", "cd", "cx",
|
||||
"ie", "lt", "mr", "tl"));
|
||||
|
||||
// common pattern: XX.AA or XX.COM.AA or XX.EDU.AA or XX.NET.AA or XX.ORG.AA or XX.GOV.AA
|
||||
private static Set<String> top4Set = new HashSet<String>(Arrays.asList("af", "bm", "bs", "bt",
|
||||
"bz", "dm", "ky", "lb", "lr", "mo", "sc", "sl", "ws"));
|
||||
|
||||
// AA or less than 3 other XX.BB.AA possible matches
|
||||
private static Set<String> top3Set = new HashSet<String>(Arrays.asList("ad", "aw", "be", "bw",
|
||||
"cl", "fi", "int", "io", "mc"));
|
||||
|
||||
// AA.UK exceptions
|
||||
private static Set<String> ukSet = new HashSet<String>(Arrays.asList( "bl", "british-library",
|
||||
"jet", "nhs", "nls", "parliament", "mod", "police"));
|
||||
|
||||
// AA.AR exceptions
|
||||
private static Set<String> arSet = new HashSet<String>(Arrays.asList( "argentina", "educ",
|
||||
"gobiernoelectronico", "nic", "promocion", "retina", "uba"));
|
||||
|
||||
// AA.OM exceptions
|
||||
private static Set<String> omSet = new HashSet<String>(Arrays.asList("mediaphone", "nawrastelecom",
|
||||
"nawras", "omanmobile", "omanpost", "omantel", "rakpetroleum", "siemens", "songfest",
|
||||
"statecouncil", "shura", "peie", "omran", "omnic", "omanet", "oman", "muriya", "kom"));
|
||||
|
||||
// any XX.BB.AA
|
||||
private static Set<String> top5Set = new HashSet<String>(Arrays.asList("au", "arpa", "bd", "bn", "ck",
|
||||
"cy", "er", "et", "fj", "fk", "gt", "gu", "il", "jm", "ke", "kh", "kw",
|
||||
"mm", "mt", "mz", "ni", "np", "nz", "pg", "sb", "sv", "tz", "uy", "ve", "ye",
|
||||
"za", "zm", "zw"));
|
||||
|
||||
// XX.CC.BB.JP
|
||||
private static Set<String> jpSet = new HashSet<String>(Arrays.asList("aichi", "akita", "aomori",
|
||||
"chiba", "ehime", "fukui", "fukuoka", "fukushima", "gifu", "gunma", "hiroshima", "hokkaido",
|
||||
"hyogo", "ibaraki", "ishikawa", "iwate", "kagawa", "kagoshima", "kanagawa", "kawasaki",
|
||||
"kitakyushu", "kobe", "kochi", "kumamoto", "kyoto", "mie", "miyagi", "miyazaki", "nagano",
|
||||
"nagasaki", "nagoya", "nara", "niigata", "oita", "okayama", "okinawa", "osaka", "saga",
|
||||
"saitama", "sapporo", "sendai", "shiga", "shimane", "shizuoka", "tochigi", "tokushima",
|
||||
"tokyo", "tottori", "toyama", "wakayama", "yamagata", "yamaguchi", "yamanashi", "yokohama"));
|
||||
|
||||
// CC.BB.JP exceptions
|
||||
private static Set<String> jp2Set = new HashSet<String>(Arrays.asList("metro.tokyo.jp",
|
||||
"pref.aichi.jp", "pref.akita.jp", "pref.aomori.jp", "pref.chiba.jp", "pref.ehime.jp",
|
||||
"pref.fukui.jp", "pref.fukuoka.jp", "pref.fukushima.jp", "pref.gifu.jp", "pref.gunma.jp",
|
||||
"pref.hiroshima.jp", "pref.hokkaido.jp", "pref.hyogo.jp", "pref.ibaraki.jp", "pref.ishikawa.jp",
|
||||
"pref.iwate.jp", "pref.kagawa.jp", "pref.kagoshima.jp", "pref.kanagawa.jp", "pref.kochi.jp",
|
||||
"pref.kumamoto.jp", "pref.kyoto.jp", "pref.mie.jp", "pref.miyagi.jp", "pref.miyazaki.jp",
|
||||
"pref.nagano.jp", "pref.nagasaki.jp", "pref.nara.jp", "pref.niigata.jp", "pref.oita.jp",
|
||||
"pref.okayama.jp", "pref.okinawa.jp", "pref.osaka.jp", "pref.saga.jp", "pref.saitama.jp",
|
||||
"pref.shiga.jp", "pref.shimane.jp", "pref.shizuoka.jp", "pref.tochigi.jp", "pref.tokushima.jp",
|
||||
"pref.tottori.jp", "pref.toyama.jp", "pref.wakayama.jp", "pref.yamagata.jp", "pref.yamaguchi.jp",
|
||||
"pref.yamanashi.jp", "city.chiba.jp", "city.fukuoka.jp", "city.hamamatsu.jp", "city.hiroshima.jp", "city.kawasaki.jp",
|
||||
"city.kitakyushu.jp", "city.kobe.jp", "city.kyoto.jp", "city.nagoya.jp", "city.niigata.jp",
|
||||
"city.okayama.jp", "city.osaka.jp", "city.sagamihara.jp", "city.saitama.jp", "city.sapporo.jp", "city.sendai.jp",
|
||||
"city.shizuoka.jp", "city.yokohama.jp"));
|
||||
|
||||
private static Set<String> usStateSet = new HashSet<String>(Arrays.asList("ak",
|
||||
"al", "ar", "as", "az", "ca", "co", "ct", "dc", "de", "fl", "ga", "gu", "hi", "ia",
|
||||
"id", "il", "in", "ks", "ky", "la", "ma", "md", "me", "mi", "mn", "mo", "ms", "mt",
|
||||
"nc", "nd", "ne", "nh", "nj", "nm", "nv", "ny", "oh", "ok", "or", "pa", "pr", "ri",
|
||||
"sc", "sd", "tn", "tx", "ut", "vi", "vt", "va", "wa", "wi", "wv", "wy"));
|
||||
|
||||
private static Set<String> usSubStateSet = new HashSet<String>(Arrays.asList("state",
|
||||
"lib", "k12", "cc", "tec", "gen", "cog", "mus", "dst"));
|
||||
|
||||
private static Map<String,Set<String>> topMap = new HashMap<>();
|
||||
private static Map<String,Set<String>> top3Map = new HashMap<>();
|
||||
|
||||
static {
|
||||
/*
|
||||
* XX.AA or XX.BB.AA
|
||||
*/
|
||||
topMap.put("ac", new HashSet<String>(Arrays.asList("com", "co", "edu", "gov", "net", "mil", "org")));
|
||||
topMap.put("ae", new HashSet<String>(Arrays.asList("co", "net", "org", "sch", "ac", "gov", "mil")));
|
||||
topMap.put("aero", new HashSet<String>(Arrays.asList("accident-investigation",
|
||||
"accident-prevention", "aerobatic", "aeroclub", "aerodrome", "agents", "aircraft",
|
||||
"airline", "airport", "air-surveillance", "airtraffic", "air-traffic-control",
|
||||
"ambulance", "amusement", "association", "author", "ballooning", "broker", "caa",
|
||||
"cargo", "catering", "certification", "championship", "charter", "civilaviation",
|
||||
"club", "conference", "consultant", "consulting", "control", "council", "crew",
|
||||
"design", "dgca", "educator", "emergency", "engine", "engineer", "entertainment",
|
||||
"equipment", "exchange", "express", "federation", "flight", "freight", "fuel",
|
||||
"gliding", "government", "groundhandling", "group", "hanggliding", "homebuilt",
|
||||
"insurance", "journal", "journalist", "leasing", "logistics", "magazine",
|
||||
"maintenance", "marketplace", "media", "microlight", "modelling", "navigation",
|
||||
"parachuting", "paragliding", "passenger-association", "pilot", "press", "production",
|
||||
"recreation", "repbody", "res", "research", "rotorcraft", "safety", "scientist",
|
||||
"services", "show", "skydiving", "software", "student", "taxi", "trader", "trading",
|
||||
"trainer", "union", "workinggroup", "works" )));
|
||||
topMap.put( "ag", new HashSet<String>(Arrays.asList("com", "org", "net", "co", "nom")));
|
||||
topMap.put( "ai", new HashSet<String>(Arrays.asList("off", "com", "net", "org")));
|
||||
topMap.put( "al", new HashSet<String>(Arrays.asList("com", "edu", "gov", "mil", "net", "org")));
|
||||
topMap.put( "an", new HashSet<String>(Arrays.asList("com")));
|
||||
topMap.put( "ao", new HashSet<String>(Arrays.asList("ed", "gv", "og", "co", "pb", "it")));
|
||||
topMap.put( "at", new HashSet<String>(Arrays.asList("ac", "co", "gv", "or", "biz", "info", "priv")));
|
||||
topMap.put( "az", new HashSet<String>(Arrays.asList("com", "net", "int", "gov", "org", "edu", "info",
|
||||
"pp", "mil", "name", "biz")));
|
||||
topMap.put( "ba", new HashSet<String>(Arrays.asList("org", "net", "edu", "gov", "mil", "unbi",
|
||||
"unmo", "unsa", "untz", "unze", "co", "com", "rs")));
|
||||
topMap.put( "bb", new HashSet<String>(Arrays.asList("biz", "com", "edu", "gov", "info", "net", "org",
|
||||
"store")));
|
||||
topMap.put( "bg", new HashSet<String>(Arrays.asList("a", "b", "c", "d", "e", "f", "g", "h", "i", "j",
|
||||
"k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1",
|
||||
"2", "3", "4", "5", "6", "7", "8", "9")));
|
||||
topMap.put( "bh", new HashSet<String>(Arrays.asList("com", "info", "cc", "edu", "biz", "net",
|
||||
"org", "gov")));
|
||||
topMap.put( "bi", new HashSet<String>(Arrays.asList("co", "com", "edu", "gov", "info", "or", "org")));
|
||||
topMap.put( "bj", new HashSet<String>(Arrays.asList("asso", "barreau", "com", "edu", "gouv", "gov", "mil")));
|
||||
topMap.put( "bo", new HashSet<String>(Arrays.asList("com", "edu", "gov", "gob", "int", "org", "net",
|
||||
"mil", "tv")));
|
||||
topMap.put( "br", new HashSet<String>(Arrays.asList("adm", "adv", "agr", "am", "arq", "art", "ato",
|
||||
"b", "bio", "blog", "bmd", "cim", "cng", "cnt", "com", "coop", "ecn", "edu", "emp", "eng",
|
||||
"esp", "etc", "eti", "far", "flog", "fm", "fnd", "fot", "fst", "g12", "ggf", "gov",
|
||||
"imb", "ind", "inf", "jor", "jus", "lel", "mat", "med", "mil", "mus", "net", "nom",
|
||||
"not", "ntr", "odo", "org", "ppg", "pro", "psc", "psi", "qsl", "radio", "rec", "slg",
|
||||
"srv", "taxi", "teo", "tmp", "trd", "tur", "tv", "vet", "vlog", "wiki", "zlg")));
|
||||
topMap.put( "bw", new HashSet<String>(Arrays.asList("co", "gov", "org")));
|
||||
topMap.put( "by", new HashSet<String>(Arrays.asList("gov", "mil", "com", "of")));
|
||||
topMap.put( "ca", new HashSet<String>(Arrays.asList("ab", "bc", "mb", "nb", "nf",
|
||||
"nl", "ns", "nt", "nu", "on", "pe", "qc", "sk", "yk", "gc")));
|
||||
topMap.put( "ci", new HashSet<String>(Arrays.asList("org", "or", "com", "co", "edu",
|
||||
"ed", "ac", "net", "go", "asso", "xn--aroport-bya", "int",
|
||||
"presse", "md", "gouv")));
|
||||
topMap.put( "com", new HashSet<String>(Arrays.asList("ad", "ar", "br", "cn", "de", "eu", "gb",
|
||||
"gr", "hu", "jpn", "kr", "no", "qc", "ru", "sa", "se", "uk", "us", "uy", "za")));
|
||||
topMap.put( "cm", new HashSet<String>(Arrays.asList("co", "com", "gov", "net")));
|
||||
topMap.put( "cn", new HashSet<String>(Arrays.asList("ac", "com", "edu", "gov", "net",
|
||||
"org", "mil", "xn--55qx5d", "xn--io0a7i",
|
||||
"ah", "bj", "cq", "fj", "gd", "gs", "gz", "gx",
|
||||
"ha", "hb", "he", "hi", "hl", "hn", "jl", "js", "jx", "ln", "nm", "nx", "qh",
|
||||
"sc", "sd", "sh", "sn", "sx", "tj", "xj", "xz", "yn", "zj", "hk", "mo", "tw")));
|
||||
topMap.put( "co", new HashSet<String>(Arrays.asList("arts", "com", "edu", "firm", "gov", "info",
|
||||
"int", "mil", "net", "nom", "org", "rec", "web")));
|
||||
topMap.put( "cr", new HashSet<String>(Arrays.asList("ac", "co", "ed", "fi", "go", "or", "sa")));
|
||||
topMap.put( "cu", new HashSet<String>(Arrays.asList("com", "edu", "org", "net", "gov", "inf")));
|
||||
topMap.put( "do", new HashSet<String>(Arrays.asList("com", "edu", "org", "net", "gov", "gob",
|
||||
"web", "art", "sld", "mil")));
|
||||
topMap.put( "dz", new HashSet<String>(Arrays.asList("com", "org", "net", "gov", "edu", "asso",
|
||||
"pol", "art")));
|
||||
topMap.put( "ec", new HashSet<String>(Arrays.asList("com", "info", "net", "fin", "k12", "med",
|
||||
"pro", "org", "edu", "gov", "gob", "mil")));
|
||||
topMap.put( "ee", new HashSet<String>(Arrays.asList("edu", "gov", "riik", "lib", "med", "com",
|
||||
"pri", "aip", "org", "fie")));
|
||||
topMap.put( "eg", new HashSet<String>(Arrays.asList("com", "edu", "eun", "gov", "mil", "name",
|
||||
"net", "org", "sci")));
|
||||
topMap.put( "es", new HashSet<String>(Arrays.asList("com", "nom", "org", "gob", "edu")));
|
||||
topMap.put( "eu", new HashSet<String>(Arrays.asList("europa")));
|
||||
topMap.put( "fr", new HashSet<String>(Arrays.asList("com", "asso", "nom", "prd", "presse",
|
||||
"tm", "aeroport", "assedic", "avocat", "avoues", "cci", "chambagri",
|
||||
"chirurgiens-dentistes", "experts-comptables", "geometre-expert", "gouv", "greta",
|
||||
"huissier-justice", "medecin", "notaires", "pharmacien", "port", "veterinaire")));
|
||||
topMap.put( "ge", new HashSet<String>(Arrays.asList("com", "edu", "gov", "org", "mil", "net", "pvt")));
|
||||
topMap.put( "gg", new HashSet<String>(Arrays.asList("co", "org", "net", "sch", "gov")));
|
||||
topMap.put( "gh", new HashSet<String>(Arrays.asList("com", "edu", "gov", "org", "mil")));
|
||||
topMap.put( "gi", new HashSet<String>(Arrays.asList("com", "ltd", "gov", "mod", "edu", "org")));
|
||||
topMap.put( "gn", new HashSet<String>(Arrays.asList("ac", "com", "edu", "gov", "org", "net")));
|
||||
topMap.put( "gp", new HashSet<String>(Arrays.asList("com", "net", "mobi", "edu", "org", "asso")));
|
||||
topMap.put( "gr", new HashSet<String>(Arrays.asList("com", "co", "net", "edu", "org", "gov",
|
||||
"mil", "mod", "sch")));
|
||||
topMap.put( "gy", new HashSet<String>(Arrays.asList("co", "com", "net", "org", "edu", "gov")));
|
||||
topMap.put( "hk", new HashSet<String>(Arrays.asList("com", "edu", "gov", "idv", "net", "org",
|
||||
/* com */ "xn--55qx5d", /* edu */ "xn--wcvs22d", /* gov */"xn--mxtq1m",
|
||||
/* idv */ "xn--gmqw5a", /* net */ "xn--od0alg", /*org*/ "xn--uc0atv")));
|
||||
topMap.put( /* hk */ "xn--j6w193g", new HashSet<String>(Arrays.asList(
|
||||
/* com */ "xn--55qx5d", /* edu */ "xn--wcvs22d", /* gov */"xn--mxtq1m",
|
||||
/* idv */ "xn--gmqw5a", /* net */ "xn--od0alg", /*org*/ "xn--uc0atv")));
|
||||
topMap.put( "hn", new HashSet<String>(Arrays.asList("com", "edu", "org", "net", "mil", "gob")));
|
||||
topMap.put( "hr", new HashSet<String>(Arrays.asList("iz.hr", "from.hr", "name.hr", "com.hr")));
|
||||
topMap.put( "ht", new HashSet<String>(Arrays.asList("com", "shop", "firm", "info", "adult",
|
||||
"net", "pro", "org", "med", "art", "coop", "pol", "asso", "edu", "rel", "gouv", "perso")));
|
||||
topMap.put( "hu", new HashSet<String>(Arrays.asList("co", "info", "org", "priv", "sport", "tm",
|
||||
"2000", "agrar", "bolt", "casino", "city", "erotica", "erotika", "film", "forum",
|
||||
"games", "hotel", "ingatlan", "jogasz", "konyvelo", "lakas", "media", "news", "reklam",
|
||||
"sex", "shop", "suli", "szex", "tozsde", "utazas", "video")));
|
||||
topMap.put( "id", new HashSet<String>(Arrays.asList("ac", "co", "go", "mil", "net", "or", "sch",
|
||||
"web")));
|
||||
topMap.put( "im", new HashSet<String>(Arrays.asList("co.im", "com", "net.im", "gov.im", "org.im",
|
||||
"ac.im")));
|
||||
topMap.put( "in", new HashSet<String>(Arrays.asList("co", "firm", "ernet", "net", "org", "gen", "ind",
|
||||
"nic", "ac", "edu", "res", "gov", "mil")));
|
||||
topMap.put( "iq", new HashSet<String>(Arrays.asList("gov", "edu", "mil", "com", "org", "net" )));
|
||||
topMap.put( "ir", new HashSet<String>(Arrays.asList("ac", "co", "gov", "id", "net", "org", "sch"
|
||||
)));
|
||||
topMap.put( "is", new HashSet<String>(Arrays.asList("net", "com", "edu", "gov", "org", "int")));
|
||||
topMap.put( "it", new HashSet<String>(Arrays.asList("gov", "edu", "agrigento", "ag", "alessandria",
|
||||
"al", "ancona", "an", "aosta", "aoste", "ao", "arezzo", "ar", "ascoli-piceno",
|
||||
"ascolipiceno", "ap", "asti", "at", "avellino", "av", "bari", "ba",
|
||||
"andria-barletta-trani", "andriabarlettatrani", "trani-barletta-andria",
|
||||
"tranibarlettaandria", "barletta-trani-andria", "barlettatraniandria",
|
||||
"andria-trani-barletta", "andriatranibarletta", "trani-andria-barletta",
|
||||
"traniandriabarletta", "bt", "belluno", "bl", "benevento", "bn", "bergamo", "bg",
|
||||
"biella", "bi", "bologna", "bo", "bolzano", "bozen", "balsan", "alto-adige",
|
||||
"altoadige", "suedtirol", "bz", "brescia", "bs", "brindisi", "br", "cagliari",
|
||||
"ca", "caltanissetta", "cl", "campobasso", "cb", "carboniaiglesias", "carbonia-iglesias",
|
||||
"iglesias-carbonia", "iglesiascarbonia", "ci", "caserta", "ce", "catania", "ct",
|
||||
"catanzaro", "cz", "chieti", "ch", "como", "co", "cosenza", "cs", "cremona", "cr",
|
||||
"crotone", "kr", "cuneo", "cn", "dell-ogliastra", "dellogliastra", "ogliastra", "og",
|
||||
"enna", "en", "ferrara", "fe", "fermo", "fm", "firenze", "florence", "fi", "foggia",
|
||||
"fg", "forli-cesena", "forlicesena", "cesena-forli", "cesenaforli", "fc", "frosinone",
|
||||
"fr", "genova", "genoa", "ge", "gorizia", "go", "grosseto", "gr", "imperia", "im",
|
||||
"isernia", "is", "laquila", "aquila", "aq", "la-spezia", "laspezia", "sp", "latina",
|
||||
"lt", "lecce", "le", "lecco", "lc", "livorno", "li", "lodi", "lo", "lucca", "lu",
|
||||
"macerata", "mc", "mantova", "mn", "massa-carrara", "massacarrara", "carrara-massa",
|
||||
"carraramassa", "ms", "matera", "mt", "medio-campidano", "mediocampidano",
|
||||
"campidano-medio", "campidanomedio", "vs", "messina", "me", "milano", "milan",
|
||||
"mi", "modena", "mo", "monza", "monza-brianza", "monzabrianza", "monzaebrianza",
|
||||
"monzaedellabrianza", "monza-e-della-brianza", "mb", "napoli", "naples", "na",
|
||||
"novara", "no", "nuoro", "nu", "oristano", "or", "padova", "padua", "pd", "palermo",
|
||||
"pa", "parma", "pr", "pavia", "pv", "perugia", "pg", "pescara", "pe", "pesaro-urbino",
|
||||
"pesarourbino", "urbino-pesaro", "urbinopesaro", "pu", "piacenza", "pc", "pisa",
|
||||
"pi", "pistoia", "pt", "pordenone", "pn", "potenza", "pz", "prato", "po", "ragusa",
|
||||
"rg", "ravenna", "ra", "reggio-calabria", "reggiocalabria", "rc", "reggio-emilia",
|
||||
"reggioemilia", "re", "rieti", "ri", "rimini", "rn", "roma", "rome", "rm", "rovigo",
|
||||
"ro", "salerno", "sa", "sassari", "ss", "savona", "sv", "siena", "si", "siracusa",
|
||||
"sr", "sondrio", "so", "taranto", "ta", "tempio-olbia", "tempioolbia", "olbia-tempio",
|
||||
"olbiatempio", "ot", "teramo", "te", "terni", "tr", "torino", "turin", "to",
|
||||
"trapani", "tp", "trento", "trentino", "tn", "treviso", "tv", "trieste", "ts",
|
||||
"udine", "ud", "varese", "va", "venezia", "venice", "ve", "verbania", "vb",
|
||||
"vercelli", "vc", "verona", "vr", "vibo-valentia", "vibovalentia", "vv", "vicenza",
|
||||
"vi", "viterbo", "vt")));
|
||||
topMap.put( "je", new HashSet<String>(Arrays.asList("co", "org", "net", "sch", "gov")));
|
||||
topMap.put( "jo", new HashSet<String>(Arrays.asList("com", "org", "net", "edu", "sch",
|
||||
"gov", "mil", "name")));
|
||||
topMap.put( "jp", new HashSet<String>(Arrays.asList("ac", "ad", "co", "ed", "go", "gr", "lg",
|
||||
"ne", "or")));
|
||||
topMap.put( "kg", new HashSet<String>(Arrays.asList("org", "net", "com", "edu", "gov", "mil")));
|
||||
topMap.put( "ki", new HashSet<String>(Arrays.asList("edu", "biz", "net", "org", "gov",
|
||||
"info", "com")));
|
||||
topMap.put( "km", new HashSet<String>(Arrays.asList("org", "nom", "gov", "prd", "tm", "edu",
|
||||
"mil", "ass", "com", "coop", "asso", "presse", "medecin", "notaires", "pharmaciens",
|
||||
"veterinaire", "gouv")));
|
||||
topMap.put( "kn", new HashSet<String>(Arrays.asList("net", "org", "edu", "gov")));
|
||||
topMap.put( "kp", new HashSet<String>(Arrays.asList("com", "edu", "gov", "org", "rep", "tra")));
|
||||
topMap.put( "kr", new HashSet<String>(Arrays.asList("ac", "co", "es", "go", "hs", "kg", "mil",
|
||||
"ms", "ne", "or", "pe", "re", "sc", "busan", "chungbuk", "chungnam", "daegu",
|
||||
"daejeon", "gangwon", "gwangju", "gyeongbuk", "gyeonggi", "gyeongnam", "incheon",
|
||||
"jeju", "jeonbuk", "jeonnam", "seoul", "ulsan")));
|
||||
topMap.put( "kz", new HashSet<String>(Arrays.asList("org", "edu", "net", "gov", "mil", "com")));
|
||||
topMap.put( "la", new HashSet<String>(Arrays.asList("int", "net", "info", "edu", "gov", "per",
|
||||
"com", "org", "c")));
|
||||
topMap.put( "lc", new HashSet<String>(Arrays.asList("com", "net", "co", "org", "edu", "gov",
|
||||
"l.lc", "p.lc")));
|
||||
topMap.put( "lk", new HashSet<String>(Arrays.asList("gov", "sch", "net", "int", "com", "org",
|
||||
"edu", "ngo", "soc", "web", "ltd", "assn", "grp", "hotel")));
|
||||
topMap.put( "ls", new HashSet<String>(Arrays.asList("co", "gov", "ac", "org")));
|
||||
topMap.put( "lv", new HashSet<String>(Arrays.asList("com", "edu", "gov", "org", "mil",
|
||||
"id", "net", "asn", "conf")));
|
||||
topMap.put( "ly", new HashSet<String>(Arrays.asList("com", "net", "gov", "plc", "edu", "sch",
|
||||
"med", "org", "id")));
|
||||
topMap.put( "ma", new HashSet<String>(Arrays.asList("co", "net", "gov", "org", "ac", "press")));
|
||||
topMap.put( "me", new HashSet<String>(Arrays.asList("co", "net", "org", "edu", "ac", "gov",
|
||||
"its", "priv")));
|
||||
topMap.put( "mg", new HashSet<String>(Arrays.asList("org", "nom", "gov", "prd", "tm",
|
||||
"edu", "mil", "com")));
|
||||
topMap.put( "mk", new HashSet<String>(Arrays.asList("com", "org", "net", "edu", "gov", "inf",
|
||||
"name", "pro")));
|
||||
topMap.put( "ml", new HashSet<String>(Arrays.asList("com", "edu", "gouv", "gov", "net",
|
||||
"org", "presse")));
|
||||
topMap.put( "mn", new HashSet<String>(Arrays.asList("gov", "edu", "org")));
|
||||
topMap.put( "mp", new HashSet<String>(Arrays.asList("gov", "co", "org")));
|
||||
topMap.put( "mu", new HashSet<String>(Arrays.asList("com", "net", "org", "gov", "ac",
|
||||
"co", "or")));
|
||||
topMap.put( "museum", new HashSet<String>(Arrays.asList("academy", "agriculture", "air",
|
||||
"airguard", "alabama", "alaska", "amber", "ambulance", "american", "americana",
|
||||
"americanantiques", "americanart", "amsterdam", "and", "annefrank", "anthro",
|
||||
"anthropology", "antiques", "aquarium", "arboretum", "archaeological", "archaeology",
|
||||
"architecture", "art", "artanddesign", "artcenter", "artdeco", "arteducation",
|
||||
"artgallery", "arts", "artsandcrafts", "asmatart", "assassination", "assisi",
|
||||
"association", "astronomy", "atlanta", "austin", "australia", "automotive", "aviation",
|
||||
"axis", "badajoz", "baghdad", "bahn", "bale", "baltimore", "barcelona", "baseball",
|
||||
"basel", "baths", "bauern", "beauxarts", "beeldengeluid", "bellevue", "bergbau",
|
||||
"berkeley", "berlin", "bern", "bible", "bilbao", "bill", "birdart", "birthplace",
|
||||
"bonn", "boston", "botanical", "botanicalgarden", "botanicgarden", "botany",
|
||||
"brandywinevalley", "brasil", "bristol", "british", "britishcolumbia", "broadcast",
|
||||
"brunel", "brussel", "brussels", "bruxelles", "building", "burghof", "bus", "bushey",
|
||||
"cadaques", "california", "cambridge", "can", "canada", "capebreton", "carrier",
|
||||
"cartoonart", "casadelamoneda", "castle", "castres", "celtic", "center", "chattanooga",
|
||||
"cheltenham", "chesapeakebay", "chicago", "children", "childrens", "childrensgarden",
|
||||
"chiropractic", "chocolate", "christiansburg", "cincinnati", "cinema", "circus",
|
||||
"civilisation", "civilization", "civilwar", "clinton", "clock", "coal", "coastaldefence",
|
||||
"cody", "coldwar", "collection", "colonialwilliamsburg", "coloradoplateau", "columbia",
|
||||
"columbus", "communication", "communications", "community", "computer",
|
||||
"computerhistory", "xn--comunicaes-v6a2o", "contemporary", "contemporaryart",
|
||||
"convent", "copenhagen", "corporation", "xn--correios-e-telecomunicaes-ghc29a",
|
||||
"corvette", "costume", "countryestate", "county", "crafts", "cranbrook", "creation",
|
||||
"cultural", "culturalcenter", "culture", "cyber", "cymru", "dali", "dallas", "database",
|
||||
"ddr", "decorativearts", "delaware", "delmenhorst", "denmark", "depot", "design",
|
||||
"detroit", "dinosaur", "discovery", "dolls", "donostia", "durham", "eastafrica",
|
||||
"eastcoast", "education", "educational", "egyptian", "eisenbahn", "elburg",
|
||||
"elvendrell", "embroidery", "encyclopedic", "england", "entomology", "environment",
|
||||
"environmentalconservation", "epilepsy", "essex", "estate", "ethnology", "exeter",
|
||||
"exhibition", "family", "farm", "farmequipment", "farmers", "farmstead", "field",
|
||||
"figueres", "filatelia", "film", "fineart", "finearts", "finland", "flanders", "florida",
|
||||
"force", "fortmissoula", "fortworth", "foundation", "francaise", "frankfurt",
|
||||
"franziskaner", "freemasonry", "freiburg", "fribourg", "frog", "fundacio", "furniture",
|
||||
"gallery", "garden", "gateway", "geelvinck", "gemological", "geology", "georgia",
|
||||
"giessen", "glas", "glass", "gorge", "grandrapids", "graz", "guernsey", "halloffame",
|
||||
"hamburg", "handson", "harvestcelebration", "hawaii", "health", "heimatunduhren",
|
||||
"hellas", "helsinki", "hembygdsforbund", "heritage", "histoire", "historical",
|
||||
"historicalsociety", "historichouses", "historisch", "historisches", "history",
|
||||
"historyofscience", "horology", "house", "humanities", "illustration", "imageandsound",
|
||||
"indian", "indiana", "indianapolis", "indianmarket", "intelligence", "interactive",
|
||||
"iraq", "iron", "isleofman", "jamison", "jefferson", "jerusalem", "jewelry",
|
||||
"jewish", "jewishart", "jfk", "journalism", "judaica", "judygarland", "juedisches",
|
||||
"juif", "karate", "karikatur", "kids", "koebenhavn", "koeln", "kunst", "kunstsammlung",
|
||||
"kunstunddesign", "labor", "labour", "lajolla", "lancashire", "landes", "lans",
|
||||
"xn--lns-qla", "larsson", "lewismiller", "lincoln", "linz", "living", "livinghistory",
|
||||
"localhistory", "london", "losangeles", "louvre", "loyalist", "lucerne", "luxembourg",
|
||||
"luzern", "mad", "madrid", "mallorca", "manchester", "mansion", "mansions", "manx",
|
||||
"marburg", "maritime", "maritimo", "maryland", "marylhurst", "media", "medical",
|
||||
"medizinhistorisches", "meeres", "memorial", "mesaverde", "michigan", "midatlantic",
|
||||
"military", "mill", "miners", "mining", "minnesota", "missile", "missoula", "modern",
|
||||
"moma", "money", "monmouth", "monticello", "montreal", "moscow", "motorcycle", "muenchen",
|
||||
"muenster", "mulhouse", "muncie", "museet", "museumcenter", "museumvereniging", "music",
|
||||
"national", "nationalfirearms", "nationalheritage", "nativeamerican", "naturalhistory",
|
||||
"naturalhistorymuseum", "naturalsciences", "nature", "naturhistorisches",
|
||||
"natuurwetenschappen", "naumburg", "naval", "nebraska", "neues", "newhampshire",
|
||||
"newjersey", "newmexico", "newport", "newspaper", "newyork", "niepce", "norfolk",
|
||||
"north", "nrw", "nuernberg", "nuremberg", "nyc", "nyny", "oceanographic",
|
||||
"oceanographique", "omaha", "online", "ontario", "openair", "oregon", "oregontrail",
|
||||
"otago", "oxford", "pacific", "paderborn", "palace", "paleo", "palmsprings", "panama",
|
||||
"paris", "pasadena", "pharmacy", "philadelphia", "philadelphiaarea", "philately",
|
||||
"phoenix", "photography", "pilots", "pittsburgh", "planetarium", "plantation",
|
||||
"plants", "plaza", "portal", "portland", "portlligat", "posts-and-telecommunications",
|
||||
"preservation", "presidio", "press", "project", "public", "pubol", "quebec",
|
||||
"railroad", "railway", "research", "resistance", "riodejaneiro", "rochester", "rockart",
|
||||
"roma", "russia", "saintlouis", "salem", "salvadordali", "salzburg", "sandiego",
|
||||
"sanfrancisco", "santabarbara", "santacruz", "santafe", "saskatchewan", "satx",
|
||||
"savannahga", "schlesisches", "schoenbrunn", "schokoladen", "school", "schweiz",
|
||||
"science", "scienceandhistory", "scienceandindustry", "sciencecenter", "sciencecenters",
|
||||
"science-fiction", "sciencehistory", "sciences", "sciencesnaturelles", "scotland",
|
||||
"seaport", "settlement", "settlers", "shell", "sherbrooke", "sibenik", "silk", "ski",
|
||||
"skole", "society", "sologne", "soundandvision", "southcarolina", "southwest", "space",
|
||||
"spy", "square", "stadt", "stalbans", "starnberg", "state", "stateofdelaware",
|
||||
"station", "steam", "steiermark", "stjohn", "stockholm", "stpetersburg", "stuttgart",
|
||||
"suisse", "surgeonshall", "surrey", "svizzera", "sweden", "sydney", "tank", "tcm",
|
||||
"technology", "telekommunikation", "television", "texas", "textile", "theater",
|
||||
"time", "timekeeping", "topology", "torino", "touch", "town", "transport", "tree",
|
||||
"trolley", "trust", "trustee", "uhren", "ulm", "undersea", "university", "usa",
|
||||
"usantiques", "usarts", "uscountryestate", "usculture", "usdecorativearts", "usgarden",
|
||||
"ushistory", "ushuaia", "uslivinghistory", "utah", "uvic", "valley", "vantaa",
|
||||
"versailles", "viking", "village", "virginia", "virtual", "virtuel", "vlaanderen",
|
||||
"volkenkunde", "wales", "wallonie", "war", "washingtondc", "watchandclock",
|
||||
"watch-and-clock", "western", "westfalen", "whaling", "wildlife", "williamsburg",
|
||||
"windmill", "workshop", "york", "yorkshire", "yosemite", "youth", "zoological",
|
||||
"zoology", "xn--9dbhblg6di", "xn--h1aegh")));
|
||||
topMap.put( "mv", new HashSet<String>(Arrays.asList("aero", "biz", "com", "coop", "edu", "gov",
|
||||
"info", "int", "mil", "museum", "name", "net", "org", "pro")));
|
||||
topMap.put( "mw", new HashSet<String>(Arrays.asList("ac", "biz", "co", "com", "coop", "edu",
|
||||
"gov", "int", "museum", "net", "org")));
|
||||
topMap.put( "mx", new HashSet<String>(Arrays.asList("com", "org", "gob", "edu", "net")));
|
||||
topMap.put( "my", new HashSet<String>(Arrays.asList("com", "net", "org", "gov", "edu",
|
||||
"mil", "name", "sch")));
|
||||
topMap.put( "na", new HashSet<String>(Arrays.asList("co", "com", "org", "edu", "edunet", "net",
|
||||
"alt", "biz", "info")));
|
||||
topMap.put( "nc", new HashSet<String>(Arrays.asList("asso", "nom")));
|
||||
topMap.put( "net", new HashSet<String>(Arrays.asList("gb", "se", "uk", "za")));
|
||||
topMap.put( "ng", new HashSet<String>(Arrays.asList("name", "sch", "mil", "mobi", "com",
|
||||
"edu", "gov", "net", "org")));
|
||||
topMap.put( "nf", new HashSet<String>(Arrays.asList("com", "net", "per", "rec", "web",
|
||||
"arts", "firm", "info", "other", "store")));
|
||||
topMap.put( "no", new HashSet<String>(Arrays.asList("fhs", "vgs", "fylkesbibl", "folkebibl",
|
||||
"museum", "idrett", "priv", "mil", "stat", "dep", "kommune", "herad", "aa",
|
||||
"ah", "bu", "fm", "hl", "hm", "jan-mayen", "mr", "nl", "nt", "of", "ol", "oslo",
|
||||
"rl", "sf", "st", "svalbard", "tm", "tr", "va", "vf", "akrehamn",
|
||||
"xn--krehamn-dxa", "algard", "xn--lgrd-poac", "arna", "brumunddal",
|
||||
"bryne", "bronnoysund", "xn--brnnysund-m8ac", "drobak",
|
||||
"xn--drbak-wua", "egersund", "fetsund", "floro", "xn--flor-jra",
|
||||
"fredrikstad", "hokksund", "honefoss", "xn--hnefoss-q1a",
|
||||
"jessheim", "jorpeland", "xn--jrpeland-54a", "kirkenes", "kopervik",
|
||||
"krokstadelva", "langevag", "xn--langevg-jxa", "leirvik", "mjondalen",
|
||||
"xn--mjndalen-64a", "mo-i-rana", "mosjoen", "xn--mosjen-eya",
|
||||
"nesoddtangen", "orkanger", "osoyro", "xn--osyro-wua",
|
||||
"raholt", "xn--rholt-mra", "sandnessjoen", "xn--sandnessjen-ogb",
|
||||
"skedsmokorset", "slattum", "spjelkavik", "stathelle", "stavern", "stjordalshalsen",
|
||||
"xn--stjrdalshalsen-sqb", "tananger", "tranby", "vossevangen", "tranby",
|
||||
"vossevangen", "afjord", "xn--fjord-lra", "agdenes", "al",
|
||||
"xn--l-1fa", "alesund", "xn--lesund-hua",
|
||||
"alstahaug", "alta", "xn--lt-liac", "alaheadju",
|
||||
"xn--laheadju-7ya", "alvdal", "amli", "xn--mli-tla",
|
||||
"amot", "xn--mot-tla", "andebu", "andoy", "xn--andy-ira",
|
||||
"andasuolo", "ardal", "xn--rdal-poa", "aremark", "arendal",
|
||||
"xn--s-1fa", "aseral", "xn--seral-lra",
|
||||
"asker", "askim", "askvoll", "askoy", "xn--asky-ira",
|
||||
"asnes", "xn--snes-poa", "audnedaln", "aukra", "aure", "aurland",
|
||||
"aurskog-holand", "xn--aurskog-hland-jnb",
|
||||
"austevoll", "austrheim", "averoy", "xn--avery-yua",
|
||||
"balestrand", "ballangen", "balat", "xn--blt-elab",
|
||||
"balsfjord", "bahccavuotna", "xn--bhccavuotna-k7a",
|
||||
"bamble", "bardu", "beardu", "beiarn", "bajddar", "xn--bjddar-pta",
|
||||
"baidar", "xn--bidr-5nac", "berg", "bergen", "berlevag", "xn--berlevg-jxa",
|
||||
"bearalvahki", "xn--bearalvhki-y4a", "bindal", "birkenes", "bjarkoy",
|
||||
"xn--bjarky-fya", "bjerkreim", "bjugn", "bodo", "xn--bod-2na",
|
||||
"badaddja", "xn--bdddj-mrabd", "budejju", "bokn",
|
||||
"bremanger", "bronnoy", "xn--brnny-wuac", "bygland",
|
||||
"bykle", "barum", "xn--brum-voa", "bievat", "xn--bievt-0qa",
|
||||
"bomlo", "xn--bmlo-gra", "batsfjord", "xn--btsfjord-9za", "bahcavuotna",
|
||||
"xn--bhcavuotna-s4a", "dovre", "drammen", "drangedal", "dyroy",
|
||||
"xn--dyry-ira", "donna", "xn--dnna-gra",
|
||||
"eid", "eidfjord", "eidsberg", "eidskog", "eidsvoll", "eigersund", "elverum",
|
||||
"enebakk", "engerdal", "etne", "etnedal", "evenes", "evenassi",
|
||||
"xn--eveni-0qa01ga", "evje-og-hornnes", "farsund", "fauske",
|
||||
"fuossko", "fuoisku", "fedje", "fet", "finnoy", "xn--finny-yua",
|
||||
"fitjar", "fjaler", "fjell", "flakstad", "flatanger", "flekkefjord", "flesberg",
|
||||
"flora", "fla", "xn--fl-zia", "folldal", "forsand", "fosnes", "frei",
|
||||
"frogn", "froland", "frosta", "frana", "xn--frna-woa",
|
||||
"froya", "xn--frya-hra", "fusa", "fyresdal", "forde",
|
||||
"xn--frde-gra", "gamvik", "gangaviika", "xn--ggaviika-8ya47h",
|
||||
"gaular", "gausdal", "gildeskal", "xn--gildeskl-g0a",
|
||||
"giske", "gjemnes", "gjerdrum", "gjerstad", "gjesdal", "gjovik",
|
||||
"xn--gjvik-wua", "gloppen", "gol", "gran", "grane", "granvin",
|
||||
"gratangen", "grimstad", "grong", "kraanghke", "xn--kranghke-b0a",
|
||||
"grue", "gulen", "hadsel", "halden", "halsa", "hamar", "hamaroy", "habmer",
|
||||
"xn--hbmer-xqa", "hapmir", "xn--hpmir-xqa",
|
||||
"hammerfest", "hammarfeasta", "xn--hmmrfeasta-s4ac",
|
||||
"haram", "hareid", "harstad", "hasvik", "aknoluokta", "xn--koluokta-7ya57h",
|
||||
"hattfjelldal", "aarborte", "haugesund", "hemne", "hemnes", "hemsedal",
|
||||
"hitra", "hjartdal", "hjelmeland",
|
||||
"hobol", "xn--hobl-ira", "hof", "hol", "hole", "holmestrand", "holtalen",
|
||||
"xn--holtlen-hxa", "hornindal", "horten", "hurdal", "hurum", "hvaler",
|
||||
"hyllestad", "hagebostad", "xn--hgebostad-g3a", "hoyanger",
|
||||
"xn--hyanger-q1a", "hoylandet", "xn--hylandet-54a",
|
||||
"ha", "xn--h-2fa", "ibestad", "inderoy", "xn--indery-fya",
|
||||
"iveland", "jevnaker", "jondal", "jolster", "xn--jlster-bya",
|
||||
"karasjok", "karasjohka", "xn--krjohka-hwab49j",
|
||||
"karlsoy", "galsa", "xn--gls-elac", "karmoy",
|
||||
"xn--karmy-yua", "kautokeino", "guovdageaidnu", "klepp", "klabu",
|
||||
"xn--klbu-woa", "kongsberg", "kongsvinger", "kragero", "xn--krager-gya",
|
||||
"kristiansand", "kristiansund", "krodsherad", "xn--krdsherad-m8a",
|
||||
"kvalsund", "rahkkeravju", "xn--rhkkervju-01af",
|
||||
"kvam", "kvinesdal", "kvinnherad", "kviteseid", "kvitsoy", "xn--kvitsy-fya",
|
||||
"kvafjord", "xn--kvfjord-nxa", "giehtavuoatna", "kvanangen",
|
||||
"xn--kvnangen-k0a", "navuotna", "xn--nvuotna-hwa",
|
||||
"kafjord", "xn--kfjord-iua", "gaivuotna", "xn--givuotna-8ya",
|
||||
"larvik", "lavangen", "lavagis", "loabat", "xn--loabt-0qa",
|
||||
"lebesby", "davvesiida", "leikanger", "leirfjord", "leka", "leksvik", "lenvik",
|
||||
"leangaviika", "xn--leagaviika-52b", "lesja", "levanger", "lier", "lierne",
|
||||
"lillehammer", "lillesand", "lindesnes", "lindas", "xn--linds-pra",
|
||||
"lom", "loppa", "lahppi", "xn--lhppi-xqa", "lund", "lunner", "luroy",
|
||||
"xn--lury-ira", "luster", "lyngdal", "lyngen", "ivgu", "lardal", "lerdal",
|
||||
"xn--lrdal-sra", "lodingen", "xn--ldingen-q1a", "lorenskog",
|
||||
"xn--lrenskog-54a", "loten", "xn--lten-gra", "malvik",
|
||||
"masoy", "xn--msy-ula0h", "muosat", "xn--muost-0qa",
|
||||
"mandal", "marker", "marnardal", "masfjorden", "meland", "meldal", "melhus",
|
||||
"meloy", "xn--mely-ira", "meraker", "xn--merker-kua", "moareke",
|
||||
"xn--moreke-jua", "midsund", "midtre-gauldal", "modalen", "modum",
|
||||
"molde", "moskenes", "moss", "mosvik", "malselv", "xn--mlselv-iua",
|
||||
"malatvuopmi", "xn--mlatvuopmi-s4a", "namdalseid", "aejrie", "namsos",
|
||||
"namsskogan", "naamesjevuemie", "xn--nmesjevuemie-tcba",
|
||||
"laakesvuemie", "nannestad", "narvik", "narviika", "naustdal", "nedre-eiker",
|
||||
"nesna", "nesodden", "nesseby", "unjarga", "xn--unjrga-rta", "nesset",
|
||||
"nissedal", "nittedal", "nord-aurdal", "nord-fron", "nord-odal", "norddal",
|
||||
"nordkapp", "davvenjarga", "xn--davvenjrga-y4a", "nordre-land",
|
||||
"nordreisa", "raisa", "xn--risa-5na", "nore-og-uvdal", "notodden", "naroy",
|
||||
"xn--nry-yla5g", "notteroy", "xn--nttery-byae",
|
||||
"odda", "oksnes", "xn--ksnes-uua", "oppdal", "oppegard",
|
||||
"xn--oppegrd-ixa", "orkdal", "orland", "xn--rland-uua",
|
||||
"orskog", "xn--rskog-uua", "orsta", "xn--rsta-fra",
|
||||
"os.hedmark", "os.hordaland", "osen", "osteroy", "xn--ostery-fya",
|
||||
"ostre-toten", "xn--stre-toten-zcb", "overhalla", "ovre-eiker",
|
||||
"xn--vre-eiker-k8a", "oyer", "xn--yer-zna",
|
||||
"oygarden", "xn--ygarden-p1a", "oystre-slidre", "xn--ystre-slidre-ujb",
|
||||
"porsanger", "porsangu", "xn--porsgu-sta26f", "porsgrunn",
|
||||
"radoy", "xn--rady-ira", "rakkestad", "rana", "ruovat", "randaberg",
|
||||
"rauma", "rendalen", "rennebu", "rennesoy", "xn--rennesy-v1a",
|
||||
"rindal", "ringebu", "ringerike", "ringsaker", "rissa", "risor",
|
||||
"xn--risr-ira", "roan", "rollag", "rygge", "ralingen", "xn--rlingen-mxa",
|
||||
"rodoy", "xn--rdy-0nab", "romskog", "xn--rmskog-bya",
|
||||
"roros", "xn--rros-gra", "rost", "xn--rst-0na",
|
||||
"royken", "xn--ryken-vua", "royrvik", "xn--ryrvik-bya",
|
||||
"rade", "xn--rde-ula", "salangen", "siellak", "saltdal", "salat",
|
||||
"xn--slt-elab", "xn--slat-5na", "samnanger",
|
||||
"sandefjord", "sandnes", "sandoy", "xn--sandy-yua", "sarpsborg",
|
||||
"sauda", "sauherad", "sel", "selbu", "selje", "seljord", "sigdal", "siljan",
|
||||
"sirdal", "skaun", "skedsmo", "ski", "skien", "skiptvet", "skjervoy",
|
||||
"xn--skjervy-v1a", "skierva", "xn--skierv-uta",
|
||||
"skjak", "xn--skjk-soa", "skodje", "skanland", "xn--sknland-fxa",
|
||||
"skanit", "xn--sknit-yqa", "smola", "xn--smla-hra",
|
||||
"snillfjord", "snasa", "xn--snsa-roa", "snoasa", "snaase",
|
||||
"xn--snase-nra", "sogndal", "sokndal", "sola", "solund", "songdalen",
|
||||
"sortland", "spydeberg", "stange", "stavanger", "steigen", "steinkjer",
|
||||
"stjordal", "xn--stjrdal-s1a", "stokke", "stor-elvdal", "stord", "stordal",
|
||||
"storfjord", "omasvuotna", "strand", "stranda", "stryn", "sula", "suldal",
|
||||
"sund", "sunndal", "surnadal", "sveio", "svelvik", "sykkylven", "sogne",
|
||||
"xn--sgne-gra", "somna", "xn--smna-gra", "sondre-land",
|
||||
"xn--sndre-land-0cb", "sor-aurdal", "xn--sr-aurdal-l8a",
|
||||
"sor-fron", "xn--sr-fron-q1a", "sor-odal", "xn--sr-odal-q1a",
|
||||
"sor-varanger", "xn--sr-varanger-ggb", "matta-varjjat",
|
||||
"xn--mtta-vrjjat-k7af", "sorfold", "xn--srfold-bya",
|
||||
"sorreisa", "xn--srreisa-q1a", "sorum", "xn--srum-gra",
|
||||
"tana", "deatnu", "time", "tingvoll", "tinn", "tjeldsund", "dielddanuorri",
|
||||
"tjome", "xn--tjme-hra", "tokke", "tolga", "torsken", "tranoy",
|
||||
"xn--trany-yua", "tromso", "xn--troms-zua", "tromsa", "romsa",
|
||||
"trondheim", "troandin", "trysil", "trana", "xn--trna-woa",
|
||||
"trogstad", "xn--trgstad-r1a", "tvedestrand", "tydal", "tynset",
|
||||
"tysfjord", "divtasvuodna", "divttasvuotna", "tysnes", "tysvar",
|
||||
"xn--tysvr-vra", "tonsberg", "xn--tnsberg-q1a",
|
||||
"ullensaker", "ullensvang", "ulvik", "utsira", "vadso", "xn--vads-jra",
|
||||
"cahcesuolo", "xn--hcesuolo-7ya35b", "vaksdal", "valle", "vang",
|
||||
"vanylven", "vardo", "xn--vard-jra", "varggat", "xn--vrggt-xqad",
|
||||
"vefsn", "vaapste", "vega", "vegarshei", "xn--vegrshei-c0a", "vennesla",
|
||||
"verdal", "verran", "vestby", "vestnes", "vestre-slidre", "vestre-toten",
|
||||
"vestvagoy", "xn--vestvgy-ixa6o", "vevelstad", "vik", "vikna",
|
||||
"vindafjord", "volda", "voss", "varoy", "xn--vry-yla5g",
|
||||
"vagan", "xn--vgan-qoa", "voagat", "vagsoy", "xn--vgsy-qoa0j",
|
||||
"vaga", "xn--vg-yiab")));
|
||||
|
||||
topMap.put( "nr", new HashSet<String>(Arrays.asList("biz", "info", "gov", "edu", "org",
|
||||
"net", "com", "co")));
|
||||
topMap.put( "pa", new HashSet<String>(Arrays.asList("ac", "gob", "com", "org",
|
||||
"sld", "edu", "net", "ing", "abo", "med", "nom")));
|
||||
topMap.put( "pe", new HashSet<String>(Arrays.asList("edu", "gob", "nom", "mil", "org", "com",
|
||||
"net", "sld")));
|
||||
topMap.put( "pf", new HashSet<String>(Arrays.asList( "com")));
|
||||
topMap.put( "ph", new HashSet<String>(Arrays.asList("com", "net", "org", "gov", "edu", "ngo", "mil")));
|
||||
topMap.put( "pk", new HashSet<String>(Arrays.asList("com", "net", "edu", "org", "fam", "biz",
|
||||
"web", "gov", "gob", "gok", "gon", "gop", "gos", "gog", "gkp", "info")));
|
||||
topMap.put( "pl", new HashSet<String>(Arrays.asList("aid", "agro", "atm", "auto", "biz", "com",
|
||||
"edu", "gmina", "gsm", "info", "mail", "miasta", "media", "mil", "net", "nieruchomosci",
|
||||
"nom", "org", "pc", "powiat", "priv", "realestate", "rel", "sex", "shop", "sklep",
|
||||
"sos", "szkola", "targi", "tm", "tourism", "travel", "turystyka", "art",
|
||||
"gov", "ngo", "augustow", "babia-gora", "bedzin", "beskidy",
|
||||
"bialowieza", "bialystok", "bielawa", "bieszczady", "boleslawiec", "bydgoszcz",
|
||||
"bytom", "cieszyn", "czeladz", "czest", "dlugoleka", "elblag", "elk", "glogow",
|
||||
"gniezno", "gorlice", "grajewo", "ilawa", "jaworzno", "jelenia-gora", "jgora",
|
||||
"kalisz", "kazimierz-dolny", "karpacz", "kartuzy", "kaszuby", "katowice", "kepno",
|
||||
"ketrzyn", "klodzko", "kobierzyce", "kolobrzeg", "konin", "konskowola", "kutno",
|
||||
"lapy", "lebork", "legnica", "lezajsk", "limanowa", "lomza", "lowicz", "lubin",
|
||||
"lukow", "malbork", "malopolska", "mazowsze", "mazury", "mielec", "mielno", "mragowo",
|
||||
"naklo", "nowaruda", "nysa", "olawa", "olecko", "olkusz", "olsztyn", "opoczno",
|
||||
"opole", "ostroda", "ostroleka", "ostrowiec", "ostrowwlkp", "pila", "pisz", "podhale",
|
||||
"podlasie", "polkowice", "pomorze", "pomorskie", "prochowice", "pruszkow", "przeworsk",
|
||||
"pulawy", "radom", "rawa-maz", "rybnik", "rzeszow", "sanok", "sejny", "siedlce",
|
||||
"slask", "slupsk", "sosnowiec", "stalowa-wola", "skoczow", "starachowice", "stargard",
|
||||
"suwalki", "swidnica", "swiebodzin", "swinoujscie", "szczecin", "szczytno", "tarnobrzeg",
|
||||
"tgory", "turek", "tychy", "ustka", "walbrzych", "warmia", "warszawa", "waw",
|
||||
"wegrow", "wielun", "wlocl", "wloclawek", "wodzislaw", "wolomin", "wroclaw",
|
||||
"zachpomor", "zagan", "zarow", "zgora", "zgorzelec", "gda", "gdansk",
|
||||
"krakow", "poznan", "wroc", "co",
|
||||
"lodz", "lublin", "torun")));
|
||||
topMap.put( "pn", new HashSet<String>(Arrays.asList("gov", "co", "org", "edu", "net")));
|
||||
topMap.put( "pr", new HashSet<String>(Arrays.asList("com", "net", "org", "gov", "edu", "isla",
|
||||
"pro", "biz", "info", "name", "est", "prof", "ac", "gobierno")));
|
||||
topMap.put( "pro", new HashSet<String>(Arrays.asList("aca", "bar", "cpa", "jur", "law",
|
||||
"med", "eng")));
|
||||
topMap.put( "ps", new HashSet<String>(Arrays.asList("edu", "gov", "sec", "plo", "com", "org", "net")));
|
||||
topMap.put( "pt", new HashSet<String>(Arrays.asList("net", "gov", "org", "edu", "int", "publ",
|
||||
"com", "nome")));
|
||||
topMap.put( "pw", new HashSet<String>(Arrays.asList("co", "ne", "or", "ed", "go", "belau")));
|
||||
topMap.put( "qa", new HashSet<String>(Arrays.asList("com", "net", "org", "gov", "edu", "mil")));
|
||||
topMap.put( "re", new HashSet<String>(Arrays.asList("com", "asso", "nom")));
|
||||
topMap.put( "ro", new HashSet<String>(Arrays.asList("com", "org", "tm", "nt", "nom", "info",
|
||||
"rec", "arts", "firm", "store", "www")));
|
||||
topMap.put( "rs", new HashSet<String>(Arrays.asList("co", "org", "edu", "ac", "gov", "in")));
|
||||
topMap.put( "ru", new HashSet<String>(Arrays.asList("ac", "com", "edu", "int", "net", "org",
|
||||
"pp", "adygeya", "altai", "amur", "arkhangelsk", "astrakhan", "bashkiria",
|
||||
"belgorod", "bir", "bryansk", "buryatia", "cap", "cbg", "chel", "chelyabinsk", "chita",
|
||||
"chukotka", "dagestan", "e-burg", "grozny", "irkutsk",
|
||||
"ivanovo", "izhevsk", "jar", "joshkar-ola", "kalmykia", "kaluga", "kamchatka",
|
||||
"karelia", "kazan", "kchr", "kemerovo", "khabarovsk", "khakassia", "khv", "kirov",
|
||||
"koenig", "komi", "kostroma", "krasnoyarsk", "kuban", "kurgan", "kursk", "lipetsk",
|
||||
"magadan", "mari", "mari-el", "marine", "mordovia", "mosreg", "msk", "murmansk",
|
||||
"nalchik", "nnov", "nov", "novosibirsk", "nsk", "omsk", "orenburg", "oryol",
|
||||
"palana", "penza", "perm", "pskov", "ptz", "rnd", "ryazan", "sakhalin", "samara",
|
||||
"saratov", "simbirsk", "smolensk", "spb", "stavropol", "stv", "surgut", "tambov",
|
||||
"tatarstan", "tom", "tomsk", "tsaritsyn", "tsk", "tula", "tuva", "tver", "tyumen",
|
||||
"udm", "udmurtia", "ulan-ude", "vladikavkaz", "vladimir", "vladivostok", "volgograd",
|
||||
"vologda", "voronezh", "vrn", "vyatka", "yakutia", "yamal", "yaroslavl",
|
||||
"yekaterinburg", "yuzhno-sakhalinsk", "amursk", "baikal", "cmw", "fareast",
|
||||
"jamal", "kms", "k-uralsk", "kustanai", "kuzbass", "magnitka", "mytis",
|
||||
"nakhodka", "nkz", "norilsk", "oskol", "pyatigorsk", "rubtsovsk", "snz", "syzran",
|
||||
"vdonsk", "zgrad", "gov", "mil", "test")));
|
||||
topMap.put( "rw", new HashSet<String>(Arrays.asList("gov", "net", "edu", "ac", "com", "co",
|
||||
"int", "mil", "gouv")));
|
||||
topMap.put( "sa", new HashSet<String>(Arrays.asList("com", "net", "org", "gov", "med", "pub",
|
||||
"edu", "sch")));
|
||||
topMap.put( "sd", new HashSet<String>(Arrays.asList("com", "net", "org", "edu", "med", "gov",
|
||||
"info", "tv")));
|
||||
topMap.put( "se", new HashSet<String>(Arrays.asList("a", "ac", "b", "bd", "brand", "c", "d",
|
||||
"e", "f", "fh", "fhsk", "fhv", "g", "h", "i", "k", "komforb", "kommunalforbund",
|
||||
"komvux", "l", "lanarb", "lanbib", "m", "n", "naturbruksgymn", "o", "org", "p", "parti",
|
||||
"pp", "press", "r", "s", "sshn", "t", "tm", "u", "w", "x", "y", "z")));
|
||||
topMap.put( "sg", new HashSet<String>(Arrays.asList("com", "net", "org", "gov", "edu", "per")));
|
||||
topMap.put( "sh", new HashSet<String>(Arrays.asList("co", "com", "net", "org", "gov", "edu", "nom")));
|
||||
topMap.put( "sk", new HashSet<String>(Arrays.asList("gov", "edu")));
|
||||
topMap.put( "sn", new HashSet<String>(Arrays.asList("art", "com", "edu", "gouv", "org", "perso",
|
||||
"univ")));
|
||||
topMap.put( "so", new HashSet<String>(Arrays.asList("com", "net", "org")));
|
||||
topMap.put( "sr", new HashSet<String>(Arrays.asList("co", "com", "consulado", "edu", "embaixada",
|
||||
"gov", "mil", "net", "org", "principe", "saotome", "store")));
|
||||
topMap.put( "sy", new HashSet<String>(Arrays.asList("edu", "gov", "net", "mil", "com", "org", "news")));
|
||||
topMap.put( "sz", new HashSet<String>(Arrays.asList("co", "ac", "org")));
|
||||
topMap.put( "th", new HashSet<String>(Arrays.asList("ac", "co", "go", "in", "mi", "net", "or")));
|
||||
topMap.put( "tj", new HashSet<String>(Arrays.asList("ac", "biz", "co", "com", "edu", "go", "gov",
|
||||
"int", "mil", "name", "net", "nic", "org", "test", "web")));
|
||||
topMap.put( "tn", new HashSet<String>(Arrays.asList("com", "ens", "fin", "gov", "ind", "intl",
|
||||
"nat", "net", "org", "info", "perso", "tourism", "edunet", "rnrt", "rns", "rnu",
|
||||
"mincom", "agrinet", "defense", "turen")));
|
||||
topMap.put( "to", new HashSet<String>(Arrays.asList("gov")));
|
||||
topMap.put( "tt", new HashSet<String>(Arrays.asList("co", "com", "org", "net", "biz", "info",
|
||||
"pro", "int", "coop", "jobs", "mobi", "travel", "museum", "aero", "name", "gov",
|
||||
"edu", "cat", "tel", "mil")));
|
||||
topMap.put( "tw", new HashSet<String>(Arrays.asList("edu", "gov", "mil", "com", "net", "org",
|
||||
"idv", "game", "ebiz", "club", "xn--zf0ao64a", "xn--uc0atv", "xn--czrw28b")));
|
||||
topMap.put( "ua", new HashSet<String>(Arrays.asList("com", "edu", "gov", "in", "net", "org",
|
||||
"cherkassy", "chernigov", "chernovtsy", "ck", "cn", "crimea", "cv", "dn",
|
||||
"dnepropetrovsk", "donetsk", "dp", "if", "ivano-frankivsk", "kh", "kharkov",
|
||||
"kherson", "kiev", "kirovograd", "km", "kr", "ks", "lg",
|
||||
"lugansk", "lutsk", "lviv", "mk", "nikolaev", "od", "odessa", "pl", "poltava",
|
||||
"rovno", "rv", "sebastopol", "sumy", "te", "ternopil", "uzhgorod", "vinnica", "vn",
|
||||
"zaporizhzhe", "zp", "zhitomir", "zt", "cr", "lt", "lv", "sb", "sm", "tr",
|
||||
"co", "biz", "in", "ne", "pp", "uz", "dominic")));
|
||||
topMap.put( "ug", new HashSet<String>(Arrays.asList("co", "ac", "sc", "go", "ne", "or", "org", "com")));
|
||||
topMap.put( "us", new HashSet<String>(Arrays.asList("dni", "fed", "isa", "kids", "nsn", "kyschools")));
|
||||
topMap.put( "uz", new HashSet<String>(Arrays.asList("co", "com", "org", "gov", "ac", "edu", "int", "pp", "net")));
|
||||
topMap.put( "vc", new HashSet<String>(Arrays.asList("com", "net", "org", "gov")));
|
||||
topMap.put( "vi", new HashSet<String>(Arrays.asList("co", "com", "k12", "net", "org")));
|
||||
topMap.put( "vn", new HashSet<String>(Arrays.asList( "com", "net", "org", "edu", "gov", "int",
|
||||
"ac", "biz", "info", "name", "pro", "health")));
|
||||
topMap.put( "vu", new HashSet<String>(Arrays.asList("co", "com", "net", "org", "edu", "gov", "de")));
|
||||
topMap.put("org", new HashSet<String>(Arrays.asList("ae", "za")));
|
||||
topMap.put("pro", new HashSet<String>(Arrays.asList("aca", "bar", "cpa", "jur", "law", "med", "eng")));
|
||||
|
||||
top3Map.put("au", new HashSet<String>(Arrays.asList("act.edu.au", "eq.edu.au",
|
||||
"nsw.edu.au", "nt.edu.au", "qld.edu.au", "sa.edu.au", "tas.edu.au", "vic.edu.au",
|
||||
"wa.edu.au", "act.gov.au", "nsw.gov.au", "nt.gov.au", "qld.gov.au", "sa.gov.au",
|
||||
"tas.gov.au", "vic.gov.au", "wa.gov.au")));
|
||||
top3Map.put("im", new HashSet<String>(Arrays.asList("ltd.co.im", "plc.co.im")));
|
||||
top3Map.put("no", new HashSet<String>(Arrays.asList("gs.aa.no", "gs.ah.no", "gs.bu.no",
|
||||
"gs.fm.no", "gs.hl.no", "gs.hm.no", "gs.jan-mayen.no", "gs.mr.no", "gs.nl.no",
|
||||
"gs.nt.no", "gs.of.no", "gs.ol.no", "gs.oslo.no", "gs.rl.no", "gs.sf.no",
|
||||
"gs.st.no", "gs.svalbard.no", "gs.tm.no", "gs.tr.no", "gs.va.no", "gs.vf.no",
|
||||
"bo.telemark.no", "xn--b-5ga.telemark.no", "bo.nordland.no",
|
||||
"xn--b-5ga.nordland.no", "heroy.more-og-romsdal.no",
|
||||
"xn--hery-ira.xn--mre-og-romsdal-qqb.no", "heroy.nordland.no",
|
||||
"xn--hery-ira.nordland.no", "nes.akershus.no", "nes.buskerud.no",
|
||||
"os.hedmark.no", "os.hordaland.no",
|
||||
"sande.more-og-romsdal.no", "sande.xn--mre-og-romsdal-qqb.no",
|
||||
"sande.vestfold.no", "valer.ostfold.no", "xn--vler-qoa.xn--stfold-9xa.no",
|
||||
"valer.hedmark.no", "xn--vler-qoa.hedmark.no")));
|
||||
top3Map.put("tr", new HashSet<String>(Arrays.asList("gov.nc.tr")));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@code sun.security.util.RegisteredDomain} representing the
|
||||
* registered part of the specified domain.
|
||||
*
|
||||
* @param domain the domain name
|
||||
* @return a {@code sun.security.util.RegisteredDomain} or null
|
||||
* if the domain is unknown or not registerable
|
||||
* @throws NullPointerException if domain is null
|
||||
*/
|
||||
public static sun.security.util.RegisteredDomain registeredDomain(String domain) {
|
||||
String name = getRegisteredDomain(domain);
|
||||
if (name.equals(domain)) {
|
||||
return null;
|
||||
}
|
||||
return new sun.security.util.RegisteredDomain() {
|
||||
private String rname = name;
|
||||
@Override
|
||||
public String name() {
|
||||
return rname;
|
||||
}
|
||||
@Override
|
||||
public sun.security.util.RegisteredDomain.Type type() {
|
||||
return sun.security.util.RegisteredDomain.Type.ICANN;
|
||||
}
|
||||
@Override
|
||||
public String publicSuffix() {
|
||||
return rname.substring(rname.indexOf(".") + 1);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the registered part of a qualified domain
|
||||
* name or the original if no match is found.
|
||||
*/
|
||||
public static String getRegisteredDomain(String cname) {
|
||||
int dot;
|
||||
|
||||
/*
|
||||
* If one dot or less than just return.
|
||||
*/
|
||||
dot = cname.lastIndexOf('.');
|
||||
if (dot == -1)
|
||||
return cname;
|
||||
if (dot == 0)
|
||||
return "";
|
||||
if (dot == cname.length() - 1) {
|
||||
cname = cname.substring(0, cname.length() -1);
|
||||
dot = cname.lastIndexOf('.');
|
||||
if (dot == -1)
|
||||
return cname;
|
||||
if (dot == 0)
|
||||
return "";
|
||||
}
|
||||
if (dot == cname.length() - 1)
|
||||
return "";
|
||||
|
||||
/*
|
||||
* Break it up into seperate labels.
|
||||
*/
|
||||
int second = cname.lastIndexOf('.', dot - 1);
|
||||
if (second == -1)
|
||||
return cname;
|
||||
if (second == 0)
|
||||
return "";
|
||||
int third = cname.lastIndexOf('.', second - 1);
|
||||
int fourth = -1;
|
||||
if (third > 0) {
|
||||
fourth = cname.lastIndexOf('.', third - 1);
|
||||
}
|
||||
int fifth = -1;
|
||||
if (fourth > 0) {
|
||||
fifth = cname.lastIndexOf('.', fourth - 1);
|
||||
}
|
||||
String s = cname.substring(dot + 1);
|
||||
String s2 = cname.substring(second + 1, dot);
|
||||
|
||||
/*
|
||||
* Look for longest matches first.
|
||||
* XX.PVT.K12.MA.US etc.
|
||||
*/
|
||||
if (fourth != -1 && s.equals("us") && usStateSet.contains(s2)) {
|
||||
String s3 = cname.substring(third + 1, second);
|
||||
String s4 = cname.substring(fourth + 1, third);
|
||||
if (s3.equals("k12")) {
|
||||
if (s2.equals("ma") && (s4.equals("chtr") || s4.equals("paroch"))) {
|
||||
return cname.substring(fifth + 1);
|
||||
} else if (s4.equals("pvt")) {
|
||||
return cname.substring(fifth + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* XX.K12.MA.US.
|
||||
*/
|
||||
String str = cname.substring(third + 1);
|
||||
if (third != -1) {
|
||||
Set<String> set = top3Map.get(s);
|
||||
if (set != null) {
|
||||
if (set.contains(str)) {
|
||||
return cname.substring(fourth + 1);
|
||||
}
|
||||
} else if (s.equals("us") && usStateSet.contains(s2)) {
|
||||
// check for known third level labels
|
||||
String s3 = cname.substring(third + 1, second);
|
||||
if (usSubStateSet.contains(s3)) {
|
||||
return fourth != -1? cname.substring(fourth + 1): cname;
|
||||
} else {
|
||||
return cname.substring(third + 1);
|
||||
}
|
||||
} else if (s.equals("uk")) {
|
||||
if (s2.equals("sch")) {
|
||||
return cname.substring(fourth + 1);
|
||||
}
|
||||
} else if (s.equals("jp")) {
|
||||
if (jpSet.contains(s2)) {
|
||||
if (jp2Set.contains(str)) {
|
||||
return cname.substring(third + 1);
|
||||
}
|
||||
return cname.substring(fourth + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* PREF.AKITA.JP etc.
|
||||
*/
|
||||
if (jp2Set.contains(str)) {
|
||||
return cname.substring(third + 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* XX.MA.US.
|
||||
*/
|
||||
Set<String> topSet = topMap.get(s);
|
||||
if (topSet != null) {
|
||||
if (topSet.contains(s2)) {
|
||||
return cname.substring(third + 1);
|
||||
}
|
||||
if (!((s.equals("us") && usStateSet.contains(s2)) || (s.equals("jp") && jpSet.contains(s2)))) {
|
||||
return cname.substring(second + 1);
|
||||
}
|
||||
} else if (top2Set.contains(s)) {
|
||||
if (s2.equals("gov")) {
|
||||
return cname.substring(third + 1);
|
||||
}
|
||||
return cname.substring(second + 1);
|
||||
} else if (top3Set.contains(s)) {
|
||||
if (s.equals("ad") && s2.equals("nom") ||
|
||||
s.equals("aw") && s2.equals("com") ||
|
||||
s.equals("be") && s2.equals("ac") ||
|
||||
s.equals("cl") && s2.equals("gov") ||
|
||||
s.equals("cl") && s2.equals("gob") ||
|
||||
s.equals("fi") && s2.equals("aland") ||
|
||||
s.equals("int") && s2.equals("eu") ||
|
||||
s.equals("io") && s2.equals("com") ||
|
||||
s.equals("mc") && s2.equals("tm") ||
|
||||
s.equals("mc") && s2.equals("asso") ||
|
||||
s.equals("vc") && s2.equals("com")) {
|
||||
return cname.substring(third + 1);
|
||||
}
|
||||
return cname.substring(second + 1);
|
||||
} else if (top4Set.contains(s)) {
|
||||
if (s2.equals("com") || s2.equals("edu") || s2.equals("gov") ||
|
||||
s2.equals("net") || s2.equals("org")) {
|
||||
return cname.substring(third + 1);
|
||||
}
|
||||
return cname.substring(second + 1);
|
||||
} else if (top5Set.contains(s)) {
|
||||
return cname.substring(third + 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* BB.AA exception cases.
|
||||
*/
|
||||
if (s.equals("tr")) {
|
||||
if (!s2.equals("nic") && !s2.equals("tsk")) {
|
||||
return cname.substring(third + 1);
|
||||
}
|
||||
return cname.substring(second + 1);
|
||||
} else if (s.equals("uk")) {
|
||||
if (!ukSet.contains(s2)) {
|
||||
return cname.substring(third + 1);
|
||||
}
|
||||
return cname.substring(second + 1);
|
||||
} else if (s.equals("ar")) {
|
||||
if (!arSet.contains(s2)) {
|
||||
return cname.substring(third + 1);
|
||||
}
|
||||
return cname.substring(second + 1);
|
||||
} else if (s.equals("om")) {
|
||||
if (!omSet.contains(s2)) {
|
||||
return cname.substring(third + 1);
|
||||
}
|
||||
return cname.substring(second + 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* XX.AA
|
||||
*/
|
||||
if (top1Set.contains(s)) {
|
||||
return cname.substring(second + 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Nothing matched so we can't shorten the string.
|
||||
*/
|
||||
return cname;
|
||||
}
|
||||
}
|
||||
83
jdkSrc/jdk8/sun/net/ResourceManager.java
Normal file
83
jdkSrc/jdk8/sun/net/ResourceManager.java
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 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 sun.net;
|
||||
|
||||
import java.net.SocketException;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import sun.security.action.GetPropertyAction;
|
||||
|
||||
/**
|
||||
* Manages count of total number of UDP sockets and ensures
|
||||
* that exception is thrown if we try to create more than the
|
||||
* configured limit.
|
||||
*
|
||||
* This functionality could be put in NetHooks some time in future.
|
||||
*/
|
||||
|
||||
public class ResourceManager {
|
||||
|
||||
/* default maximum number of udp sockets per VM
|
||||
* when a security manager is enabled.
|
||||
* The default is 25 which is high enough to be useful
|
||||
* but low enough to be well below the maximum number
|
||||
* of port numbers actually available on all OSes
|
||||
* when multiplied by the maximum feasible number of VM processes
|
||||
* that could practically be spawned.
|
||||
*/
|
||||
|
||||
private static final int DEFAULT_MAX_SOCKETS = 25;
|
||||
private static final int maxSockets;
|
||||
private static final AtomicInteger numSockets;
|
||||
|
||||
static {
|
||||
String prop = java.security.AccessController.doPrivileged(
|
||||
new GetPropertyAction("sun.net.maxDatagramSockets")
|
||||
);
|
||||
int defmax = DEFAULT_MAX_SOCKETS;
|
||||
try {
|
||||
if (prop != null) {
|
||||
defmax = Integer.parseInt(prop);
|
||||
}
|
||||
} catch (NumberFormatException e) {}
|
||||
maxSockets = defmax;
|
||||
numSockets = new AtomicInteger(0);
|
||||
}
|
||||
|
||||
public static void beforeUdpCreate() throws SocketException {
|
||||
if (System.getSecurityManager() != null) {
|
||||
if (numSockets.incrementAndGet() > maxSockets) {
|
||||
numSockets.decrementAndGet();
|
||||
throw new SocketException("maximum number of DatagramSockets reached");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void afterUdpClose() {
|
||||
if (System.getSecurityManager() != null) {
|
||||
numSockets.decrementAndGet();
|
||||
}
|
||||
}
|
||||
}
|
||||
49
jdkSrc/jdk8/sun/net/SocksProxy.java
Normal file
49
jdkSrc/jdk8/sun/net/SocksProxy.java
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 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 sun.net;
|
||||
|
||||
import java.net.Proxy;
|
||||
import java.net.SocketAddress;
|
||||
|
||||
/**
|
||||
* Proxy wrapper class so we can determine the socks protocol version.
|
||||
*/
|
||||
public final class SocksProxy extends Proxy {
|
||||
private final int version;
|
||||
|
||||
private SocksProxy(SocketAddress addr, int version) {
|
||||
super(Proxy.Type.SOCKS, addr);
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public static SocksProxy create(SocketAddress addr, int version) {
|
||||
return new SocksProxy(addr, version);
|
||||
}
|
||||
|
||||
public int protocolVersion() {
|
||||
return version;
|
||||
}
|
||||
}
|
||||
151
jdkSrc/jdk8/sun/net/TelnetInputStream.java
Normal file
151
jdkSrc/jdk8/sun/net/TelnetInputStream.java
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 1995, 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 sun.net;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* This class provides input and output streams for telnet clients.
|
||||
* This class overrides read to do CRLF processing as specified in
|
||||
* RFC 854. The class assumes it is running on a system where lines
|
||||
* are terminated with a single newline <LF> character.
|
||||
*
|
||||
* This is the relevant section of RFC 824 regarding CRLF processing:
|
||||
*
|
||||
* <pre>
|
||||
* The sequence "CR LF", as defined, will cause the NVT to be
|
||||
* positioned at the left margin of the next print line (as would,
|
||||
* for example, the sequence "LF CR"). However, many systems and
|
||||
* terminals do not treat CR and LF independently, and will have to
|
||||
* go to some effort to simulate their effect. (For example, some
|
||||
* terminals do not have a CR independent of the LF, but on such
|
||||
* terminals it may be possible to simulate a CR by backspacing.)
|
||||
* Therefore, the sequence "CR LF" must be treated as a single "new
|
||||
* line" character and used whenever their combined action is
|
||||
* intended; the sequence "CR NUL" must be used where a carriage
|
||||
* return alone is actually desired; and the CR character must be
|
||||
* avoided in other contexts. This rule gives assurance to systems
|
||||
* which must decide whether to perform a "new line" function or a
|
||||
* multiple-backspace that the TELNET stream contains a character
|
||||
* following a CR that will allow a rational decision.
|
||||
*
|
||||
* Note that "CR LF" or "CR NUL" is required in both directions
|
||||
* (in the default ASCII mode), to preserve the symmetry of the
|
||||
* NVT model. Even though it may be known in some situations
|
||||
* (e.g., with remote echo and suppress go ahead options in
|
||||
* effect) that characters are not being sent to an actual
|
||||
* printer, nonetheless, for the sake of consistency, the protocol
|
||||
* requires that a NUL be inserted following a CR not followed by
|
||||
* a LF in the data stream. The converse of this is that a NUL
|
||||
* received in the data stream after a CR (in the absence of
|
||||
* options negotiations which explicitly specify otherwise) should
|
||||
* be stripped out prior to applying the NVT to local character
|
||||
* set mapping.
|
||||
* </pre>
|
||||
*
|
||||
* @author Jonathan Payne
|
||||
*/
|
||||
|
||||
public class TelnetInputStream extends FilterInputStream {
|
||||
/** If stickyCRLF is true, then we're a machine, like an IBM PC,
|
||||
where a Newline is a CR followed by LF. On UNIX, this is false
|
||||
because Newline is represented with just a LF character. */
|
||||
boolean stickyCRLF = false;
|
||||
boolean seenCR = false;
|
||||
|
||||
public boolean binaryMode = false;
|
||||
|
||||
public TelnetInputStream(InputStream fd, boolean binary) {
|
||||
super(fd);
|
||||
binaryMode = binary;
|
||||
}
|
||||
|
||||
public void setStickyCRLF(boolean on) {
|
||||
stickyCRLF = on;
|
||||
}
|
||||
|
||||
public int read() throws IOException {
|
||||
if (binaryMode)
|
||||
return super.read();
|
||||
|
||||
int c;
|
||||
|
||||
/* If last time we determined we saw a CRLF pair, and we're
|
||||
not turning that into just a Newline (that is, we're
|
||||
stickyCRLF), then return the LF part of that sticky
|
||||
pair now. */
|
||||
|
||||
if (seenCR) {
|
||||
seenCR = false;
|
||||
return '\n';
|
||||
}
|
||||
|
||||
if ((c = super.read()) == '\r') { /* CR */
|
||||
switch (c = super.read()) {
|
||||
default:
|
||||
case -1: /* this is an error */
|
||||
throw new TelnetProtocolException("misplaced CR in input");
|
||||
|
||||
case 0: /* NUL - treat CR as CR */
|
||||
return '\r';
|
||||
|
||||
case '\n': /* CRLF - treat as NL */
|
||||
if (stickyCRLF) {
|
||||
seenCR = true;
|
||||
return '\r';
|
||||
} else {
|
||||
return '\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
/** read into a byte array */
|
||||
public int read(byte bytes[]) throws IOException {
|
||||
return read(bytes, 0, bytes.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read into a byte array at offset <i>off</i> for length <i>length</i>
|
||||
* bytes.
|
||||
*/
|
||||
public int read(byte bytes[], int off, int length) throws IOException {
|
||||
if (binaryMode)
|
||||
return super.read(bytes, off, length);
|
||||
|
||||
int c;
|
||||
int offStart = off;
|
||||
|
||||
while (--length >= 0) {
|
||||
c = read();
|
||||
if (c == -1)
|
||||
break;
|
||||
bytes[off++] = (byte)c;
|
||||
}
|
||||
return (off > offStart) ? off - offStart : -1;
|
||||
}
|
||||
}
|
||||
140
jdkSrc/jdk8/sun/net/TelnetOutputStream.java
Normal file
140
jdkSrc/jdk8/sun/net/TelnetOutputStream.java
Normal file
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 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 sun.net;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* This class provides input and output streams for telnet clients.
|
||||
* This class overrides write to do CRLF processing as specified in
|
||||
* RFC 854. The class assumes it is running on a system where lines
|
||||
* are terminated with a single newline <LF> character.
|
||||
*
|
||||
* This is the relevant section of RFC 824 regarding CRLF processing:
|
||||
*
|
||||
* <pre>
|
||||
* The sequence "CR LF", as defined, will cause the NVT to be
|
||||
* positioned at the left margin of the next print line (as would,
|
||||
* for example, the sequence "LF CR"). However, many systems and
|
||||
* terminals do not treat CR and LF independently, and will have to
|
||||
* go to some effort to simulate their effect. (For example, some
|
||||
* terminals do not have a CR independent of the LF, but on such
|
||||
* terminals it may be possible to simulate a CR by backspacing.)
|
||||
* Therefore, the sequence "CR LF" must be treated as a single "new
|
||||
* line" character and used whenever their combined action is
|
||||
* intended; the sequence "CR NUL" must be used where a carriage
|
||||
* return alone is actually desired; and the CR character must be
|
||||
* avoided in other contexts. This rule gives assurance to systems
|
||||
* which must decide whether to perform a "new line" function or a
|
||||
* multiple-backspace that the TELNET stream contains a character
|
||||
* following a CR that will allow a rational decision.
|
||||
*
|
||||
* Note that "CR LF" or "CR NUL" is required in both directions
|
||||
* (in the default ASCII mode), to preserve the symmetry of the
|
||||
* NVT model. Even though it may be known in some situations
|
||||
* (e.g., with remote echo and suppress go ahead options in
|
||||
* effect) that characters are not being sent to an actual
|
||||
* printer, nonetheless, for the sake of consistency, the protocol
|
||||
* requires that a NUL be inserted following a CR not followed by
|
||||
* a LF in the data stream. The converse of this is that a NUL
|
||||
* received in the data stream after a CR (in the absence of
|
||||
* options negotiations which explicitly specify otherwise) should
|
||||
* be stripped out prior to applying the NVT to local character
|
||||
* set mapping.
|
||||
* </pre>
|
||||
*
|
||||
* @author Jonathan Payne
|
||||
*/
|
||||
|
||||
public class TelnetOutputStream extends BufferedOutputStream {
|
||||
boolean stickyCRLF = false;
|
||||
boolean seenCR = false;
|
||||
|
||||
public boolean binaryMode = false;
|
||||
|
||||
public TelnetOutputStream(OutputStream fd, boolean binary) {
|
||||
super(fd);
|
||||
binaryMode = binary;
|
||||
}
|
||||
|
||||
/**
|
||||
* set the stickyCRLF flag. Tells whether the terminal considers CRLF as a single
|
||||
* char.
|
||||
*
|
||||
* @param on the <code>boolean</code> to set the flag to.
|
||||
*/
|
||||
public void setStickyCRLF(boolean on) {
|
||||
stickyCRLF = on;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the int to the stream and does CR LF processing if necessary.
|
||||
*/
|
||||
public void write(int c) throws IOException {
|
||||
if (binaryMode) {
|
||||
super.write(c);
|
||||
return;
|
||||
}
|
||||
|
||||
if (seenCR) {
|
||||
if (c != '\n')
|
||||
super.write(0);
|
||||
super.write(c);
|
||||
if (c != '\r')
|
||||
seenCR = false;
|
||||
} else { // !seenCR
|
||||
if (c == '\n') {
|
||||
super.write('\r');
|
||||
super.write('\n');
|
||||
return;
|
||||
}
|
||||
if (c == '\r') {
|
||||
if (stickyCRLF)
|
||||
seenCR = true;
|
||||
else {
|
||||
super.write('\r');
|
||||
c = 0;
|
||||
}
|
||||
}
|
||||
super.write(c);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the bytes at offset <i>off</i> in buffer <i>bytes</i> for
|
||||
* <i>length</i> bytes.
|
||||
*/
|
||||
public void write(byte bytes[], int off, int length) throws IOException {
|
||||
if (binaryMode) {
|
||||
super.write(bytes, off, length);
|
||||
return;
|
||||
}
|
||||
|
||||
while (--length >= 0) {
|
||||
write(bytes[off++]);
|
||||
}
|
||||
}
|
||||
}
|
||||
43
jdkSrc/jdk8/sun/net/TelnetProtocolException.java
Normal file
43
jdkSrc/jdk8/sun/net/TelnetProtocolException.java
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 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 sun.net;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* An unexpected result was received by the client when talking to the
|
||||
* telnet server.
|
||||
*
|
||||
* @author Jonathan Payne
|
||||
*/
|
||||
|
||||
public class TelnetProtocolException extends IOException {
|
||||
private static final long serialVersionUID = 8509127047257111343L;
|
||||
|
||||
public TelnetProtocolException(String s) {
|
||||
super(s);
|
||||
}
|
||||
}
|
||||
139
jdkSrc/jdk8/sun/net/TransferProtocolClient.java
Normal file
139
jdkSrc/jdk8/sun/net/TransferProtocolClient.java
Normal file
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2011, 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 sun.net;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* This class implements that basic intefaces of transfer protocols.
|
||||
* It is used by subclasses implementing specific protocols.
|
||||
*
|
||||
* @author Jonathan Payne
|
||||
* @see sun.net.ftp.FtpClient
|
||||
* @see sun.net.nntp.NntpClient
|
||||
*/
|
||||
|
||||
public class TransferProtocolClient extends NetworkClient {
|
||||
static final boolean debug = false;
|
||||
|
||||
/** Array of strings (usually 1 entry) for the last reply
|
||||
from the server. */
|
||||
protected Vector<String> serverResponse = new Vector<>(1);
|
||||
|
||||
/** code for last reply */
|
||||
protected int lastReplyCode;
|
||||
|
||||
|
||||
/**
|
||||
* Pulls the response from the server and returns the code as a
|
||||
* number. Returns -1 on failure.
|
||||
*/
|
||||
public int readServerResponse() throws IOException {
|
||||
StringBuffer replyBuf = new StringBuffer(32);
|
||||
int c;
|
||||
int continuingCode = -1;
|
||||
int code;
|
||||
String response;
|
||||
|
||||
serverResponse.setSize(0);
|
||||
while (true) {
|
||||
while ((c = serverInput.read()) != -1) {
|
||||
if (c == '\r') {
|
||||
if ((c = serverInput.read()) != '\n')
|
||||
replyBuf.append('\r');
|
||||
}
|
||||
replyBuf.append((char)c);
|
||||
if (c == '\n')
|
||||
break;
|
||||
}
|
||||
response = replyBuf.toString();
|
||||
replyBuf.setLength(0);
|
||||
if (debug) {
|
||||
System.out.print(response);
|
||||
}
|
||||
|
||||
if (response.length() == 0) {
|
||||
code = -1;
|
||||
} else {
|
||||
try {
|
||||
code = Integer.parseInt(response.substring(0, 3));
|
||||
} catch (NumberFormatException e) {
|
||||
code = -1;
|
||||
} catch (StringIndexOutOfBoundsException e) {
|
||||
/* this line doesn't contain a response code, so
|
||||
we just completely ignore it */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
serverResponse.addElement(response);
|
||||
if (continuingCode != -1) {
|
||||
/* we've seen a XXX- sequence */
|
||||
if (code != continuingCode ||
|
||||
(response.length() >= 4 && response.charAt(3) == '-')) {
|
||||
continue;
|
||||
} else {
|
||||
/* seen the end of code sequence */
|
||||
continuingCode = -1;
|
||||
break;
|
||||
}
|
||||
} else if (response.length() >= 4 && response.charAt(3) == '-') {
|
||||
continuingCode = code;
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return lastReplyCode = code;
|
||||
}
|
||||
|
||||
/** Sends command <i>cmd</i> to the server. */
|
||||
public void sendServer(String cmd) {
|
||||
serverOutput.print(cmd);
|
||||
if (debug) {
|
||||
System.out.print("Sending: " + cmd);
|
||||
}
|
||||
}
|
||||
|
||||
/** converts the server response into a string. */
|
||||
public String getResponseString() {
|
||||
return serverResponse.elementAt(0);
|
||||
}
|
||||
|
||||
/** Returns all server response strings. */
|
||||
public Vector<String> getResponseStrings() {
|
||||
return serverResponse;
|
||||
}
|
||||
|
||||
/** standard constructor to host <i>host</i>, port <i>port</i>. */
|
||||
public TransferProtocolClient(String host, int port) throws IOException {
|
||||
super(host, port);
|
||||
}
|
||||
|
||||
/** creates an uninitialized instance of this class. */
|
||||
public TransferProtocolClient() {}
|
||||
}
|
||||
127
jdkSrc/jdk8/sun/net/URLCanonicalizer.java
Normal file
127
jdkSrc/jdk8/sun/net/URLCanonicalizer.java
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 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 sun.net;
|
||||
|
||||
/**
|
||||
* Helper class to map URL "abbreviations" to real URLs.
|
||||
* The default implementation supports the following mappings:
|
||||
* ftp.mumble.bar/... => ftp://ftp.mumble.bar/...
|
||||
* gopher.mumble.bar/... => gopher://gopher.mumble.bar/...
|
||||
* other.name.dom/... => http://other.name.dom/...
|
||||
* /foo/... => file:/foo/...
|
||||
*
|
||||
* Full URLs (those including a protocol name) are passed through unchanged.
|
||||
*
|
||||
* Subclassers can override or extend this behavior to support different
|
||||
* or additional canonicalization policies.
|
||||
*
|
||||
* @author Steve Byrne
|
||||
*/
|
||||
|
||||
public class URLCanonicalizer {
|
||||
/**
|
||||
* Creates the default canonicalizer instance.
|
||||
*/
|
||||
public URLCanonicalizer() { }
|
||||
|
||||
/**
|
||||
* Given a possibly abbreviated URL (missing a protocol name, typically),
|
||||
* this method's job is to transform that URL into a canonical form,
|
||||
* by including a protocol name and additional syntax, if necessary.
|
||||
*
|
||||
* For a correctly formed URL, this method should just return its argument.
|
||||
*/
|
||||
public String canonicalize(String simpleURL) {
|
||||
String resultURL = simpleURL;
|
||||
if (simpleURL.startsWith("ftp.")) {
|
||||
resultURL = "ftp://" + simpleURL;
|
||||
} else if (simpleURL.startsWith("gopher.")) {
|
||||
resultURL = "gopher://" + simpleURL;
|
||||
} else if (simpleURL.startsWith("/")) {
|
||||
resultURL = "file:" + simpleURL;
|
||||
} else if (!hasProtocolName(simpleURL)) {
|
||||
if (isSimpleHostName(simpleURL)) {
|
||||
simpleURL = "www." + simpleURL + ".com";
|
||||
}
|
||||
resultURL = "http://" + simpleURL;
|
||||
}
|
||||
|
||||
return resultURL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a possibly abbreviated URL, this predicate function returns
|
||||
* true if it appears that the URL contains a protocol name
|
||||
*/
|
||||
public boolean hasProtocolName(String url) {
|
||||
int index = url.indexOf(':');
|
||||
if (index <= 0) { // treat ":foo" as not having a protocol spec
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < index; i++) {
|
||||
char c = url.charAt(i);
|
||||
|
||||
// REMIND: this is a guess at legal characters in a protocol --
|
||||
// need to be verified
|
||||
if ((c >= 'A' && c <= 'Z')
|
||||
|| (c >= 'a' && c <= 'z')
|
||||
|| (c == '-')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// found an illegal character
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the URL is just a single name, no periods or
|
||||
* slashes, false otherwise
|
||||
**/
|
||||
protected boolean isSimpleHostName(String url) {
|
||||
|
||||
for (int i = 0; i < url.length(); i++) {
|
||||
char c = url.charAt(i);
|
||||
|
||||
// REMIND: this is a guess at legal characters in a protocol --
|
||||
// need to be verified
|
||||
if ((c >= 'A' && c <= 'Z')
|
||||
|| (c >= 'a' && c <= 'z')
|
||||
|| (c >= '0' && c <= '9')
|
||||
|| (c == '-')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// found an illegal character
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
122
jdkSrc/jdk8/sun/net/dns/ResolverConfiguration.java
Normal file
122
jdkSrc/jdk8/sun/net/dns/ResolverConfiguration.java
Normal file
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 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 sun.net.dns;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The configuration of the client resolver.
|
||||
*
|
||||
* <p>A ResolverConfiguration is a singleton that represents the
|
||||
* configuration of the client resolver. The ResolverConfiguration
|
||||
* is opened by invoking the {@link #open() open} method.
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
|
||||
public abstract class ResolverConfiguration {
|
||||
|
||||
private static final Object lock = new Object();
|
||||
|
||||
private static ResolverConfiguration provider;
|
||||
|
||||
protected ResolverConfiguration() { }
|
||||
|
||||
/**
|
||||
* Opens the resolver configuration.
|
||||
*
|
||||
* @return the resolver configuration
|
||||
*/
|
||||
public static ResolverConfiguration open() {
|
||||
synchronized (lock) {
|
||||
if (provider == null) {
|
||||
provider = new sun.net.dns.ResolverConfigurationImpl();
|
||||
}
|
||||
return provider;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list corresponding to the domain search path. The
|
||||
* list is ordered by the search order used for host name lookup.
|
||||
* Each element in the list returns a {@link java.lang.String}
|
||||
* containing a domain name or suffix.
|
||||
*
|
||||
* @return list of domain names
|
||||
*/
|
||||
public abstract List<String> searchlist();
|
||||
|
||||
/**
|
||||
* Returns a list of name servers used for host name lookup.
|
||||
* Each element in the list returns a {@link java.lang.String}
|
||||
* containing the textual representation of the IP address of
|
||||
* the name server.
|
||||
*
|
||||
* @return list of the name servers
|
||||
*/
|
||||
public abstract List<String> nameservers();
|
||||
|
||||
|
||||
/**
|
||||
* Options representing certain resolver variables of
|
||||
* a {@link ResolverConfiguration}.
|
||||
*/
|
||||
public static abstract class Options {
|
||||
|
||||
/**
|
||||
* Returns the maximum number of attempts the resolver
|
||||
* will connect to each name server before giving up
|
||||
* and returning an error.
|
||||
*
|
||||
* @return the resolver attempts value or -1 is unknown
|
||||
*/
|
||||
public int attempts() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the basic retransmit timeout, in milliseconds,
|
||||
* used by the resolver. The resolver will typically use
|
||||
* an exponential backoff algorithm where the timeout is
|
||||
* doubled for every retransmit attempt. The basic
|
||||
* retransmit timeout, returned here, is the initial
|
||||
* timeout for the exponential backoff algorithm.
|
||||
*
|
||||
* @return the basic retransmit timeout value or -1
|
||||
* if unknown
|
||||
*/
|
||||
public int retrans() {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link #Options} for the resolver.
|
||||
*
|
||||
* @return options for the resolver
|
||||
*/
|
||||
public abstract Options options();
|
||||
}
|
||||
183
jdkSrc/jdk8/sun/net/dns/ResolverConfigurationImpl.java
Normal file
183
jdkSrc/jdk8/sun/net/dns/ResolverConfigurationImpl.java
Normal file
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 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 sun.net.dns;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.LinkedList;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
/*
|
||||
* An implementation of sun.net.ResolverConfiguration for Windows.
|
||||
*/
|
||||
|
||||
public class ResolverConfigurationImpl
|
||||
extends ResolverConfiguration
|
||||
{
|
||||
// Lock helds whilst loading configuration or checking
|
||||
private static Object lock = new Object();
|
||||
|
||||
// Resolver options
|
||||
private final Options opts;
|
||||
|
||||
// Addreses have changed
|
||||
private static boolean changed = false;
|
||||
|
||||
// Time of last refresh.
|
||||
private static long lastRefresh = -1;
|
||||
|
||||
// Cache timeout (120 seconds) - should be converted into property
|
||||
// or configured as preference in the future.
|
||||
private static final int TIMEOUT = 120000;
|
||||
|
||||
// DNS suffix list and name servers populated by native method
|
||||
private static String os_searchlist;
|
||||
private static String os_nameservers;
|
||||
|
||||
// Cached lists
|
||||
private static LinkedList<String> searchlist;
|
||||
private static LinkedList<String> nameservers;
|
||||
|
||||
// Parse string that consists of token delimited by space or commas
|
||||
// and return LinkedHashMap
|
||||
private LinkedList<String> stringToList(String str) {
|
||||
LinkedList<String> ll = new LinkedList<>();
|
||||
|
||||
// comma and space are valid delimites
|
||||
StringTokenizer st = new StringTokenizer(str, ", ");
|
||||
while (st.hasMoreTokens()) {
|
||||
String s = st.nextToken();
|
||||
if (!ll.contains(s)) {
|
||||
ll.add(s);
|
||||
}
|
||||
}
|
||||
return ll;
|
||||
}
|
||||
|
||||
// Load DNS configuration from OS
|
||||
|
||||
private void loadConfig() {
|
||||
assert Thread.holdsLock(lock);
|
||||
|
||||
// if address have changed then DNS probably changed aswell;
|
||||
// otherwise check if cached settings have expired.
|
||||
//
|
||||
if (changed) {
|
||||
changed = false;
|
||||
} else {
|
||||
if (lastRefresh >= 0) {
|
||||
long currTime = System.currentTimeMillis();
|
||||
if ((currTime - lastRefresh) < TIMEOUT) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// load DNS configuration, update timestamp, create
|
||||
// new HashMaps from the loaded configuration
|
||||
//
|
||||
loadDNSconfig0();
|
||||
|
||||
lastRefresh = System.currentTimeMillis();
|
||||
searchlist = stringToList(os_searchlist);
|
||||
nameservers = stringToList(os_nameservers);
|
||||
os_searchlist = null; // can be GC'ed
|
||||
os_nameservers = null;
|
||||
}
|
||||
|
||||
ResolverConfigurationImpl() {
|
||||
opts = new OptionsImpl();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked") // clone()
|
||||
public List<String> searchlist() {
|
||||
synchronized (lock) {
|
||||
loadConfig();
|
||||
|
||||
// List is mutable so return a shallow copy
|
||||
return (List<String>)searchlist.clone();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked") // clone()
|
||||
public List<String> nameservers() {
|
||||
synchronized (lock) {
|
||||
loadConfig();
|
||||
|
||||
// List is mutable so return a shallow copy
|
||||
return (List<String>)nameservers.clone();
|
||||
}
|
||||
}
|
||||
|
||||
public Options options() {
|
||||
return opts;
|
||||
}
|
||||
|
||||
// --- Address Change Listener
|
||||
|
||||
static class AddressChangeListener extends Thread {
|
||||
public void run() {
|
||||
for (;;) {
|
||||
// wait for configuration to change
|
||||
if (notifyAddrChange0() != 0)
|
||||
return;
|
||||
synchronized (lock) {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// --- Native methods --
|
||||
|
||||
static native void init0();
|
||||
|
||||
static native void loadDNSconfig0();
|
||||
|
||||
static native int notifyAddrChange0();
|
||||
|
||||
static {
|
||||
java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
System.loadLibrary("net");
|
||||
return null;
|
||||
}
|
||||
});
|
||||
init0();
|
||||
|
||||
// start the address listener thread
|
||||
AddressChangeListener thr = new AddressChangeListener();
|
||||
thr.setDaemon(true);
|
||||
thr.start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of {@link ResolverConfiguration.Options}
|
||||
*/
|
||||
class OptionsImpl extends ResolverConfiguration.Options {
|
||||
}
|
||||
943
jdkSrc/jdk8/sun/net/ftp/FtpClient.java
Normal file
943
jdkSrc/jdk8/sun/net/ftp/FtpClient.java
Normal file
@@ -0,0 +1,943 @@
|
||||
/*
|
||||
* Copyright (c) 2009, 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 sun.net.ftp;
|
||||
|
||||
import java.net.*;
|
||||
import java.io.*;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* A class that implements the FTP protocol according to
|
||||
* RFCs <A href="http://www.ietf.org/rfc/rfc0959.txt">959</A>,
|
||||
* <A href="http://www.ietf.org/rfc/rfc2228.txt">2228</A>,
|
||||
* <A href="http://www.ietf.org/rfc/rfc2389.txt">2389</A>,
|
||||
* <A href="http://www.ietf.org/rfc/rfc2428.txt">2428</A>,
|
||||
* <A href="http://www.ietf.org/rfc/rfc3659.txt">3659</A>,
|
||||
* <A href="http://www.ietf.org/rfc/rfc4217.txt">4217</A>.
|
||||
* Which includes support for FTP over SSL/TLS (aka ftps).
|
||||
*
|
||||
* {@code FtpClient} provides all the functionalities of a typical FTP
|
||||
* client, like storing or retrieving files, listing or creating directories.
|
||||
* A typical usage would consist of connecting the client to the server,
|
||||
* log in, issue a few commands then logout.
|
||||
* Here is a code example:
|
||||
* <pre>
|
||||
* FtpClient cl = FtpClient.create();
|
||||
* cl.connect("ftp.gnu.org").login("anonymous", "john.doe@mydomain.com".toCharArray())).changeDirectory("pub/gnu");
|
||||
* Iterator<FtpDirEntry> dir = cl.listFiles();
|
||||
* while (dir.hasNext()) {
|
||||
* FtpDirEntry f = dir.next();
|
||||
* System.err.println(f.getName());
|
||||
* }
|
||||
* cl.close();
|
||||
* }
|
||||
* </pre>
|
||||
* <p><b>Error reporting:</b> There are, mostly, two families of errors that
|
||||
* can occur during an FTP session. The first kind are the network related issues
|
||||
* like a connection reset, and they are usually fatal to the session, meaning,
|
||||
* in all likelyhood the connection to the server has been lost and the session
|
||||
* should be restarted from scratch. These errors are reported by throwing an
|
||||
* {@link IOException}. The second kind are the errors reported by the FTP server,
|
||||
* like when trying to download a non-existing file for example. These errors
|
||||
* are usually non fatal to the session, meaning more commands can be sent to the
|
||||
* server. In these cases, a {@link FtpProtocolException} is thrown.</p>
|
||||
* <p>
|
||||
* It should be noted that this is not a thread-safe API, as it wouldn't make
|
||||
* too much sense, due to the very sequential nature of FTP, to provide a
|
||||
* client able to be manipulated from multiple threads.
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
public abstract class FtpClient implements java.io.Closeable {
|
||||
|
||||
private static final int FTP_PORT = 21;
|
||||
|
||||
public static enum TransferType {
|
||||
|
||||
ASCII, BINARY, EBCDIC
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the default FTP port number.
|
||||
*
|
||||
* @return the port number.
|
||||
*/
|
||||
public static final int defaultPort() {
|
||||
return FTP_PORT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of FtpClient. The client is not connected to any
|
||||
* server yet.
|
||||
*
|
||||
*/
|
||||
protected FtpClient() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of {@code FtpClient}. The client is not connected to any
|
||||
* server yet.
|
||||
*
|
||||
* @return the created {@code FtpClient}
|
||||
*/
|
||||
public static FtpClient create() {
|
||||
FtpClientProvider provider = FtpClientProvider.provider();
|
||||
return provider.createFtpClient();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of FtpClient and connects it to the specified
|
||||
* address.
|
||||
*
|
||||
* @param dest the {@code InetSocketAddress} to connect to.
|
||||
* @return The created {@code FtpClient}
|
||||
* @throws IOException if the connection fails
|
||||
* @see #connect(java.net.SocketAddress)
|
||||
*/
|
||||
public static FtpClient create(InetSocketAddress dest) throws FtpProtocolException, IOException {
|
||||
FtpClient client = create();
|
||||
if (dest != null) {
|
||||
client.connect(dest);
|
||||
}
|
||||
return client;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of {@code FtpClient} and connects it to the
|
||||
* specified host on the default FTP port.
|
||||
*
|
||||
* @param dest the {@code String} containing the name of the host
|
||||
* to connect to.
|
||||
* @return The created {@code FtpClient}
|
||||
* @throws IOException if the connection fails.
|
||||
* @throws FtpProtocolException if the server rejected the connection
|
||||
*/
|
||||
public static FtpClient create(String dest) throws FtpProtocolException, IOException {
|
||||
return create(new InetSocketAddress(dest, FTP_PORT));
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables, or disables, the use of the <I>passive</I> mode. In that mode,
|
||||
* data connections are established by having the client connect to the server.
|
||||
* This is the recommended default mode as it will work best through
|
||||
* firewalls and NATs. If set to {@code false} the mode is said to be
|
||||
* <I>active</I> which means the server will connect back to the client
|
||||
* after a PORT command to establish a data connection.
|
||||
*
|
||||
* <p><b>Note:</b> Since the passive mode might not be supported by all
|
||||
* FTP servers, enabling it means the client will try to use it. If the
|
||||
* server rejects it, then the client will attempt to fall back to using
|
||||
* the <I>active</I> mode by issuing a {@code PORT} command instead.</p>
|
||||
*
|
||||
* @param passive {@code true} to force passive mode.
|
||||
* @return This FtpClient
|
||||
* @see #isPassiveModeEnabled()
|
||||
*/
|
||||
public abstract FtpClient enablePassiveMode(boolean passive);
|
||||
|
||||
/**
|
||||
* Tests whether passive mode is enabled.
|
||||
*
|
||||
* @return {@code true} if the passive mode has been enabled.
|
||||
* @see #enablePassiveMode(boolean)
|
||||
*/
|
||||
public abstract boolean isPassiveModeEnabled();
|
||||
|
||||
/**
|
||||
* Sets the default timeout value to use when connecting to the server,
|
||||
*
|
||||
* @param timeout the timeout value, in milliseconds, to use for the connect
|
||||
* operation. A value of zero or less, means use the default timeout.
|
||||
*
|
||||
* @return This FtpClient
|
||||
*/
|
||||
public abstract FtpClient setConnectTimeout(int timeout);
|
||||
|
||||
/**
|
||||
* Returns the current default connection timeout value.
|
||||
*
|
||||
* @return the value, in milliseconds, of the current connect timeout.
|
||||
* @see #setConnectTimeout(int)
|
||||
*/
|
||||
public abstract int getConnectTimeout();
|
||||
|
||||
/**
|
||||
* Sets the timeout value to use when reading from the server,
|
||||
*
|
||||
* @param timeout the timeout value, in milliseconds, to use for the read
|
||||
* operation. A value of zero or less, means use the default timeout.
|
||||
* @return This FtpClient
|
||||
*/
|
||||
public abstract FtpClient setReadTimeout(int timeout);
|
||||
|
||||
/**
|
||||
* Returns the current read timeout value.
|
||||
*
|
||||
* @return the value, in milliseconds, of the current read timeout.
|
||||
* @see #setReadTimeout(int)
|
||||
*/
|
||||
public abstract int getReadTimeout();
|
||||
|
||||
/**
|
||||
* Set the {@code Proxy} to be used for the next connection.
|
||||
* If the client is already connected, it doesn't affect the current
|
||||
* connection. However it is not recommended to change this during a session.
|
||||
*
|
||||
* @param p the {@code Proxy} to use, or {@code null} for no proxy.
|
||||
* @return This FtpClient
|
||||
*/
|
||||
public abstract FtpClient setProxy(Proxy p);
|
||||
|
||||
/**
|
||||
* Get the proxy of this FtpClient
|
||||
*
|
||||
* @return the {@code Proxy}, this client is using, or {@code null}
|
||||
* if none is used.
|
||||
* @see #setProxy(Proxy)
|
||||
*/
|
||||
public abstract Proxy getProxy();
|
||||
|
||||
/**
|
||||
* Tests whether this client is connected or not to a server.
|
||||
*
|
||||
* @return {@code true} if the client is connected.
|
||||
*/
|
||||
public abstract boolean isConnected();
|
||||
|
||||
/**
|
||||
* Connects the {@code FtpClient} to the specified destination server.
|
||||
*
|
||||
* @param dest the address of the destination server
|
||||
* @return this FtpClient
|
||||
* @throws IOException if connection failed.
|
||||
* @throws SecurityException if there is a SecurityManager installed and it
|
||||
* denied the authorization to connect to the destination.
|
||||
* @throws FtpProtocolException
|
||||
*/
|
||||
public abstract FtpClient connect(SocketAddress dest) throws FtpProtocolException, IOException;
|
||||
|
||||
/**
|
||||
* Connects the FtpClient to the specified destination server.
|
||||
*
|
||||
* @param dest the address of the destination server
|
||||
* @param timeout the value, in milliseconds, to use as a connection timeout
|
||||
* @return this FtpClient
|
||||
* @throws IOException if connection failed.
|
||||
* @throws SecurityException if there is a SecurityManager installed and it
|
||||
* denied the authorization to connect to the destination.
|
||||
* @throws FtpProtocolException
|
||||
*/
|
||||
public abstract FtpClient connect(SocketAddress dest, int timeout) throws FtpProtocolException, IOException;
|
||||
|
||||
/**
|
||||
* Retrieves the address of the FTP server this client is connected to.
|
||||
*
|
||||
* @return the {@link SocketAddress} of the server, or {@code null} if this
|
||||
* client is not connected yet.
|
||||
*/
|
||||
public abstract SocketAddress getServerAddress();
|
||||
|
||||
/**
|
||||
* Attempts to log on the server with the specified user name and password.
|
||||
*
|
||||
* @param user The user name
|
||||
* @param password The password for that user
|
||||
* @return this FtpClient
|
||||
* @throws IOException if an error occurred during the transmission
|
||||
* @throws FtpProtocolException if the login was refused by the server
|
||||
*/
|
||||
public abstract FtpClient login(String user, char[] password) throws FtpProtocolException, IOException;
|
||||
|
||||
/**
|
||||
* Attempts to log on the server with the specified user name, password and
|
||||
* account name.
|
||||
*
|
||||
* @param user The user name
|
||||
* @param password The password for that user.
|
||||
* @param account The account name for that user.
|
||||
* @return this FtpClient
|
||||
* @throws IOException if an error occurs during the transmission.
|
||||
* @throws FtpProtocolException if the login was refused by the server
|
||||
*/
|
||||
public abstract FtpClient login(String user, char[] password, String account) throws FtpProtocolException, IOException;
|
||||
|
||||
/**
|
||||
* Closes the current connection. Logs out the current user, if any, by
|
||||
* issuing the QUIT command to the server.
|
||||
* This is in effect terminates the current
|
||||
* session and the connection to the server will be closed.
|
||||
* <p>After a close, the client can then be connected to another server
|
||||
* to start an entirely different session.</P>
|
||||
*
|
||||
* @throws IOException if an error occurs during transmission
|
||||
*/
|
||||
public abstract void close() throws IOException;
|
||||
|
||||
/**
|
||||
* Checks whether the client is logged in to the server or not.
|
||||
*
|
||||
* @return {@code true} if the client has already completed a login.
|
||||
*/
|
||||
public abstract boolean isLoggedIn();
|
||||
|
||||
/**
|
||||
* Changes to a specific directory on a remote FTP server
|
||||
*
|
||||
* @param remoteDirectory path of the directory to CD to.
|
||||
* @return this FtpClient
|
||||
* @throws IOException if an error occurs during the transmission.
|
||||
* @throws FtpProtocolException if the command was refused by the server
|
||||
*/
|
||||
public abstract FtpClient changeDirectory(String remoteDirectory) throws FtpProtocolException, IOException;
|
||||
|
||||
/**
|
||||
* Changes to the parent directory, sending the CDUP command to the server.
|
||||
*
|
||||
* @return this FtpClient
|
||||
* @throws IOException if an error occurs during the transmission.
|
||||
* @throws FtpProtocolException if the command was refused by the server
|
||||
*/
|
||||
public abstract FtpClient changeToParentDirectory() throws FtpProtocolException, IOException;
|
||||
|
||||
/**
|
||||
* Retrieve the server current working directory using the PWD command.
|
||||
*
|
||||
* @return a {@code String} containing the current working directory
|
||||
* @throws IOException if an error occurs during transmission
|
||||
* @throws FtpProtocolException if the command was refused by the server,
|
||||
*/
|
||||
public abstract String getWorkingDirectory() throws FtpProtocolException, IOException;
|
||||
|
||||
/**
|
||||
* Sets the restart offset to the specified value. That value will be
|
||||
* sent through a {@code REST} command to server before the next file
|
||||
* transfer and has the effect of resuming a file transfer from the
|
||||
* specified point. After the transfer the restart offset is set back to
|
||||
* zero.
|
||||
*
|
||||
* @param offset the offset in the remote file at which to start the next
|
||||
* transfer. This must be a value greater than or equal to zero.
|
||||
* @return this FtpClient
|
||||
* @throws IllegalArgumentException if the offset is negative.
|
||||
*/
|
||||
public abstract FtpClient setRestartOffset(long offset);
|
||||
|
||||
/**
|
||||
* Retrieves a file from the ftp server and writes its content to the specified
|
||||
* {@code OutputStream}.
|
||||
* <p>If the restart offset was set, then a {@code REST} command will be
|
||||
* sent before the {@code RETR} in order to restart the tranfer from the specified
|
||||
* offset.</p>
|
||||
* <p>The {@code OutputStream} is not closed by this method at the end
|
||||
* of the transfer. </p>
|
||||
* <p>This method will block until the transfer is complete or an exception
|
||||
* is thrown.</p>
|
||||
*
|
||||
* @param name a {@code String} containing the name of the file to
|
||||
* retreive from the server.
|
||||
* @param local the {@code OutputStream} the file should be written to.
|
||||
* @return this FtpClient
|
||||
* @throws IOException if the transfer fails.
|
||||
* @throws FtpProtocolException if the command was refused by the server
|
||||
* @see #setRestartOffset(long)
|
||||
*/
|
||||
public abstract FtpClient getFile(String name, OutputStream local) throws FtpProtocolException, IOException;
|
||||
|
||||
/**
|
||||
* Retrieves a file from the ftp server, using the {@code RETR} command, and
|
||||
* returns the InputStream from the established data connection.
|
||||
* {@link #completePending()} <b>has</b> to be called once the application
|
||||
* is done reading from the returned stream.
|
||||
* <p>If the restart offset was set, then a {@code REST} command will be
|
||||
* sent before the {@code RETR} in order to restart the tranfer from the specified
|
||||
* offset.</p>
|
||||
*
|
||||
* @param name the name of the remote file
|
||||
* @return the {@link java.io.InputStream} from the data connection
|
||||
* @throws IOException if an error occurred during the transmission.
|
||||
* @throws FtpProtocolException if the command was refused by the server
|
||||
* @see #setRestartOffset(long)
|
||||
*/
|
||||
public abstract InputStream getFileStream(String name) throws FtpProtocolException, IOException;
|
||||
|
||||
/**
|
||||
* Transfers a file from the client to the server (aka a <I>put</I>)
|
||||
* by sending the STOR command, and returns the {@code OutputStream}
|
||||
* from the established data connection.
|
||||
*
|
||||
* A new file is created at the server site if the file specified does
|
||||
* not already exist.
|
||||
*
|
||||
* {@link #completePending()} <b>has</b> to be called once the application
|
||||
* is finished writing to the returned stream.
|
||||
*
|
||||
* @param name the name of the remote file to write.
|
||||
* @return the {@link java.io.OutputStream} from the data connection or
|
||||
* {@code null} if the command was unsuccessful.
|
||||
* @throws IOException if an error occurred during the transmission.
|
||||
* @throws FtpProtocolException if the command was rejected by the server
|
||||
*/
|
||||
public OutputStream putFileStream(String name) throws FtpProtocolException, IOException {
|
||||
return putFileStream(name, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfers a file from the client to the server (aka a <I>put</I>)
|
||||
* by sending the STOR or STOU command, depending on the
|
||||
* {@code unique} argument, and returns the {@code OutputStream}
|
||||
* from the established data connection.
|
||||
* {@link #completePending()} <b>has</b> to be called once the application
|
||||
* is finished writing to the stream.
|
||||
*
|
||||
* A new file is created at the server site if the file specified does
|
||||
* not already exist.
|
||||
*
|
||||
* If {@code unique} is set to {@code true}, the resultant file
|
||||
* is to be created under a name unique to that directory, meaning
|
||||
* it will not overwrite an existing file, instead the server will
|
||||
* generate a new, unique, file name.
|
||||
* The name of the remote file can be retrieved, after completion of the
|
||||
* transfer, by calling {@link #getLastFileName()}.
|
||||
*
|
||||
* @param name the name of the remote file to write.
|
||||
* @param unique {@code true} if the remote files should be unique,
|
||||
* in which case the STOU command will be used.
|
||||
* @return the {@link java.io.OutputStream} from the data connection.
|
||||
* @throws IOException if an error occurred during the transmission.
|
||||
* @throws FtpProtocolException if the command was rejected by the server
|
||||
*/
|
||||
public abstract OutputStream putFileStream(String name, boolean unique) throws FtpProtocolException, IOException;
|
||||
|
||||
/**
|
||||
* Transfers a file from the client to the server (aka a <I>put</I>)
|
||||
* by sending the STOR or STOU command, depending on the
|
||||
* {@code unique} argument. The content of the {@code InputStream}
|
||||
* passed in argument is written into the remote file, overwriting any
|
||||
* existing data.
|
||||
*
|
||||
* A new file is created at the server site if the file specified does
|
||||
* not already exist.
|
||||
*
|
||||
* If {@code unique} is set to {@code true}, the resultant file
|
||||
* is to be created under a name unique to that directory, meaning
|
||||
* it will not overwrite an existing file, instead the server will
|
||||
* generate a new, unique, file name.
|
||||
* The name of the remote file can be retrieved, after completion of the
|
||||
* transfer, by calling {@link #getLastFileName()}.
|
||||
*
|
||||
* <p>This method will block until the transfer is complete or an exception
|
||||
* is thrown.</p>
|
||||
*
|
||||
* @param name the name of the remote file to write.
|
||||
* @param local the {@code InputStream} that points to the data to
|
||||
* transfer.
|
||||
* @return this FtpClient
|
||||
* @throws IOException if an error occurred during the transmission.
|
||||
* @throws FtpProtocolException if the command was rejected by the server
|
||||
*/
|
||||
public FtpClient putFile(String name, InputStream local) throws FtpProtocolException, IOException {
|
||||
return putFile(name, local, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfers a file from the client to the server (aka a <I>put</I>)
|
||||
* by sending the STOR command. The content of the {@code InputStream}
|
||||
* passed in argument is written into the remote file, overwriting any
|
||||
* existing data.
|
||||
*
|
||||
* A new file is created at the server site if the file specified does
|
||||
* not already exist.
|
||||
*
|
||||
* <p>This method will block until the transfer is complete or an exception
|
||||
* is thrown.</p>
|
||||
*
|
||||
* @param name the name of the remote file to write.
|
||||
* @param local the {@code InputStream} that points to the data to
|
||||
* transfer.
|
||||
* @param unique {@code true} if the remote file should be unique
|
||||
* (i.e. not already existing), {@code false} otherwise.
|
||||
* @return this FtpClient
|
||||
* @throws IOException if an error occurred during the transmission.
|
||||
* @throws FtpProtocolException if the command was rejected by the server
|
||||
* @see #getLastFileName()
|
||||
*/
|
||||
public abstract FtpClient putFile(String name, InputStream local, boolean unique) throws FtpProtocolException, IOException;
|
||||
|
||||
/**
|
||||
* Sends the APPE command to the server in order to transfer a data stream
|
||||
* passed in argument and append it to the content of the specified remote
|
||||
* file.
|
||||
*
|
||||
* <p>This method will block until the transfer is complete or an exception
|
||||
* is thrown.</p>
|
||||
*
|
||||
* @param name A {@code String} containing the name of the remote file
|
||||
* to append to.
|
||||
* @param local The {@code InputStream} providing access to the data
|
||||
* to be appended.
|
||||
* @return this FtpClient
|
||||
* @throws IOException if an error occurred during the transmission.
|
||||
* @throws FtpProtocolException if the command was rejected by the server
|
||||
*/
|
||||
public abstract FtpClient appendFile(String name, InputStream local) throws FtpProtocolException, IOException;
|
||||
|
||||
/**
|
||||
* Renames a file on the server.
|
||||
*
|
||||
* @param from the name of the file being renamed
|
||||
* @param to the new name for the file
|
||||
* @return this FtpClient
|
||||
* @throws IOException if an error occurred during the transmission.
|
||||
* @throws FtpProtocolException if the command was rejected by the server
|
||||
*/
|
||||
public abstract FtpClient rename(String from, String to) throws FtpProtocolException, IOException;
|
||||
|
||||
/**
|
||||
* Deletes a file on the server.
|
||||
*
|
||||
* @param name a {@code String} containing the name of the file
|
||||
* to delete.
|
||||
* @return this FtpClient
|
||||
* @throws IOException if an error occurred during the exchange
|
||||
* @throws FtpProtocolException if the command was rejected by the server
|
||||
*/
|
||||
public abstract FtpClient deleteFile(String name) throws FtpProtocolException, IOException;
|
||||
|
||||
/**
|
||||
* Creates a new directory on the server.
|
||||
*
|
||||
* @param name a {@code String} containing the name of the directory
|
||||
* to create.
|
||||
* @return this FtpClient
|
||||
* @throws IOException if an error occurred during the exchange
|
||||
* @throws FtpProtocolException if the command was rejected by the server
|
||||
*/
|
||||
public abstract FtpClient makeDirectory(String name) throws FtpProtocolException, IOException;
|
||||
|
||||
/**
|
||||
* Removes a directory on the server.
|
||||
*
|
||||
* @param name a {@code String} containing the name of the directory
|
||||
* to remove.
|
||||
*
|
||||
* @return this FtpClient
|
||||
* @throws IOException if an error occurred during the exchange.
|
||||
* @throws FtpProtocolException if the command was rejected by the server
|
||||
*/
|
||||
public abstract FtpClient removeDirectory(String name) throws FtpProtocolException, IOException;
|
||||
|
||||
/**
|
||||
* Sends a No-operation command. It's useful for testing the connection
|
||||
* status or as a <I>keep alive</I> mechanism.
|
||||
*
|
||||
* @return this FtpClient
|
||||
* @throws IOException if an error occurred during the transmission.
|
||||
* @throws FtpProtocolException if the command was rejected by the server
|
||||
*/
|
||||
public abstract FtpClient noop() throws FtpProtocolException, IOException;
|
||||
|
||||
/**
|
||||
* Sends the {@code STAT} command to the server.
|
||||
* This can be used while a data connection is open to get a status
|
||||
* on the current transfer, in that case the parameter should be
|
||||
* {@code null}.
|
||||
* If used between file transfers, it may have a pathname as argument
|
||||
* in which case it will work as the LIST command except no data
|
||||
* connection will be created.
|
||||
*
|
||||
* @param name an optional {@code String} containing the pathname
|
||||
* the STAT command should apply to.
|
||||
* @return the response from the server
|
||||
* @throws IOException if an error occurred during the transmission.
|
||||
* @throws FtpProtocolException if the command was rejected by the server
|
||||
*/
|
||||
public abstract String getStatus(String name) throws FtpProtocolException, IOException;
|
||||
|
||||
/**
|
||||
* Sends the {@code FEAT} command to the server and returns the list of supported
|
||||
* features in the form of strings.
|
||||
*
|
||||
* The features are the supported commands, like AUTH TLS, PROT or PASV.
|
||||
* See the RFCs for a complete list.
|
||||
*
|
||||
* Note that not all FTP servers support that command, in which case
|
||||
* a {@link FtpProtocolException} will be thrown.
|
||||
*
|
||||
* @return a {@code List} of {@code Strings} describing the
|
||||
* supported additional features
|
||||
* @throws IOException if an error occurs during the transmission.
|
||||
* @throws FtpProtocolException if the command is rejected by the server
|
||||
*/
|
||||
public abstract List<String> getFeatures() throws FtpProtocolException, IOException;
|
||||
|
||||
/**
|
||||
* Sends the {@code ABOR} command to the server.
|
||||
* <p>It tells the server to stop the previous command or transfer. No action
|
||||
* will be taken if the previous command has already been completed.</p>
|
||||
* <p>This doesn't abort the current session, more commands can be issued
|
||||
* after an abort.</p>
|
||||
*
|
||||
* @return this FtpClient
|
||||
* @throws IOException if an error occurred during the transmission.
|
||||
* @throws FtpProtocolException if the command was rejected by the server
|
||||
*/
|
||||
public abstract FtpClient abort() throws FtpProtocolException, IOException;
|
||||
|
||||
/**
|
||||
* Some methods do not wait until completion before returning, so this
|
||||
* method can be called to wait until completion. This is typically the case
|
||||
* with commands that trigger a transfer like {@link #getFileStream(String)}.
|
||||
* So this method should be called before accessing information related to
|
||||
* such a command.
|
||||
* <p>This method will actually block reading on the command channel for a
|
||||
* notification from the server that the command is finished. Such a
|
||||
* notification often carries extra information concerning the completion
|
||||
* of the pending action (e.g. number of bytes transfered).</p>
|
||||
* <p>Note that this will return immediately if no command or action
|
||||
* is pending</p>
|
||||
* <p>It should be also noted that most methods issuing commands to the ftp
|
||||
* server will call this method if a previous command is pending.
|
||||
* <p>Example of use:
|
||||
* <pre>
|
||||
* InputStream in = cl.getFileStream("file");
|
||||
* ...
|
||||
* cl.completePending();
|
||||
* long size = cl.getLastTransferSize();
|
||||
* </pre>
|
||||
* On the other hand, it's not necessary in a case like:
|
||||
* <pre>
|
||||
* InputStream in = cl.getFileStream("file");
|
||||
* // read content
|
||||
* ...
|
||||
* cl.close();
|
||||
* </pre>
|
||||
* <p>Since {@link #close()} will call completePending() if necessary.</p>
|
||||
* @return this FtpClient
|
||||
* @throws IOException if an error occurred during the transfer
|
||||
* @throws FtpProtocolException if the command didn't complete successfully
|
||||
*/
|
||||
public abstract FtpClient completePending() throws FtpProtocolException, IOException;
|
||||
|
||||
/**
|
||||
* Reinitializes the USER parameters on the FTP server
|
||||
*
|
||||
* @return this FtpClient
|
||||
* @throws IOException if an error occurs during transmission
|
||||
* @throws FtpProtocolException if the command fails
|
||||
*/
|
||||
public abstract FtpClient reInit() throws FtpProtocolException, IOException;
|
||||
|
||||
/**
|
||||
* Changes the transfer type (binary, ascii, ebcdic) and issue the
|
||||
* proper command (e.g. TYPE A) to the server.
|
||||
*
|
||||
* @param type the {@code TransferType} to use.
|
||||
* @return This FtpClient
|
||||
* @throws IOException if an error occurs during transmission.
|
||||
* @throws FtpProtocolException if the command was rejected by the server
|
||||
*/
|
||||
public abstract FtpClient setType(TransferType type) throws FtpProtocolException, IOException;
|
||||
|
||||
/**
|
||||
* Changes the current transfer type to binary.
|
||||
* This is a convenience method that is equivalent to
|
||||
* {@code setType(TransferType.BINARY)}
|
||||
*
|
||||
* @return This FtpClient
|
||||
* @throws IOException if an error occurs during the transmission.
|
||||
* @throws FtpProtocolException if the command was rejected by the server
|
||||
* @see #setType(TransferType)
|
||||
*/
|
||||
public FtpClient setBinaryType() throws FtpProtocolException, IOException {
|
||||
setType(TransferType.BINARY);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the current transfer type to ascii.
|
||||
* This is a convenience method that is equivalent to
|
||||
* {@code setType(TransferType.ASCII)}
|
||||
*
|
||||
* @return This FtpClient
|
||||
* @throws IOException if an error occurs during the transmission.
|
||||
* @throws FtpProtocolException if the command was rejected by the server
|
||||
* @see #setType(TransferType)
|
||||
*/
|
||||
public FtpClient setAsciiType() throws FtpProtocolException, IOException {
|
||||
setType(TransferType.ASCII);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Issues a {@code LIST} command to the server to get the current directory
|
||||
* listing, and returns the InputStream from the data connection.
|
||||
*
|
||||
* <p>{@link #completePending()} <b>has</b> to be called once the application
|
||||
* is finished reading from the stream.</p>
|
||||
*
|
||||
* @param path the pathname of the directory to list, or {@code null}
|
||||
* for the current working directory.
|
||||
* @return the {@code InputStream} from the resulting data connection
|
||||
* @throws IOException if an error occurs during the transmission.
|
||||
* @throws FtpProtocolException if the command was rejected by the server
|
||||
* @see #changeDirectory(String)
|
||||
* @see #listFiles(String)
|
||||
*/
|
||||
public abstract InputStream list(String path) throws FtpProtocolException, IOException;
|
||||
|
||||
/**
|
||||
* Issues a {@code NLST path} command to server to get the specified directory
|
||||
* content. It differs from {@link #list(String)} method by the fact that
|
||||
* it will only list the file names which would make the parsing of the
|
||||
* somewhat easier.
|
||||
*
|
||||
* <p>{@link #completePending()} <b>has</b> to be called once the application
|
||||
* is finished reading from the stream.</p>
|
||||
*
|
||||
* @param path a {@code String} containing the pathname of the
|
||||
* directory to list or {@code null} for the current working directory.
|
||||
* @return the {@code InputStream} from the resulting data connection
|
||||
* @throws IOException if an error occurs during the transmission.
|
||||
* @throws FtpProtocolException if the command was rejected by the server
|
||||
*/
|
||||
public abstract InputStream nameList(String path) throws FtpProtocolException, IOException;
|
||||
|
||||
/**
|
||||
* Issues the {@code SIZE [path]} command to the server to get the size of a
|
||||
* specific file on the server.
|
||||
* Note that this command may not be supported by the server. In which
|
||||
* case -1 will be returned.
|
||||
*
|
||||
* @param path a {@code String} containing the pathname of the
|
||||
* file.
|
||||
* @return a {@code long} containing the size of the file or -1 if
|
||||
* the server returned an error, which can be checked with
|
||||
* {@link #getLastReplyCode()}.
|
||||
* @throws IOException if an error occurs during the transmission.
|
||||
* @throws FtpProtocolException if the command was rejected by the server
|
||||
*/
|
||||
public abstract long getSize(String path) throws FtpProtocolException, IOException;
|
||||
|
||||
/**
|
||||
* Issues the {@code MDTM [path]} command to the server to get the modification
|
||||
* time of a specific file on the server.
|
||||
* Note that this command may not be supported by the server, in which
|
||||
* case {@code null} will be returned.
|
||||
*
|
||||
* @param path a {@code String} containing the pathname of the file.
|
||||
* @return a {@code Date} representing the last modification time
|
||||
* or {@code null} if the server returned an error, which
|
||||
* can be checked with {@link #getLastReplyCode()}.
|
||||
* @throws IOException if an error occurs during the transmission.
|
||||
* @throws FtpProtocolException if the command was rejected by the server
|
||||
*/
|
||||
public abstract Date getLastModified(String path) throws FtpProtocolException, IOException;
|
||||
|
||||
/**
|
||||
* Sets the parser used to handle the directory output to the specified
|
||||
* one. By default the parser is set to one that can handle most FTP
|
||||
* servers output (Unix base mostly). However it may be necessary for
|
||||
* and application to provide its own parser due to some uncommon
|
||||
* output format.
|
||||
*
|
||||
* @param p The {@code FtpDirParser} to use.
|
||||
* @return this FtpClient
|
||||
* @see #listFiles(String)
|
||||
*/
|
||||
public abstract FtpClient setDirParser(FtpDirParser p);
|
||||
|
||||
/**
|
||||
* Issues a {@code MLSD} command to the server to get the specified directory
|
||||
* listing and applies the internal parser to create an Iterator of
|
||||
* {@link java.net.FtpDirEntry}. Note that the Iterator returned is also a
|
||||
* {@link java.io.Closeable}.
|
||||
* <p>If the server doesn't support the MLSD command, the LIST command is used
|
||||
* instead and the parser set by {@link #setDirParser(java.net.FtpDirParser) }
|
||||
* is used instead.</p>
|
||||
*
|
||||
* {@link #completePending()} <b>has</b> to be called once the application
|
||||
* is finished iterating through the files.
|
||||
*
|
||||
* @param path the pathname of the directory to list or {@code null}
|
||||
* for the current working directoty.
|
||||
* @return a {@code Iterator} of files or {@code null} if the
|
||||
* command failed.
|
||||
* @throws IOException if an error occurred during the transmission
|
||||
* @see #setDirParser(FtpDirParser)
|
||||
* @see #changeDirectory(String)
|
||||
* @throws FtpProtocolException if the command was rejected by the server
|
||||
*/
|
||||
public abstract Iterator<FtpDirEntry> listFiles(String path) throws FtpProtocolException, IOException;
|
||||
|
||||
/**
|
||||
* Attempts to use Kerberos GSSAPI as an authentication mechanism with the
|
||||
* ftp server. This will issue an {@code AUTH GSSAPI} command, and if
|
||||
* it is accepted by the server, will followup with {@code ADAT}
|
||||
* command to exchange the various tokens until authentication is
|
||||
* successful. This conforms to Appendix I of RFC 2228.
|
||||
*
|
||||
* @return this FtpClient
|
||||
* @throws IOException if an error occurs during the transmission.
|
||||
* @throws FtpProtocolException if the command was rejected by the server
|
||||
*/
|
||||
public abstract FtpClient useKerberos() throws FtpProtocolException, IOException;
|
||||
|
||||
/**
|
||||
* Returns the Welcome string the server sent during initial connection.
|
||||
*
|
||||
* @return a {@code String} containing the message the server
|
||||
* returned during connection or {@code null}.
|
||||
*/
|
||||
public abstract String getWelcomeMsg();
|
||||
|
||||
/**
|
||||
* Returns the last reply code sent by the server.
|
||||
*
|
||||
* @return the lastReplyCode or {@code null} if none were received yet.
|
||||
*/
|
||||
public abstract FtpReplyCode getLastReplyCode();
|
||||
|
||||
/**
|
||||
* Returns the last response string sent by the server.
|
||||
*
|
||||
* @return the message string, which can be quite long, last returned
|
||||
* by the server, or {@code null} if no response were received yet.
|
||||
*/
|
||||
public abstract String getLastResponseString();
|
||||
|
||||
/**
|
||||
* Returns, when available, the size of the latest started transfer.
|
||||
* This is retreived by parsing the response string received as an initial
|
||||
* response to a {@code RETR} or similar request.
|
||||
*
|
||||
* @return the size of the latest transfer or -1 if either there was no
|
||||
* transfer or the information was unavailable.
|
||||
*/
|
||||
public abstract long getLastTransferSize();
|
||||
|
||||
/**
|
||||
* Returns, when available, the remote name of the last transfered file.
|
||||
* This is mainly useful for "put" operation when the unique flag was
|
||||
* set since it allows to recover the unique file name created on the
|
||||
* server which may be different from the one submitted with the command.
|
||||
*
|
||||
* @return the name the latest transfered file remote name, or
|
||||
* {@code null} if that information is unavailable.
|
||||
*/
|
||||
public abstract String getLastFileName();
|
||||
|
||||
/**
|
||||
* Attempts to switch to a secure, encrypted connection. This is done by
|
||||
* sending the {@code AUTH TLS} command.
|
||||
* <p>See <a href="http://www.ietf.org/rfc/rfc4217.txt">RFC 4217</a></p>
|
||||
* If successful this will establish a secure command channel with the
|
||||
* server, it will also make it so that all other transfers (e.g. a RETR
|
||||
* command) will be done over an encrypted channel as well unless a
|
||||
* {@link #reInit()} command or a {@link #endSecureSession()} command is issued.
|
||||
* <p>This method should be called after a successful {@link #connect(java.net.InetSocketAddress) }
|
||||
* but before calling {@link #login(java.lang.String, char[]) }.</p>
|
||||
*
|
||||
* @return this FtpCLient
|
||||
* @throws IOException if an error occurred during the transmission.
|
||||
* @throws FtpProtocolException if the command was rejected by the server
|
||||
* @see #endSecureSession()
|
||||
*/
|
||||
public abstract FtpClient startSecureSession() throws FtpProtocolException, IOException;
|
||||
|
||||
/**
|
||||
* Sends a {@code CCC} command followed by a {@code PROT C}
|
||||
* command to the server terminating an encrypted session and reverting
|
||||
* back to a non encrypted transmission.
|
||||
*
|
||||
* @return this FtpClient
|
||||
* @throws IOException if an error occurred during transmission.
|
||||
* @throws FtpProtocolException if the command was rejected by the server
|
||||
* @see #startSecureSession()
|
||||
*/
|
||||
public abstract FtpClient endSecureSession() throws FtpProtocolException, IOException;
|
||||
|
||||
/**
|
||||
* Sends the "Allocate" ({@code ALLO}) command to the server telling it to
|
||||
* pre-allocate the specified number of bytes for the next transfer.
|
||||
*
|
||||
* @param size The number of bytes to allocate.
|
||||
* @return this FtpClient
|
||||
* @throws IOException if an error occurred during the transmission.
|
||||
* @throws FtpProtocolException if the command was rejected by the server
|
||||
*/
|
||||
public abstract FtpClient allocate(long size) throws FtpProtocolException, IOException;
|
||||
|
||||
/**
|
||||
* Sends the "Structure Mount" ({@code SMNT}) command to the server. This let the
|
||||
* user mount a different file system data structure without altering his
|
||||
* login or accounting information.
|
||||
*
|
||||
* @param struct a {@code String} containing the name of the
|
||||
* structure to mount.
|
||||
* @return this FtpClient
|
||||
* @throws IOException if an error occurred during the transmission.
|
||||
* @throws FtpProtocolException if the command was rejected by the server
|
||||
*/
|
||||
public abstract FtpClient structureMount(String struct) throws FtpProtocolException, IOException;
|
||||
|
||||
/**
|
||||
* Sends a System ({@code SYST}) command to the server and returns the String
|
||||
* sent back by the server describing the operating system at the
|
||||
* server.
|
||||
*
|
||||
* @return a {@code String} describing the OS, or {@code null}
|
||||
* if the operation was not successful.
|
||||
* @throws IOException if an error occurred during the transmission.
|
||||
* @throws FtpProtocolException if the command was rejected by the server
|
||||
*/
|
||||
public abstract String getSystem() throws FtpProtocolException, IOException;
|
||||
|
||||
/**
|
||||
* Sends the {@code HELP} command to the server, with an optional command, like
|
||||
* SITE, and returns the text sent back by the server.
|
||||
*
|
||||
* @param cmd the command for which the help is requested or
|
||||
* {@code null} for the general help
|
||||
* @return a {@code String} containing the text sent back by the
|
||||
* server, or {@code null} if the command failed.
|
||||
* @throws IOException if an error occurred during transmission
|
||||
* @throws FtpProtocolException if the command was rejected by the server
|
||||
*/
|
||||
public abstract String getHelp(String cmd) throws FtpProtocolException, IOException;
|
||||
|
||||
/**
|
||||
* Sends the {@code SITE} command to the server. This is used by the server
|
||||
* to provide services specific to his system that are essential
|
||||
* to file transfer.
|
||||
*
|
||||
* @param cmd the command to be sent.
|
||||
* @return this FtpClient
|
||||
* @throws IOException if an error occurred during transmission
|
||||
* @throws FtpProtocolException if the command was rejected by the server
|
||||
*/
|
||||
public abstract FtpClient siteCmd(String cmd) throws FtpProtocolException, IOException;
|
||||
}
|
||||
157
jdkSrc/jdk8/sun/net/ftp/FtpClientProvider.java
Normal file
157
jdkSrc/jdk8/sun/net/ftp/FtpClientProvider.java
Normal file
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Copyright (c) 2009, 2011, 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 sun.net.ftp;
|
||||
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.ServiceConfigurationError;
|
||||
//import java.util.ServiceLoader;
|
||||
|
||||
/**
|
||||
* Service provider class for FtpClient.
|
||||
* Sub-classes of FtpClientProvider provide an implementation of {@link FtpClient}
|
||||
* and associated classes. Applications do not normally use this class directly.
|
||||
* See {@link #provider() } for how providers are found and loaded.
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
public abstract class FtpClientProvider {
|
||||
|
||||
/**
|
||||
* Creates a FtpClient from this provider.
|
||||
*
|
||||
* @return The created {@link FtpClient}.
|
||||
*/
|
||||
public abstract FtpClient createFtpClient();
|
||||
private static final Object lock = new Object();
|
||||
private static FtpClientProvider provider = null;
|
||||
|
||||
/**
|
||||
* Initializes a new instance of this class.
|
||||
*
|
||||
* @throws SecurityException if a security manager is installed and it denies
|
||||
* {@link RuntimePermission}<tt>("ftpClientProvider")</tt>
|
||||
*/
|
||||
protected FtpClientProvider() {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
sm.checkPermission(new RuntimePermission("ftpClientProvider"));
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean loadProviderFromProperty() {
|
||||
String cm = System.getProperty("sun.net.ftpClientProvider");
|
||||
if (cm == null) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
Class<?> c = Class.forName(cm, true, null);
|
||||
provider = (FtpClientProvider) c.newInstance();
|
||||
return true;
|
||||
} catch (ClassNotFoundException |
|
||||
IllegalAccessException |
|
||||
InstantiationException |
|
||||
SecurityException x) {
|
||||
throw new ServiceConfigurationError(x.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean loadProviderAsService() {
|
||||
// Iterator<FtpClientProvider> i =
|
||||
// ServiceLoader.load(FtpClientProvider.class,
|
||||
// ClassLoader.getSystemClassLoader()).iterator();
|
||||
//
|
||||
// while (i.hasNext()) {
|
||||
// try {
|
||||
// provider = i.next();
|
||||
// return true;
|
||||
// } catch (ServiceConfigurationError sce) {
|
||||
// if (sce.getCause() instanceof SecurityException) {
|
||||
// // Ignore, try next provider, if any
|
||||
// continue;
|
||||
// }
|
||||
// throw sce;
|
||||
// }
|
||||
// }
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the system wide default FtpClientProvider for this invocation of
|
||||
* the Java virtual machine.
|
||||
*
|
||||
* <p> The first invocation of this method locates the default provider
|
||||
* object as follows: </p>
|
||||
*
|
||||
* <ol>
|
||||
*
|
||||
* <li><p> If the system property
|
||||
* <tt>java.net.FtpClientProvider</tt> is defined then it is
|
||||
* taken to be the fully-qualified name of a concrete provider class.
|
||||
* The class is loaded and instantiated; if this process fails then an
|
||||
* unspecified unchecked error or exception is thrown. </p></li>
|
||||
*
|
||||
* <li><p> If a provider class has been installed in a jar file that is
|
||||
* visible to the system class loader, and that jar file contains a
|
||||
* provider-configuration file named
|
||||
* <tt>java.net.FtpClientProvider</tt> in the resource
|
||||
* directory <tt>META-INF/services</tt>, then the first class name
|
||||
* specified in that file is taken. The class is loaded and
|
||||
* instantiated; if this process fails then an unspecified unchecked error or exception is
|
||||
* thrown. </p></li>
|
||||
*
|
||||
* <li><p> Finally, if no provider has been specified by any of the above
|
||||
* means then the system-default provider class is instantiated and the
|
||||
* result is returned. </p></li>
|
||||
*
|
||||
* </ol>
|
||||
*
|
||||
* <p> Subsequent invocations of this method return the provider that was
|
||||
* returned by the first invocation. </p>
|
||||
*
|
||||
* @return The system-wide default FtpClientProvider
|
||||
*/
|
||||
public static FtpClientProvider provider() {
|
||||
synchronized (lock) {
|
||||
if (provider != null) {
|
||||
return provider;
|
||||
}
|
||||
return (FtpClientProvider) AccessController.doPrivileged(
|
||||
new PrivilegedAction<Object>() {
|
||||
|
||||
public Object run() {
|
||||
if (loadProviderFromProperty()) {
|
||||
return provider;
|
||||
}
|
||||
if (loadProviderAsService()) {
|
||||
return provider;
|
||||
}
|
||||
provider = new sun.net.ftp.impl.DefaultFtpClientProvider();
|
||||
return provider;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
331
jdkSrc/jdk8/sun/net/ftp/FtpDirEntry.java
Normal file
331
jdkSrc/jdk8/sun/net/ftp/FtpDirEntry.java
Normal file
@@ -0,0 +1,331 @@
|
||||
/*
|
||||
* Copyright (c) 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 sun.net.ftp;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* A {@code FtpDirEntry} is a class agregating all the information that the FTP client
|
||||
* can gather from the server by doing a {@code LST} (or {@code NLST}) command and
|
||||
* parsing the output. It will typically contain the name, type, size, last modification
|
||||
* time, owner and group of the file, although some of these could be unavailable
|
||||
* due to specific FTP server limitations.
|
||||
*
|
||||
* @see sun.net.ftp.FtpDirParser
|
||||
* @since 1.7
|
||||
*/
|
||||
public class FtpDirEntry {
|
||||
|
||||
public enum Type {
|
||||
|
||||
FILE, DIR, PDIR, CDIR, LINK
|
||||
};
|
||||
|
||||
public enum Permission {
|
||||
|
||||
USER(0), GROUP(1), OTHERS(2);
|
||||
int value;
|
||||
|
||||
Permission(int v) {
|
||||
value = v;
|
||||
}
|
||||
};
|
||||
private final String name;
|
||||
private String user = null;
|
||||
private String group = null;
|
||||
private long size = -1;
|
||||
private java.util.Date created = null;
|
||||
private java.util.Date lastModified = null;
|
||||
private Type type = Type.FILE;
|
||||
private boolean[][] permissions = null;
|
||||
private HashMap<String, String> facts = new HashMap<String, String>();
|
||||
|
||||
private FtpDirEntry() {
|
||||
name = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an FtpDirEntry instance with only the name being set.
|
||||
*
|
||||
* @param name The name of the file
|
||||
*/
|
||||
public FtpDirEntry(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the remote file.
|
||||
*
|
||||
* @return a {@code String} containing the name of the remote file.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the user name of the owner of the file as returned by the FTP
|
||||
* server, if provided. This could be a name or a user id (number).
|
||||
*
|
||||
* @return a {@code String} containing the user name or
|
||||
* {@code null} if that information is not available.
|
||||
*/
|
||||
public String getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the user name of the owner of the file. Intended mostly to be
|
||||
* used from inside a {@link java.net.FtpDirParser} implementation.
|
||||
*
|
||||
* @param user The user name of the owner of the file, or {@code null}
|
||||
* if that information is not available.
|
||||
* @return this FtpDirEntry
|
||||
*/
|
||||
public FtpDirEntry setUser(String user) {
|
||||
this.user = user;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the group name of the file as returned by the FTP
|
||||
* server, if provided. This could be a name or a group id (number).
|
||||
*
|
||||
* @return a {@code String} containing the group name or
|
||||
* {@code null} if that information is not available.
|
||||
*/
|
||||
public String getGroup() {
|
||||
return group;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name of the group to which the file belong. Intended mostly to be
|
||||
* used from inside a {@link java.net.FtpDirParser} implementation.
|
||||
*
|
||||
* @param group The name of the group to which the file belong, or {@code null}
|
||||
* if that information is not available.
|
||||
* @return this FtpDirEntry
|
||||
*/
|
||||
public FtpDirEntry setGroup(String group) {
|
||||
this.group = group;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of the remote file as it was returned by the FTP
|
||||
* server, if provided.
|
||||
*
|
||||
* @return the size of the file or -1 if that information is not available.
|
||||
*/
|
||||
public long getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the size of that file. Intended mostly to be used from inside an
|
||||
* {@link java.net.FtpDirParser} implementation.
|
||||
*
|
||||
* @param size The size, in bytes, of that file. or -1 if unknown.
|
||||
* @return this FtpDirEntry
|
||||
*/
|
||||
public FtpDirEntry setSize(long size) {
|
||||
this.size = size;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of the remote file as it was returned by the FTP
|
||||
* server, if provided.
|
||||
* It returns a FtpDirEntry.Type enum and the values can be:
|
||||
* - FtpDirEntry.Type.FILE for a normal file
|
||||
* - FtpDirEntry.Type.DIR for a directory
|
||||
* - FtpDirEntry.Type.LINK for a symbolic link
|
||||
*
|
||||
* @return a {@code FtpDirEntry.Type} describing the type of the file
|
||||
* or {@code null} if that information is not available.
|
||||
*/
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the type of the file. Intended mostly to be used from inside an
|
||||
* {@link java.net.FtpDirParser} implementation.
|
||||
*
|
||||
* @param type the type of this file or {@code null} if that information
|
||||
* is not available.
|
||||
* @return this FtpDirEntry
|
||||
*/
|
||||
public FtpDirEntry setType(Type type) {
|
||||
this.type = type;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last modification time of the remote file as it was returned
|
||||
* by the FTP server, if provided, {@code null} otherwise.
|
||||
*
|
||||
* @return a <code>Date</code> representing the last time the file was
|
||||
* modified on the server, or {@code null} if that
|
||||
* information is not available.
|
||||
*/
|
||||
public java.util.Date getLastModified() {
|
||||
return this.lastModified;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the last modification time of the file. Intended mostly to be used
|
||||
* from inside an {@link java.net.FtpDirParser} implementation.
|
||||
*
|
||||
* @param lastModified The Date representing the last modification time, or
|
||||
* {@code null} if that information is not available.
|
||||
* @return this FtpDirEntry
|
||||
*/
|
||||
public FtpDirEntry setLastModified(Date lastModified) {
|
||||
this.lastModified = lastModified;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether read access is granted for a specific permission.
|
||||
*
|
||||
* @param p the Permission (user, group, others) to check.
|
||||
* @return {@code true} if read access is granted.
|
||||
*/
|
||||
public boolean canRead(Permission p) {
|
||||
if (permissions != null) {
|
||||
return permissions[p.value][0];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether write access is granted for a specific permission.
|
||||
*
|
||||
* @param p the Permission (user, group, others) to check.
|
||||
* @return {@code true} if write access is granted.
|
||||
*/
|
||||
public boolean canWrite(Permission p) {
|
||||
if (permissions != null) {
|
||||
return permissions[p.value][1];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether execute access is granted for a specific permission.
|
||||
*
|
||||
* @param p the Permission (user, group, others) to check.
|
||||
* @return {@code true} if execute access is granted.
|
||||
*/
|
||||
public boolean canExexcute(Permission p) {
|
||||
if (permissions != null) {
|
||||
return permissions[p.value][2];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the permissions for that file. Intended mostly to be used
|
||||
* from inside an {@link java.net.FtpDirParser} implementation.
|
||||
* The permissions array is a 3x3 {@code boolean} array, the first index being
|
||||
* the User, group or owner (0, 1 and 2 respectively) while the second
|
||||
* index is read, write or execute (0, 1 and 2 respectively again).
|
||||
* <p>E.G.: {@code permissions[1][2]} is the group/execute permission.</p>
|
||||
*
|
||||
* @param permissions a 3x3 {@code boolean} array
|
||||
* @return this {@code FtpDirEntry}
|
||||
*/
|
||||
public FtpDirEntry setPermissions(boolean[][] permissions) {
|
||||
this.permissions = permissions;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a 'fact', as defined in RFC 3659, to the list of facts of this file.
|
||||
* Intended mostly to be used from inside a {@link java.net.FtpDirParser}
|
||||
* implementation.
|
||||
*
|
||||
* @param fact the name of the fact (e.g. "Media-Type"). It is not case-sensitive.
|
||||
* @param value the value associated with this fact.
|
||||
* @return this {@code FtpDirEntry}
|
||||
*/
|
||||
public FtpDirEntry addFact(String fact, String value) {
|
||||
facts.put(fact.toLowerCase(), value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested 'fact', as defined in RFC 3659, if available.
|
||||
*
|
||||
* @param fact The name of the fact *e.g. "Media-Type"). It is not case sensitive.
|
||||
* @return The value of the fact or, {@code null} if that fact wasn't
|
||||
* provided by the server.
|
||||
*/
|
||||
public String getFact(String fact) {
|
||||
return facts.get(fact.toLowerCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the creation time of the file, when provided by the server.
|
||||
*
|
||||
* @return The Date representing the creation time, or {@code null}
|
||||
* if the server didn't provide that information.
|
||||
*/
|
||||
public Date getCreated() {
|
||||
return created;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the creation time for that file. Intended mostly to be used from
|
||||
* inside a {@link java.net.FtpDirParser} implementation.
|
||||
*
|
||||
* @param created the Date representing the creation time for that file, or
|
||||
* {@code null} if that information is not available.
|
||||
* @return this FtpDirEntry
|
||||
*/
|
||||
public FtpDirEntry setCreated(Date created) {
|
||||
this.created = created;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of the object.
|
||||
* The {@code toString} method for class {@code FtpDirEntry}
|
||||
* returns a string consisting of the name of the file, followed by its
|
||||
* type between brackets, followed by the user and group between
|
||||
* parenthesis, then size between '{', and, finally, the lastModified of last
|
||||
* modification if it's available.
|
||||
*
|
||||
* @return a string representation of the object.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
if (lastModified == null) {
|
||||
return name + " [" + type + "] (" + user + " / " + group + ") " + size;
|
||||
}
|
||||
return name + " [" + type + "] (" + user + " / " + group + ") {" + size + "} " + java.text.DateFormat.getDateInstance().format(lastModified);
|
||||
}
|
||||
}
|
||||
49
jdkSrc/jdk8/sun/net/ftp/FtpDirParser.java
Normal file
49
jdkSrc/jdk8/sun/net/ftp/FtpDirParser.java
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 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 sun.net.ftp;
|
||||
|
||||
/**
|
||||
* This interface describes a parser for the FtpClient class. Such a parser is
|
||||
* used when listing a remote directory to transform text lines like:
|
||||
* drwxr-xr-x 1 user01 ftp 512 Jan 29 23:32 prog
|
||||
* into FtpDirEntry instances.
|
||||
*
|
||||
* @see java.net.FtpClient#setFileParser(FtpDirParser)
|
||||
* @since 1.7
|
||||
*/
|
||||
public interface FtpDirParser {
|
||||
|
||||
/**
|
||||
* Takes one line from a directory listing and returns an FtpDirEntry instance
|
||||
* based on the information contained.
|
||||
*
|
||||
* @param line a <code>String</code>, a line sent by the FTP server as a
|
||||
* result of the LST command.
|
||||
* @return an <code>FtpDirEntry</code> instance.
|
||||
* @see java.net.FtpDirEntry
|
||||
*/
|
||||
public FtpDirEntry parseLine(String line);
|
||||
}
|
||||
42
jdkSrc/jdk8/sun/net/ftp/FtpLoginException.java
Normal file
42
jdkSrc/jdk8/sun/net/ftp/FtpLoginException.java
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 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 sun.net.ftp;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* This exception is thrown when an error is encountered during an
|
||||
* FTP login operation.
|
||||
*
|
||||
* @author Jonathan Payne
|
||||
*/
|
||||
public class FtpLoginException extends IOException {
|
||||
private static final long serialVersionUID = 2218162403237941536L;
|
||||
|
||||
public FtpLoginException(String s) {
|
||||
super(s);
|
||||
}
|
||||
}
|
||||
70
jdkSrc/jdk8/sun/net/ftp/FtpProtocolException.java
Normal file
70
jdkSrc/jdk8/sun/net/ftp/FtpProtocolException.java
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 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 sun.net.ftp;
|
||||
|
||||
/**
|
||||
* Thrown to indicate that the FTP server reported an error.
|
||||
* For instance that the requested file doesn't exist or
|
||||
* that a command isn't supported.
|
||||
* <p>The specific error code can be retreived with {@link #getReplyCode() }.</p>
|
||||
* @author Jonathan Payne
|
||||
*/
|
||||
public class FtpProtocolException extends Exception {
|
||||
private static final long serialVersionUID = 5978077070276545054L;
|
||||
private final FtpReplyCode code;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code FtpProtocolException} from the
|
||||
* specified detail message. The reply code is set to unknow error.
|
||||
*
|
||||
* @param detail the detail message.
|
||||
*/
|
||||
public FtpProtocolException(String detail) {
|
||||
super(detail);
|
||||
code = FtpReplyCode.UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code FtpProtocolException} from the
|
||||
* specified response code and exception detail message
|
||||
*
|
||||
* @param detail the detail message.
|
||||
* @param code The {@code FtpRelyCode} received from server.
|
||||
*/
|
||||
public FtpProtocolException(String detail, FtpReplyCode code) {
|
||||
super(detail);
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the reply code sent by the server that led to this exception
|
||||
* being thrown.
|
||||
*
|
||||
* @return The {@link FtpReplyCode} associated with that exception.
|
||||
*/
|
||||
public FtpReplyCode getReplyCode() {
|
||||
return code;
|
||||
}
|
||||
}
|
||||
248
jdkSrc/jdk8/sun/net/ftp/FtpReplyCode.java
Normal file
248
jdkSrc/jdk8/sun/net/ftp/FtpReplyCode.java
Normal file
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
* Copyright (c) 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 sun.net.ftp;
|
||||
|
||||
/**
|
||||
* This class describes a FTP protocol reply code and associates a meaning
|
||||
* to the numerical value according to the various RFCs (RFC 959 in
|
||||
* particular).
|
||||
*
|
||||
*/
|
||||
public enum FtpReplyCode {
|
||||
|
||||
RESTART_MARKER(110),
|
||||
SERVICE_READY_IN(120),
|
||||
DATA_CONNECTION_ALREADY_OPEN(125),
|
||||
FILE_STATUS_OK(150),
|
||||
COMMAND_OK(200),
|
||||
NOT_IMPLEMENTED(202),
|
||||
SYSTEM_STATUS(211),
|
||||
DIRECTORY_STATUS(212),
|
||||
FILE_STATUS(213),
|
||||
HELP_MESSAGE(214),
|
||||
NAME_SYSTEM_TYPE(215),
|
||||
SERVICE_READY(220),
|
||||
SERVICE_CLOSING(221),
|
||||
DATA_CONNECTION_OPEN(225),
|
||||
CLOSING_DATA_CONNECTION(226),
|
||||
ENTERING_PASSIVE_MODE(227),
|
||||
ENTERING_EXT_PASSIVE_MODE(229),
|
||||
LOGGED_IN(230),
|
||||
SECURELY_LOGGED_IN(232),
|
||||
SECURITY_EXCHANGE_OK(234),
|
||||
SECURITY_EXCHANGE_COMPLETE(235),
|
||||
FILE_ACTION_OK(250),
|
||||
PATHNAME_CREATED(257),
|
||||
NEED_PASSWORD(331),
|
||||
NEED_ACCOUNT(332),
|
||||
NEED_ADAT(334),
|
||||
NEED_MORE_ADAT(335),
|
||||
FILE_ACTION_PENDING(350),
|
||||
SERVICE_NOT_AVAILABLE(421),
|
||||
CANT_OPEN_DATA_CONNECTION(425),
|
||||
CONNECTION_CLOSED(426),
|
||||
NEED_SECURITY_RESOURCE(431),
|
||||
FILE_ACTION_NOT_TAKEN(450),
|
||||
ACTION_ABORTED(451),
|
||||
INSUFFICIENT_STORAGE(452),
|
||||
COMMAND_UNRECOGNIZED(500),
|
||||
INVALID_PARAMETER(501),
|
||||
BAD_SEQUENCE(503),
|
||||
NOT_IMPLEMENTED_FOR_PARAMETER(504),
|
||||
NOT_LOGGED_IN(530),
|
||||
NEED_ACCOUNT_FOR_STORING(532),
|
||||
PROT_LEVEL_DENIED(533),
|
||||
REQUEST_DENIED(534),
|
||||
FAILED_SECURITY_CHECK(535),
|
||||
UNSUPPORTED_PROT_LEVEL(536),
|
||||
PROT_LEVEL_NOT_SUPPORTED_BY_SECURITY(537),
|
||||
FILE_UNAVAILABLE(550),
|
||||
PAGE_TYPE_UNKNOWN(551),
|
||||
EXCEEDED_STORAGE(552),
|
||||
FILE_NAME_NOT_ALLOWED(553),
|
||||
PROTECTED_REPLY(631),
|
||||
UNKNOWN_ERROR(999);
|
||||
private final int value;
|
||||
|
||||
FtpReplyCode(int val) {
|
||||
this.value = val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the numerical value of the code.
|
||||
*
|
||||
* @return the numerical value.
|
||||
*/
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the code is a Positive Preliminary response.
|
||||
* This means beginning with a 1 (which means a value between 100 and 199)
|
||||
*
|
||||
* @return <code>true</code> if the reply code is a positive preliminary
|
||||
* response.
|
||||
*/
|
||||
public boolean isPositivePreliminary() {
|
||||
return value >= 100 && value < 200;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the code is a Positive Completion response.
|
||||
* This means beginning with a 2 (which means a value between 200 and 299)
|
||||
*
|
||||
* @return <code>true</code> if the reply code is a positive completion
|
||||
* response.
|
||||
*/
|
||||
public boolean isPositiveCompletion() {
|
||||
return value >= 200 && value < 300;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the code is a positive internediate response.
|
||||
* This means beginning with a 3 (which means a value between 300 and 399)
|
||||
*
|
||||
* @return <code>true</code> if the reply code is a positive intermediate
|
||||
* response.
|
||||
*/
|
||||
public boolean isPositiveIntermediate() {
|
||||
return value >= 300 && value < 400;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the code is a transient negative response.
|
||||
* This means beginning with a 4 (which means a value between 400 and 499)
|
||||
*
|
||||
* @return <code>true</code> if the reply code is a transient negative
|
||||
* response.
|
||||
*/
|
||||
public boolean isTransientNegative() {
|
||||
return value >= 400 && value < 500;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the code is a permanent negative response.
|
||||
* This means beginning with a 5 (which means a value between 500 and 599)
|
||||
*
|
||||
* @return <code>true</code> if the reply code is a permanent negative
|
||||
* response.
|
||||
*/
|
||||
public boolean isPermanentNegative() {
|
||||
return value >= 500 && value < 600;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the code is a protected reply response.
|
||||
* This means beginning with a 6 (which means a value between 600 and 699)
|
||||
*
|
||||
* @return <code>true</code> if the reply code is a protected reply
|
||||
* response.
|
||||
*/
|
||||
public boolean isProtectedReply() {
|
||||
return value >= 600 && value < 700;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the code is a syntax related response.
|
||||
* This means the second digit is a 0.
|
||||
*
|
||||
* @return <code>true</code> if the reply code is a syntax related
|
||||
* response.
|
||||
*/
|
||||
public boolean isSyntax() {
|
||||
return ((value / 10) - ((value / 100) * 10)) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the code is an information related response.
|
||||
* This means the second digit is a 1.
|
||||
*
|
||||
* @return <code>true</code> if the reply code is an information related
|
||||
* response.
|
||||
*/
|
||||
public boolean isInformation() {
|
||||
return ((value / 10) - ((value / 100) * 10)) == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the code is a connection related response.
|
||||
* This means the second digit is a 2.
|
||||
*
|
||||
* @return <code>true</code> if the reply code is a connection related
|
||||
* response.
|
||||
*/
|
||||
public boolean isConnection() {
|
||||
return ((value / 10) - ((value / 100) * 10)) == 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the code is an authentication related response.
|
||||
* This means the second digit is a 3.
|
||||
*
|
||||
* @return <code>true</code> if the reply code is an authentication related
|
||||
* response.
|
||||
*/
|
||||
public boolean isAuthentication() {
|
||||
return ((value / 10) - ((value / 100) * 10)) == 3;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the code is an unspecified type of response.
|
||||
* This means the second digit is a 4.
|
||||
*
|
||||
* @return <code>true</code> if the reply code is an unspecified type of
|
||||
* response.
|
||||
*/
|
||||
public boolean isUnspecified() {
|
||||
return ((value / 10) - ((value / 100) * 10)) == 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the code is a file system related response.
|
||||
* This means the second digit is a 5.
|
||||
*
|
||||
* @return <code>true</code> if the reply code is a file system related
|
||||
* response.
|
||||
*/
|
||||
public boolean isFileSystem() {
|
||||
return ((value / 10) - ((value / 100) * 10)) == 5;
|
||||
}
|
||||
|
||||
/**
|
||||
* Static utility method to convert a value into a FtpReplyCode.
|
||||
*
|
||||
* @param v the value to convert
|
||||
* @return the <code>FtpReplyCode</code> associated with the value.
|
||||
*/
|
||||
public static FtpReplyCode find(int v) {
|
||||
for (FtpReplyCode code : FtpReplyCode.values()) {
|
||||
if (code.getValue() == v) {
|
||||
return code;
|
||||
}
|
||||
}
|
||||
return UNKNOWN_ERROR;
|
||||
}
|
||||
}
|
||||
38
jdkSrc/jdk8/sun/net/ftp/impl/DefaultFtpClientProvider.java
Normal file
38
jdkSrc/jdk8/sun/net/ftp/impl/DefaultFtpClientProvider.java
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 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 sun.net.ftp.impl;
|
||||
|
||||
/**
|
||||
* Default FtpClientProvider.
|
||||
* Uses sun.net.ftp.FtpCLient.
|
||||
*/
|
||||
public class DefaultFtpClientProvider extends sun.net.ftp.FtpClientProvider {
|
||||
|
||||
@Override
|
||||
public sun.net.ftp.FtpClient createFtpClient() {
|
||||
return sun.net.ftp.impl.FtpClient.create();
|
||||
}
|
||||
|
||||
}
|
||||
2331
jdkSrc/jdk8/sun/net/ftp/impl/FtpClient.java
Normal file
2331
jdkSrc/jdk8/sun/net/ftp/impl/FtpClient.java
Normal file
File diff suppressed because it is too large
Load Diff
86
jdkSrc/jdk8/sun/net/httpserver/AuthFilter.java
Normal file
86
jdkSrc/jdk8/sun/net/httpserver/AuthFilter.java
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2006, 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 sun.net.httpserver;
|
||||
|
||||
import com.sun.net.httpserver.*;
|
||||
import java.io.*;
|
||||
import java.nio.*;
|
||||
import java.nio.channels.*;
|
||||
import sun.net.www.MessageHeader;
|
||||
import java.util.*;
|
||||
import javax.security.auth.*;
|
||||
import javax.security.auth.callback.*;
|
||||
import javax.security.auth.login.*;
|
||||
|
||||
public class AuthFilter extends Filter {
|
||||
|
||||
private Authenticator authenticator;
|
||||
|
||||
public AuthFilter (Authenticator authenticator) {
|
||||
this.authenticator = authenticator;
|
||||
}
|
||||
|
||||
public String description () {
|
||||
return "Authentication filter";
|
||||
}
|
||||
|
||||
public void setAuthenticator (Authenticator a) {
|
||||
authenticator = a;
|
||||
}
|
||||
|
||||
public void consumeInput (HttpExchange t) throws IOException {
|
||||
InputStream i = t.getRequestBody();
|
||||
byte[] b = new byte [4096];
|
||||
while (i.read (b) != -1);
|
||||
i.close ();
|
||||
}
|
||||
|
||||
/**
|
||||
* The filter's implementation, which is invoked by the server
|
||||
*/
|
||||
public void doFilter (HttpExchange t, Filter.Chain chain) throws IOException
|
||||
{
|
||||
if (authenticator != null) {
|
||||
Authenticator.Result r = authenticator.authenticate (t);
|
||||
if (r instanceof Authenticator.Success) {
|
||||
Authenticator.Success s = (Authenticator.Success)r;
|
||||
ExchangeImpl e = ExchangeImpl.get (t);
|
||||
e.setPrincipal (s.getPrincipal());
|
||||
chain.doFilter (t);
|
||||
} else if (r instanceof Authenticator.Retry) {
|
||||
Authenticator.Retry ry = (Authenticator.Retry)r;
|
||||
consumeInput (t);
|
||||
t.sendResponseHeaders (ry.getResponseCode(), -1);
|
||||
} else if (r instanceof Authenticator.Failure) {
|
||||
Authenticator.Failure f = (Authenticator.Failure)r;
|
||||
consumeInput (t);
|
||||
t.sendResponseHeaders (f.getResponseCode(), -1);
|
||||
}
|
||||
} else {
|
||||
chain.doFilter (t);
|
||||
}
|
||||
}
|
||||
}
|
||||
186
jdkSrc/jdk8/sun/net/httpserver/ChunkedInputStream.java
Normal file
186
jdkSrc/jdk8/sun/net/httpserver/ChunkedInputStream.java
Normal file
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2017, 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 sun.net.httpserver;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import com.sun.net.httpserver.*;
|
||||
import com.sun.net.httpserver.spi.*;
|
||||
|
||||
class ChunkedInputStream extends LeftOverInputStream {
|
||||
ChunkedInputStream (ExchangeImpl t, InputStream src) {
|
||||
super (t, src);
|
||||
}
|
||||
|
||||
private int remaining;
|
||||
|
||||
/* true when a chunk header needs to be read */
|
||||
|
||||
private boolean needToReadHeader = true;
|
||||
|
||||
final static char CR = '\r';
|
||||
final static char LF = '\n';
|
||||
/*
|
||||
* Maximum chunk header size of 2KB + 2 bytes for CRLF
|
||||
*/
|
||||
private final static int MAX_CHUNK_HEADER_SIZE = 2050;
|
||||
|
||||
private int numeric (char[] arr, int nchars) throws IOException {
|
||||
assert arr.length >= nchars;
|
||||
int len = 0;
|
||||
for (int i=0; i<nchars; i++) {
|
||||
char c = arr[i];
|
||||
int val=0;
|
||||
if (c>='0' && c <='9') {
|
||||
val = c - '0';
|
||||
} else if (c>='a' && c<= 'f') {
|
||||
val = c - 'a' + 10;
|
||||
} else if (c>='A' && c<= 'F') {
|
||||
val = c - 'A' + 10;
|
||||
} else {
|
||||
throw new IOException ("invalid chunk length");
|
||||
}
|
||||
len = len * 16 + val;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
/* read the chunk header line and return the chunk length
|
||||
* any chunk extensions are ignored
|
||||
*/
|
||||
private int readChunkHeader () throws IOException {
|
||||
boolean gotCR = false;
|
||||
int c;
|
||||
char[] len_arr = new char [16];
|
||||
int len_size = 0;
|
||||
boolean end_of_len = false;
|
||||
int read = 0;
|
||||
|
||||
while ((c=in.read())!= -1) {
|
||||
char ch = (char) c;
|
||||
read++;
|
||||
if ((len_size == len_arr.length -1) ||
|
||||
(read > MAX_CHUNK_HEADER_SIZE))
|
||||
{
|
||||
throw new IOException ("invalid chunk header");
|
||||
}
|
||||
if (gotCR) {
|
||||
if (ch == LF) {
|
||||
int l = numeric (len_arr, len_size);
|
||||
return l;
|
||||
} else {
|
||||
gotCR = false;
|
||||
}
|
||||
if (!end_of_len) {
|
||||
len_arr[len_size++] = ch;
|
||||
}
|
||||
} else {
|
||||
if (ch == CR) {
|
||||
gotCR = true;
|
||||
} else if (ch == ';') {
|
||||
end_of_len = true;
|
||||
} else if (!end_of_len) {
|
||||
len_arr[len_size++] = ch;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new IOException ("end of stream reading chunk header");
|
||||
}
|
||||
|
||||
protected int readImpl (byte[]b, int off, int len) throws IOException {
|
||||
if (eof) {
|
||||
return -1;
|
||||
}
|
||||
if (needToReadHeader) {
|
||||
remaining = readChunkHeader();
|
||||
if (remaining == 0) {
|
||||
eof = true;
|
||||
consumeCRLF();
|
||||
t.getServerImpl().requestCompleted (t.getConnection());
|
||||
return -1;
|
||||
}
|
||||
needToReadHeader = false;
|
||||
}
|
||||
if (len > remaining) {
|
||||
len = remaining;
|
||||
}
|
||||
int n = in.read(b, off, len);
|
||||
if (n > -1) {
|
||||
remaining -= n;
|
||||
}
|
||||
if (remaining == 0) {
|
||||
needToReadHeader = true;
|
||||
consumeCRLF();
|
||||
}
|
||||
if (n < 0 && !eof)
|
||||
throw new IOException("connection closed before all data received");
|
||||
return n;
|
||||
}
|
||||
|
||||
private void consumeCRLF () throws IOException {
|
||||
char c;
|
||||
c = (char)in.read(); /* CR */
|
||||
if (c != CR) {
|
||||
throw new IOException ("invalid chunk end");
|
||||
}
|
||||
c = (char)in.read(); /* LF */
|
||||
if (c != LF) {
|
||||
throw new IOException ("invalid chunk end");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the number of bytes available to read in the current chunk
|
||||
* which may be less than the real amount, but we'll live with that
|
||||
* limitation for the moment. It only affects potential efficiency
|
||||
* rather than correctness.
|
||||
*/
|
||||
public int available () throws IOException {
|
||||
if (eof || closed) {
|
||||
return 0;
|
||||
}
|
||||
int n = in.available();
|
||||
return n > remaining? remaining: n;
|
||||
}
|
||||
|
||||
/* called after the stream is closed to see if bytes
|
||||
* have been read from the underlying channel
|
||||
* and buffered internally
|
||||
*/
|
||||
public boolean isDataBuffered () throws IOException {
|
||||
assert eof;
|
||||
return in.available() > 0;
|
||||
}
|
||||
|
||||
public boolean markSupported () {return false;}
|
||||
|
||||
public void mark (int l) {
|
||||
}
|
||||
|
||||
public void reset () throws IOException {
|
||||
throw new IOException ("mark/reset not supported");
|
||||
}
|
||||
}
|
||||
163
jdkSrc/jdk8/sun/net/httpserver/ChunkedOutputStream.java
Normal file
163
jdkSrc/jdk8/sun/net/httpserver/ChunkedOutputStream.java
Normal file
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 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 sun.net.httpserver;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import com.sun.net.httpserver.*;
|
||||
import com.sun.net.httpserver.spi.*;
|
||||
|
||||
/**
|
||||
* a class which allows the caller to write an arbitrary
|
||||
* number of bytes to an underlying stream.
|
||||
* normal close() does not close the underlying stream
|
||||
*
|
||||
* This class is buffered.
|
||||
*
|
||||
* Each chunk is written in one go as :-
|
||||
* abcd\r\nxxxxxxxxxxxxxx\r\n
|
||||
*
|
||||
* abcd is the chunk-size, and xxx is the chunk data
|
||||
* If the length is less than 4 chars (in size) then the buffer
|
||||
* is written with an offset.
|
||||
* Final chunk is:
|
||||
* 0\r\n\r\n
|
||||
*/
|
||||
|
||||
class ChunkedOutputStream extends FilterOutputStream
|
||||
{
|
||||
private boolean closed = false;
|
||||
/* max. amount of user data per chunk */
|
||||
final static int CHUNK_SIZE = 4096;
|
||||
/* allow 4 bytes for chunk-size plus 4 for CRLFs */
|
||||
final static int OFFSET = 6; /* initial <=4 bytes for len + CRLF */
|
||||
private int pos = OFFSET;
|
||||
private int count = 0;
|
||||
private byte[] buf = new byte [CHUNK_SIZE+OFFSET+2];
|
||||
ExchangeImpl t;
|
||||
|
||||
ChunkedOutputStream (ExchangeImpl t, OutputStream src) {
|
||||
super (src);
|
||||
this.t = t;
|
||||
}
|
||||
|
||||
public void write (int b) throws IOException {
|
||||
if (closed) {
|
||||
throw new StreamClosedException ();
|
||||
}
|
||||
buf [pos++] = (byte)b;
|
||||
count ++;
|
||||
if (count == CHUNK_SIZE) {
|
||||
writeChunk();
|
||||
}
|
||||
assert count < CHUNK_SIZE;
|
||||
}
|
||||
|
||||
public void write (byte[]b, int off, int len) throws IOException {
|
||||
if (closed) {
|
||||
throw new StreamClosedException ();
|
||||
}
|
||||
int remain = CHUNK_SIZE - count;
|
||||
if (len > remain) {
|
||||
System.arraycopy (b,off,buf,pos,remain);
|
||||
count = CHUNK_SIZE;
|
||||
writeChunk();
|
||||
len -= remain;
|
||||
off += remain;
|
||||
while (len >= CHUNK_SIZE) {
|
||||
System.arraycopy (b,off,buf,OFFSET,CHUNK_SIZE);
|
||||
len -= CHUNK_SIZE;
|
||||
off += CHUNK_SIZE;
|
||||
count = CHUNK_SIZE;
|
||||
writeChunk();
|
||||
}
|
||||
}
|
||||
if (len > 0) {
|
||||
System.arraycopy (b,off,buf,pos,len);
|
||||
count += len;
|
||||
pos += len;
|
||||
}
|
||||
if (count == CHUNK_SIZE) {
|
||||
writeChunk();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* write out a chunk , and reset the pointers
|
||||
* chunk does not have to be CHUNK_SIZE bytes
|
||||
* count must == number of user bytes (<= CHUNK_SIZE)
|
||||
*/
|
||||
private void writeChunk () throws IOException {
|
||||
char[] c = Integer.toHexString (count).toCharArray();
|
||||
int clen = c.length;
|
||||
int startByte = 4 - clen;
|
||||
int i;
|
||||
for (i=0; i<clen; i++) {
|
||||
buf[startByte+i] = (byte)c[i];
|
||||
}
|
||||
buf[startByte + (i++)] = '\r';
|
||||
buf[startByte + (i++)] = '\n';
|
||||
buf[startByte + (i++) + count] = '\r';
|
||||
buf[startByte + (i++) + count] = '\n';
|
||||
out.write (buf, startByte, i+count);
|
||||
count = 0;
|
||||
pos = OFFSET;
|
||||
}
|
||||
|
||||
public void close () throws IOException {
|
||||
if (closed) {
|
||||
return;
|
||||
}
|
||||
flush();
|
||||
try {
|
||||
/* write an empty chunk */
|
||||
writeChunk();
|
||||
out.flush();
|
||||
LeftOverInputStream is = t.getOriginalInputStream();
|
||||
if (!is.isClosed()) {
|
||||
is.close();
|
||||
}
|
||||
/* some clients close the connection before empty chunk is sent */
|
||||
} catch (IOException e) {
|
||||
|
||||
} finally {
|
||||
closed = true;
|
||||
}
|
||||
|
||||
WriteFinishedEvent e = new WriteFinishedEvent (t);
|
||||
t.getHttpContext().getServerImpl().addEvent (e);
|
||||
}
|
||||
|
||||
public void flush () throws IOException {
|
||||
if (closed) {
|
||||
throw new StreamClosedException ();
|
||||
}
|
||||
if (count > 0) {
|
||||
writeChunk();
|
||||
}
|
||||
out.flush();
|
||||
}
|
||||
}
|
||||
109
jdkSrc/jdk8/sun/net/httpserver/Code.java
Normal file
109
jdkSrc/jdk8/sun/net/httpserver/Code.java
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2006, 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 sun.net.httpserver;
|
||||
|
||||
class Code {
|
||||
|
||||
public static final int HTTP_CONTINUE = 100;
|
||||
public static final int HTTP_OK = 200;
|
||||
public static final int HTTP_CREATED = 201;
|
||||
public static final int HTTP_ACCEPTED = 202;
|
||||
public static final int HTTP_NOT_AUTHORITATIVE = 203;
|
||||
public static final int HTTP_NO_CONTENT = 204;
|
||||
public static final int HTTP_RESET = 205;
|
||||
public static final int HTTP_PARTIAL = 206;
|
||||
public static final int HTTP_MULT_CHOICE = 300;
|
||||
public static final int HTTP_MOVED_PERM = 301;
|
||||
public static final int HTTP_MOVED_TEMP = 302;
|
||||
public static final int HTTP_SEE_OTHER = 303;
|
||||
public static final int HTTP_NOT_MODIFIED = 304;
|
||||
public static final int HTTP_USE_PROXY = 305;
|
||||
public static final int HTTP_BAD_REQUEST = 400;
|
||||
public static final int HTTP_UNAUTHORIZED = 401;
|
||||
public static final int HTTP_PAYMENT_REQUIRED = 402;
|
||||
public static final int HTTP_FORBIDDEN = 403;
|
||||
public static final int HTTP_NOT_FOUND = 404;
|
||||
public static final int HTTP_BAD_METHOD = 405;
|
||||
public static final int HTTP_NOT_ACCEPTABLE = 406;
|
||||
public static final int HTTP_PROXY_AUTH = 407;
|
||||
public static final int HTTP_CLIENT_TIMEOUT = 408;
|
||||
public static final int HTTP_CONFLICT = 409;
|
||||
public static final int HTTP_GONE = 410;
|
||||
public static final int HTTP_LENGTH_REQUIRED = 411;
|
||||
public static final int HTTP_PRECON_FAILED = 412;
|
||||
public static final int HTTP_ENTITY_TOO_LARGE = 413;
|
||||
public static final int HTTP_REQ_TOO_LONG = 414;
|
||||
public static final int HTTP_UNSUPPORTED_TYPE = 415;
|
||||
public static final int HTTP_INTERNAL_ERROR = 500;
|
||||
public static final int HTTP_NOT_IMPLEMENTED = 501;
|
||||
public static final int HTTP_BAD_GATEWAY = 502;
|
||||
public static final int HTTP_UNAVAILABLE = 503;
|
||||
public static final int HTTP_GATEWAY_TIMEOUT = 504;
|
||||
public static final int HTTP_VERSION = 505;
|
||||
|
||||
static String msg (int code) {
|
||||
|
||||
switch (code) {
|
||||
case HTTP_OK: return " OK";
|
||||
case HTTP_CONTINUE: return " Continue";
|
||||
case HTTP_CREATED: return " Created";
|
||||
case HTTP_ACCEPTED: return " Accepted";
|
||||
case HTTP_NOT_AUTHORITATIVE: return " Non-Authoritative Information";
|
||||
case HTTP_NO_CONTENT: return " No Content";
|
||||
case HTTP_RESET: return " Reset Content";
|
||||
case HTTP_PARTIAL: return " Partial Content";
|
||||
case HTTP_MULT_CHOICE: return " Multiple Choices";
|
||||
case HTTP_MOVED_PERM: return " Moved Permanently";
|
||||
case HTTP_MOVED_TEMP: return " Temporary Redirect";
|
||||
case HTTP_SEE_OTHER: return " See Other";
|
||||
case HTTP_NOT_MODIFIED: return " Not Modified";
|
||||
case HTTP_USE_PROXY: return " Use Proxy";
|
||||
case HTTP_BAD_REQUEST: return " Bad Request";
|
||||
case HTTP_UNAUTHORIZED: return " Unauthorized" ;
|
||||
case HTTP_PAYMENT_REQUIRED: return " Payment Required";
|
||||
case HTTP_FORBIDDEN: return " Forbidden";
|
||||
case HTTP_NOT_FOUND: return " Not Found";
|
||||
case HTTP_BAD_METHOD: return " Method Not Allowed";
|
||||
case HTTP_NOT_ACCEPTABLE: return " Not Acceptable";
|
||||
case HTTP_PROXY_AUTH: return " Proxy Authentication Required";
|
||||
case HTTP_CLIENT_TIMEOUT: return " Request Time-Out";
|
||||
case HTTP_CONFLICT: return " Conflict";
|
||||
case HTTP_GONE: return " Gone";
|
||||
case HTTP_LENGTH_REQUIRED: return " Length Required";
|
||||
case HTTP_PRECON_FAILED: return " Precondition Failed";
|
||||
case HTTP_ENTITY_TOO_LARGE: return " Request Entity Too Large";
|
||||
case HTTP_REQ_TOO_LONG: return " Request-URI Too Large";
|
||||
case HTTP_UNSUPPORTED_TYPE: return " Unsupported Media Type";
|
||||
case HTTP_INTERNAL_ERROR: return " Internal Server Error";
|
||||
case HTTP_NOT_IMPLEMENTED: return " Not Implemented";
|
||||
case HTTP_BAD_GATEWAY: return " Bad Gateway";
|
||||
case HTTP_UNAVAILABLE: return " Service Unavailable";
|
||||
case HTTP_GATEWAY_TIMEOUT: return " Gateway Timeout";
|
||||
case HTTP_VERSION: return " HTTP Version Not Supported";
|
||||
default: return " ";
|
||||
}
|
||||
}
|
||||
}
|
||||
97
jdkSrc/jdk8/sun/net/httpserver/ContextList.java
Normal file
97
jdkSrc/jdk8/sun/net/httpserver/ContextList.java
Normal file
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (c) 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 sun.net.httpserver;
|
||||
|
||||
import java.util.*;
|
||||
import com.sun.net.httpserver.*;
|
||||
import com.sun.net.httpserver.spi.*;
|
||||
|
||||
class ContextList {
|
||||
|
||||
final static int MAX_CONTEXTS = 50;
|
||||
|
||||
LinkedList<HttpContextImpl> list = new LinkedList<HttpContextImpl>();
|
||||
|
||||
public synchronized void add (HttpContextImpl ctx) {
|
||||
assert ctx.getPath() != null;
|
||||
list.add (ctx);
|
||||
}
|
||||
|
||||
public synchronized int size () {
|
||||
return list.size();
|
||||
}
|
||||
|
||||
/* initially contexts are located only by protocol:path.
|
||||
* Context with longest prefix matches (currently case-sensitive)
|
||||
*/
|
||||
synchronized HttpContextImpl findContext (String protocol, String path) {
|
||||
return findContext (protocol, path, false);
|
||||
}
|
||||
|
||||
synchronized HttpContextImpl findContext (String protocol, String path, boolean exact) {
|
||||
protocol = protocol.toLowerCase();
|
||||
String longest = "";
|
||||
HttpContextImpl lc = null;
|
||||
for (HttpContextImpl ctx: list) {
|
||||
if (!ctx.getProtocol().equals(protocol)) {
|
||||
continue;
|
||||
}
|
||||
String cpath = ctx.getPath();
|
||||
if (exact && !cpath.equals (path)) {
|
||||
continue;
|
||||
} else if (!exact && !path.startsWith(cpath)) {
|
||||
continue;
|
||||
}
|
||||
if (cpath.length() > longest.length()) {
|
||||
longest = cpath;
|
||||
lc = ctx;
|
||||
}
|
||||
}
|
||||
return lc;
|
||||
}
|
||||
|
||||
public synchronized void remove (String protocol, String path)
|
||||
throws IllegalArgumentException
|
||||
{
|
||||
HttpContextImpl ctx = findContext (protocol, path, true);
|
||||
if (ctx == null) {
|
||||
throw new IllegalArgumentException ("cannot remove element from list");
|
||||
}
|
||||
list.remove (ctx);
|
||||
}
|
||||
|
||||
public synchronized void remove (HttpContextImpl context)
|
||||
throws IllegalArgumentException
|
||||
{
|
||||
for (HttpContextImpl ctx: list) {
|
||||
if (ctx.equals (context)) {
|
||||
list.remove (ctx);
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException ("no such context in list");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 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 sun.net.httpserver;
|
||||
|
||||
import java.net.*;
|
||||
import java.io.*;
|
||||
import com.sun.net.httpserver.*;
|
||||
import com.sun.net.httpserver.spi.*;
|
||||
|
||||
public class DefaultHttpServerProvider extends HttpServerProvider {
|
||||
public HttpServer createHttpServer (InetSocketAddress addr, int backlog) throws IOException {
|
||||
return new HttpServerImpl (addr, backlog);
|
||||
}
|
||||
|
||||
public HttpsServer createHttpsServer (InetSocketAddress addr, int backlog) throws IOException {
|
||||
return new HttpsServerImpl (addr, backlog);
|
||||
}
|
||||
}
|
||||
38
jdkSrc/jdk8/sun/net/httpserver/Event.java
Normal file
38
jdkSrc/jdk8/sun/net/httpserver/Event.java
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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 sun.net.httpserver;
|
||||
|
||||
import com.sun.net.httpserver.*;
|
||||
import com.sun.net.httpserver.spi.*;
|
||||
|
||||
class Event {
|
||||
|
||||
ExchangeImpl exchange;
|
||||
|
||||
protected Event (ExchangeImpl t) {
|
||||
this.exchange = t;
|
||||
}
|
||||
}
|
||||
456
jdkSrc/jdk8/sun/net/httpserver/ExchangeImpl.java
Normal file
456
jdkSrc/jdk8/sun/net/httpserver/ExchangeImpl.java
Normal file
@@ -0,0 +1,456 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 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 sun.net.httpserver;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import javax.net.ssl.*;
|
||||
import java.util.*;
|
||||
import java.util.logging.Logger;
|
||||
import java.text.*;
|
||||
import com.sun.net.httpserver.*;
|
||||
|
||||
class ExchangeImpl {
|
||||
|
||||
Headers reqHdrs, rspHdrs;
|
||||
Request req;
|
||||
String method;
|
||||
boolean writefinished;
|
||||
URI uri;
|
||||
HttpConnection connection;
|
||||
long reqContentLen;
|
||||
long rspContentLen;
|
||||
/* raw streams which access the socket directly */
|
||||
InputStream ris;
|
||||
OutputStream ros;
|
||||
Thread thread;
|
||||
/* close the underlying connection when this exchange finished */
|
||||
boolean close;
|
||||
boolean closed;
|
||||
boolean http10 = false;
|
||||
|
||||
/* for formatting the Date: header */
|
||||
private static final String pattern = "EEE, dd MMM yyyy HH:mm:ss zzz";
|
||||
private static final TimeZone gmtTZ = TimeZone.getTimeZone("GMT");
|
||||
private static final ThreadLocal<DateFormat> dateFormat =
|
||||
new ThreadLocal<DateFormat>() {
|
||||
@Override protected DateFormat initialValue() {
|
||||
DateFormat df = new SimpleDateFormat(pattern, Locale.US);
|
||||
df.setTimeZone(gmtTZ);
|
||||
return df;
|
||||
}
|
||||
};
|
||||
|
||||
private static final String HEAD = "HEAD";
|
||||
|
||||
/* streams which take care of the HTTP protocol framing
|
||||
* and are passed up to higher layers
|
||||
*/
|
||||
InputStream uis;
|
||||
OutputStream uos;
|
||||
LeftOverInputStream uis_orig; // uis may have be a user supplied wrapper
|
||||
PlaceholderOutputStream uos_orig;
|
||||
|
||||
boolean sentHeaders; /* true after response headers sent */
|
||||
Map<String,Object> attributes;
|
||||
int rcode = -1;
|
||||
HttpPrincipal principal;
|
||||
ServerImpl server;
|
||||
|
||||
ExchangeImpl (
|
||||
String m, URI u, Request req, long len, HttpConnection connection
|
||||
) throws IOException {
|
||||
this.req = req;
|
||||
this.reqHdrs = req.headers();
|
||||
this.rspHdrs = new Headers();
|
||||
this.method = m;
|
||||
this.uri = u;
|
||||
this.connection = connection;
|
||||
this.reqContentLen = len;
|
||||
/* ros only used for headers, body written directly to stream */
|
||||
this.ros = req.outputStream();
|
||||
this.ris = req.inputStream();
|
||||
server = getServerImpl();
|
||||
server.startExchange();
|
||||
}
|
||||
|
||||
public Headers getRequestHeaders () {
|
||||
return new UnmodifiableHeaders (reqHdrs);
|
||||
}
|
||||
|
||||
public Headers getResponseHeaders () {
|
||||
return rspHdrs;
|
||||
}
|
||||
|
||||
public URI getRequestURI () {
|
||||
return uri;
|
||||
}
|
||||
|
||||
public String getRequestMethod (){
|
||||
return method;
|
||||
}
|
||||
|
||||
public HttpContextImpl getHttpContext (){
|
||||
return connection.getHttpContext();
|
||||
}
|
||||
|
||||
private boolean isHeadRequest() {
|
||||
return HEAD.equals(getRequestMethod());
|
||||
}
|
||||
|
||||
public void close () {
|
||||
if (closed) {
|
||||
return;
|
||||
}
|
||||
closed = true;
|
||||
|
||||
/* close the underlying connection if,
|
||||
* a) the streams not set up yet, no response can be sent, or
|
||||
* b) if the wrapper output stream is not set up, or
|
||||
* c) if the close of the input/outpu stream fails
|
||||
*/
|
||||
try {
|
||||
if (uis_orig == null || uos == null) {
|
||||
connection.close();
|
||||
return;
|
||||
}
|
||||
if (!uos_orig.isWrapped()) {
|
||||
connection.close();
|
||||
return;
|
||||
}
|
||||
if (!uis_orig.isClosed()) {
|
||||
uis_orig.close();
|
||||
}
|
||||
uos.close();
|
||||
} catch (IOException e) {
|
||||
connection.close();
|
||||
}
|
||||
}
|
||||
|
||||
public InputStream getRequestBody () {
|
||||
if (uis != null) {
|
||||
return uis;
|
||||
}
|
||||
if (reqContentLen == -1L) {
|
||||
uis_orig = new ChunkedInputStream (this, ris);
|
||||
uis = uis_orig;
|
||||
} else {
|
||||
uis_orig = new FixedLengthInputStream (this, ris, reqContentLen);
|
||||
uis = uis_orig;
|
||||
}
|
||||
return uis;
|
||||
}
|
||||
|
||||
LeftOverInputStream getOriginalInputStream () {
|
||||
return uis_orig;
|
||||
}
|
||||
|
||||
public int getResponseCode () {
|
||||
return rcode;
|
||||
}
|
||||
|
||||
public OutputStream getResponseBody () {
|
||||
/* TODO. Change spec to remove restriction below. Filters
|
||||
* cannot work with this restriction
|
||||
*
|
||||
* if (!sentHeaders) {
|
||||
* throw new IllegalStateException ("headers not sent");
|
||||
* }
|
||||
*/
|
||||
if (uos == null) {
|
||||
uos_orig = new PlaceholderOutputStream (null);
|
||||
uos = uos_orig;
|
||||
}
|
||||
return uos;
|
||||
}
|
||||
|
||||
|
||||
/* returns the place holder stream, which is the stream
|
||||
* returned from the 1st call to getResponseBody()
|
||||
* The "real" ouputstream is then placed inside this
|
||||
*/
|
||||
PlaceholderOutputStream getPlaceholderResponseBody () {
|
||||
getResponseBody();
|
||||
return uos_orig;
|
||||
}
|
||||
|
||||
public void sendResponseHeaders (int rCode, long contentLen)
|
||||
throws IOException
|
||||
{
|
||||
if (sentHeaders) {
|
||||
throw new IOException ("headers already sent");
|
||||
}
|
||||
this.rcode = rCode;
|
||||
String statusLine = "HTTP/1.1 "+rCode+Code.msg(rCode)+"\r\n";
|
||||
OutputStream tmpout = new BufferedOutputStream (ros);
|
||||
PlaceholderOutputStream o = getPlaceholderResponseBody();
|
||||
tmpout.write (bytes(statusLine, 0), 0, statusLine.length());
|
||||
boolean noContentToSend = false; // assume there is content
|
||||
rspHdrs.set ("Date", dateFormat.get().format (new Date()));
|
||||
|
||||
/* check for response type that is not allowed to send a body */
|
||||
|
||||
if ((rCode>=100 && rCode <200) /* informational */
|
||||
||(rCode == 204) /* no content */
|
||||
||(rCode == 304)) /* not modified */
|
||||
{
|
||||
if (contentLen != -1) {
|
||||
Logger logger = server.getLogger();
|
||||
String msg = "sendResponseHeaders: rCode = "+ rCode
|
||||
+ ": forcing contentLen = -1";
|
||||
logger.warning (msg);
|
||||
}
|
||||
contentLen = -1;
|
||||
}
|
||||
|
||||
if (isHeadRequest()) {
|
||||
/* HEAD requests should not set a content length by passing it
|
||||
* through this API, but should instead manually set the required
|
||||
* headers.*/
|
||||
if (contentLen >= 0) {
|
||||
final Logger logger = server.getLogger();
|
||||
String msg =
|
||||
"sendResponseHeaders: being invoked with a content length for a HEAD request";
|
||||
logger.warning (msg);
|
||||
}
|
||||
noContentToSend = true;
|
||||
contentLen = 0;
|
||||
} else { /* not a HEAD request */
|
||||
if (contentLen == 0) {
|
||||
if (http10) {
|
||||
o.setWrappedStream (new UndefLengthOutputStream (this, ros));
|
||||
close = true;
|
||||
} else {
|
||||
rspHdrs.set ("Transfer-encoding", "chunked");
|
||||
o.setWrappedStream (new ChunkedOutputStream (this, ros));
|
||||
}
|
||||
} else {
|
||||
if (contentLen == -1) {
|
||||
noContentToSend = true;
|
||||
contentLen = 0;
|
||||
}
|
||||
rspHdrs.set("Content-length", Long.toString(contentLen));
|
||||
o.setWrappedStream (new FixedLengthOutputStream (this, ros, contentLen));
|
||||
}
|
||||
}
|
||||
write (rspHdrs, tmpout);
|
||||
this.rspContentLen = contentLen;
|
||||
tmpout.flush() ;
|
||||
tmpout = null;
|
||||
sentHeaders = true;
|
||||
if (noContentToSend) {
|
||||
WriteFinishedEvent e = new WriteFinishedEvent (this);
|
||||
server.addEvent (e);
|
||||
closed = true;
|
||||
}
|
||||
server.logReply (rCode, req.requestLine(), null);
|
||||
}
|
||||
|
||||
void write (Headers map, OutputStream os) throws IOException {
|
||||
Set<Map.Entry<String,List<String>>> entries = map.entrySet();
|
||||
for (Map.Entry<String,List<String>> entry : entries) {
|
||||
String key = entry.getKey();
|
||||
byte[] buf;
|
||||
List<String> values = entry.getValue();
|
||||
for (String val : values) {
|
||||
int i = key.length();
|
||||
buf = bytes (key, 2);
|
||||
buf[i++] = ':';
|
||||
buf[i++] = ' ';
|
||||
os.write (buf, 0, i);
|
||||
buf = bytes (val, 2);
|
||||
i = val.length();
|
||||
buf[i++] = '\r';
|
||||
buf[i++] = '\n';
|
||||
os.write (buf, 0, i);
|
||||
}
|
||||
}
|
||||
os.write ('\r');
|
||||
os.write ('\n');
|
||||
}
|
||||
|
||||
private byte[] rspbuf = new byte [128]; // used by bytes()
|
||||
|
||||
/**
|
||||
* convert string to byte[], using rspbuf
|
||||
* Make sure that at least "extra" bytes are free at end
|
||||
* of rspbuf. Reallocate rspbuf if not big enough.
|
||||
* caller must check return value to see if rspbuf moved
|
||||
*/
|
||||
private byte[] bytes (String s, int extra) {
|
||||
int slen = s.length();
|
||||
if (slen+extra > rspbuf.length) {
|
||||
int diff = slen + extra - rspbuf.length;
|
||||
rspbuf = new byte [2* (rspbuf.length + diff)];
|
||||
}
|
||||
char c[] = s.toCharArray();
|
||||
for (int i=0; i<c.length; i++) {
|
||||
rspbuf[i] = (byte)c[i];
|
||||
}
|
||||
return rspbuf;
|
||||
}
|
||||
|
||||
public InetSocketAddress getRemoteAddress (){
|
||||
Socket s = connection.getChannel().socket();
|
||||
InetAddress ia = s.getInetAddress();
|
||||
int port = s.getPort();
|
||||
return new InetSocketAddress (ia, port);
|
||||
}
|
||||
|
||||
public InetSocketAddress getLocalAddress (){
|
||||
Socket s = connection.getChannel().socket();
|
||||
InetAddress ia = s.getLocalAddress();
|
||||
int port = s.getLocalPort();
|
||||
return new InetSocketAddress (ia, port);
|
||||
}
|
||||
|
||||
public String getProtocol (){
|
||||
String reqline = req.requestLine();
|
||||
int index = reqline.lastIndexOf (' ');
|
||||
return reqline.substring (index+1);
|
||||
}
|
||||
|
||||
public SSLSession getSSLSession () {
|
||||
SSLEngine e = connection.getSSLEngine();
|
||||
if (e == null) {
|
||||
return null;
|
||||
}
|
||||
return e.getSession();
|
||||
}
|
||||
|
||||
public Object getAttribute (String name) {
|
||||
if (name == null) {
|
||||
throw new NullPointerException ("null name parameter");
|
||||
}
|
||||
if (attributes == null) {
|
||||
attributes = getHttpContext().getAttributes();
|
||||
}
|
||||
return attributes.get (name);
|
||||
}
|
||||
|
||||
public void setAttribute (String name, Object value) {
|
||||
if (name == null) {
|
||||
throw new NullPointerException ("null name parameter");
|
||||
}
|
||||
if (attributes == null) {
|
||||
attributes = getHttpContext().getAttributes();
|
||||
}
|
||||
attributes.put (name, value);
|
||||
}
|
||||
|
||||
public void setStreams (InputStream i, OutputStream o) {
|
||||
assert uis != null;
|
||||
if (i != null) {
|
||||
uis = i;
|
||||
}
|
||||
if (o != null) {
|
||||
uos = o;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* PP
|
||||
*/
|
||||
HttpConnection getConnection () {
|
||||
return connection;
|
||||
}
|
||||
|
||||
ServerImpl getServerImpl () {
|
||||
return getHttpContext().getServerImpl();
|
||||
}
|
||||
|
||||
public HttpPrincipal getPrincipal () {
|
||||
return principal;
|
||||
}
|
||||
|
||||
void setPrincipal (HttpPrincipal principal) {
|
||||
this.principal = principal;
|
||||
}
|
||||
|
||||
static ExchangeImpl get (HttpExchange t) {
|
||||
if (t instanceof HttpExchangeImpl) {
|
||||
return ((HttpExchangeImpl)t).getExchangeImpl();
|
||||
} else {
|
||||
assert t instanceof HttpsExchangeImpl;
|
||||
return ((HttpsExchangeImpl)t).getExchangeImpl();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An OutputStream which wraps another stream
|
||||
* which is supplied either at creation time, or sometime later.
|
||||
* If a caller/user tries to write to this stream before
|
||||
* the wrapped stream has been provided, then an IOException will
|
||||
* be thrown.
|
||||
*/
|
||||
class PlaceholderOutputStream extends java.io.OutputStream {
|
||||
|
||||
OutputStream wrapped;
|
||||
|
||||
PlaceholderOutputStream (OutputStream os) {
|
||||
wrapped = os;
|
||||
}
|
||||
|
||||
void setWrappedStream (OutputStream os) {
|
||||
wrapped = os;
|
||||
}
|
||||
|
||||
boolean isWrapped () {
|
||||
return wrapped != null;
|
||||
}
|
||||
|
||||
private void checkWrap () throws IOException {
|
||||
if (wrapped == null) {
|
||||
throw new IOException ("response headers not sent yet");
|
||||
}
|
||||
}
|
||||
|
||||
public void write(int b) throws IOException {
|
||||
checkWrap();
|
||||
wrapped.write (b);
|
||||
}
|
||||
|
||||
public void write(byte b[]) throws IOException {
|
||||
checkWrap();
|
||||
wrapped.write (b);
|
||||
}
|
||||
|
||||
public void write(byte b[], int off, int len) throws IOException {
|
||||
checkWrap();
|
||||
wrapped.write (b, off, len);
|
||||
}
|
||||
|
||||
public void flush() throws IOException {
|
||||
checkWrap();
|
||||
wrapped.flush();
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
checkWrap();
|
||||
wrapped.close();
|
||||
}
|
||||
}
|
||||
87
jdkSrc/jdk8/sun/net/httpserver/FixedLengthInputStream.java
Normal file
87
jdkSrc/jdk8/sun/net/httpserver/FixedLengthInputStream.java
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2017, 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 sun.net.httpserver;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import com.sun.net.httpserver.*;
|
||||
import com.sun.net.httpserver.spi.*;
|
||||
|
||||
/**
|
||||
* a class which allows the caller to read up to a defined
|
||||
* number of bytes off an underlying stream
|
||||
* close() does not close the underlying stream
|
||||
*/
|
||||
|
||||
class FixedLengthInputStream extends LeftOverInputStream {
|
||||
private long remaining;
|
||||
|
||||
FixedLengthInputStream (ExchangeImpl t, InputStream src, long len) {
|
||||
super (t, src);
|
||||
if (len < 0) {
|
||||
throw new IllegalArgumentException("Content-Length: " + len);
|
||||
}
|
||||
this.remaining = len;
|
||||
}
|
||||
|
||||
protected int readImpl (byte[]b, int off, int len) throws IOException {
|
||||
|
||||
eof = (remaining == 0L);
|
||||
if (eof) {
|
||||
return -1;
|
||||
}
|
||||
if (len > remaining) {
|
||||
len = (int)remaining;
|
||||
}
|
||||
int n = in.read(b, off, len);
|
||||
if (n > -1) {
|
||||
remaining -= n;
|
||||
if (remaining == 0) {
|
||||
t.getServerImpl().requestCompleted (t.getConnection());
|
||||
}
|
||||
}
|
||||
if (n < 0 && !eof)
|
||||
throw new IOException("connection closed before all data received");
|
||||
return n;
|
||||
}
|
||||
|
||||
public int available () throws IOException {
|
||||
if (eof) {
|
||||
return 0;
|
||||
}
|
||||
int n = in.available();
|
||||
return n < remaining? n: (int)remaining;
|
||||
}
|
||||
|
||||
public boolean markSupported () {return false;}
|
||||
|
||||
public void mark (int l) {
|
||||
}
|
||||
|
||||
public void reset () throws IOException {
|
||||
throw new IOException ("mark/reset not supported");
|
||||
}
|
||||
}
|
||||
107
jdkSrc/jdk8/sun/net/httpserver/FixedLengthOutputStream.java
Normal file
107
jdkSrc/jdk8/sun/net/httpserver/FixedLengthOutputStream.java
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2006, 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 sun.net.httpserver;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import com.sun.net.httpserver.*;
|
||||
import com.sun.net.httpserver.spi.*;
|
||||
|
||||
/**
|
||||
* a class which allows the caller to write up to a defined
|
||||
* number of bytes to an underlying stream. The caller *must*
|
||||
* write the pre-defined number or else an exception will be thrown
|
||||
* and the whole request aborted.
|
||||
* normal close() does not close the underlying stream
|
||||
*/
|
||||
|
||||
class FixedLengthOutputStream extends FilterOutputStream
|
||||
{
|
||||
private long remaining;
|
||||
private boolean eof = false;
|
||||
private boolean closed = false;
|
||||
ExchangeImpl t;
|
||||
|
||||
FixedLengthOutputStream (ExchangeImpl t, OutputStream src, long len) {
|
||||
super (src);
|
||||
if (len < 0) {
|
||||
throw new IllegalArgumentException("Content-Length: " + len);
|
||||
}
|
||||
this.t = t;
|
||||
this.remaining = len;
|
||||
}
|
||||
|
||||
public void write (int b) throws IOException {
|
||||
if (closed) {
|
||||
throw new IOException ("stream closed");
|
||||
}
|
||||
eof = (remaining == 0);
|
||||
if (eof) {
|
||||
throw new StreamClosedException();
|
||||
}
|
||||
out.write(b);
|
||||
remaining --;
|
||||
}
|
||||
|
||||
public void write (byte[]b, int off, int len) throws IOException {
|
||||
if (closed) {
|
||||
throw new IOException ("stream closed");
|
||||
}
|
||||
eof = (remaining == 0);
|
||||
if (eof) {
|
||||
throw new StreamClosedException();
|
||||
}
|
||||
if (len > remaining) {
|
||||
// stream is still open, caller can retry
|
||||
throw new IOException ("too many bytes to write to stream");
|
||||
}
|
||||
out.write(b, off, len);
|
||||
remaining -= len;
|
||||
}
|
||||
|
||||
public void close () throws IOException {
|
||||
if (closed) {
|
||||
return;
|
||||
}
|
||||
closed = true;
|
||||
if (remaining > 0) {
|
||||
t.close();
|
||||
throw new IOException ("insufficient bytes written to stream");
|
||||
}
|
||||
flush();
|
||||
eof = true;
|
||||
LeftOverInputStream is = t.getOriginalInputStream();
|
||||
if (!is.isClosed()) {
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException e) {}
|
||||
}
|
||||
WriteFinishedEvent e = new WriteFinishedEvent (t);
|
||||
t.getHttpContext().getServerImpl().addEvent (e);
|
||||
}
|
||||
|
||||
// flush is a pass-through
|
||||
}
|
||||
194
jdkSrc/jdk8/sun/net/httpserver/HttpConnection.java
Normal file
194
jdkSrc/jdk8/sun/net/httpserver/HttpConnection.java
Normal file
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 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 sun.net.httpserver;
|
||||
|
||||
import java.io.*;
|
||||
import javax.net.ssl.*;
|
||||
import java.nio.channels.*;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* encapsulates all the connection specific state for a HTTP/S connection
|
||||
* one of these is hung from the selector attachment and is used to locate
|
||||
* everything from that.
|
||||
*/
|
||||
class HttpConnection {
|
||||
|
||||
HttpContextImpl context;
|
||||
SSLEngine engine;
|
||||
SSLContext sslContext;
|
||||
SSLStreams sslStreams;
|
||||
|
||||
/* high level streams returned to application */
|
||||
InputStream i;
|
||||
|
||||
/* low level stream that sits directly over channel */
|
||||
InputStream raw;
|
||||
OutputStream rawout;
|
||||
|
||||
SocketChannel chan;
|
||||
SelectionKey selectionKey;
|
||||
String protocol;
|
||||
long idleStartTime; // absolute time in milli seconds, starting when the connection was marked idle
|
||||
volatile long reqStartedTime; // time when the request was initiated
|
||||
volatile long rspStartedTime; // time we started writing the response
|
||||
int remaining;
|
||||
boolean closed = false;
|
||||
Logger logger;
|
||||
|
||||
public enum State {IDLE, REQUEST, RESPONSE, NEWLY_ACCEPTED};
|
||||
volatile State state;
|
||||
|
||||
public String toString() {
|
||||
String s = null;
|
||||
if (chan != null) {
|
||||
s = chan.toString();
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
HttpConnection () {
|
||||
}
|
||||
|
||||
void setChannel (SocketChannel c) {
|
||||
chan = c;
|
||||
}
|
||||
|
||||
void setContext (HttpContextImpl ctx) {
|
||||
context = ctx;
|
||||
}
|
||||
|
||||
State getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
void setState (State s) {
|
||||
state = s;
|
||||
}
|
||||
|
||||
void setParameters (
|
||||
InputStream in, OutputStream rawout, SocketChannel chan,
|
||||
SSLEngine engine, SSLStreams sslStreams, SSLContext sslContext, String protocol,
|
||||
HttpContextImpl context, InputStream raw
|
||||
)
|
||||
{
|
||||
this.context = context;
|
||||
this.i = in;
|
||||
this.rawout = rawout;
|
||||
this.raw = raw;
|
||||
this.protocol = protocol;
|
||||
this.engine = engine;
|
||||
this.chan = chan;
|
||||
this.sslContext = sslContext;
|
||||
this.sslStreams = sslStreams;
|
||||
this.logger = context.getLogger();
|
||||
}
|
||||
|
||||
SocketChannel getChannel () {
|
||||
return chan;
|
||||
}
|
||||
|
||||
synchronized void close () {
|
||||
if (closed) {
|
||||
return;
|
||||
}
|
||||
closed = true;
|
||||
if (logger != null && chan != null) {
|
||||
logger.finest ("Closing connection: " + chan.toString());
|
||||
}
|
||||
|
||||
if (!chan.isOpen()) {
|
||||
ServerImpl.dprint ("Channel already closed");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
/* need to ensure temporary selectors are closed */
|
||||
if (raw != null) {
|
||||
raw.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
ServerImpl.dprint (e);
|
||||
}
|
||||
try {
|
||||
if (rawout != null) {
|
||||
rawout.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
ServerImpl.dprint (e);
|
||||
}
|
||||
try {
|
||||
if (sslStreams != null) {
|
||||
sslStreams.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
ServerImpl.dprint (e);
|
||||
}
|
||||
try {
|
||||
chan.close();
|
||||
} catch (IOException e) {
|
||||
ServerImpl.dprint (e);
|
||||
}
|
||||
}
|
||||
|
||||
/* remaining is the number of bytes left on the lowest level inputstream
|
||||
* after the exchange is finished
|
||||
*/
|
||||
void setRemaining (int r) {
|
||||
remaining = r;
|
||||
}
|
||||
|
||||
int getRemaining () {
|
||||
return remaining;
|
||||
}
|
||||
|
||||
SelectionKey getSelectionKey () {
|
||||
return selectionKey;
|
||||
}
|
||||
|
||||
InputStream getInputStream () {
|
||||
return i;
|
||||
}
|
||||
|
||||
OutputStream getRawOutputStream () {
|
||||
return rawout;
|
||||
}
|
||||
|
||||
String getProtocol () {
|
||||
return protocol;
|
||||
}
|
||||
|
||||
SSLEngine getSSLEngine () {
|
||||
return engine;
|
||||
}
|
||||
|
||||
SSLContext getSSLContext () {
|
||||
return sslContext;
|
||||
}
|
||||
|
||||
HttpContextImpl getHttpContext () {
|
||||
return context;
|
||||
}
|
||||
}
|
||||
152
jdkSrc/jdk8/sun/net/httpserver/HttpContextImpl.java
Normal file
152
jdkSrc/jdk8/sun/net/httpserver/HttpContextImpl.java
Normal file
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2006, 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 sun.net.httpserver;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.logging.Logger;
|
||||
import com.sun.net.httpserver.*;
|
||||
import com.sun.net.httpserver.spi.*;
|
||||
|
||||
/**
|
||||
* HttpContext represents a mapping between a protocol (http or https) together with a root URI path
|
||||
* to a {@link HttpHandler} which is invoked to handle requests destined
|
||||
* for the protocol/path on the associated HttpServer.
|
||||
* <p>
|
||||
* HttpContext instances are created by {@link HttpServer#createContext(String,String,HttpHandler,Object)}
|
||||
* <p>
|
||||
*/
|
||||
class HttpContextImpl extends HttpContext {
|
||||
|
||||
private String path;
|
||||
private String protocol;
|
||||
private HttpHandler handler;
|
||||
private Map<String,Object> attributes = new HashMap<String,Object>();
|
||||
private ServerImpl server;
|
||||
/* system filters, not visible to applications */
|
||||
private LinkedList<Filter> sfilters = new LinkedList<Filter>();
|
||||
/* user filters, set by applications */
|
||||
private LinkedList<Filter> ufilters = new LinkedList<Filter>();
|
||||
private Authenticator authenticator;
|
||||
private AuthFilter authfilter;
|
||||
|
||||
/**
|
||||
* constructor is package private.
|
||||
*/
|
||||
HttpContextImpl (String protocol, String path, HttpHandler cb, ServerImpl server) {
|
||||
if (path == null || protocol == null || path.length() < 1 || path.charAt(0) != '/') {
|
||||
throw new IllegalArgumentException ("Illegal value for path or protocol");
|
||||
}
|
||||
this.protocol = protocol.toLowerCase();
|
||||
this.path = path;
|
||||
if (!this.protocol.equals ("http") && !this.protocol.equals ("https")) {
|
||||
throw new IllegalArgumentException ("Illegal value for protocol");
|
||||
}
|
||||
this.handler = cb;
|
||||
this.server = server;
|
||||
authfilter = new AuthFilter(null);
|
||||
sfilters.add (authfilter);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the handler for this context
|
||||
* @return the HttpHandler for this context
|
||||
*/
|
||||
public HttpHandler getHandler () {
|
||||
return handler;
|
||||
}
|
||||
|
||||
public void setHandler (HttpHandler h) {
|
||||
if (h == null) {
|
||||
throw new NullPointerException ("Null handler parameter");
|
||||
}
|
||||
if (handler != null) {
|
||||
throw new IllegalArgumentException ("handler already set");
|
||||
}
|
||||
handler = h;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the path this context was created with
|
||||
* @return this context's path
|
||||
*/
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the server this context was created with
|
||||
* @return this context's server
|
||||
*/
|
||||
public HttpServer getServer () {
|
||||
return server.getWrapper();
|
||||
}
|
||||
|
||||
ServerImpl getServerImpl () {
|
||||
return server;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the protocol this context was created with
|
||||
* @return this context's path
|
||||
*/
|
||||
public String getProtocol() {
|
||||
return protocol;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a mutable Map, which can be used to pass
|
||||
* configuration and other data to Filter modules
|
||||
* and to the context's exchange handler.
|
||||
* <p>
|
||||
* Every attribute stored in this Map will be visible to
|
||||
* every HttpExchange processed by this context
|
||||
*/
|
||||
public Map<String,Object> getAttributes() {
|
||||
return attributes;
|
||||
}
|
||||
|
||||
public List<Filter> getFilters () {
|
||||
return ufilters;
|
||||
}
|
||||
|
||||
List<Filter> getSystemFilters () {
|
||||
return sfilters;
|
||||
}
|
||||
|
||||
public Authenticator setAuthenticator (Authenticator auth) {
|
||||
Authenticator old = authenticator;
|
||||
authenticator = auth;
|
||||
authfilter.setAuthenticator (auth);
|
||||
return old;
|
||||
}
|
||||
|
||||
public Authenticator getAuthenticator () {
|
||||
return authenticator;
|
||||
}
|
||||
Logger getLogger () {
|
||||
return server.getLogger();
|
||||
}
|
||||
}
|
||||
37
jdkSrc/jdk8/sun/net/httpserver/HttpError.java
Normal file
37
jdkSrc/jdk8/sun/net/httpserver/HttpError.java
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 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 sun.net.httpserver;
|
||||
|
||||
/**
|
||||
* A Http error
|
||||
*/
|
||||
class HttpError extends RuntimeException {
|
||||
private static final long serialVersionUID = 8769596371344178179L;
|
||||
|
||||
public HttpError (String msg) {
|
||||
super (msg);
|
||||
}
|
||||
}
|
||||
120
jdkSrc/jdk8/sun/net/httpserver/HttpExchangeImpl.java
Normal file
120
jdkSrc/jdk8/sun/net/httpserver/HttpExchangeImpl.java
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2006, 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 sun.net.httpserver;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.*;
|
||||
import java.nio.channels.*;
|
||||
import java.net.*;
|
||||
import javax.net.ssl.*;
|
||||
import java.util.*;
|
||||
import sun.net.www.MessageHeader;
|
||||
import com.sun.net.httpserver.*;
|
||||
import com.sun.net.httpserver.spi.*;
|
||||
|
||||
class HttpExchangeImpl extends HttpExchange {
|
||||
|
||||
ExchangeImpl impl;
|
||||
|
||||
HttpExchangeImpl (ExchangeImpl impl) {
|
||||
this.impl = impl;
|
||||
}
|
||||
|
||||
public Headers getRequestHeaders () {
|
||||
return impl.getRequestHeaders();
|
||||
}
|
||||
|
||||
public Headers getResponseHeaders () {
|
||||
return impl.getResponseHeaders();
|
||||
}
|
||||
|
||||
public URI getRequestURI () {
|
||||
return impl.getRequestURI();
|
||||
}
|
||||
|
||||
public String getRequestMethod (){
|
||||
return impl.getRequestMethod();
|
||||
}
|
||||
|
||||
public HttpContextImpl getHttpContext (){
|
||||
return impl.getHttpContext();
|
||||
}
|
||||
|
||||
public void close () {
|
||||
impl.close();
|
||||
}
|
||||
|
||||
public InputStream getRequestBody () {
|
||||
return impl.getRequestBody();
|
||||
}
|
||||
|
||||
public int getResponseCode () {
|
||||
return impl.getResponseCode();
|
||||
}
|
||||
|
||||
public OutputStream getResponseBody () {
|
||||
return impl.getResponseBody();
|
||||
}
|
||||
|
||||
|
||||
public void sendResponseHeaders (int rCode, long contentLen)
|
||||
throws IOException
|
||||
{
|
||||
impl.sendResponseHeaders (rCode, contentLen);
|
||||
}
|
||||
|
||||
public InetSocketAddress getRemoteAddress (){
|
||||
return impl.getRemoteAddress();
|
||||
}
|
||||
|
||||
public InetSocketAddress getLocalAddress (){
|
||||
return impl.getLocalAddress();
|
||||
}
|
||||
|
||||
public String getProtocol (){
|
||||
return impl.getProtocol();
|
||||
}
|
||||
|
||||
public Object getAttribute (String name) {
|
||||
return impl.getAttribute (name);
|
||||
}
|
||||
|
||||
public void setAttribute (String name, Object value) {
|
||||
impl.setAttribute (name, value);
|
||||
}
|
||||
|
||||
public void setStreams (InputStream i, OutputStream o) {
|
||||
impl.setStreams (i, o);
|
||||
}
|
||||
|
||||
public HttpPrincipal getPrincipal () {
|
||||
return impl.getPrincipal();
|
||||
}
|
||||
|
||||
ExchangeImpl getExchangeImpl () {
|
||||
return impl;
|
||||
}
|
||||
}
|
||||
92
jdkSrc/jdk8/sun/net/httpserver/HttpServerImpl.java
Normal file
92
jdkSrc/jdk8/sun/net/httpserver/HttpServerImpl.java
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (c) 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 sun.net.httpserver;
|
||||
|
||||
import java.net.*;
|
||||
import java.io.*;
|
||||
import java.nio.*;
|
||||
import java.security.*;
|
||||
import java.nio.channels.*;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
import javax.net.ssl.*;
|
||||
import com.sun.net.httpserver.*;
|
||||
import com.sun.net.httpserver.spi.*;
|
||||
|
||||
public class HttpServerImpl extends HttpServer {
|
||||
|
||||
ServerImpl server;
|
||||
|
||||
HttpServerImpl () throws IOException {
|
||||
this (new InetSocketAddress(80), 0);
|
||||
}
|
||||
|
||||
HttpServerImpl (
|
||||
InetSocketAddress addr, int backlog
|
||||
) throws IOException {
|
||||
server = new ServerImpl (this, "http", addr, backlog);
|
||||
}
|
||||
|
||||
public void bind (InetSocketAddress addr, int backlog) throws IOException {
|
||||
server.bind (addr, backlog);
|
||||
}
|
||||
|
||||
public void start () {
|
||||
server.start();
|
||||
}
|
||||
|
||||
public void setExecutor (Executor executor) {
|
||||
server.setExecutor(executor);
|
||||
}
|
||||
|
||||
public Executor getExecutor () {
|
||||
return server.getExecutor();
|
||||
}
|
||||
|
||||
public void stop (int delay) {
|
||||
server.stop (delay);
|
||||
}
|
||||
|
||||
public HttpContextImpl createContext (String path, HttpHandler handler) {
|
||||
return server.createContext (path, handler);
|
||||
}
|
||||
|
||||
public HttpContextImpl createContext (String path) {
|
||||
return server.createContext (path);
|
||||
}
|
||||
|
||||
public void removeContext (String path) throws IllegalArgumentException {
|
||||
server.removeContext (path);
|
||||
}
|
||||
|
||||
public void removeContext (HttpContext context) throws IllegalArgumentException {
|
||||
server.removeContext (context);
|
||||
}
|
||||
|
||||
public InetSocketAddress getAddress() {
|
||||
return server.getAddress();
|
||||
}
|
||||
}
|
||||
124
jdkSrc/jdk8/sun/net/httpserver/HttpsExchangeImpl.java
Normal file
124
jdkSrc/jdk8/sun/net/httpserver/HttpsExchangeImpl.java
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2006, 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 sun.net.httpserver;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.*;
|
||||
import java.nio.channels.*;
|
||||
import java.net.*;
|
||||
import javax.net.ssl.*;
|
||||
import java.util.*;
|
||||
import sun.net.www.MessageHeader;
|
||||
import com.sun.net.httpserver.*;
|
||||
import com.sun.net.httpserver.spi.*;
|
||||
|
||||
class HttpsExchangeImpl extends HttpsExchange {
|
||||
|
||||
ExchangeImpl impl;
|
||||
|
||||
HttpsExchangeImpl (ExchangeImpl impl) throws IOException {
|
||||
this.impl = impl;
|
||||
}
|
||||
|
||||
public Headers getRequestHeaders () {
|
||||
return impl.getRequestHeaders();
|
||||
}
|
||||
|
||||
public Headers getResponseHeaders () {
|
||||
return impl.getResponseHeaders();
|
||||
}
|
||||
|
||||
public URI getRequestURI () {
|
||||
return impl.getRequestURI();
|
||||
}
|
||||
|
||||
public String getRequestMethod (){
|
||||
return impl.getRequestMethod();
|
||||
}
|
||||
|
||||
public HttpContextImpl getHttpContext (){
|
||||
return impl.getHttpContext();
|
||||
}
|
||||
|
||||
public void close () {
|
||||
impl.close();
|
||||
}
|
||||
|
||||
public InputStream getRequestBody () {
|
||||
return impl.getRequestBody();
|
||||
}
|
||||
|
||||
public int getResponseCode () {
|
||||
return impl.getResponseCode();
|
||||
}
|
||||
|
||||
public OutputStream getResponseBody () {
|
||||
return impl.getResponseBody();
|
||||
}
|
||||
|
||||
|
||||
public void sendResponseHeaders (int rCode, long contentLen)
|
||||
throws IOException
|
||||
{
|
||||
impl.sendResponseHeaders (rCode, contentLen);
|
||||
}
|
||||
|
||||
public InetSocketAddress getRemoteAddress (){
|
||||
return impl.getRemoteAddress();
|
||||
}
|
||||
|
||||
public InetSocketAddress getLocalAddress (){
|
||||
return impl.getLocalAddress();
|
||||
}
|
||||
|
||||
public String getProtocol (){
|
||||
return impl.getProtocol();
|
||||
}
|
||||
|
||||
public SSLSession getSSLSession () {
|
||||
return impl.getSSLSession ();
|
||||
}
|
||||
|
||||
public Object getAttribute (String name) {
|
||||
return impl.getAttribute (name);
|
||||
}
|
||||
|
||||
public void setAttribute (String name, Object value) {
|
||||
impl.setAttribute (name, value);
|
||||
}
|
||||
|
||||
public void setStreams (InputStream i, OutputStream o) {
|
||||
impl.setStreams (i, o);
|
||||
}
|
||||
|
||||
public HttpPrincipal getPrincipal () {
|
||||
return impl.getPrincipal();
|
||||
}
|
||||
|
||||
ExchangeImpl getExchangeImpl () {
|
||||
return impl;
|
||||
}
|
||||
}
|
||||
100
jdkSrc/jdk8/sun/net/httpserver/HttpsServerImpl.java
Normal file
100
jdkSrc/jdk8/sun/net/httpserver/HttpsServerImpl.java
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (c) 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 sun.net.httpserver;
|
||||
|
||||
import java.net.*;
|
||||
import java.io.*;
|
||||
import java.nio.*;
|
||||
import java.security.*;
|
||||
import java.nio.channels.*;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
import javax.net.ssl.*;
|
||||
import com.sun.net.httpserver.*;
|
||||
import com.sun.net.httpserver.spi.*;
|
||||
|
||||
public class HttpsServerImpl extends HttpsServer {
|
||||
|
||||
ServerImpl server;
|
||||
|
||||
HttpsServerImpl () throws IOException {
|
||||
this (new InetSocketAddress(443), 0);
|
||||
}
|
||||
|
||||
HttpsServerImpl (
|
||||
InetSocketAddress addr, int backlog
|
||||
) throws IOException {
|
||||
server = new ServerImpl (this, "https", addr, backlog);
|
||||
}
|
||||
|
||||
public void setHttpsConfigurator (HttpsConfigurator config) {
|
||||
server.setHttpsConfigurator (config);
|
||||
}
|
||||
|
||||
public HttpsConfigurator getHttpsConfigurator () {
|
||||
return server.getHttpsConfigurator();
|
||||
}
|
||||
|
||||
public void bind (InetSocketAddress addr, int backlog) throws IOException {
|
||||
server.bind (addr, backlog);
|
||||
}
|
||||
|
||||
public void start () {
|
||||
server.start();
|
||||
}
|
||||
|
||||
public void setExecutor (Executor executor) {
|
||||
server.setExecutor(executor);
|
||||
}
|
||||
|
||||
public Executor getExecutor () {
|
||||
return server.getExecutor();
|
||||
}
|
||||
|
||||
public void stop (int delay) {
|
||||
server.stop (delay);
|
||||
}
|
||||
|
||||
public HttpContextImpl createContext (String path, HttpHandler handler) {
|
||||
return server.createContext (path, handler);
|
||||
}
|
||||
|
||||
public HttpContextImpl createContext (String path) {
|
||||
return server.createContext (path);
|
||||
}
|
||||
|
||||
public void removeContext (String path) throws IllegalArgumentException {
|
||||
server.removeContext (path);
|
||||
}
|
||||
|
||||
public void removeContext (HttpContext context) throws IllegalArgumentException {
|
||||
server.removeContext (context);
|
||||
}
|
||||
|
||||
public InetSocketAddress getAddress() {
|
||||
return server.getAddress();
|
||||
}
|
||||
}
|
||||
122
jdkSrc/jdk8/sun/net/httpserver/LeftOverInputStream.java
Normal file
122
jdkSrc/jdk8/sun/net/httpserver/LeftOverInputStream.java
Normal file
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2007, 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 sun.net.httpserver;
|
||||
|
||||
import java.io.*;
|
||||
import com.sun.net.httpserver.*;
|
||||
import com.sun.net.httpserver.spi.*;
|
||||
|
||||
/**
|
||||
* a (filter) input stream which can tell us if bytes are "left over"
|
||||
* on the underlying stream which can be read (without blocking)
|
||||
* on another instance of this class.
|
||||
*
|
||||
* The class can also report if all bytes "expected" to be read
|
||||
* were read, by the time close() was called. In that case,
|
||||
* bytes may be drained to consume them (by calling drain() ).
|
||||
*
|
||||
* isEOF() returns true, when all expected bytes have been read
|
||||
*/
|
||||
abstract class LeftOverInputStream extends FilterInputStream {
|
||||
ExchangeImpl t;
|
||||
ServerImpl server;
|
||||
protected boolean closed = false;
|
||||
protected boolean eof = false;
|
||||
byte[] one = new byte [1];
|
||||
|
||||
public LeftOverInputStream (ExchangeImpl t, InputStream src) {
|
||||
super (src);
|
||||
this.t = t;
|
||||
this.server = t.getServerImpl();
|
||||
}
|
||||
/**
|
||||
* if bytes are left over buffered on *the UNDERLYING* stream
|
||||
*/
|
||||
public boolean isDataBuffered () throws IOException {
|
||||
assert eof;
|
||||
return super.available() > 0;
|
||||
}
|
||||
|
||||
public void close () throws IOException {
|
||||
if (closed) {
|
||||
return;
|
||||
}
|
||||
closed = true;
|
||||
if (!eof) {
|
||||
eof = drain (ServerConfig.getDrainAmount());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isClosed () {
|
||||
return closed;
|
||||
}
|
||||
|
||||
public boolean isEOF () {
|
||||
return eof;
|
||||
}
|
||||
|
||||
protected abstract int readImpl (byte[]b, int off, int len) throws IOException;
|
||||
|
||||
public synchronized int read () throws IOException {
|
||||
if (closed) {
|
||||
throw new IOException ("Stream is closed");
|
||||
}
|
||||
int c = readImpl (one, 0, 1);
|
||||
if (c == -1 || c == 0) {
|
||||
return c;
|
||||
} else {
|
||||
return one[0] & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized int read (byte[]b, int off, int len) throws IOException {
|
||||
if (closed) {
|
||||
throw new IOException ("Stream is closed");
|
||||
}
|
||||
return readImpl (b, off, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* read and discard up to l bytes or "eof" occurs,
|
||||
* (whichever is first). Then return true if the stream
|
||||
* is at eof (ie. all bytes were read) or false if not
|
||||
* (still bytes to be read)
|
||||
*/
|
||||
public boolean drain (long l) throws IOException {
|
||||
int bufSize = 2048;
|
||||
byte[] db = new byte [bufSize];
|
||||
while (l > 0) {
|
||||
long len = readImpl (db, 0, bufSize);
|
||||
if (len == -1) {
|
||||
eof = true;
|
||||
return true;
|
||||
} else {
|
||||
l = l - len;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
408
jdkSrc/jdk8/sun/net/httpserver/Request.java
Normal file
408
jdkSrc/jdk8/sun/net/httpserver/Request.java
Normal file
@@ -0,0 +1,408 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 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 sun.net.httpserver;
|
||||
|
||||
import java.nio.*;
|
||||
import java.io.*;
|
||||
import java.nio.channels.*;
|
||||
import com.sun.net.httpserver.*;
|
||||
|
||||
/**
|
||||
*/
|
||||
class Request {
|
||||
|
||||
final static int BUF_LEN = 2048;
|
||||
final static byte CR = 13;
|
||||
final static byte LF = 10;
|
||||
|
||||
private String startLine;
|
||||
private SocketChannel chan;
|
||||
private InputStream is;
|
||||
private OutputStream os;
|
||||
|
||||
Request (InputStream rawInputStream, OutputStream rawout) throws IOException {
|
||||
is = rawInputStream;
|
||||
os = rawout;
|
||||
do {
|
||||
startLine = readLine();
|
||||
if (startLine == null) {
|
||||
return;
|
||||
}
|
||||
/* skip blank lines */
|
||||
} while (startLine == null ? false : startLine.equals (""));
|
||||
}
|
||||
|
||||
|
||||
char[] buf = new char [BUF_LEN];
|
||||
int pos;
|
||||
StringBuffer lineBuf;
|
||||
|
||||
public InputStream inputStream () {
|
||||
return is;
|
||||
}
|
||||
|
||||
public OutputStream outputStream () {
|
||||
return os;
|
||||
}
|
||||
|
||||
/**
|
||||
* read a line from the stream returning as a String.
|
||||
* Not used for reading headers.
|
||||
*/
|
||||
|
||||
public String readLine () throws IOException {
|
||||
boolean gotCR = false, gotLF = false;
|
||||
pos = 0; lineBuf = new StringBuffer();
|
||||
while (!gotLF) {
|
||||
int c = is.read();
|
||||
if (c == -1) {
|
||||
return null;
|
||||
}
|
||||
if (gotCR) {
|
||||
if (c == LF) {
|
||||
gotLF = true;
|
||||
} else {
|
||||
gotCR = false;
|
||||
consume (CR);
|
||||
consume (c);
|
||||
}
|
||||
} else {
|
||||
if (c == CR) {
|
||||
gotCR = true;
|
||||
} else {
|
||||
consume (c);
|
||||
}
|
||||
}
|
||||
}
|
||||
lineBuf.append (buf, 0, pos);
|
||||
return new String (lineBuf);
|
||||
}
|
||||
|
||||
private void consume (int c) {
|
||||
if (pos == BUF_LEN) {
|
||||
lineBuf.append (buf);
|
||||
pos = 0;
|
||||
}
|
||||
buf[pos++] = (char)c;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the request line (first line of a request)
|
||||
*/
|
||||
public String requestLine () {
|
||||
return startLine;
|
||||
}
|
||||
|
||||
Headers hdrs = null;
|
||||
@SuppressWarnings("fallthrough")
|
||||
Headers headers () throws IOException {
|
||||
if (hdrs != null) {
|
||||
return hdrs;
|
||||
}
|
||||
hdrs = new Headers();
|
||||
|
||||
char s[] = new char[10];
|
||||
int len = 0;
|
||||
|
||||
int firstc = is.read();
|
||||
|
||||
// check for empty headers
|
||||
if (firstc == CR || firstc == LF) {
|
||||
int c = is.read();
|
||||
if (c == CR || c == LF) {
|
||||
return hdrs;
|
||||
}
|
||||
s[0] = (char)firstc;
|
||||
len = 1;
|
||||
firstc = c;
|
||||
}
|
||||
|
||||
while (firstc != LF && firstc != CR && firstc >= 0) {
|
||||
int keyend = -1;
|
||||
int c;
|
||||
boolean inKey = firstc > ' ';
|
||||
s[len++] = (char) firstc;
|
||||
parseloop:{
|
||||
while ((c = is.read()) >= 0) {
|
||||
switch (c) {
|
||||
/*fallthrough*/
|
||||
case ':':
|
||||
if (inKey && len > 0)
|
||||
keyend = len;
|
||||
inKey = false;
|
||||
break;
|
||||
case '\t':
|
||||
c = ' ';
|
||||
case ' ':
|
||||
inKey = false;
|
||||
break;
|
||||
case CR:
|
||||
case LF:
|
||||
firstc = is.read();
|
||||
if (c == CR && firstc == LF) {
|
||||
firstc = is.read();
|
||||
if (firstc == CR)
|
||||
firstc = is.read();
|
||||
}
|
||||
if (firstc == LF || firstc == CR || firstc > ' ')
|
||||
break parseloop;
|
||||
/* continuation */
|
||||
c = ' ';
|
||||
break;
|
||||
}
|
||||
if (len >= s.length) {
|
||||
char ns[] = new char[s.length * 2];
|
||||
System.arraycopy(s, 0, ns, 0, len);
|
||||
s = ns;
|
||||
}
|
||||
s[len++] = (char) c;
|
||||
}
|
||||
firstc = -1;
|
||||
}
|
||||
while (len > 0 && s[len - 1] <= ' ')
|
||||
len--;
|
||||
String k;
|
||||
if (keyend <= 0) {
|
||||
k = null;
|
||||
keyend = 0;
|
||||
} else {
|
||||
k = String.copyValueOf(s, 0, keyend);
|
||||
if (keyend < len && s[keyend] == ':')
|
||||
keyend++;
|
||||
while (keyend < len && s[keyend] <= ' ')
|
||||
keyend++;
|
||||
}
|
||||
String v;
|
||||
if (keyend >= len)
|
||||
v = new String();
|
||||
else
|
||||
v = String.copyValueOf(s, keyend, len - keyend);
|
||||
|
||||
if (hdrs.size() >= ServerConfig.getMaxReqHeaders()) {
|
||||
throw new IOException("Maximum number of request headers (" +
|
||||
"sun.net.httpserver.maxReqHeaders) exceeded, " +
|
||||
ServerConfig.getMaxReqHeaders() + ".");
|
||||
}
|
||||
if (k == null) { // Headers disallows null keys, use empty string
|
||||
k = ""; // instead to represent invalid key
|
||||
}
|
||||
hdrs.add (k,v);
|
||||
len = 0;
|
||||
}
|
||||
return hdrs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements blocking reading semantics on top of a non-blocking channel
|
||||
*/
|
||||
|
||||
static class ReadStream extends InputStream {
|
||||
SocketChannel channel;
|
||||
ByteBuffer chanbuf;
|
||||
byte[] one;
|
||||
private boolean closed = false, eof = false;
|
||||
ByteBuffer markBuf; /* reads may be satisfied from this buffer */
|
||||
boolean marked;
|
||||
boolean reset;
|
||||
int readlimit;
|
||||
static long readTimeout;
|
||||
ServerImpl server;
|
||||
final static int BUFSIZE = 8 * 1024;
|
||||
|
||||
public ReadStream (ServerImpl server, SocketChannel chan) throws IOException {
|
||||
this.channel = chan;
|
||||
this.server = server;
|
||||
chanbuf = ByteBuffer.allocate (BUFSIZE);
|
||||
chanbuf.clear();
|
||||
one = new byte[1];
|
||||
closed = marked = reset = false;
|
||||
}
|
||||
|
||||
public synchronized int read (byte[] b) throws IOException {
|
||||
return read (b, 0, b.length);
|
||||
}
|
||||
|
||||
public synchronized int read () throws IOException {
|
||||
int result = read (one, 0, 1);
|
||||
if (result == 1) {
|
||||
return one[0] & 0xFF;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized int read (byte[] b, int off, int srclen) throws IOException {
|
||||
|
||||
int canreturn, willreturn;
|
||||
|
||||
if (closed)
|
||||
throw new IOException ("Stream closed");
|
||||
|
||||
if (eof) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
assert channel.isBlocking();
|
||||
|
||||
if (off < 0 || srclen < 0|| srclen > (b.length-off)) {
|
||||
throw new IndexOutOfBoundsException ();
|
||||
}
|
||||
|
||||
if (reset) { /* satisfy from markBuf */
|
||||
canreturn = markBuf.remaining ();
|
||||
willreturn = canreturn>srclen ? srclen : canreturn;
|
||||
markBuf.get(b, off, willreturn);
|
||||
if (canreturn == willreturn) {
|
||||
reset = false;
|
||||
}
|
||||
} else { /* satisfy from channel */
|
||||
chanbuf.clear ();
|
||||
if (srclen < BUFSIZE) {
|
||||
chanbuf.limit (srclen);
|
||||
}
|
||||
do {
|
||||
willreturn = channel.read (chanbuf);
|
||||
} while (willreturn == 0);
|
||||
if (willreturn == -1) {
|
||||
eof = true;
|
||||
return -1;
|
||||
}
|
||||
chanbuf.flip ();
|
||||
chanbuf.get(b, off, willreturn);
|
||||
|
||||
if (marked) { /* copy into markBuf */
|
||||
try {
|
||||
markBuf.put (b, off, willreturn);
|
||||
} catch (BufferOverflowException e) {
|
||||
marked = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return willreturn;
|
||||
}
|
||||
|
||||
public boolean markSupported () {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Does not query the OS socket */
|
||||
public synchronized int available () throws IOException {
|
||||
if (closed)
|
||||
throw new IOException ("Stream is closed");
|
||||
|
||||
if (eof)
|
||||
return -1;
|
||||
|
||||
if (reset)
|
||||
return markBuf.remaining();
|
||||
|
||||
return chanbuf.remaining();
|
||||
}
|
||||
|
||||
public void close () throws IOException {
|
||||
if (closed) {
|
||||
return;
|
||||
}
|
||||
channel.close ();
|
||||
closed = true;
|
||||
}
|
||||
|
||||
public synchronized void mark (int readlimit) {
|
||||
if (closed)
|
||||
return;
|
||||
this.readlimit = readlimit;
|
||||
markBuf = ByteBuffer.allocate (readlimit);
|
||||
marked = true;
|
||||
reset = false;
|
||||
}
|
||||
|
||||
public synchronized void reset () throws IOException {
|
||||
if (closed )
|
||||
return;
|
||||
if (!marked)
|
||||
throw new IOException ("Stream not marked");
|
||||
marked = false;
|
||||
reset = true;
|
||||
markBuf.flip ();
|
||||
}
|
||||
}
|
||||
|
||||
static class WriteStream extends java.io.OutputStream {
|
||||
SocketChannel channel;
|
||||
ByteBuffer buf;
|
||||
SelectionKey key;
|
||||
boolean closed;
|
||||
byte[] one;
|
||||
ServerImpl server;
|
||||
|
||||
public WriteStream (ServerImpl server, SocketChannel channel) throws IOException {
|
||||
this.channel = channel;
|
||||
this.server = server;
|
||||
assert channel.isBlocking();
|
||||
closed = false;
|
||||
one = new byte [1];
|
||||
buf = ByteBuffer.allocate (4096);
|
||||
}
|
||||
|
||||
public synchronized void write (int b) throws IOException {
|
||||
one[0] = (byte)b;
|
||||
write (one, 0, 1);
|
||||
}
|
||||
|
||||
public synchronized void write (byte[] b) throws IOException {
|
||||
write (b, 0, b.length);
|
||||
}
|
||||
|
||||
public synchronized void write (byte[] b, int off, int len) throws IOException {
|
||||
int l = len;
|
||||
if (closed)
|
||||
throw new IOException ("stream is closed");
|
||||
|
||||
int cap = buf.capacity();
|
||||
if (cap < len) {
|
||||
int diff = len - cap;
|
||||
buf = ByteBuffer.allocate (2*(cap+diff));
|
||||
}
|
||||
buf.clear();
|
||||
buf.put (b, off, len);
|
||||
buf.flip ();
|
||||
int n;
|
||||
while ((n = channel.write (buf)) < l) {
|
||||
l -= n;
|
||||
if (l == 0)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public void close () throws IOException {
|
||||
if (closed)
|
||||
return;
|
||||
//server.logStackTrace ("Request.OS.close: isOpen="+channel.isOpen());
|
||||
channel.close ();
|
||||
closed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
666
jdkSrc/jdk8/sun/net/httpserver/SSLStreams.java
Normal file
666
jdkSrc/jdk8/sun/net/httpserver/SSLStreams.java
Normal file
@@ -0,0 +1,666 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 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 sun.net.httpserver;
|
||||
|
||||
import java.net.*;
|
||||
import java.nio.*;
|
||||
import java.io.*;
|
||||
import java.nio.channels.*;
|
||||
import java.util.concurrent.locks.*;
|
||||
import javax.net.ssl.*;
|
||||
import javax.net.ssl.SSLEngineResult.*;
|
||||
import com.sun.net.httpserver.*;
|
||||
|
||||
/**
|
||||
* given a non-blocking SocketChannel, it produces
|
||||
* (blocking) streams which encrypt/decrypt the SSL content
|
||||
* and handle the SSL handshaking automatically.
|
||||
*/
|
||||
|
||||
class SSLStreams {
|
||||
|
||||
SSLContext sslctx;
|
||||
SocketChannel chan;
|
||||
ServerImpl server;
|
||||
SSLEngine engine;
|
||||
EngineWrapper wrapper;
|
||||
OutputStream os;
|
||||
InputStream is;
|
||||
|
||||
/* held by thread doing the hand-shake on this connection */
|
||||
Lock handshaking = new ReentrantLock();
|
||||
|
||||
SSLStreams (ServerImpl server, SSLContext sslctx, SocketChannel chan) throws IOException {
|
||||
this.server = server;
|
||||
this.sslctx= sslctx;
|
||||
this.chan= chan;
|
||||
InetSocketAddress addr =
|
||||
(InetSocketAddress)chan.socket().getRemoteSocketAddress();
|
||||
engine = sslctx.createSSLEngine (addr.getHostName(), addr.getPort());
|
||||
engine.setUseClientMode (false);
|
||||
HttpsConfigurator cfg = server.getHttpsConfigurator();
|
||||
configureEngine (cfg, addr);
|
||||
wrapper = new EngineWrapper (chan, engine);
|
||||
}
|
||||
|
||||
private void configureEngine(HttpsConfigurator cfg, InetSocketAddress addr){
|
||||
if (cfg != null) {
|
||||
Parameters params = new Parameters (cfg, addr);
|
||||
//BEGIN_TIGER_EXCLUDE
|
||||
cfg.configure (params);
|
||||
SSLParameters sslParams = params.getSSLParameters();
|
||||
if (sslParams != null) {
|
||||
engine.setSSLParameters (sslParams);
|
||||
} else
|
||||
//END_TIGER_EXCLUDE
|
||||
{
|
||||
/* tiger compatibility */
|
||||
if (params.getCipherSuites() != null) {
|
||||
try {
|
||||
engine.setEnabledCipherSuites (
|
||||
params.getCipherSuites()
|
||||
);
|
||||
} catch (IllegalArgumentException e) { /* LOG */}
|
||||
}
|
||||
engine.setNeedClientAuth (params.getNeedClientAuth());
|
||||
engine.setWantClientAuth (params.getWantClientAuth());
|
||||
if (params.getProtocols() != null) {
|
||||
try {
|
||||
engine.setEnabledProtocols (
|
||||
params.getProtocols()
|
||||
);
|
||||
} catch (IllegalArgumentException e) { /* LOG */}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Parameters extends HttpsParameters {
|
||||
InetSocketAddress addr;
|
||||
HttpsConfigurator cfg;
|
||||
|
||||
Parameters (HttpsConfigurator cfg, InetSocketAddress addr) {
|
||||
this.addr = addr;
|
||||
this.cfg = cfg;
|
||||
}
|
||||
public InetSocketAddress getClientAddress () {
|
||||
return addr;
|
||||
}
|
||||
public HttpsConfigurator getHttpsConfigurator() {
|
||||
return cfg;
|
||||
}
|
||||
//BEGIN_TIGER_EXCLUDE
|
||||
SSLParameters params;
|
||||
public void setSSLParameters (SSLParameters p) {
|
||||
params = p;
|
||||
}
|
||||
SSLParameters getSSLParameters () {
|
||||
return params;
|
||||
}
|
||||
//END_TIGER_EXCLUDE
|
||||
}
|
||||
|
||||
/**
|
||||
* cleanup resources allocated inside this object
|
||||
*/
|
||||
void close () throws IOException {
|
||||
wrapper.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* return the SSL InputStream
|
||||
*/
|
||||
InputStream getInputStream () throws IOException {
|
||||
if (is == null) {
|
||||
is = new InputStream();
|
||||
}
|
||||
return is;
|
||||
}
|
||||
|
||||
/**
|
||||
* return the SSL OutputStream
|
||||
*/
|
||||
OutputStream getOutputStream () throws IOException {
|
||||
if (os == null) {
|
||||
os = new OutputStream();
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
SSLEngine getSSLEngine () {
|
||||
return engine;
|
||||
}
|
||||
|
||||
/**
|
||||
* request the engine to repeat the handshake on this session
|
||||
* the handshake must be driven by reads/writes on the streams
|
||||
* Normally, not necessary to call this.
|
||||
*/
|
||||
void beginHandshake() throws SSLException {
|
||||
engine.beginHandshake();
|
||||
}
|
||||
|
||||
class WrapperResult {
|
||||
SSLEngineResult result;
|
||||
|
||||
/* if passed in buffer was not big enough then the
|
||||
* a reallocated buffer is returned here
|
||||
*/
|
||||
ByteBuffer buf;
|
||||
}
|
||||
|
||||
int app_buf_size;
|
||||
int packet_buf_size;
|
||||
|
||||
enum BufType {
|
||||
PACKET, APPLICATION
|
||||
};
|
||||
|
||||
private ByteBuffer allocate (BufType type) {
|
||||
return allocate (type, -1);
|
||||
}
|
||||
|
||||
private ByteBuffer allocate (BufType type, int len) {
|
||||
assert engine != null;
|
||||
synchronized (this) {
|
||||
int size;
|
||||
if (type == BufType.PACKET) {
|
||||
if (packet_buf_size == 0) {
|
||||
SSLSession sess = engine.getSession();
|
||||
packet_buf_size = sess.getPacketBufferSize();
|
||||
}
|
||||
if (len > packet_buf_size) {
|
||||
packet_buf_size = len;
|
||||
}
|
||||
size = packet_buf_size;
|
||||
} else {
|
||||
if (app_buf_size == 0) {
|
||||
SSLSession sess = engine.getSession();
|
||||
app_buf_size = sess.getApplicationBufferSize();
|
||||
}
|
||||
if (len > app_buf_size) {
|
||||
app_buf_size = len;
|
||||
}
|
||||
size = app_buf_size;
|
||||
}
|
||||
return ByteBuffer.allocate (size);
|
||||
}
|
||||
}
|
||||
|
||||
/* reallocates the buffer by :-
|
||||
* 1. creating a new buffer double the size of the old one
|
||||
* 2. putting the contents of the old buffer into the new one
|
||||
* 3. set xx_buf_size to the new size if it was smaller than new size
|
||||
*
|
||||
* flip is set to true if the old buffer needs to be flipped
|
||||
* before it is copied.
|
||||
*/
|
||||
private ByteBuffer realloc (ByteBuffer b, boolean flip, BufType type) {
|
||||
synchronized (this) {
|
||||
int nsize = 2 * b.capacity();
|
||||
ByteBuffer n = allocate (type, nsize);
|
||||
if (flip) {
|
||||
b.flip();
|
||||
}
|
||||
n.put(b);
|
||||
b = n;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
/**
|
||||
* This is a thin wrapper over SSLEngine and the SocketChannel,
|
||||
* which guarantees the ordering of wraps/unwraps with respect to the underlying
|
||||
* channel read/writes. It handles the UNDER/OVERFLOW status codes
|
||||
* It does not handle the handshaking status codes, or the CLOSED status code
|
||||
* though once the engine is closed, any attempt to read/write to it
|
||||
* will get an exception. The overall result is returned.
|
||||
* It functions synchronously/blocking
|
||||
*/
|
||||
class EngineWrapper {
|
||||
|
||||
SocketChannel chan;
|
||||
SSLEngine engine;
|
||||
Object wrapLock, unwrapLock;
|
||||
ByteBuffer unwrap_src, wrap_dst;
|
||||
boolean closed = false;
|
||||
int u_remaining; // the number of bytes left in unwrap_src after an unwrap()
|
||||
|
||||
EngineWrapper (SocketChannel chan, SSLEngine engine) throws IOException {
|
||||
this.chan = chan;
|
||||
this.engine = engine;
|
||||
wrapLock = new Object();
|
||||
unwrapLock = new Object();
|
||||
unwrap_src = allocate(BufType.PACKET);
|
||||
wrap_dst = allocate(BufType.PACKET);
|
||||
}
|
||||
|
||||
void close () throws IOException {
|
||||
}
|
||||
|
||||
/* try to wrap and send the data in src. Handles OVERFLOW.
|
||||
* Might block if there is an outbound blockage or if another
|
||||
* thread is calling wrap(). Also, might not send any data
|
||||
* if an unwrap is needed.
|
||||
*/
|
||||
WrapperResult wrapAndSend(ByteBuffer src) throws IOException {
|
||||
return wrapAndSendX(src, false);
|
||||
}
|
||||
|
||||
WrapperResult wrapAndSendX(ByteBuffer src, boolean ignoreClose) throws IOException {
|
||||
if (closed && !ignoreClose) {
|
||||
throw new IOException ("Engine is closed");
|
||||
}
|
||||
Status status;
|
||||
WrapperResult r = new WrapperResult();
|
||||
synchronized (wrapLock) {
|
||||
wrap_dst.clear();
|
||||
do {
|
||||
r.result = engine.wrap (src, wrap_dst);
|
||||
status = r.result.getStatus();
|
||||
if (status == Status.BUFFER_OVERFLOW) {
|
||||
wrap_dst = realloc (wrap_dst, true, BufType.PACKET);
|
||||
}
|
||||
} while (status == Status.BUFFER_OVERFLOW);
|
||||
if (status == Status.CLOSED && !ignoreClose) {
|
||||
closed = true;
|
||||
return r;
|
||||
}
|
||||
if (r.result.bytesProduced() > 0) {
|
||||
wrap_dst.flip();
|
||||
int l = wrap_dst.remaining();
|
||||
assert l == r.result.bytesProduced();
|
||||
while (l>0) {
|
||||
l -= chan.write (wrap_dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/* block until a complete message is available and return it
|
||||
* in dst, together with the Result. dst may have been re-allocated
|
||||
* so caller should check the returned value in Result
|
||||
* If handshaking is in progress then, possibly no data is returned
|
||||
*/
|
||||
WrapperResult recvAndUnwrap(ByteBuffer dst) throws IOException {
|
||||
Status status = Status.OK;
|
||||
WrapperResult r = new WrapperResult();
|
||||
r.buf = dst;
|
||||
if (closed) {
|
||||
throw new IOException ("Engine is closed");
|
||||
}
|
||||
boolean needData;
|
||||
if (u_remaining > 0) {
|
||||
unwrap_src.compact();
|
||||
unwrap_src.flip();
|
||||
needData = false;
|
||||
} else {
|
||||
unwrap_src.clear();
|
||||
needData = true;
|
||||
}
|
||||
synchronized (unwrapLock) {
|
||||
int x;
|
||||
do {
|
||||
if (needData) {
|
||||
do {
|
||||
x = chan.read (unwrap_src);
|
||||
} while (x == 0);
|
||||
if (x == -1) {
|
||||
throw new IOException ("connection closed for reading");
|
||||
}
|
||||
unwrap_src.flip();
|
||||
}
|
||||
r.result = engine.unwrap (unwrap_src, r.buf);
|
||||
status = r.result.getStatus();
|
||||
if (status == Status.BUFFER_UNDERFLOW) {
|
||||
if (unwrap_src.limit() == unwrap_src.capacity()) {
|
||||
/* buffer not big enough */
|
||||
unwrap_src = realloc (
|
||||
unwrap_src, false, BufType.PACKET
|
||||
);
|
||||
} else {
|
||||
/* Buffer not full, just need to read more
|
||||
* data off the channel. Reset pointers
|
||||
* for reading off SocketChannel
|
||||
*/
|
||||
unwrap_src.position (unwrap_src.limit());
|
||||
unwrap_src.limit (unwrap_src.capacity());
|
||||
}
|
||||
needData = true;
|
||||
} else if (status == Status.BUFFER_OVERFLOW) {
|
||||
r.buf = realloc (r.buf, true, BufType.APPLICATION);
|
||||
needData = false;
|
||||
} else if (status == Status.CLOSED) {
|
||||
closed = true;
|
||||
r.buf.flip();
|
||||
return r;
|
||||
}
|
||||
} while (status != Status.OK);
|
||||
}
|
||||
u_remaining = unwrap_src.remaining();
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* send the data in the given ByteBuffer. If a handshake is needed
|
||||
* then this is handled within this method. When this call returns,
|
||||
* all of the given user data has been sent and any handshake has been
|
||||
* completed. Caller should check if engine has been closed.
|
||||
*/
|
||||
public WrapperResult sendData (ByteBuffer src) throws IOException {
|
||||
WrapperResult r=null;
|
||||
while (src.remaining() > 0) {
|
||||
r = wrapper.wrapAndSend(src);
|
||||
Status status = r.result.getStatus();
|
||||
if (status == Status.CLOSED) {
|
||||
doClosure ();
|
||||
return r;
|
||||
}
|
||||
HandshakeStatus hs_status = r.result.getHandshakeStatus();
|
||||
if (hs_status != HandshakeStatus.FINISHED &&
|
||||
hs_status != HandshakeStatus.NOT_HANDSHAKING)
|
||||
{
|
||||
doHandshake(hs_status);
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* read data thru the engine into the given ByteBuffer. If the
|
||||
* given buffer was not large enough, a new one is allocated
|
||||
* and returned. This call handles handshaking automatically.
|
||||
* Caller should check if engine has been closed.
|
||||
*/
|
||||
public WrapperResult recvData (ByteBuffer dst) throws IOException {
|
||||
/* we wait until some user data arrives */
|
||||
WrapperResult r = null;
|
||||
assert dst.position() == 0;
|
||||
while (dst.position() == 0) {
|
||||
r = wrapper.recvAndUnwrap (dst);
|
||||
dst = (r.buf != dst) ? r.buf: dst;
|
||||
Status status = r.result.getStatus();
|
||||
if (status == Status.CLOSED) {
|
||||
doClosure ();
|
||||
return r;
|
||||
}
|
||||
|
||||
HandshakeStatus hs_status = r.result.getHandshakeStatus();
|
||||
if (hs_status != HandshakeStatus.FINISHED &&
|
||||
hs_status != HandshakeStatus.NOT_HANDSHAKING)
|
||||
{
|
||||
doHandshake (hs_status);
|
||||
}
|
||||
}
|
||||
dst.flip();
|
||||
return r;
|
||||
}
|
||||
|
||||
/* we've received a close notify. Need to call wrap to send
|
||||
* the response
|
||||
*/
|
||||
void doClosure () throws IOException {
|
||||
try {
|
||||
handshaking.lock();
|
||||
ByteBuffer tmp = allocate(BufType.APPLICATION);
|
||||
WrapperResult r;
|
||||
Status st;
|
||||
HandshakeStatus hs;
|
||||
do {
|
||||
tmp.clear();
|
||||
tmp.flip ();
|
||||
r = wrapper.wrapAndSendX (tmp, true);
|
||||
hs = r.result.getHandshakeStatus();
|
||||
st = r.result.getStatus();
|
||||
} while (st != Status.CLOSED &&
|
||||
!(st == Status.OK && hs == HandshakeStatus.NOT_HANDSHAKING));
|
||||
} finally {
|
||||
handshaking.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/* do the (complete) handshake after acquiring the handshake lock.
|
||||
* If two threads call this at the same time, then we depend
|
||||
* on the wrapper methods being idempotent. eg. if wrapAndSend()
|
||||
* is called with no data to send then there must be no problem
|
||||
*/
|
||||
@SuppressWarnings("fallthrough")
|
||||
void doHandshake (HandshakeStatus hs_status) throws IOException {
|
||||
try {
|
||||
handshaking.lock();
|
||||
ByteBuffer tmp = allocate(BufType.APPLICATION);
|
||||
while (hs_status != HandshakeStatus.FINISHED &&
|
||||
hs_status != HandshakeStatus.NOT_HANDSHAKING)
|
||||
{
|
||||
WrapperResult r = null;
|
||||
switch (hs_status) {
|
||||
case NEED_TASK:
|
||||
Runnable task;
|
||||
while ((task = engine.getDelegatedTask()) != null) {
|
||||
/* run in current thread, because we are already
|
||||
* running an external Executor
|
||||
*/
|
||||
task.run();
|
||||
}
|
||||
/* fall thru - call wrap again */
|
||||
case NEED_WRAP:
|
||||
tmp.clear();
|
||||
tmp.flip();
|
||||
r = wrapper.wrapAndSend(tmp);
|
||||
break;
|
||||
|
||||
case NEED_UNWRAP:
|
||||
tmp.clear();
|
||||
r = wrapper.recvAndUnwrap (tmp);
|
||||
if (r.buf != tmp) {
|
||||
tmp = r.buf;
|
||||
}
|
||||
assert tmp.position() == 0;
|
||||
break;
|
||||
}
|
||||
hs_status = r.result.getHandshakeStatus();
|
||||
}
|
||||
} finally {
|
||||
handshaking.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* represents an SSL input stream. Multiple https requests can
|
||||
* be sent over one stream. closing this stream causes an SSL close
|
||||
* input.
|
||||
*/
|
||||
class InputStream extends java.io.InputStream {
|
||||
|
||||
ByteBuffer bbuf;
|
||||
boolean closed = false;
|
||||
|
||||
/* this stream eof */
|
||||
boolean eof = false;
|
||||
|
||||
boolean needData = true;
|
||||
|
||||
InputStream () {
|
||||
bbuf = allocate (BufType.APPLICATION);
|
||||
}
|
||||
|
||||
public int read (byte[] buf, int off, int len) throws IOException {
|
||||
if (closed) {
|
||||
throw new IOException ("SSL stream is closed");
|
||||
}
|
||||
if (eof) {
|
||||
return -1;
|
||||
}
|
||||
int available=0;
|
||||
if (!needData) {
|
||||
available = bbuf.remaining();
|
||||
needData = (available==0);
|
||||
}
|
||||
if (needData) {
|
||||
bbuf.clear();
|
||||
WrapperResult r = recvData (bbuf);
|
||||
bbuf = r.buf== bbuf? bbuf: r.buf;
|
||||
if ((available=bbuf.remaining()) == 0) {
|
||||
eof = true;
|
||||
return -1;
|
||||
} else {
|
||||
needData = false;
|
||||
}
|
||||
}
|
||||
/* copy as much as possible from buf into users buf */
|
||||
if (len > available) {
|
||||
len = available;
|
||||
}
|
||||
bbuf.get (buf, off, len);
|
||||
return len;
|
||||
}
|
||||
|
||||
public int available () throws IOException {
|
||||
return bbuf.remaining();
|
||||
}
|
||||
|
||||
public boolean markSupported () {
|
||||
return false; /* not possible with SSLEngine */
|
||||
}
|
||||
|
||||
public void reset () throws IOException {
|
||||
throw new IOException ("mark/reset not supported");
|
||||
}
|
||||
|
||||
public long skip (long s) throws IOException {
|
||||
int n = (int)s;
|
||||
if (closed) {
|
||||
throw new IOException ("SSL stream is closed");
|
||||
}
|
||||
if (eof) {
|
||||
return 0;
|
||||
}
|
||||
int ret = n;
|
||||
while (n > 0) {
|
||||
if (bbuf.remaining() >= n) {
|
||||
bbuf.position (bbuf.position()+n);
|
||||
return ret;
|
||||
} else {
|
||||
n -= bbuf.remaining();
|
||||
bbuf.clear();
|
||||
WrapperResult r = recvData (bbuf);
|
||||
bbuf = r.buf==bbuf? bbuf: r.buf;
|
||||
}
|
||||
}
|
||||
return ret; /* not reached */
|
||||
}
|
||||
|
||||
/**
|
||||
* close the SSL connection. All data must have been consumed
|
||||
* before this is called. Otherwise an exception will be thrown.
|
||||
* [Note. May need to revisit this. not quite the normal close() semantics
|
||||
*/
|
||||
public void close () throws IOException {
|
||||
eof = true;
|
||||
engine.closeInbound ();
|
||||
}
|
||||
|
||||
public int read (byte[] buf) throws IOException {
|
||||
return read (buf, 0, buf.length);
|
||||
}
|
||||
|
||||
byte single[] = new byte [1];
|
||||
|
||||
public int read () throws IOException {
|
||||
if (eof) {
|
||||
return -1;
|
||||
}
|
||||
int n = read (single, 0, 1);
|
||||
if (n <= 0) {
|
||||
return -1;
|
||||
} else {
|
||||
return single[0] & 0xFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* represents an SSL output stream. plain text data written to this stream
|
||||
* is encrypted by the stream. Multiple HTTPS responses can be sent on
|
||||
* one stream. closing this stream initiates an SSL closure
|
||||
*/
|
||||
class OutputStream extends java.io.OutputStream {
|
||||
ByteBuffer buf;
|
||||
boolean closed = false;
|
||||
byte single[] = new byte[1];
|
||||
|
||||
OutputStream() {
|
||||
buf = allocate(BufType.APPLICATION);
|
||||
}
|
||||
|
||||
public void write(int b) throws IOException {
|
||||
single[0] = (byte)b;
|
||||
write (single, 0, 1);
|
||||
}
|
||||
|
||||
public void write(byte b[]) throws IOException {
|
||||
write (b, 0, b.length);
|
||||
}
|
||||
public void write(byte b[], int off, int len) throws IOException {
|
||||
if (closed) {
|
||||
throw new IOException ("output stream is closed");
|
||||
}
|
||||
while (len > 0) {
|
||||
int l = len > buf.capacity() ? buf.capacity() : len;
|
||||
buf.clear();
|
||||
buf.put (b, off, l);
|
||||
len -= l;
|
||||
off += l;
|
||||
buf.flip();
|
||||
WrapperResult r = sendData (buf);
|
||||
if (r.result.getStatus() == Status.CLOSED) {
|
||||
closed = true;
|
||||
if (len > 0) {
|
||||
throw new IOException ("output stream is closed");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void flush() throws IOException {
|
||||
/* no-op */
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
WrapperResult r=null;
|
||||
engine.closeOutbound();
|
||||
closed = true;
|
||||
HandshakeStatus stat = HandshakeStatus.NEED_WRAP;
|
||||
buf.clear();
|
||||
while (stat == HandshakeStatus.NEED_WRAP) {
|
||||
r = wrapper.wrapAndSend (buf);
|
||||
stat = r.result.getHandshakeStatus();
|
||||
}
|
||||
assert r.result.getStatus() == Status.CLOSED;
|
||||
}
|
||||
}
|
||||
}
|
||||
239
jdkSrc/jdk8/sun/net/httpserver/ServerConfig.java
Normal file
239
jdkSrc/jdk8/sun/net/httpserver/ServerConfig.java
Normal file
@@ -0,0 +1,239 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 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 sun.net.httpserver;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
/**
|
||||
* Parameters that users will not likely need to set
|
||||
* but are useful for debugging
|
||||
*/
|
||||
|
||||
class ServerConfig {
|
||||
|
||||
private static final int DEFAULT_IDLE_TIMER_SCHEDULE_MILLIS = 10000 ; // 10 sec.
|
||||
|
||||
private static final long DEFAULT_IDLE_INTERVAL_IN_SECS = 30;
|
||||
private static final int DEFAULT_MAX_CONNECTIONS = -1 ; // no limit on maximum connections
|
||||
private static final int DEFAULT_MAX_IDLE_CONNECTIONS = 200 ;
|
||||
|
||||
private static final long DEFAULT_MAX_REQ_TIME = -1; // default: forever
|
||||
private static final long DEFAULT_MAX_RSP_TIME = -1; // default: forever
|
||||
// default timer schedule, in milli seconds, for the timer task that's responsible for
|
||||
// timing out request/response if max request/response time is configured
|
||||
private static final long DEFAULT_REQ_RSP_TIMER_TASK_SCHEDULE_MILLIS = 1000;
|
||||
private static final int DEFAULT_MAX_REQ_HEADERS = 200;
|
||||
private static final long DEFAULT_DRAIN_AMOUNT = 64 * 1024;
|
||||
|
||||
private static long idleTimerScheduleMillis;
|
||||
private static long idleIntervalMillis;
|
||||
// The maximum number of bytes to drain from an inputstream
|
||||
private static long drainAmount;
|
||||
// the maximum number of connections that the server will allow to be open
|
||||
// after which it will no longer "accept()" any new connections, till the
|
||||
// current connection count goes down due to completion of processing the requests
|
||||
private static int maxConnections;
|
||||
private static int maxIdleConnections;
|
||||
// The maximum number of request headers allowable
|
||||
private static int maxReqHeaders;
|
||||
// max time a request or response is allowed to take
|
||||
private static long maxReqTime;
|
||||
private static long maxRspTime;
|
||||
private static long reqRspTimerScheduleMillis;
|
||||
private static boolean debug;
|
||||
|
||||
// the value of the TCP_NODELAY socket-level option
|
||||
private static boolean noDelay;
|
||||
|
||||
static {
|
||||
java.security.AccessController.doPrivileged(
|
||||
new PrivilegedAction<Void>() {
|
||||
@Override
|
||||
public Void run () {
|
||||
idleIntervalMillis = Long.getLong("sun.net.httpserver.idleInterval",
|
||||
DEFAULT_IDLE_INTERVAL_IN_SECS) * 1000;
|
||||
if (idleIntervalMillis <= 0) {
|
||||
idleIntervalMillis = DEFAULT_IDLE_INTERVAL_IN_SECS * 1000;
|
||||
}
|
||||
|
||||
idleTimerScheduleMillis = Long.getLong("sun.net.httpserver.clockTick",
|
||||
DEFAULT_IDLE_TIMER_SCHEDULE_MILLIS);
|
||||
if (idleTimerScheduleMillis <= 0) {
|
||||
// ignore zero or negative value and use the default schedule
|
||||
idleTimerScheduleMillis = DEFAULT_IDLE_TIMER_SCHEDULE_MILLIS;
|
||||
}
|
||||
|
||||
maxConnections = Integer.getInteger(
|
||||
"jdk.httpserver.maxConnections",
|
||||
DEFAULT_MAX_CONNECTIONS);
|
||||
|
||||
maxIdleConnections = Integer.getInteger(
|
||||
"sun.net.httpserver.maxIdleConnections",
|
||||
DEFAULT_MAX_IDLE_CONNECTIONS);
|
||||
|
||||
drainAmount = Long.getLong("sun.net.httpserver.drainAmount",
|
||||
DEFAULT_DRAIN_AMOUNT);
|
||||
|
||||
maxReqHeaders = Integer.getInteger(
|
||||
"sun.net.httpserver.maxReqHeaders",
|
||||
DEFAULT_MAX_REQ_HEADERS);
|
||||
|
||||
maxReqTime = Long.getLong("sun.net.httpserver.maxReqTime",
|
||||
DEFAULT_MAX_REQ_TIME);
|
||||
|
||||
maxRspTime = Long.getLong("sun.net.httpserver.maxRspTime",
|
||||
DEFAULT_MAX_RSP_TIME);
|
||||
|
||||
reqRspTimerScheduleMillis = Long.getLong("sun.net.httpserver.timerMillis",
|
||||
DEFAULT_REQ_RSP_TIMER_TASK_SCHEDULE_MILLIS);
|
||||
if (reqRspTimerScheduleMillis <= 0) {
|
||||
// ignore any negative or zero value for this configuration and reset
|
||||
// to default schedule
|
||||
reqRspTimerScheduleMillis = DEFAULT_REQ_RSP_TIMER_TASK_SCHEDULE_MILLIS;
|
||||
}
|
||||
|
||||
debug = Boolean.getBoolean("sun.net.httpserver.debug");
|
||||
|
||||
noDelay = Boolean.getBoolean("sun.net.httpserver.nodelay");
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
static void checkLegacyProperties(final Logger logger) {
|
||||
|
||||
// legacy properties that are no longer used
|
||||
// print a warning to logger if they are set.
|
||||
|
||||
java.security.AccessController.doPrivileged(
|
||||
new PrivilegedAction<Void>() {
|
||||
public Void run () {
|
||||
if (System.getProperty("sun.net.httpserver.readTimeout")
|
||||
!=null)
|
||||
{
|
||||
logger.warning ("sun.net.httpserver.readTimeout "+
|
||||
"property is no longer used. "+
|
||||
"Use sun.net.httpserver.maxReqTime instead."
|
||||
);
|
||||
}
|
||||
if (System.getProperty("sun.net.httpserver.writeTimeout")
|
||||
!=null)
|
||||
{
|
||||
logger.warning ("sun.net.httpserver.writeTimeout "+
|
||||
"property is no longer used. Use "+
|
||||
"sun.net.httpserver.maxRspTime instead."
|
||||
);
|
||||
}
|
||||
if (System.getProperty("sun.net.httpserver.selCacheTimeout")
|
||||
!=null)
|
||||
{
|
||||
logger.warning ("sun.net.httpserver.selCacheTimeout "+
|
||||
"property is no longer used."
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
static boolean debugEnabled() {
|
||||
return debug;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return Returns the maximum duration, in milli seconds, a connection can be idle}
|
||||
*/
|
||||
static long getIdleIntervalMillis() {
|
||||
return idleIntervalMillis;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return Returns the schedule, in milli seconds, for the timer task that is responsible
|
||||
* for managing the idle connections}
|
||||
*/
|
||||
static long getIdleTimerScheduleMillis() {
|
||||
return idleTimerScheduleMillis;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the maximum number of connections that can be open at any given time.
|
||||
* This method can return a value of 0 or negative to represent that the limit hasn't
|
||||
* been configured.
|
||||
*/
|
||||
static int getMaxConnections() {
|
||||
return maxConnections;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the maximum number of connections that can be idle. This method
|
||||
* can return a value of 0 or negative.
|
||||
*/
|
||||
static int getMaxIdleConnections() {
|
||||
return maxIdleConnections;
|
||||
}
|
||||
|
||||
static long getDrainAmount() {
|
||||
return drainAmount;
|
||||
}
|
||||
|
||||
static int getMaxReqHeaders() {
|
||||
return maxReqHeaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the maximum amount of time the server will wait for the request to be read
|
||||
* completely. This method can return a value of 0 or negative to imply no maximum limit has
|
||||
* been configured.
|
||||
*/
|
||||
static long getMaxReqTime() {
|
||||
return maxReqTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the maximum amount of time the server will wait for the response to be generated
|
||||
* for a request that is being processed. This method can return a value of 0 or negative to
|
||||
* imply no maximum limit has been configured.
|
||||
*/
|
||||
static long getMaxRspTime() {
|
||||
return maxRspTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return Returns the timer schedule of the task that's responsible for timing out
|
||||
* request/response that have been running longer than any configured timeout}
|
||||
*/
|
||||
static long getReqRspTimerScheduleMillis() {
|
||||
return reqRspTimerScheduleMillis;
|
||||
}
|
||||
|
||||
static boolean noDelay() {
|
||||
return noDelay;
|
||||
}
|
||||
}
|
||||
1067
jdkSrc/jdk8/sun/net/httpserver/ServerImpl.java
Normal file
1067
jdkSrc/jdk8/sun/net/httpserver/ServerImpl.java
Normal file
File diff suppressed because it is too large
Load Diff
32
jdkSrc/jdk8/sun/net/httpserver/StreamClosedException.java
Normal file
32
jdkSrc/jdk8/sun/net/httpserver/StreamClosedException.java
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 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 sun.net.httpserver;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
class StreamClosedException extends IOException {
|
||||
private static final long serialVersionUID = -4485921499356327937L;
|
||||
}
|
||||
81
jdkSrc/jdk8/sun/net/httpserver/UndefLengthOutputStream.java
Normal file
81
jdkSrc/jdk8/sun/net/httpserver/UndefLengthOutputStream.java
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 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 sun.net.httpserver;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import com.sun.net.httpserver.*;
|
||||
import com.sun.net.httpserver.spi.*;
|
||||
|
||||
/**
|
||||
* a class which allows the caller to write an indefinite
|
||||
* number of bytes to an underlying stream , but without using
|
||||
* chunked encoding. Used for http/1.0 clients only
|
||||
* The underlying connection needs to be closed afterwards.
|
||||
*/
|
||||
|
||||
class UndefLengthOutputStream extends FilterOutputStream
|
||||
{
|
||||
private boolean closed = false;
|
||||
ExchangeImpl t;
|
||||
|
||||
UndefLengthOutputStream (ExchangeImpl t, OutputStream src) {
|
||||
super (src);
|
||||
this.t = t;
|
||||
}
|
||||
|
||||
public void write (int b) throws IOException {
|
||||
if (closed) {
|
||||
throw new IOException ("stream closed");
|
||||
}
|
||||
out.write(b);
|
||||
}
|
||||
|
||||
public void write (byte[]b, int off, int len) throws IOException {
|
||||
if (closed) {
|
||||
throw new IOException ("stream closed");
|
||||
}
|
||||
out.write(b, off, len);
|
||||
}
|
||||
|
||||
public void close () throws IOException {
|
||||
if (closed) {
|
||||
return;
|
||||
}
|
||||
closed = true;
|
||||
flush();
|
||||
LeftOverInputStream is = t.getOriginalInputStream();
|
||||
if (!is.isClosed()) {
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException e) {}
|
||||
}
|
||||
WriteFinishedEvent e = new WriteFinishedEvent (t);
|
||||
t.getHttpContext().getServerImpl().addEvent (e);
|
||||
}
|
||||
|
||||
// flush is a pass-through
|
||||
}
|
||||
101
jdkSrc/jdk8/sun/net/httpserver/UnmodifiableHeaders.java
Normal file
101
jdkSrc/jdk8/sun/net/httpserver/UnmodifiableHeaders.java
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (c) 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 sun.net.httpserver;
|
||||
|
||||
import java.util.*;
|
||||
import com.sun.net.httpserver.*;
|
||||
|
||||
class UnmodifiableHeaders extends Headers {
|
||||
|
||||
Headers map;
|
||||
|
||||
UnmodifiableHeaders(Headers map) {
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
public int size() {return map.size();}
|
||||
|
||||
public boolean isEmpty() {return map.isEmpty();}
|
||||
|
||||
public boolean containsKey(Object key) {
|
||||
return map.containsKey (key);
|
||||
}
|
||||
|
||||
public boolean containsValue(Object value) {
|
||||
return map.containsValue(value);
|
||||
}
|
||||
|
||||
public List<String> get(Object key) {
|
||||
return map.get(key);
|
||||
}
|
||||
|
||||
public String getFirst (String key) {
|
||||
return map.getFirst(key);
|
||||
}
|
||||
|
||||
|
||||
public List<String> put(String key, List<String> value) {
|
||||
return map.put (key, value);
|
||||
}
|
||||
|
||||
public void add (String key, String value) {
|
||||
throw new UnsupportedOperationException ("unsupported operation");
|
||||
}
|
||||
|
||||
public void set (String key, String value) {
|
||||
throw new UnsupportedOperationException ("unsupported operation");
|
||||
}
|
||||
|
||||
public List<String> remove(Object key) {
|
||||
throw new UnsupportedOperationException ("unsupported operation");
|
||||
}
|
||||
|
||||
public void putAll(Map<? extends String,? extends List<String>> t) {
|
||||
throw new UnsupportedOperationException ("unsupported operation");
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
throw new UnsupportedOperationException ("unsupported operation");
|
||||
}
|
||||
|
||||
public Set<String> keySet() {
|
||||
return Collections.unmodifiableSet (map.keySet());
|
||||
}
|
||||
|
||||
public Collection<List<String>> values() {
|
||||
return Collections.unmodifiableCollection(map.values());
|
||||
}
|
||||
|
||||
/* TODO check that contents of set are not modifable : security */
|
||||
|
||||
public Set<Map.Entry<String, List<String>>> entrySet() {
|
||||
return Collections.unmodifiableSet (map.entrySet());
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {return map.equals(o);}
|
||||
|
||||
public int hashCode() {return map.hashCode();}
|
||||
}
|
||||
34
jdkSrc/jdk8/sun/net/httpserver/WriteFinishedEvent.java
Normal file
34
jdkSrc/jdk8/sun/net/httpserver/WriteFinishedEvent.java
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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 sun.net.httpserver;
|
||||
|
||||
class WriteFinishedEvent extends Event {
|
||||
WriteFinishedEvent (ExchangeImpl t) {
|
||||
super (t);
|
||||
assert !t.writefinished;
|
||||
t.writefinished = true;
|
||||
}
|
||||
}
|
||||
511
jdkSrc/jdk8/sun/net/idn/Punycode.java
Normal file
511
jdkSrc/jdk8/sun/net/idn/Punycode.java
Normal file
@@ -0,0 +1,511 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2003-2004, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
//
|
||||
// CHANGELOG
|
||||
// 2005-05-19 Edward Wang
|
||||
// - copy this file from icu4jsrc_3_2/src/com/ibm/icu/text/Punycode.java
|
||||
// - move from package com.ibm.icu.text to package sun.net.idn
|
||||
// - use ParseException instead of StringPrepParseException
|
||||
// 2007-08-14 Martin Buchholz
|
||||
// - remove redundant casts
|
||||
//
|
||||
package sun.net.idn;
|
||||
|
||||
import java.text.ParseException;
|
||||
import sun.text.normalizer.UCharacter;
|
||||
import sun.text.normalizer.UTF16;
|
||||
|
||||
/**
|
||||
* Ported code from ICU punycode.c
|
||||
* @author ram
|
||||
*/
|
||||
|
||||
/* Package Private class */
|
||||
public final class Punycode {
|
||||
|
||||
/* Punycode parameters for Bootstring */
|
||||
private static final int BASE = 36;
|
||||
private static final int TMIN = 1;
|
||||
private static final int TMAX = 26;
|
||||
private static final int SKEW = 38;
|
||||
private static final int DAMP = 700;
|
||||
private static final int INITIAL_BIAS = 72;
|
||||
private static final int INITIAL_N = 0x80;
|
||||
|
||||
/* "Basic" Unicode/ASCII code points */
|
||||
private static final int HYPHEN = 0x2d;
|
||||
private static final int DELIMITER = HYPHEN;
|
||||
|
||||
private static final int ZERO = 0x30;
|
||||
private static final int NINE = 0x39;
|
||||
|
||||
private static final int SMALL_A = 0x61;
|
||||
private static final int SMALL_Z = 0x7a;
|
||||
|
||||
private static final int CAPITAL_A = 0x41;
|
||||
private static final int CAPITAL_Z = 0x5a;
|
||||
|
||||
// TODO: eliminate the 256 limitation
|
||||
private static final int MAX_CP_COUNT = 256;
|
||||
|
||||
private static final int UINT_MAGIC = 0x80000000;
|
||||
private static final long ULONG_MAGIC = 0x8000000000000000L;
|
||||
|
||||
private static int adaptBias(int delta, int length, boolean firstTime){
|
||||
if(firstTime){
|
||||
delta /=DAMP;
|
||||
}else{
|
||||
delta /= 2;
|
||||
}
|
||||
delta += delta/length;
|
||||
|
||||
int count=0;
|
||||
for(; delta>((BASE-TMIN)*TMAX)/2; count+=BASE) {
|
||||
delta/=(BASE-TMIN);
|
||||
}
|
||||
|
||||
return count+(((BASE-TMIN+1)*delta)/(delta+SKEW));
|
||||
}
|
||||
|
||||
/**
|
||||
* basicToDigit[] contains the numeric value of a basic code
|
||||
* point (for use in representing integers) in the range 0 to
|
||||
* BASE-1, or -1 if b is does not represent a value.
|
||||
*/
|
||||
static final int[] basicToDigit= new int[]{
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1,
|
||||
|
||||
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
|
||||
|
||||
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
|
||||
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
|
||||
};
|
||||
|
||||
private static char asciiCaseMap(char b, boolean uppercase) {
|
||||
if(uppercase) {
|
||||
if(SMALL_A<=b && b<=SMALL_Z) {
|
||||
b-=(SMALL_A-CAPITAL_A);
|
||||
}
|
||||
} else {
|
||||
if(CAPITAL_A<=b && b<=CAPITAL_Z) {
|
||||
b+=(SMALL_A-CAPITAL_A);
|
||||
}
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
/**
|
||||
* digitToBasic() returns the basic code point whose value
|
||||
* (when used for representing integers) is d, which must be in the
|
||||
* range 0 to BASE-1. The lowercase form is used unless the uppercase flag is
|
||||
* nonzero, in which case the uppercase form is used.
|
||||
*/
|
||||
private static char digitToBasic(int digit, boolean uppercase) {
|
||||
/* 0..25 map to ASCII a..z or A..Z */
|
||||
/* 26..35 map to ASCII 0..9 */
|
||||
if(digit<26) {
|
||||
if(uppercase) {
|
||||
return (char)(CAPITAL_A+digit);
|
||||
} else {
|
||||
return (char)(SMALL_A+digit);
|
||||
}
|
||||
} else {
|
||||
return (char)((ZERO-26)+digit);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Converts Unicode to Punycode.
|
||||
* The input string must not contain single, unpaired surrogates.
|
||||
* The output will be represented as an array of ASCII code points.
|
||||
*
|
||||
* @param src
|
||||
* @param caseFlags
|
||||
* @return
|
||||
* @throws ParseException
|
||||
*/
|
||||
public static StringBuffer encode(StringBuffer src, boolean[] caseFlags) throws ParseException{
|
||||
|
||||
int[] cpBuffer = new int[MAX_CP_COUNT];
|
||||
int n, delta, handledCPCount, basicLength, destLength, bias, j, m, q, k, t, srcCPCount;
|
||||
char c, c2;
|
||||
int srcLength = src.length();
|
||||
int destCapacity = MAX_CP_COUNT;
|
||||
char[] dest = new char[destCapacity];
|
||||
StringBuffer result = new StringBuffer();
|
||||
/*
|
||||
* Handle the basic code points and
|
||||
* convert extended ones to UTF-32 in cpBuffer (caseFlag in sign bit):
|
||||
*/
|
||||
srcCPCount=destLength=0;
|
||||
|
||||
for(j=0; j<srcLength; ++j) {
|
||||
if(srcCPCount==MAX_CP_COUNT) {
|
||||
/* too many input code points */
|
||||
throw new ParseException("Too many input code points", -1);
|
||||
}
|
||||
c=src.charAt(j);
|
||||
if(isBasic(c)) {
|
||||
if(destLength<destCapacity) {
|
||||
cpBuffer[srcCPCount++]=0;
|
||||
dest[destLength]=
|
||||
caseFlags!=null ?
|
||||
asciiCaseMap(c, caseFlags[j]) :
|
||||
c;
|
||||
}
|
||||
++destLength;
|
||||
} else {
|
||||
n=((caseFlags!=null && caseFlags[j])? 1 : 0)<<31L;
|
||||
if(!UTF16.isSurrogate(c)) {
|
||||
n|=c;
|
||||
} else if(UTF16.isLeadSurrogate(c) && (j+1)<srcLength && UTF16.isTrailSurrogate(c2=src.charAt(j+1))) {
|
||||
++j;
|
||||
|
||||
n|=UCharacter.getCodePoint(c, c2);
|
||||
} else {
|
||||
/* error: unmatched surrogate */
|
||||
throw new ParseException("Illegal char found", -1);
|
||||
}
|
||||
cpBuffer[srcCPCount++]=n;
|
||||
}
|
||||
}
|
||||
|
||||
/* Finish the basic string - if it is not empty - with a delimiter. */
|
||||
basicLength=destLength;
|
||||
if(basicLength>0) {
|
||||
if(destLength<destCapacity) {
|
||||
dest[destLength]=DELIMITER;
|
||||
}
|
||||
++destLength;
|
||||
}
|
||||
|
||||
/*
|
||||
* handledCPCount is the number of code points that have been handled
|
||||
* basicLength is the number of basic code points
|
||||
* destLength is the number of chars that have been output
|
||||
*/
|
||||
|
||||
/* Initialize the state: */
|
||||
n=INITIAL_N;
|
||||
delta=0;
|
||||
bias=INITIAL_BIAS;
|
||||
|
||||
/* Main encoding loop: */
|
||||
for(handledCPCount=basicLength; handledCPCount<srcCPCount; /* no op */) {
|
||||
/*
|
||||
* All non-basic code points < n have been handled already.
|
||||
* Find the next larger one:
|
||||
*/
|
||||
for(m=0x7fffffff, j=0; j<srcCPCount; ++j) {
|
||||
q=cpBuffer[j]&0x7fffffff; /* remove case flag from the sign bit */
|
||||
if(n<=q && q<m) {
|
||||
m=q;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Increase delta enough to advance the decoder's
|
||||
* <n,i> state to <m,0>, but guard against overflow:
|
||||
*/
|
||||
if(m-n>(0x7fffffff-MAX_CP_COUNT-delta)/(handledCPCount+1)) {
|
||||
throw new RuntimeException("Internal program error");
|
||||
}
|
||||
delta+=(m-n)*(handledCPCount+1);
|
||||
n=m;
|
||||
|
||||
/* Encode a sequence of same code points n */
|
||||
for(j=0; j<srcCPCount; ++j) {
|
||||
q=cpBuffer[j]&0x7fffffff; /* remove case flag from the sign bit */
|
||||
if(q<n) {
|
||||
++delta;
|
||||
} else if(q==n) {
|
||||
/* Represent delta as a generalized variable-length integer: */
|
||||
for(q=delta, k=BASE; /* no condition */; k+=BASE) {
|
||||
|
||||
/** RAM: comment out the old code for conformance with draft-ietf-idn-punycode-03.txt
|
||||
|
||||
t=k-bias;
|
||||
if(t<TMIN) {
|
||||
t=TMIN;
|
||||
} else if(t>TMAX) {
|
||||
t=TMAX;
|
||||
}
|
||||
*/
|
||||
|
||||
t=k-bias;
|
||||
if(t<TMIN) {
|
||||
t=TMIN;
|
||||
} else if(k>=(bias+TMAX)) {
|
||||
t=TMAX;
|
||||
}
|
||||
|
||||
if(q<t) {
|
||||
break;
|
||||
}
|
||||
|
||||
if(destLength<destCapacity) {
|
||||
dest[destLength++]=digitToBasic(t+(q-t)%(BASE-t), false);
|
||||
}
|
||||
q=(q-t)/(BASE-t);
|
||||
}
|
||||
|
||||
if(destLength<destCapacity) {
|
||||
dest[destLength++]=digitToBasic(q, (cpBuffer[j]<0));
|
||||
}
|
||||
bias=adaptBias(delta, handledCPCount+1,(handledCPCount==basicLength));
|
||||
delta=0;
|
||||
++handledCPCount;
|
||||
}
|
||||
}
|
||||
|
||||
++delta;
|
||||
++n;
|
||||
}
|
||||
|
||||
return result.append(dest, 0, destLength);
|
||||
}
|
||||
|
||||
private static boolean isBasic(int ch){
|
||||
return (ch < INITIAL_N);
|
||||
}
|
||||
|
||||
private static boolean isBasicUpperCase(int ch){
|
||||
return( CAPITAL_A <= ch && ch <= CAPITAL_Z);
|
||||
}
|
||||
|
||||
private static boolean isSurrogate(int ch){
|
||||
return (((ch)&0xfffff800)==0xd800);
|
||||
}
|
||||
/**
|
||||
* Converts Punycode to Unicode.
|
||||
* The Unicode string will be at most as long as the Punycode string.
|
||||
*
|
||||
* @param src
|
||||
* @param caseFlags
|
||||
* @return
|
||||
* @throws ParseException
|
||||
*/
|
||||
public static StringBuffer decode(StringBuffer src, boolean[] caseFlags)
|
||||
throws ParseException{
|
||||
int srcLength = src.length();
|
||||
StringBuffer result = new StringBuffer();
|
||||
int n, destLength, i, bias, basicLength, j, in, oldi, w, k, digit, t,
|
||||
destCPCount, firstSupplementaryIndex, cpLength;
|
||||
char b;
|
||||
int destCapacity = MAX_CP_COUNT;
|
||||
char[] dest = new char[destCapacity];
|
||||
|
||||
/*
|
||||
* Handle the basic code points:
|
||||
* Let basicLength be the number of input code points
|
||||
* before the last delimiter, or 0 if there is none,
|
||||
* then copy the first basicLength code points to the output.
|
||||
*
|
||||
* The two following loops iterate backward.
|
||||
*/
|
||||
for(j=srcLength; j>0;) {
|
||||
if(src.charAt(--j)==DELIMITER) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
destLength=basicLength=destCPCount=j;
|
||||
|
||||
while(j>0) {
|
||||
b=src.charAt(--j);
|
||||
if(!isBasic(b)) {
|
||||
throw new ParseException("Illegal char found", -1);
|
||||
}
|
||||
|
||||
if(j<destCapacity) {
|
||||
dest[j]= b;
|
||||
|
||||
if(caseFlags!=null) {
|
||||
caseFlags[j]=isBasicUpperCase(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize the state: */
|
||||
n=INITIAL_N;
|
||||
i=0;
|
||||
bias=INITIAL_BIAS;
|
||||
firstSupplementaryIndex=1000000000;
|
||||
|
||||
/*
|
||||
* Main decoding loop:
|
||||
* Start just after the last delimiter if any
|
||||
* basic code points were copied; start at the beginning otherwise.
|
||||
*/
|
||||
for(in=basicLength>0 ? basicLength+1 : 0; in<srcLength; /* no op */) {
|
||||
/*
|
||||
* in is the index of the next character to be consumed, and
|
||||
* destCPCount is the number of code points in the output array.
|
||||
*
|
||||
* Decode a generalized variable-length integer into delta,
|
||||
* which gets added to i. The overflow checking is easier
|
||||
* if we increase i as we go, then subtract off its starting
|
||||
* value at the end to obtain delta.
|
||||
*/
|
||||
for(oldi=i, w=1, k=BASE; /* no condition */; k+=BASE) {
|
||||
if(in>=srcLength) {
|
||||
throw new ParseException("Illegal char found", -1);
|
||||
}
|
||||
|
||||
digit=basicToDigit[(byte)src.charAt(in++)];
|
||||
if(digit<0) {
|
||||
throw new ParseException("Invalid char found", -1);
|
||||
}
|
||||
if(digit>(0x7fffffff-i)/w) {
|
||||
/* integer overflow */
|
||||
throw new ParseException("Illegal char found", -1);
|
||||
}
|
||||
|
||||
i+=digit*w;
|
||||
t=k-bias;
|
||||
if(t<TMIN) {
|
||||
t=TMIN;
|
||||
} else if(k>=(bias+TMAX)) {
|
||||
t=TMAX;
|
||||
}
|
||||
if(digit<t) {
|
||||
break;
|
||||
}
|
||||
|
||||
if(w>0x7fffffff/(BASE-t)) {
|
||||
/* integer overflow */
|
||||
throw new ParseException("Illegal char found", -1);
|
||||
}
|
||||
w*=BASE-t;
|
||||
}
|
||||
|
||||
/*
|
||||
* Modification from sample code:
|
||||
* Increments destCPCount here,
|
||||
* where needed instead of in for() loop tail.
|
||||
*/
|
||||
++destCPCount;
|
||||
bias=adaptBias(i-oldi, destCPCount, (oldi==0));
|
||||
|
||||
/*
|
||||
* i was supposed to wrap around from (incremented) destCPCount to 0,
|
||||
* incrementing n each time, so we'll fix that now:
|
||||
*/
|
||||
if(i/destCPCount>(0x7fffffff-n)) {
|
||||
/* integer overflow */
|
||||
throw new ParseException("Illegal char found", -1);
|
||||
}
|
||||
|
||||
n+=i/destCPCount;
|
||||
i%=destCPCount;
|
||||
/* not needed for Punycode: */
|
||||
/* if (decode_digit(n) <= BASE) return punycode_invalid_input; */
|
||||
|
||||
if(n>0x10ffff || isSurrogate(n)) {
|
||||
/* Unicode code point overflow */
|
||||
throw new ParseException("Illegal char found", -1);
|
||||
}
|
||||
|
||||
/* Insert n at position i of the output: */
|
||||
cpLength=UTF16.getCharCount(n);
|
||||
if((destLength+cpLength)<destCapacity) {
|
||||
int codeUnitIndex;
|
||||
|
||||
/*
|
||||
* Handle indexes when supplementary code points are present.
|
||||
*
|
||||
* In almost all cases, there will be only BMP code points before i
|
||||
* and even in the entire string.
|
||||
* This is handled with the same efficiency as with UTF-32.
|
||||
*
|
||||
* Only the rare cases with supplementary code points are handled
|
||||
* more slowly - but not too bad since this is an insertion anyway.
|
||||
*/
|
||||
if(i<=firstSupplementaryIndex) {
|
||||
codeUnitIndex=i;
|
||||
if(cpLength>1) {
|
||||
firstSupplementaryIndex=codeUnitIndex;
|
||||
} else {
|
||||
++firstSupplementaryIndex;
|
||||
}
|
||||
} else {
|
||||
codeUnitIndex=firstSupplementaryIndex;
|
||||
codeUnitIndex=UTF16.moveCodePointOffset(dest, 0, destLength, codeUnitIndex, i-codeUnitIndex);
|
||||
}
|
||||
|
||||
/* use the UChar index codeUnitIndex instead of the code point index i */
|
||||
if(codeUnitIndex<destLength) {
|
||||
System.arraycopy(dest, codeUnitIndex,
|
||||
dest, codeUnitIndex+cpLength,
|
||||
(destLength-codeUnitIndex));
|
||||
if(caseFlags!=null) {
|
||||
System.arraycopy(caseFlags, codeUnitIndex,
|
||||
caseFlags, codeUnitIndex+cpLength,
|
||||
destLength-codeUnitIndex);
|
||||
}
|
||||
}
|
||||
if(cpLength==1) {
|
||||
/* BMP, insert one code unit */
|
||||
dest[codeUnitIndex]=(char)n;
|
||||
} else {
|
||||
/* supplementary character, insert two code units */
|
||||
dest[codeUnitIndex]=UTF16.getLeadSurrogate(n);
|
||||
dest[codeUnitIndex+1]=UTF16.getTrailSurrogate(n);
|
||||
}
|
||||
if(caseFlags!=null) {
|
||||
/* Case of last character determines uppercase flag: */
|
||||
caseFlags[codeUnitIndex]=isBasicUpperCase(src.charAt(in-1));
|
||||
if(cpLength==2) {
|
||||
caseFlags[codeUnitIndex+1]=false;
|
||||
}
|
||||
}
|
||||
}
|
||||
destLength+=cpLength;
|
||||
++i;
|
||||
}
|
||||
result.append(dest, 0, destLength);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
487
jdkSrc/jdk8/sun/net/idn/StringPrep.java
Normal file
487
jdkSrc/jdk8/sun/net/idn/StringPrep.java
Normal file
@@ -0,0 +1,487 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2003-2004, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
//
|
||||
// CHANGELOG
|
||||
// 2005-05-19 Edward Wang
|
||||
// - copy this file from icu4jsrc_3_2/src/com/ibm/icu/text/StringPrep.java
|
||||
// - move from package com.ibm.icu.text to package sun.net.idn
|
||||
// - use ParseException instead of StringPrepParseException
|
||||
// - change 'Normalizer.getUnicodeVersion()' to 'NormalizerImpl.getUnicodeVersion()'
|
||||
// - remove all @deprecated tag to make compiler happy
|
||||
// 2007-08-14 Martin Buchholz
|
||||
// - remove redundant casts
|
||||
//
|
||||
package sun.net.idn;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.text.ParseException;
|
||||
|
||||
import sun.text.Normalizer;
|
||||
import sun.text.normalizer.CharTrie;
|
||||
import sun.text.normalizer.Trie;
|
||||
import sun.text.normalizer.NormalizerImpl;
|
||||
import sun.text.normalizer.VersionInfo;
|
||||
import sun.text.normalizer.UCharacter;
|
||||
import sun.text.normalizer.UCharacterIterator;
|
||||
import sun.text.normalizer.UTF16;
|
||||
import sun.net.idn.UCharacterDirection;
|
||||
import sun.net.idn.StringPrepDataReader;
|
||||
|
||||
/**
|
||||
* StringPrep API implements the StingPrep framework as described by
|
||||
* <a href="http://www.ietf.org/rfc/rfc3454.txt">RFC 3454</a>.
|
||||
* StringPrep prepares Unicode strings for use in network protocols.
|
||||
* Profiles of StingPrep are set of rules and data according to which the
|
||||
* Unicode Strings are prepared. Each profiles contains tables which describe
|
||||
* how a code point should be treated. The tables are broadly classied into
|
||||
* <ul>
|
||||
* <li> Unassigned Table: Contains code points that are unassigned
|
||||
* in the Unicode Version supported by StringPrep. Currently
|
||||
* RFC 3454 supports Unicode 3.2. </li>
|
||||
* <li> Prohibited Table: Contains code points that are prohibted from
|
||||
* the output of the StringPrep processing function. </li>
|
||||
* <li> Mapping Table: Contains code ponts that are deleted from the output or case mapped. </li>
|
||||
* </ul>
|
||||
*
|
||||
* The procedure for preparing Unicode strings:
|
||||
* <ol>
|
||||
* <li> Map: For each character in the input, check if it has a mapping
|
||||
* and, if so, replace it with its mapping. </li>
|
||||
* <li> Normalize: Possibly normalize the result of step 1 using Unicode
|
||||
* normalization. </li>
|
||||
* <li> Prohibit: Check for any characters that are not allowed in the
|
||||
* output. If any are found, return an error.</li>
|
||||
* <li> Check bidi: Possibly check for right-to-left characters, and if
|
||||
* any are found, make sure that the whole string satisfies the
|
||||
* requirements for bidirectional strings. If the string does not
|
||||
* satisfy the requirements for bidirectional strings, return an
|
||||
* error. </li>
|
||||
* </ol>
|
||||
* @author Ram Viswanadha
|
||||
* @draft ICU 2.8
|
||||
*/
|
||||
public final class StringPrep {
|
||||
/**
|
||||
* Option to prohibit processing of unassigned code points in the input
|
||||
*
|
||||
* @see #prepare
|
||||
* @draft ICU 2.8
|
||||
*/
|
||||
public static final int DEFAULT = 0x0000;
|
||||
|
||||
/**
|
||||
* Option to allow processing of unassigned code points in the input
|
||||
*
|
||||
* @see #prepare
|
||||
* @draft ICU 2.8
|
||||
*/
|
||||
public static final int ALLOW_UNASSIGNED = 0x0001;
|
||||
|
||||
private static final int UNASSIGNED = 0x0000;
|
||||
private static final int MAP = 0x0001;
|
||||
private static final int PROHIBITED = 0x0002;
|
||||
private static final int DELETE = 0x0003;
|
||||
private static final int TYPE_LIMIT = 0x0004;
|
||||
|
||||
private static final int NORMALIZATION_ON = 0x0001;
|
||||
private static final int CHECK_BIDI_ON = 0x0002;
|
||||
|
||||
private static final int TYPE_THRESHOLD = 0xFFF0;
|
||||
private static final int MAX_INDEX_VALUE = 0x3FBF; /*16139*/
|
||||
private static final int MAX_INDEX_TOP_LENGTH = 0x0003;
|
||||
|
||||
/* indexes[] value names */
|
||||
private static final int INDEX_TRIE_SIZE = 0; /* number of bytes in normalization trie */
|
||||
private static final int INDEX_MAPPING_DATA_SIZE = 1; /* The array that contains the mapping */
|
||||
private static final int NORM_CORRECTNS_LAST_UNI_VERSION = 2; /* The index of Unicode version of last entry in NormalizationCorrections.txt */
|
||||
private static final int ONE_UCHAR_MAPPING_INDEX_START = 3; /* The starting index of 1 UChar mapping index in the mapping data array */
|
||||
private static final int TWO_UCHARS_MAPPING_INDEX_START = 4; /* The starting index of 2 UChars mapping index in the mapping data array */
|
||||
private static final int THREE_UCHARS_MAPPING_INDEX_START = 5;
|
||||
private static final int FOUR_UCHARS_MAPPING_INDEX_START = 6;
|
||||
private static final int OPTIONS = 7; /* Bit set of options to turn on in the profile */
|
||||
private static final int INDEX_TOP = 16; /* changing this requires a new formatVersion */
|
||||
|
||||
|
||||
/**
|
||||
* Default buffer size of datafile
|
||||
*/
|
||||
private static final int DATA_BUFFER_SIZE = 25000;
|
||||
|
||||
/* Wrappers for Trie implementations */
|
||||
private static final class StringPrepTrieImpl implements Trie.DataManipulate{
|
||||
private CharTrie sprepTrie = null;
|
||||
/**
|
||||
* Called by com.ibm.icu.util.Trie to extract from a lead surrogate's
|
||||
* data the index array offset of the indexes for that lead surrogate.
|
||||
* @param property data value for a surrogate from the trie, including
|
||||
* the folding offset
|
||||
* @return data offset or 0 if there is no data for the lead surrogate
|
||||
*/
|
||||
public int getFoldingOffset(int value){
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
// CharTrie implementation for reading the trie data
|
||||
private StringPrepTrieImpl sprepTrieImpl;
|
||||
// Indexes read from the data file
|
||||
private int[] indexes;
|
||||
// mapping data read from the data file
|
||||
private char[] mappingData;
|
||||
// format version of the data file
|
||||
private byte[] formatVersion;
|
||||
// the version of Unicode supported by the data file
|
||||
private VersionInfo sprepUniVer;
|
||||
// the Unicode version of last entry in the
|
||||
// NormalizationCorrections.txt file if normalization
|
||||
// is turned on
|
||||
private VersionInfo normCorrVer;
|
||||
// Option to turn on Normalization
|
||||
private boolean doNFKC;
|
||||
// Option to turn on checking for BiDi rules
|
||||
private boolean checkBiDi;
|
||||
|
||||
|
||||
private char getCodePointValue(int ch){
|
||||
return sprepTrieImpl.sprepTrie.getCodePointValue(ch);
|
||||
}
|
||||
|
||||
private static VersionInfo getVersionInfo(int comp){
|
||||
int micro = comp & 0xFF;
|
||||
int milli =(comp >> 8) & 0xFF;
|
||||
int minor =(comp >> 16) & 0xFF;
|
||||
int major =(comp >> 24) & 0xFF;
|
||||
return VersionInfo.getInstance(major,minor,milli,micro);
|
||||
}
|
||||
private static VersionInfo getVersionInfo(byte[] version){
|
||||
if(version.length != 4){
|
||||
return null;
|
||||
}
|
||||
return VersionInfo.getInstance((int)version[0],(int) version[1],(int) version[2],(int) version[3]);
|
||||
}
|
||||
/**
|
||||
* Creates an StringPrep object after reading the input stream.
|
||||
* The object does not hold a reference to the input steam, so the stream can be
|
||||
* closed after the method returns.
|
||||
*
|
||||
* @param inputStream The stream for reading the StringPrep profile binarySun
|
||||
* @throws IOException
|
||||
* @draft ICU 2.8
|
||||
*/
|
||||
public StringPrep(InputStream inputStream) throws IOException{
|
||||
|
||||
BufferedInputStream b = new BufferedInputStream(inputStream,DATA_BUFFER_SIZE);
|
||||
|
||||
StringPrepDataReader reader = new StringPrepDataReader(b);
|
||||
|
||||
// read the indexes
|
||||
indexes = reader.readIndexes(INDEX_TOP);
|
||||
|
||||
byte[] sprepBytes = new byte[indexes[INDEX_TRIE_SIZE]];
|
||||
|
||||
|
||||
//indexes[INDEX_MAPPING_DATA_SIZE] store the size of mappingData in bytes
|
||||
mappingData = new char[indexes[INDEX_MAPPING_DATA_SIZE]/2];
|
||||
// load the rest of the data data and initialize the data members
|
||||
reader.read(sprepBytes,mappingData);
|
||||
|
||||
sprepTrieImpl = new StringPrepTrieImpl();
|
||||
sprepTrieImpl.sprepTrie = new CharTrie( new ByteArrayInputStream(sprepBytes),sprepTrieImpl );
|
||||
|
||||
// get the data format version
|
||||
formatVersion = reader.getDataFormatVersion();
|
||||
|
||||
// get the options
|
||||
doNFKC = ((indexes[OPTIONS] & NORMALIZATION_ON) > 0);
|
||||
checkBiDi = ((indexes[OPTIONS] & CHECK_BIDI_ON) > 0);
|
||||
sprepUniVer = getVersionInfo(reader.getUnicodeVersion());
|
||||
normCorrVer = getVersionInfo(indexes[NORM_CORRECTNS_LAST_UNI_VERSION]);
|
||||
VersionInfo normUniVer = NormalizerImpl.getUnicodeVersion();
|
||||
if(normUniVer.compareTo(sprepUniVer) < 0 && /* the Unicode version of SPREP file must be less than the Unicode Vesion of the normalization data */
|
||||
normUniVer.compareTo(normCorrVer) < 0 && /* the Unicode version of the NormalizationCorrections.txt file should be less than the Unicode Vesion of the normalization data */
|
||||
((indexes[OPTIONS] & NORMALIZATION_ON) > 0) /* normalization turned on*/
|
||||
){
|
||||
throw new IOException("Normalization Correction version not supported");
|
||||
}
|
||||
b.close();
|
||||
}
|
||||
|
||||
private static final class Values{
|
||||
boolean isIndex;
|
||||
int value;
|
||||
int type;
|
||||
public void reset(){
|
||||
isIndex = false;
|
||||
value = 0;
|
||||
type = -1;
|
||||
}
|
||||
}
|
||||
|
||||
private static final void getValues(char trieWord,Values values){
|
||||
values.reset();
|
||||
if(trieWord == 0){
|
||||
/*
|
||||
* Initial value stored in the mapping table
|
||||
* just return TYPE_LIMIT .. so that
|
||||
* the source codepoint is copied to the destination
|
||||
*/
|
||||
values.type = TYPE_LIMIT;
|
||||
}else if(trieWord >= TYPE_THRESHOLD){
|
||||
values.type = (trieWord - TYPE_THRESHOLD);
|
||||
}else{
|
||||
/* get the type */
|
||||
values.type = MAP;
|
||||
/* ascertain if the value is index or delta */
|
||||
if((trieWord & 0x02)>0){
|
||||
values.isIndex = true;
|
||||
values.value = trieWord >> 2; //mask off the lower 2 bits and shift
|
||||
|
||||
}else{
|
||||
values.isIndex = false;
|
||||
values.value = (trieWord<<16)>>16;
|
||||
values.value = (values.value >> 2);
|
||||
|
||||
}
|
||||
|
||||
if((trieWord>>2) == MAX_INDEX_VALUE){
|
||||
values.type = DELETE;
|
||||
values.isIndex = false;
|
||||
values.value = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private StringBuffer map( UCharacterIterator iter, int options)
|
||||
throws ParseException {
|
||||
|
||||
Values val = new Values();
|
||||
char result = 0;
|
||||
int ch = UCharacterIterator.DONE;
|
||||
StringBuffer dest = new StringBuffer();
|
||||
boolean allowUnassigned = ((options & ALLOW_UNASSIGNED)>0);
|
||||
|
||||
while((ch=iter.nextCodePoint())!= UCharacterIterator.DONE){
|
||||
|
||||
result = getCodePointValue(ch);
|
||||
getValues(result,val);
|
||||
|
||||
// check if the source codepoint is unassigned
|
||||
if(val.type == UNASSIGNED && allowUnassigned == false){
|
||||
throw new ParseException("An unassigned code point was found in the input " +
|
||||
iter.getText(), iter.getIndex());
|
||||
}else if((val.type == MAP)){
|
||||
int index, length;
|
||||
|
||||
if(val.isIndex){
|
||||
index = val.value;
|
||||
if(index >= indexes[ONE_UCHAR_MAPPING_INDEX_START] &&
|
||||
index < indexes[TWO_UCHARS_MAPPING_INDEX_START]){
|
||||
length = 1;
|
||||
}else if(index >= indexes[TWO_UCHARS_MAPPING_INDEX_START] &&
|
||||
index < indexes[THREE_UCHARS_MAPPING_INDEX_START]){
|
||||
length = 2;
|
||||
}else if(index >= indexes[THREE_UCHARS_MAPPING_INDEX_START] &&
|
||||
index < indexes[FOUR_UCHARS_MAPPING_INDEX_START]){
|
||||
length = 3;
|
||||
}else{
|
||||
length = mappingData[index++];
|
||||
}
|
||||
/* copy mapping to destination */
|
||||
dest.append(mappingData,index,length);
|
||||
continue;
|
||||
|
||||
}else{
|
||||
ch -= val.value;
|
||||
}
|
||||
}else if(val.type == DELETE){
|
||||
// just consume the codepoint and contine
|
||||
continue;
|
||||
}
|
||||
//copy the source into destination
|
||||
UTF16.append(dest,ch);
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
||||
private StringBuffer normalize(StringBuffer src){
|
||||
/*
|
||||
* Option UNORM_BEFORE_PRI_29:
|
||||
*
|
||||
* IDNA as interpreted by IETF members (see unicode mailing list 2004H1)
|
||||
* requires strict adherence to Unicode 3.2 normalization,
|
||||
* including buggy composition from before fixing Public Review Issue #29.
|
||||
* Note that this results in some valid but nonsensical text to be
|
||||
* either corrupted or rejected, depending on the text.
|
||||
* See http://www.unicode.org/review/resolved-pri.html#pri29
|
||||
* See unorm.cpp and cnormtst.c
|
||||
*/
|
||||
return new StringBuffer(
|
||||
Normalizer.normalize(
|
||||
src.toString(),
|
||||
java.text.Normalizer.Form.NFKC,
|
||||
Normalizer.UNICODE_3_2|NormalizerImpl.BEFORE_PRI_29));
|
||||
}
|
||||
/*
|
||||
boolean isLabelSeparator(int ch){
|
||||
int result = getCodePointValue(ch);
|
||||
if( (result & 0x07) == LABEL_SEPARATOR){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
1) Map -- For each character in the input, check if it has a mapping
|
||||
and, if so, replace it with its mapping.
|
||||
|
||||
2) Normalize -- Possibly normalize the result of step 1 using Unicode
|
||||
normalization.
|
||||
|
||||
3) Prohibit -- Check for any characters that are not allowed in the
|
||||
output. If any are found, return an error.
|
||||
|
||||
4) Check bidi -- Possibly check for right-to-left characters, and if
|
||||
any are found, make sure that the whole string satisfies the
|
||||
requirements for bidirectional strings. If the string does not
|
||||
satisfy the requirements for bidirectional strings, return an
|
||||
error.
|
||||
[Unicode3.2] defines several bidirectional categories; each character
|
||||
has one bidirectional category assigned to it. For the purposes of
|
||||
the requirements below, an "RandALCat character" is a character that
|
||||
has Unicode bidirectional categories "R" or "AL"; an "LCat character"
|
||||
is a character that has Unicode bidirectional category "L". Note
|
||||
|
||||
|
||||
that there are many characters which fall in neither of the above
|
||||
definitions; Latin digits (<U+0030> through <U+0039>) are examples of
|
||||
this because they have bidirectional category "EN".
|
||||
|
||||
In any profile that specifies bidirectional character handling, all
|
||||
three of the following requirements MUST be met:
|
||||
|
||||
1) The characters in section 5.8 MUST be prohibited.
|
||||
|
||||
2) If a string contains any RandALCat character, the string MUST NOT
|
||||
contain any LCat character.
|
||||
|
||||
3) If a string contains any RandALCat character, a RandALCat
|
||||
character MUST be the first character of the string, and a
|
||||
RandALCat character MUST be the last character of the string.
|
||||
*/
|
||||
/**
|
||||
* Prepare the input buffer for use in applications with the given profile. This operation maps, normalizes(NFKC),
|
||||
* checks for prohited and BiDi characters in the order defined by RFC 3454
|
||||
* depending on the options specified in the profile.
|
||||
*
|
||||
* @param src A UCharacterIterator object containing the source string
|
||||
* @param options A bit set of options:
|
||||
*
|
||||
* - StringPrep.NONE Prohibit processing of unassigned code points in the input
|
||||
*
|
||||
* - StringPrep.ALLOW_UNASSIGNED Treat the unassigned code points are in the input
|
||||
* as normal Unicode code points.
|
||||
*
|
||||
* @return StringBuffer A StringBuffer containing the output
|
||||
* @throws ParseException
|
||||
* @draft ICU 2.8
|
||||
*/
|
||||
public StringBuffer prepare(UCharacterIterator src, int options)
|
||||
throws ParseException{
|
||||
|
||||
// map
|
||||
StringBuffer mapOut = map(src,options);
|
||||
StringBuffer normOut = mapOut;// initialize
|
||||
|
||||
if(doNFKC){
|
||||
// normalize
|
||||
normOut = normalize(mapOut);
|
||||
}
|
||||
|
||||
int ch;
|
||||
char result;
|
||||
UCharacterIterator iter = UCharacterIterator.getInstance(normOut);
|
||||
Values val = new Values();
|
||||
int direction=UCharacterDirection.CHAR_DIRECTION_COUNT,
|
||||
firstCharDir=UCharacterDirection.CHAR_DIRECTION_COUNT;
|
||||
int rtlPos=-1, ltrPos=-1;
|
||||
boolean rightToLeft=false, leftToRight=false;
|
||||
|
||||
while((ch=iter.nextCodePoint())!= UCharacterIterator.DONE){
|
||||
result = getCodePointValue(ch);
|
||||
getValues(result,val);
|
||||
|
||||
if(val.type == PROHIBITED ){
|
||||
throw new ParseException("A prohibited code point was found in the input" +
|
||||
iter.getText(), val.value);
|
||||
}
|
||||
|
||||
direction = UCharacter.getDirection(ch);
|
||||
if(firstCharDir == UCharacterDirection.CHAR_DIRECTION_COUNT){
|
||||
firstCharDir = direction;
|
||||
}
|
||||
if(direction == UCharacterDirection.LEFT_TO_RIGHT){
|
||||
leftToRight = true;
|
||||
ltrPos = iter.getIndex()-1;
|
||||
}
|
||||
if(direction == UCharacterDirection.RIGHT_TO_LEFT || direction == UCharacterDirection.RIGHT_TO_LEFT_ARABIC){
|
||||
rightToLeft = true;
|
||||
rtlPos = iter.getIndex()-1;
|
||||
}
|
||||
}
|
||||
if(checkBiDi == true){
|
||||
// satisfy 2
|
||||
if( leftToRight == true && rightToLeft == true){
|
||||
throw new ParseException("The input does not conform to the rules for BiDi code points." +
|
||||
iter.getText(),
|
||||
(rtlPos>ltrPos) ? rtlPos : ltrPos);
|
||||
}
|
||||
|
||||
//satisfy 3
|
||||
if( rightToLeft == true &&
|
||||
!((firstCharDir == UCharacterDirection.RIGHT_TO_LEFT || firstCharDir == UCharacterDirection.RIGHT_TO_LEFT_ARABIC) &&
|
||||
(direction == UCharacterDirection.RIGHT_TO_LEFT || direction == UCharacterDirection.RIGHT_TO_LEFT_ARABIC))
|
||||
){
|
||||
throw new ParseException("The input does not conform to the rules for BiDi code points." +
|
||||
iter.getText(),
|
||||
(rtlPos>ltrPos) ? rtlPos : ltrPos);
|
||||
}
|
||||
}
|
||||
return normOut;
|
||||
|
||||
}
|
||||
}
|
||||
127
jdkSrc/jdk8/sun/net/idn/StringPrepDataReader.java
Normal file
127
jdkSrc/jdk8/sun/net/idn/StringPrepDataReader.java
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
/*
|
||||
******************************************************************************
|
||||
* Copyright (C) 2003, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
******************************************************************************
|
||||
*
|
||||
* Created on May 2, 2003
|
||||
*
|
||||
* To change the template for this generated file go to
|
||||
* Window>Preferences>Java>Code Generation>Code and Comments
|
||||
*/
|
||||
// CHANGELOG
|
||||
// 2005-05-19 Edward Wang
|
||||
// - copy this file from icu4jsrc_3_2/src/com/ibm/icu/impl/StringPrepDataReader.java
|
||||
// - move from package com.ibm.icu.impl to package sun.net.idn
|
||||
//
|
||||
package sun.net.idn;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import sun.text.normalizer.ICUBinary;
|
||||
|
||||
|
||||
/**
|
||||
* @author ram
|
||||
*
|
||||
* To change the template for this generated type comment go to
|
||||
* Window>Preferences>Java>Code Generation>Code and Comments
|
||||
*/
|
||||
final class StringPrepDataReader implements ICUBinary.Authenticate {
|
||||
|
||||
/**
|
||||
* <p>private constructor.</p>
|
||||
* @param inputStream ICU uprop.dat file input stream
|
||||
* @exception IOException throw if data file fails authentication
|
||||
* @draft 2.1
|
||||
*/
|
||||
public StringPrepDataReader(InputStream inputStream)
|
||||
throws IOException{
|
||||
|
||||
unicodeVersion = ICUBinary.readHeader(inputStream, DATA_FORMAT_ID, this);
|
||||
|
||||
|
||||
dataInputStream = new DataInputStream(inputStream);
|
||||
|
||||
}
|
||||
|
||||
public void read(byte[] idnaBytes,
|
||||
char[] mappingTable)
|
||||
throws IOException{
|
||||
|
||||
//Read the bytes that make up the idnaTrie
|
||||
dataInputStream.read(idnaBytes);
|
||||
|
||||
//Read the extra data
|
||||
for(int i=0;i<mappingTable.length;i++){
|
||||
mappingTable[i]=dataInputStream.readChar();
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] getDataFormatVersion(){
|
||||
return DATA_FORMAT_VERSION;
|
||||
}
|
||||
|
||||
public boolean isDataVersionAcceptable(byte version[]){
|
||||
return version[0] == DATA_FORMAT_VERSION[0]
|
||||
&& version[2] == DATA_FORMAT_VERSION[2]
|
||||
&& version[3] == DATA_FORMAT_VERSION[3];
|
||||
}
|
||||
public int[] readIndexes(int length)throws IOException{
|
||||
int[] indexes = new int[length];
|
||||
//Read the indexes
|
||||
for (int i = 0; i <length ; i++) {
|
||||
indexes[i] = dataInputStream.readInt();
|
||||
}
|
||||
return indexes;
|
||||
}
|
||||
|
||||
public byte[] getUnicodeVersion(){
|
||||
return unicodeVersion;
|
||||
}
|
||||
// private data members -------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* ICU data file input stream
|
||||
*/
|
||||
private DataInputStream dataInputStream;
|
||||
private byte[] unicodeVersion;
|
||||
/**
|
||||
* File format version that this class understands.
|
||||
* No guarantees are made if a older version is used
|
||||
* see store.c of gennorm for more information and values
|
||||
*/
|
||||
///* dataFormat="SPRP" 0x53, 0x50, 0x52, 0x50 */
|
||||
private static final byte DATA_FORMAT_ID[] = {(byte)0x53, (byte)0x50,
|
||||
(byte)0x52, (byte)0x50};
|
||||
private static final byte DATA_FORMAT_VERSION[] = {(byte)0x3, (byte)0x2,
|
||||
(byte)0x5, (byte)0x2};
|
||||
|
||||
}
|
||||
111
jdkSrc/jdk8/sun/net/idn/UCharacterDirection.java
Normal file
111
jdkSrc/jdk8/sun/net/idn/UCharacterDirection.java
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
/**
|
||||
*******************************************************************************
|
||||
* Copyright (C) 1996-2004, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
// CHANGELOG
|
||||
// 2005-05-19 Edward Wang
|
||||
// - copy this file from icu4jsrc_3_2/src/com/ibm/icu/lang/UCharacterDirection.java
|
||||
// - move from package com.ibm.icu.lang to package sun.net.idn
|
||||
//
|
||||
|
||||
package sun.net.idn;
|
||||
|
||||
/**
|
||||
* Enumerated Unicode character linguistic direction constants.
|
||||
* Used as return results from <a href=UCharacter.html>UCharacter</a>
|
||||
* <p>
|
||||
* This class is not subclassable
|
||||
* </p>
|
||||
* @author Syn Wee Quek
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
|
||||
final class UCharacterDirection implements UCharacterEnums.ECharacterDirection {
|
||||
|
||||
// private constructor =========================================
|
||||
///CLOVER:OFF
|
||||
/**
|
||||
* Private constructor to prevent initialisation
|
||||
*/
|
||||
private UCharacterDirection()
|
||||
{
|
||||
}
|
||||
///CLOVER:ON
|
||||
|
||||
/**
|
||||
* Gets the name of the argument direction
|
||||
* @param dir direction type to retrieve name
|
||||
* @return directional name
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static String toString(int dir) {
|
||||
switch(dir)
|
||||
{
|
||||
case LEFT_TO_RIGHT :
|
||||
return "Left-to-Right";
|
||||
case RIGHT_TO_LEFT :
|
||||
return "Right-to-Left";
|
||||
case EUROPEAN_NUMBER :
|
||||
return "European Number";
|
||||
case EUROPEAN_NUMBER_SEPARATOR :
|
||||
return "European Number Separator";
|
||||
case EUROPEAN_NUMBER_TERMINATOR :
|
||||
return "European Number Terminator";
|
||||
case ARABIC_NUMBER :
|
||||
return "Arabic Number";
|
||||
case COMMON_NUMBER_SEPARATOR :
|
||||
return "Common Number Separator";
|
||||
case BLOCK_SEPARATOR :
|
||||
return "Paragraph Separator";
|
||||
case SEGMENT_SEPARATOR :
|
||||
return "Segment Separator";
|
||||
case WHITE_SPACE_NEUTRAL :
|
||||
return "Whitespace";
|
||||
case OTHER_NEUTRAL :
|
||||
return "Other Neutrals";
|
||||
case LEFT_TO_RIGHT_EMBEDDING :
|
||||
return "Left-to-Right Embedding";
|
||||
case LEFT_TO_RIGHT_OVERRIDE :
|
||||
return "Left-to-Right Override";
|
||||
case RIGHT_TO_LEFT_ARABIC :
|
||||
return "Right-to-Left Arabic";
|
||||
case RIGHT_TO_LEFT_EMBEDDING :
|
||||
return "Right-to-Left Embedding";
|
||||
case RIGHT_TO_LEFT_OVERRIDE :
|
||||
return "Right-to-Left Override";
|
||||
case POP_DIRECTIONAL_FORMAT :
|
||||
return "Pop Directional Format";
|
||||
case DIR_NON_SPACING_MARK :
|
||||
return "Non-Spacing Mark";
|
||||
case BOUNDARY_NEUTRAL :
|
||||
return "Boundary Neutral";
|
||||
}
|
||||
return "Unassigned";
|
||||
}
|
||||
}
|
||||
587
jdkSrc/jdk8/sun/net/idn/UCharacterEnums.java
Normal file
587
jdkSrc/jdk8/sun/net/idn/UCharacterEnums.java
Normal file
@@ -0,0 +1,587 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
/**
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2004, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
// CHANGELOG
|
||||
// 2005-05-19 Edward Wang
|
||||
// - copy this file from icu4jsrc_3_2/src/com/ibm/icu/lang/UCharacterEnums.java
|
||||
// - move from package com.ibm.icu.lang to package sun.net.idn
|
||||
//
|
||||
// 2011-09-06 Kurchi Subhra Hazra
|
||||
// - Added @Deprecated tag to the following:
|
||||
// - class UCharacterEnums
|
||||
// - interfaces ECharacterCategory, ECharacterDirection
|
||||
// - fields INITIAL_QUOTE_PUNCTUATION, FINAL_QUOTE_PUNCTUATION,
|
||||
// DIRECTIONALITY_LEFT_TO_RIGHT, DIRECTIONALITY_RIGHT_TO_LEFT,
|
||||
// DIRECTIONALITY_EUROPEAN_NUMBER, DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR
|
||||
// DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR, DIRECTIONALITY_ARABIC_NUMBER,
|
||||
// DIRECTIONALITY_COMMON_NUMBER_SEPARATOR, DIRECTIONALITY_PARAGRAPH_SEPARATOR,
|
||||
// DIRECTIONALITY_SEGMENT_SEPARATOR, DIRECTIONALITY_WHITESPACE,
|
||||
// DIRECTIONALITY_OTHER_NEUTRALS, DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING,
|
||||
// DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE, DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC,
|
||||
// DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING, DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE,
|
||||
// DIRECTIONALITY_POP_DIRECTIONAL_FORMAT, DIRECTIONALITY_NON_SPACING_MARK,
|
||||
// DIRECTIONALITY_BOUNDARY_NEUTRAL, DIRECTIONALITY_UNDEFINED
|
||||
//
|
||||
|
||||
package sun.net.idn;
|
||||
|
||||
/**
|
||||
* A container for the different 'enumerated types' used by UCharacter.
|
||||
* @draft ICU 3.0
|
||||
* @deprecated This is a draft API and might change in a future release of ICU.
|
||||
*/
|
||||
|
||||
@Deprecated
|
||||
class UCharacterEnums {
|
||||
|
||||
/** This is just a namespace, it is not instantiatable. */
|
||||
private UCharacterEnums() {};
|
||||
|
||||
/**
|
||||
* 'Enum' for the CharacterCategory constants. These constants are
|
||||
* compatible in name <b>but not in value</b> with those defined in
|
||||
* <code>java.lang.Character</code>.
|
||||
* @see UCharacterCategory
|
||||
* @draft ICU 3.0
|
||||
* @deprecated This is a draft API and might change in a future release of ICU.
|
||||
*/
|
||||
@Deprecated
|
||||
public static interface ECharacterCategory {
|
||||
/**
|
||||
* Unassigned character type
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int UNASSIGNED = 0;
|
||||
|
||||
/**
|
||||
* Character type Cn
|
||||
* Not Assigned (no characters in [UnicodeData.txt] have this property)
|
||||
* @stable ICU 2.6
|
||||
*/
|
||||
public static final int GENERAL_OTHER_TYPES = 0;
|
||||
|
||||
/**
|
||||
* Character type Lu
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int UPPERCASE_LETTER = 1;
|
||||
|
||||
/**
|
||||
* Character type Ll
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int LOWERCASE_LETTER = 2;
|
||||
|
||||
/**
|
||||
* Character type Lt
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
|
||||
public static final int TITLECASE_LETTER = 3;
|
||||
|
||||
/**
|
||||
* Character type Lm
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int MODIFIER_LETTER = 4;
|
||||
|
||||
/**
|
||||
* Character type Lo
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int OTHER_LETTER = 5;
|
||||
|
||||
/**
|
||||
* Character type Mn
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int NON_SPACING_MARK = 6;
|
||||
|
||||
/**
|
||||
* Character type Me
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int ENCLOSING_MARK = 7;
|
||||
|
||||
/**
|
||||
* Character type Mc
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int COMBINING_SPACING_MARK = 8;
|
||||
|
||||
/**
|
||||
* Character type Nd
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int DECIMAL_DIGIT_NUMBER = 9;
|
||||
|
||||
/**
|
||||
* Character type Nl
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int LETTER_NUMBER = 10;
|
||||
|
||||
/**
|
||||
* Character type No
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int OTHER_NUMBER = 11;
|
||||
|
||||
/**
|
||||
* Character type Zs
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int SPACE_SEPARATOR = 12;
|
||||
|
||||
/**
|
||||
* Character type Zl
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int LINE_SEPARATOR = 13;
|
||||
|
||||
/**
|
||||
* Character type Zp
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int PARAGRAPH_SEPARATOR = 14;
|
||||
|
||||
/**
|
||||
* Character type Cc
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int CONTROL = 15;
|
||||
|
||||
/**
|
||||
* Character type Cf
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int FORMAT = 16;
|
||||
|
||||
/**
|
||||
* Character type Co
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int PRIVATE_USE = 17;
|
||||
|
||||
/**
|
||||
* Character type Cs
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int SURROGATE = 18;
|
||||
|
||||
/**
|
||||
* Character type Pd
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int DASH_PUNCTUATION = 19;
|
||||
|
||||
/**
|
||||
* Character type Ps
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int START_PUNCTUATION = 20;
|
||||
|
||||
/**
|
||||
* Character type Pe
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int END_PUNCTUATION = 21;
|
||||
|
||||
/**
|
||||
* Character type Pc
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int CONNECTOR_PUNCTUATION = 22;
|
||||
|
||||
/**
|
||||
* Character type Po
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int OTHER_PUNCTUATION = 23;
|
||||
|
||||
/**
|
||||
* Character type Sm
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int MATH_SYMBOL = 24;
|
||||
|
||||
/**
|
||||
* Character type Sc
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int CURRENCY_SYMBOL = 25;
|
||||
|
||||
/**
|
||||
* Character type Sk
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int MODIFIER_SYMBOL = 26;
|
||||
|
||||
/**
|
||||
* Character type So
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int OTHER_SYMBOL = 27;
|
||||
|
||||
/**
|
||||
* Character type Pi
|
||||
* @see #INITIAL_QUOTE_PUNCTUATION
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int INITIAL_PUNCTUATION = 28;
|
||||
|
||||
/**
|
||||
* Character type Pi
|
||||
* This name is compatible with java.lang.Character's name for this type.
|
||||
* @see #INITIAL_PUNCTUATION
|
||||
* @draft ICU 2.8
|
||||
* @deprecated This is a draft API and might change in a future release of ICU.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final int INITIAL_QUOTE_PUNCTUATION = 28;
|
||||
|
||||
/**
|
||||
* Character type Pf
|
||||
* @see #FINAL_QUOTE_PUNCTUATION
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int FINAL_PUNCTUATION = 29;
|
||||
|
||||
/**
|
||||
* Character type Pf
|
||||
* This name is compatible with java.lang.Character's name for this type.
|
||||
* @see #FINAL_PUNCTUATION
|
||||
* @draft ICU 2.8
|
||||
* @deprecated This is a draft API and might change in a future release of ICU.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final int FINAL_QUOTE_PUNCTUATION = 29;
|
||||
|
||||
/**
|
||||
* Character type count
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int CHAR_CATEGORY_COUNT = 30;
|
||||
}
|
||||
|
||||
/**
|
||||
* 'Enum' for the CharacterDirection constants. There are two sets
|
||||
* of names, those used in ICU, and those used in the JDK. The
|
||||
* JDK constants are compatible in name <b>but not in value</b>
|
||||
* with those defined in <code>java.lang.Character</code>.
|
||||
* @see UCharacterDirection
|
||||
* @draft ICU 3.0
|
||||
* @deprecated This is a draft API and might change in a future release of ICU.
|
||||
*/
|
||||
|
||||
@Deprecated
|
||||
public static interface ECharacterDirection {
|
||||
/**
|
||||
* Directional type L
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int LEFT_TO_RIGHT = 0;
|
||||
|
||||
/**
|
||||
* JDK-compatible synonum for LEFT_TO_RIGHT.
|
||||
* @draft ICU 3.0
|
||||
* @deprecated This is a draft API and might change in a future release of ICU.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final byte DIRECTIONALITY_LEFT_TO_RIGHT = (byte)LEFT_TO_RIGHT;
|
||||
|
||||
/**
|
||||
* Directional type R
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int RIGHT_TO_LEFT = 1;
|
||||
|
||||
/**
|
||||
* JDK-compatible synonum for RIGHT_TO_LEFT.
|
||||
* @draft ICU 3.0
|
||||
* @deprecated This is a draft API and might change in a future release of ICU.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final byte DIRECTIONALITY_RIGHT_TO_LEFT = (byte)RIGHT_TO_LEFT;
|
||||
|
||||
/**
|
||||
* Directional type EN
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int EUROPEAN_NUMBER = 2;
|
||||
|
||||
/**
|
||||
* JDK-compatible synonum for EUROPEAN_NUMBER.
|
||||
* @draft ICU 3.0
|
||||
* @deprecated This is a draft API and might change in a future release of ICU.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final byte DIRECTIONALITY_EUROPEAN_NUMBER = (byte)EUROPEAN_NUMBER;
|
||||
|
||||
/**
|
||||
* Directional type ES
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int EUROPEAN_NUMBER_SEPARATOR = 3;
|
||||
|
||||
/**
|
||||
* JDK-compatible synonum for EUROPEAN_NUMBER_SEPARATOR.
|
||||
* @draft ICU 3.0
|
||||
* @deprecated This is a draft API and might change in a future release of ICU.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final byte DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR = (byte)EUROPEAN_NUMBER_SEPARATOR;
|
||||
|
||||
/**
|
||||
* Directional type ET
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int EUROPEAN_NUMBER_TERMINATOR = 4;
|
||||
|
||||
/**
|
||||
* JDK-compatible synonum for EUROPEAN_NUMBER_TERMINATOR.
|
||||
* @draft ICU 3.0
|
||||
* @deprecated This is a draft API and might change in a future release of ICU.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final byte DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR = (byte)EUROPEAN_NUMBER_TERMINATOR;
|
||||
|
||||
/**
|
||||
* Directional type AN
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int ARABIC_NUMBER = 5;
|
||||
|
||||
/**
|
||||
* JDK-compatible synonum for ARABIC_NUMBER.
|
||||
* @draft ICU 3.0
|
||||
* @deprecated This is a draft API and might change in a future release of ICU.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final byte DIRECTIONALITY_ARABIC_NUMBER = (byte)ARABIC_NUMBER;
|
||||
|
||||
/**
|
||||
* Directional type CS
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int COMMON_NUMBER_SEPARATOR = 6;
|
||||
|
||||
/**
|
||||
* JDK-compatible synonum for COMMON_NUMBER_SEPARATOR.
|
||||
* @draft ICU 3.0
|
||||
* @deprecated This is a draft API and might change in a future release of ICU.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final byte DIRECTIONALITY_COMMON_NUMBER_SEPARATOR = (byte)COMMON_NUMBER_SEPARATOR;
|
||||
|
||||
/**
|
||||
* Directional type B
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int BLOCK_SEPARATOR = 7;
|
||||
|
||||
/**
|
||||
* JDK-compatible synonum for BLOCK_SEPARATOR.
|
||||
* @draft ICU 3.0
|
||||
* @deprecated This is a draft API and might change in a future release of ICU.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final byte DIRECTIONALITY_PARAGRAPH_SEPARATOR = (byte)BLOCK_SEPARATOR;
|
||||
|
||||
/**
|
||||
* Directional type S
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int SEGMENT_SEPARATOR = 8;
|
||||
|
||||
/**
|
||||
* JDK-compatible synonum for SEGMENT_SEPARATOR.
|
||||
* @draft ICU 3.0
|
||||
* @deprecated This is a draft API and might change in a future release of ICU.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final byte DIRECTIONALITY_SEGMENT_SEPARATOR = (byte)SEGMENT_SEPARATOR;
|
||||
|
||||
/**
|
||||
* Directional type WS
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int WHITE_SPACE_NEUTRAL = 9;
|
||||
|
||||
/**
|
||||
* JDK-compatible synonum for WHITE_SPACE_NEUTRAL.
|
||||
* @draft ICU 3.0
|
||||
* @deprecated This is a draft API and might change in a future release of ICU.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final byte DIRECTIONALITY_WHITESPACE = (byte)WHITE_SPACE_NEUTRAL;
|
||||
|
||||
/**
|
||||
* Directional type ON
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int OTHER_NEUTRAL = 10;
|
||||
|
||||
/**
|
||||
* JDK-compatible synonum for OTHER_NEUTRAL.
|
||||
* @draft ICU 3.0
|
||||
* @deprecated This is a draft API and might change in a future release of ICU.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final byte DIRECTIONALITY_OTHER_NEUTRALS = (byte)OTHER_NEUTRAL;
|
||||
|
||||
/**
|
||||
* Directional type LRE
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int LEFT_TO_RIGHT_EMBEDDING = 11;
|
||||
|
||||
/**
|
||||
* JDK-compatible synonum for LEFT_TO_RIGHT_EMBEDDING.
|
||||
* @draft ICU 3.0
|
||||
* @deprecated This is a draft API and might change in a future release of ICU.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final byte DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING = (byte)LEFT_TO_RIGHT_EMBEDDING;
|
||||
|
||||
/**
|
||||
* Directional type LRO
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int LEFT_TO_RIGHT_OVERRIDE = 12;
|
||||
|
||||
/**
|
||||
* JDK-compatible synonum for LEFT_TO_RIGHT_OVERRIDE.
|
||||
* @draft ICU 3.0
|
||||
* @deprecated This is a draft API and might change in a future release of ICU.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final byte DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE = (byte)LEFT_TO_RIGHT_OVERRIDE;
|
||||
|
||||
/**
|
||||
* Directional type AL
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int RIGHT_TO_LEFT_ARABIC = 13;
|
||||
|
||||
/**
|
||||
* JDK-compatible synonum for RIGHT_TO_LEFT_ARABIC.
|
||||
* @draft ICU 3.0
|
||||
* @deprecated This is a draft API and might change in a future release of ICU.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final byte DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC = (byte)RIGHT_TO_LEFT_ARABIC;
|
||||
|
||||
/**
|
||||
* Directional type RLE
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int RIGHT_TO_LEFT_EMBEDDING = 14;
|
||||
|
||||
/**
|
||||
* JDK-compatible synonum for RIGHT_TO_LEFT_EMBEDDING.
|
||||
* @draft ICU 3.0
|
||||
* @deprecated This is a draft API and might change in a future release of ICU.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final byte DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING = (byte)RIGHT_TO_LEFT_EMBEDDING;
|
||||
|
||||
/**
|
||||
* Directional type RLO
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int RIGHT_TO_LEFT_OVERRIDE = 15;
|
||||
|
||||
/**
|
||||
* JDK-compatible synonum for RIGHT_TO_LEFT_OVERRIDE.
|
||||
* @draft ICU 3.0
|
||||
* @deprecated This is a draft API and might change in a future release of ICU.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final byte DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE = (byte)RIGHT_TO_LEFT_OVERRIDE;
|
||||
|
||||
/**
|
||||
* Directional type PDF
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int POP_DIRECTIONAL_FORMAT = 16;
|
||||
|
||||
/**
|
||||
* JDK-compatible synonum for POP_DIRECTIONAL_FORMAT.
|
||||
* @draft ICU 3.0
|
||||
* @deprecated This is a draft API and might change in a future release of ICU.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final byte DIRECTIONALITY_POP_DIRECTIONAL_FORMAT = (byte)POP_DIRECTIONAL_FORMAT;
|
||||
|
||||
/**
|
||||
* Directional type NSM
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int DIR_NON_SPACING_MARK = 17;
|
||||
|
||||
/**
|
||||
* JDK-compatible synonum for DIR_NON_SPACING_MARK.
|
||||
* @draft ICU 3.0
|
||||
* @deprecated This is a draft API and might change in a future release of ICU.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final byte DIRECTIONALITY_NON_SPACING_MARK = (byte)DIR_NON_SPACING_MARK;
|
||||
|
||||
/**
|
||||
* Directional type BN
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int BOUNDARY_NEUTRAL = 18;
|
||||
|
||||
/**
|
||||
* JDK-compatible synonum for BOUNDARY_NEUTRAL.
|
||||
* @draft ICU 3.0
|
||||
* @deprecated This is a draft API and might change in a future release of ICU.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final byte DIRECTIONALITY_BOUNDARY_NEUTRAL = (byte)BOUNDARY_NEUTRAL;
|
||||
|
||||
/**
|
||||
* Number of directional types
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static final int CHAR_DIRECTION_COUNT = 19;
|
||||
|
||||
/**
|
||||
* Undefined bidirectional character type. Undefined <code>char</code>
|
||||
* values have undefined directionality in the Unicode specification.
|
||||
* @draft ICU 3.0
|
||||
* @deprecated This is a draft API and might change in a future release of ICU.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final byte DIRECTIONALITY_UNDEFINED = -1;
|
||||
}
|
||||
}
|
||||
86
jdkSrc/jdk8/sun/net/sdp/SdpSupport.java
Normal file
86
jdkSrc/jdk8/sun/net/sdp/SdpSupport.java
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 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 sun.net.sdp;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.FileDescriptor;
|
||||
import java.security.AccessController;
|
||||
|
||||
import sun.misc.SharedSecrets;
|
||||
import sun.misc.JavaIOFileDescriptorAccess;
|
||||
|
||||
|
||||
/**
|
||||
* This class defines methods for creating SDP sockets or "converting" existing
|
||||
* file descriptors, referencing (unbound) TCP sockets, to SDP.
|
||||
*/
|
||||
|
||||
public final class SdpSupport {
|
||||
private static final String os = AccessController
|
||||
.doPrivileged(new sun.security.action.GetPropertyAction("os.name"));
|
||||
private static final boolean isSupported = (os.equals("SunOS") || (os.equals("Linux")));
|
||||
private static final JavaIOFileDescriptorAccess fdAccess =
|
||||
SharedSecrets.getJavaIOFileDescriptorAccess();
|
||||
|
||||
private SdpSupport() { }
|
||||
|
||||
/**
|
||||
* Creates a SDP socket, returning file descriptor referencing the socket.
|
||||
*/
|
||||
public static FileDescriptor createSocket() throws IOException {
|
||||
if (!isSupported)
|
||||
throw new UnsupportedOperationException("SDP not supported on this platform");
|
||||
int fdVal = create0();
|
||||
FileDescriptor fd = new FileDescriptor();
|
||||
fdAccess.set(fd, fdVal);
|
||||
return fd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an existing file descriptor, that references an unbound TCP socket,
|
||||
* to SDP.
|
||||
*/
|
||||
public static void convertSocket(FileDescriptor fd) throws IOException {
|
||||
if (!isSupported)
|
||||
throw new UnsupportedOperationException("SDP not supported on this platform");
|
||||
int fdVal = fdAccess.get(fd);
|
||||
convert0(fdVal);
|
||||
}
|
||||
|
||||
private static native int create0() throws IOException;
|
||||
|
||||
private static native void convert0(int fd) throws IOException;
|
||||
|
||||
static {
|
||||
AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
System.loadLibrary("net");
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
291
jdkSrc/jdk8/sun/net/smtp/SmtpClient.java
Normal file
291
jdkSrc/jdk8/sun/net/smtp/SmtpClient.java
Normal file
@@ -0,0 +1,291 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2017, 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 sun.net.smtp;
|
||||
|
||||
import java.util.StringTokenizer;
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import sun.net.TransferProtocolClient;
|
||||
|
||||
/**
|
||||
* This class implements the SMTP client.
|
||||
* You can send a piece of mail by creating a new SmtpClient, calling
|
||||
* the "to" method to add destinations, calling "from" to name the
|
||||
* sender, calling startMessage to return a stream to which you write
|
||||
* the message (with RFC733 headers) and then you finally close the Smtp
|
||||
* Client.
|
||||
*
|
||||
* @author James Gosling
|
||||
*/
|
||||
|
||||
public class SmtpClient extends TransferProtocolClient {
|
||||
|
||||
private static int DEFAULT_SMTP_PORT = 25;
|
||||
String mailhost;
|
||||
SmtpPrintStream message;
|
||||
|
||||
/**
|
||||
* issue the QUIT command to the SMTP server and close the connection.
|
||||
*/
|
||||
public void closeServer() throws IOException {
|
||||
if (serverIsOpen()) {
|
||||
closeMessage();
|
||||
issueCommand("QUIT\r\n", 221);
|
||||
super.closeServer();
|
||||
}
|
||||
}
|
||||
|
||||
void issueCommand(String cmd, int expect) throws IOException {
|
||||
sendServer(cmd);
|
||||
int reply;
|
||||
while ((reply = readServerResponse()) != expect)
|
||||
if (reply != 220) {
|
||||
throw new SmtpProtocolException(getResponseString());
|
||||
}
|
||||
}
|
||||
|
||||
private void toCanonical(String s) throws IOException {
|
||||
if (s.startsWith("<"))
|
||||
issueCommand("rcpt to: " + s + "\r\n", 250);
|
||||
else
|
||||
issueCommand("rcpt to: <" + s + ">\r\n", 250);
|
||||
}
|
||||
|
||||
public void to(String s) throws IOException {
|
||||
if (s.indexOf('\n') != -1) {
|
||||
throw new IOException("Illegal SMTP command",
|
||||
new IllegalArgumentException("Illegal carriage return"));
|
||||
}
|
||||
int st = 0;
|
||||
int limit = s.length();
|
||||
int pos = 0;
|
||||
int lastnonsp = 0;
|
||||
int parendepth = 0;
|
||||
boolean ignore = false;
|
||||
while (pos < limit) {
|
||||
int c = s.charAt(pos);
|
||||
if (parendepth > 0) {
|
||||
if (c == '(')
|
||||
parendepth++;
|
||||
else if (c == ')')
|
||||
parendepth--;
|
||||
if (parendepth == 0)
|
||||
if (lastnonsp > st)
|
||||
ignore = true;
|
||||
else
|
||||
st = pos + 1;
|
||||
} else if (c == '(')
|
||||
parendepth++;
|
||||
else if (c == '<')
|
||||
st = lastnonsp = pos + 1;
|
||||
else if (c == '>')
|
||||
ignore = true;
|
||||
else if (c == ',') {
|
||||
if (lastnonsp > st)
|
||||
toCanonical(s.substring(st, lastnonsp));
|
||||
st = pos + 1;
|
||||
ignore = false;
|
||||
} else {
|
||||
if (c > ' ' && !ignore)
|
||||
lastnonsp = pos + 1;
|
||||
else if (st == pos)
|
||||
st++;
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
if (lastnonsp > st)
|
||||
toCanonical(s.substring(st, lastnonsp));
|
||||
}
|
||||
|
||||
public void from(String s) throws IOException {
|
||||
if (s.indexOf('\n') != -1) {
|
||||
throw new IOException("Illegal SMTP command",
|
||||
new IllegalArgumentException("Illegal carriage return"));
|
||||
}
|
||||
if (s.startsWith("<")) {
|
||||
issueCommand("mail from: " + s + "\r\n", 250);
|
||||
} else {
|
||||
issueCommand("mail from: <" + s + ">\r\n", 250);
|
||||
}
|
||||
}
|
||||
|
||||
/** open a SMTP connection to host <i>host</i>. */
|
||||
private void openServer(String host) throws IOException {
|
||||
mailhost = host;
|
||||
openServer(mailhost, DEFAULT_SMTP_PORT);
|
||||
issueCommand("helo "+InetAddress.getLocalHost().getHostName()+"\r\n", 250);
|
||||
}
|
||||
|
||||
public PrintStream startMessage() throws IOException {
|
||||
issueCommand("data\r\n", 354);
|
||||
try {
|
||||
message = new SmtpPrintStream(serverOutput, this);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new InternalError(encoding+" encoding not found", e);
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
void closeMessage() throws IOException {
|
||||
if (message != null)
|
||||
message.close();
|
||||
}
|
||||
|
||||
/** New SMTP client connected to host <i>host</i>. */
|
||||
public SmtpClient (String host) throws IOException {
|
||||
super();
|
||||
if (host != null) {
|
||||
try {
|
||||
openServer(host);
|
||||
mailhost = host;
|
||||
return;
|
||||
} catch(Exception e) {
|
||||
}
|
||||
}
|
||||
try {
|
||||
String s;
|
||||
mailhost = java.security.AccessController.doPrivileged(
|
||||
new sun.security.action.GetPropertyAction("mail.host"));
|
||||
if (mailhost != null) {
|
||||
openServer(mailhost);
|
||||
return;
|
||||
}
|
||||
} catch(Exception e) {
|
||||
}
|
||||
try {
|
||||
mailhost = "localhost";
|
||||
openServer(mailhost);
|
||||
} catch(Exception e) {
|
||||
mailhost = "mailhost";
|
||||
openServer(mailhost);
|
||||
}
|
||||
}
|
||||
|
||||
/** Create an uninitialized SMTP client. */
|
||||
public SmtpClient () throws IOException {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public SmtpClient(int to) throws IOException {
|
||||
super();
|
||||
setConnectTimeout(to);
|
||||
try {
|
||||
String s;
|
||||
mailhost = java.security.AccessController.doPrivileged(
|
||||
new sun.security.action.GetPropertyAction("mail.host"));
|
||||
if (mailhost != null) {
|
||||
openServer(mailhost);
|
||||
return;
|
||||
}
|
||||
} catch(Exception e) {
|
||||
}
|
||||
try {
|
||||
mailhost = "localhost";
|
||||
openServer(mailhost);
|
||||
} catch(Exception e) {
|
||||
mailhost = "mailhost";
|
||||
openServer(mailhost);
|
||||
}
|
||||
}
|
||||
|
||||
public String getMailHost() {
|
||||
return mailhost;
|
||||
}
|
||||
|
||||
String getEncoding () {
|
||||
return encoding;
|
||||
}
|
||||
}
|
||||
|
||||
class SmtpPrintStream extends java.io.PrintStream {
|
||||
private SmtpClient target;
|
||||
private int lastc = '\n';
|
||||
|
||||
SmtpPrintStream (OutputStream fos, SmtpClient cl) throws UnsupportedEncodingException {
|
||||
super(fos, false, cl.getEncoding());
|
||||
target = cl;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
if (target == null)
|
||||
return;
|
||||
if (lastc != '\n') {
|
||||
write('\n');
|
||||
}
|
||||
try {
|
||||
target.issueCommand(".\r\n", 250);
|
||||
target.message = null;
|
||||
out = null;
|
||||
target = null;
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
|
||||
public void write(int b) {
|
||||
try {
|
||||
// quote a dot at the beginning of a line
|
||||
if (lastc == '\n' && b == '.') {
|
||||
out.write('.');
|
||||
}
|
||||
|
||||
// translate NL to CRLF
|
||||
if (b == '\n' && lastc != '\r') {
|
||||
out.write('\r');
|
||||
}
|
||||
out.write(b);
|
||||
lastc = b;
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
|
||||
public void write(byte b[], int off, int len) {
|
||||
try {
|
||||
int lc = lastc;
|
||||
while (--len >= 0) {
|
||||
int c = b[off++];
|
||||
|
||||
// quote a dot at the beginning of a line
|
||||
if (lc == '\n' && c == '.')
|
||||
out.write('.');
|
||||
|
||||
// translate NL to CRLF
|
||||
if (c == '\n' && lc != '\r') {
|
||||
out.write('\r');
|
||||
}
|
||||
out.write(c);
|
||||
lc = c;
|
||||
}
|
||||
lastc = lc;
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
public void print(String s) {
|
||||
int len = s.length();
|
||||
for (int i = 0; i < len; i++) {
|
||||
write(s.charAt(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
40
jdkSrc/jdk8/sun/net/smtp/SmtpProtocolException.java
Normal file
40
jdkSrc/jdk8/sun/net/smtp/SmtpProtocolException.java
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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 sun.net.smtp;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* This exception is thrown when unexpected results are returned during
|
||||
* an SMTP session.
|
||||
*/
|
||||
public class SmtpProtocolException extends IOException {
|
||||
private static final long serialVersionUID = -7547136771133814908L;
|
||||
|
||||
SmtpProtocolException(String s) {
|
||||
super(s);
|
||||
}
|
||||
}
|
||||
395
jdkSrc/jdk8/sun/net/spi/DefaultProxySelector.java
Normal file
395
jdkSrc/jdk8/sun/net/spi/DefaultProxySelector.java
Normal file
@@ -0,0 +1,395 @@
|
||||
/*
|
||||
* 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 sun.net.spi;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Proxy;
|
||||
import java.net.ProxySelector;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.io.IOException;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.StringJoiner;
|
||||
import java.util.regex.Pattern;
|
||||
import sun.net.NetProperties;
|
||||
import sun.net.SocksProxy;
|
||||
import static java.util.regex.Pattern.quote;
|
||||
|
||||
/**
|
||||
* Supports proxy settings using system properties This proxy selector
|
||||
* provides backward compatibility with the old http protocol handler
|
||||
* as far as how proxy is set
|
||||
*
|
||||
* Most of the implementation copied from the old http protocol handler
|
||||
*
|
||||
* Supports http/https/ftp.proxyHost, http/https/ftp.proxyPort,
|
||||
* proxyHost, proxyPort, and http/https/ftp.nonProxyHost, and socks.
|
||||
* NOTE: need to do gopher as well
|
||||
*/
|
||||
public class DefaultProxySelector extends ProxySelector {
|
||||
|
||||
/**
|
||||
* This is where we define all the valid System Properties we have to
|
||||
* support for each given protocol.
|
||||
* The format of this 2 dimensional array is :
|
||||
* - 1 row per protocol (http, ftp, ...)
|
||||
* - 1st element of each row is the protocol name
|
||||
* - subsequent elements are prefixes for Host & Port properties
|
||||
* listed in order of priority.
|
||||
* Example:
|
||||
* {"ftp", "ftp.proxy", "ftpProxy", "proxy", "socksProxy"},
|
||||
* means for FTP we try in that oder:
|
||||
* + ftp.proxyHost & ftp.proxyPort
|
||||
* + ftpProxyHost & ftpProxyPort
|
||||
* + proxyHost & proxyPort
|
||||
* + socksProxyHost & socksProxyPort
|
||||
*
|
||||
* Note that the socksProxy should *always* be the last on the list
|
||||
*/
|
||||
final static String[][] props = {
|
||||
/*
|
||||
* protocol, Property prefix 1, Property prefix 2, ...
|
||||
*/
|
||||
{"http", "http.proxy", "proxy", "socksProxy"},
|
||||
{"https", "https.proxy", "proxy", "socksProxy"},
|
||||
{"ftp", "ftp.proxy", "ftpProxy", "proxy", "socksProxy"},
|
||||
{"gopher", "gopherProxy", "socksProxy"},
|
||||
{"socket", "socksProxy"}
|
||||
};
|
||||
|
||||
private static final String SOCKS_PROXY_VERSION = "socksProxyVersion";
|
||||
|
||||
private static boolean hasSystemProxies = false;
|
||||
|
||||
static {
|
||||
final String key = "java.net.useSystemProxies";
|
||||
Boolean b = AccessController.doPrivileged(
|
||||
new PrivilegedAction<Boolean>() {
|
||||
public Boolean run() {
|
||||
return NetProperties.getBoolean(key);
|
||||
}});
|
||||
if (b != null && b.booleanValue()) {
|
||||
java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
System.loadLibrary("net");
|
||||
return null;
|
||||
}
|
||||
});
|
||||
hasSystemProxies = init();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* How to deal with "non proxy hosts":
|
||||
* since we do have to generate a pattern we don't want to do that if
|
||||
* it's not necessary. Therefore we do cache the result, on a per-protocol
|
||||
* basis, and change it only when the "source", i.e. the system property,
|
||||
* did change.
|
||||
*/
|
||||
|
||||
static class NonProxyInfo {
|
||||
// Default value for nonProxyHosts, this provides backward compatibility
|
||||
// by excluding localhost and its litteral notations.
|
||||
static final String defStringVal = "localhost|127.*|[::1]|0.0.0.0|[::0]";
|
||||
|
||||
String hostsSource;
|
||||
Pattern pattern;
|
||||
final String property;
|
||||
final String defaultVal;
|
||||
static NonProxyInfo ftpNonProxyInfo = new NonProxyInfo("ftp.nonProxyHosts", null, null, defStringVal);
|
||||
static NonProxyInfo httpNonProxyInfo = new NonProxyInfo("http.nonProxyHosts", null, null, defStringVal);
|
||||
static NonProxyInfo socksNonProxyInfo = new NonProxyInfo("socksNonProxyHosts", null, null, defStringVal);
|
||||
|
||||
NonProxyInfo(String p, String s, Pattern pattern, String d) {
|
||||
property = p;
|
||||
hostsSource = s;
|
||||
this.pattern = pattern;
|
||||
defaultVal = d;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* select() method. Where all the hard work is done.
|
||||
* Build a list of proxies depending on URI.
|
||||
* Since we're only providing compatibility with the system properties
|
||||
* from previous releases (see list above), that list will always
|
||||
* contain 1 single proxy, default being NO_PROXY.
|
||||
*/
|
||||
public java.util.List<Proxy> select(URI uri) {
|
||||
if (uri == null) {
|
||||
throw new IllegalArgumentException("URI can't be null.");
|
||||
}
|
||||
String protocol = uri.getScheme();
|
||||
String host = uri.getHost();
|
||||
|
||||
if (host == null) {
|
||||
// This is a hack to ensure backward compatibility in two
|
||||
// cases: 1. hostnames contain non-ascii characters,
|
||||
// internationalized domain names. in which case, URI will
|
||||
// return null, see BugID 4957669; 2. Some hostnames can
|
||||
// contain '_' chars even though it's not supposed to be
|
||||
// legal, in which case URI will return null for getHost,
|
||||
// but not for getAuthority() See BugID 4913253
|
||||
String auth = uri.getAuthority();
|
||||
if (auth != null) {
|
||||
int i;
|
||||
i = auth.indexOf('@');
|
||||
if (i >= 0) {
|
||||
auth = auth.substring(i+1);
|
||||
}
|
||||
i = auth.lastIndexOf(':');
|
||||
if (i >= 0) {
|
||||
auth = auth.substring(0,i);
|
||||
}
|
||||
host = auth;
|
||||
}
|
||||
}
|
||||
|
||||
if (protocol == null || host == null) {
|
||||
throw new IllegalArgumentException("protocol = "+protocol+" host = "+host);
|
||||
}
|
||||
List<Proxy> proxyl = new ArrayList<Proxy>(1);
|
||||
|
||||
NonProxyInfo pinfo = null;
|
||||
|
||||
if ("http".equalsIgnoreCase(protocol)) {
|
||||
pinfo = NonProxyInfo.httpNonProxyInfo;
|
||||
} else if ("https".equalsIgnoreCase(protocol)) {
|
||||
// HTTPS uses the same property as HTTP, for backward
|
||||
// compatibility
|
||||
pinfo = NonProxyInfo.httpNonProxyInfo;
|
||||
} else if ("ftp".equalsIgnoreCase(protocol)) {
|
||||
pinfo = NonProxyInfo.ftpNonProxyInfo;
|
||||
} else if ("socket".equalsIgnoreCase(protocol)) {
|
||||
pinfo = NonProxyInfo.socksNonProxyInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Let's check the System properties for that protocol
|
||||
*/
|
||||
final String proto = protocol;
|
||||
final NonProxyInfo nprop = pinfo;
|
||||
final String urlhost = host.toLowerCase();
|
||||
|
||||
/**
|
||||
* This is one big doPrivileged call, but we're trying to optimize
|
||||
* the code as much as possible. Since we're checking quite a few
|
||||
* System properties it does help having only 1 call to doPrivileged.
|
||||
* Be mindful what you do in here though!
|
||||
*/
|
||||
Proxy p = AccessController.doPrivileged(
|
||||
new PrivilegedAction<Proxy>() {
|
||||
public Proxy run() {
|
||||
int i, j;
|
||||
String phost = null;
|
||||
int pport = 0;
|
||||
String nphosts = null;
|
||||
InetSocketAddress saddr = null;
|
||||
|
||||
// Then let's walk the list of protocols in our array
|
||||
for (i=0; i<props.length; i++) {
|
||||
if (props[i][0].equalsIgnoreCase(proto)) {
|
||||
for (j = 1; j < props[i].length; j++) {
|
||||
/* System.getProp() will give us an empty
|
||||
* String, "" for a defined but "empty"
|
||||
* property.
|
||||
*/
|
||||
phost = NetProperties.get(props[i][j]+"Host");
|
||||
if (phost != null && phost.length() != 0)
|
||||
break;
|
||||
}
|
||||
if (phost == null || phost.length() == 0) {
|
||||
/**
|
||||
* No system property defined for that
|
||||
* protocol. Let's check System Proxy
|
||||
* settings (Gnome & Windows) if we were
|
||||
* instructed to.
|
||||
*/
|
||||
if (hasSystemProxies) {
|
||||
String sproto;
|
||||
if (proto.equalsIgnoreCase("socket"))
|
||||
sproto = "socks";
|
||||
else
|
||||
sproto = proto;
|
||||
Proxy sproxy = getSystemProxy(sproto, urlhost);
|
||||
if (sproxy != null) {
|
||||
return sproxy;
|
||||
}
|
||||
}
|
||||
return Proxy.NO_PROXY;
|
||||
}
|
||||
// If a Proxy Host is defined for that protocol
|
||||
// Let's get the NonProxyHosts property
|
||||
if (nprop != null) {
|
||||
nphosts = NetProperties.get(nprop.property);
|
||||
synchronized (nprop) {
|
||||
if (nphosts == null) {
|
||||
if (nprop.defaultVal != null) {
|
||||
nphosts = nprop.defaultVal;
|
||||
} else {
|
||||
nprop.hostsSource = null;
|
||||
nprop.pattern = null;
|
||||
}
|
||||
} else if (nphosts.length() != 0) {
|
||||
// add the required default patterns
|
||||
// but only if property no set. If it
|
||||
// is empty, leave empty.
|
||||
nphosts += "|" + NonProxyInfo
|
||||
.defStringVal;
|
||||
}
|
||||
if (nphosts != null) {
|
||||
if (!nphosts.equals(nprop.hostsSource)) {
|
||||
nprop.pattern = toPattern(nphosts);
|
||||
nprop.hostsSource = nphosts;
|
||||
}
|
||||
}
|
||||
if (shouldNotUseProxyFor(nprop.pattern, urlhost)) {
|
||||
return Proxy.NO_PROXY;
|
||||
}
|
||||
}
|
||||
}
|
||||
// We got a host, let's check for port
|
||||
|
||||
pport = NetProperties.getInteger(props[i][j]+"Port", 0).intValue();
|
||||
if (pport == 0 && j < (props[i].length - 1)) {
|
||||
// Can't find a port with same prefix as Host
|
||||
// AND it's not a SOCKS proxy
|
||||
// Let's try the other prefixes for that proto
|
||||
for (int k = 1; k < (props[i].length - 1); k++) {
|
||||
if ((k != j) && (pport == 0))
|
||||
pport = NetProperties.getInteger(props[i][k]+"Port", 0).intValue();
|
||||
}
|
||||
}
|
||||
|
||||
// Still couldn't find a port, let's use default
|
||||
if (pport == 0) {
|
||||
if (j == (props[i].length - 1)) // SOCKS
|
||||
pport = defaultPort("socket");
|
||||
else
|
||||
pport = defaultPort(proto);
|
||||
}
|
||||
// We did find a proxy definition.
|
||||
// Let's create the address, but don't resolve it
|
||||
// as this will be done at connection time
|
||||
saddr = InetSocketAddress.createUnresolved(phost, pport);
|
||||
// Socks is *always* the last on the list.
|
||||
if (j == (props[i].length - 1)) {
|
||||
int version = NetProperties.getInteger(SOCKS_PROXY_VERSION, 5).intValue();
|
||||
return SocksProxy.create(saddr, version);
|
||||
} else {
|
||||
return new Proxy(Proxy.Type.HTTP, saddr);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Proxy.NO_PROXY;
|
||||
}});
|
||||
|
||||
proxyl.add(p);
|
||||
|
||||
/*
|
||||
* If no specific property was set for that URI, we should be
|
||||
* returning an iterator to an empty List.
|
||||
*/
|
||||
return proxyl;
|
||||
}
|
||||
|
||||
public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
|
||||
if (uri == null || sa == null || ioe == null) {
|
||||
throw new IllegalArgumentException("Arguments can't be null.");
|
||||
}
|
||||
// ignored
|
||||
}
|
||||
|
||||
|
||||
private int defaultPort(String protocol) {
|
||||
if ("http".equalsIgnoreCase(protocol)) {
|
||||
return 80;
|
||||
} else if ("https".equalsIgnoreCase(protocol)) {
|
||||
return 443;
|
||||
} else if ("ftp".equalsIgnoreCase(protocol)) {
|
||||
return 80;
|
||||
} else if ("socket".equalsIgnoreCase(protocol)) {
|
||||
return 1080;
|
||||
} else if ("gopher".equalsIgnoreCase(protocol)) {
|
||||
return 80;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
private native static boolean init();
|
||||
private synchronized native Proxy getSystemProxy(String protocol, String host);
|
||||
|
||||
/**
|
||||
* @return {@code true} if given this pattern for non-proxy hosts and this
|
||||
* urlhost the proxy should NOT be used to access this urlhost
|
||||
*/
|
||||
static boolean shouldNotUseProxyFor(Pattern pattern, String urlhost) {
|
||||
if (pattern == null || urlhost.isEmpty())
|
||||
return false;
|
||||
boolean matches = pattern.matcher(urlhost).matches();
|
||||
return matches;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mask non-null mask
|
||||
* @return {@link java.util.regex.Pattern} corresponding to this mask
|
||||
* or {@code null} in case mask should not match anything
|
||||
*/
|
||||
static Pattern toPattern(String mask) {
|
||||
boolean disjunctionEmpty = true;
|
||||
StringJoiner joiner = new StringJoiner("|");
|
||||
for (String disjunct : mask.split("\\|")) {
|
||||
if (disjunct.isEmpty())
|
||||
continue;
|
||||
disjunctionEmpty = false;
|
||||
String regex = disjunctToRegex(disjunct.toLowerCase());
|
||||
joiner.add(regex);
|
||||
}
|
||||
return disjunctionEmpty ? null : Pattern.compile(joiner.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param disjunct non-null mask disjunct
|
||||
* @return java regex string corresponding to this mask
|
||||
*/
|
||||
static String disjunctToRegex(String disjunct) {
|
||||
String regex;
|
||||
if (disjunct.startsWith("*")) {
|
||||
regex = ".*" + quote(disjunct.substring(1));
|
||||
} else if (disjunct.endsWith("*")) {
|
||||
regex = quote(disjunct.substring(0, disjunct.length() - 1)) + ".*";
|
||||
} else {
|
||||
regex = quote(disjunct);
|
||||
}
|
||||
return regex;
|
||||
}
|
||||
}
|
||||
33
jdkSrc/jdk8/sun/net/spi/nameservice/NameService.java
Normal file
33
jdkSrc/jdk8/sun/net/spi/nameservice/NameService.java
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 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 sun.net.spi.nameservice;
|
||||
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
public interface NameService {
|
||||
public java.net.InetAddress[] lookupAllHostAddr(String host) throws UnknownHostException;
|
||||
public String getHostByAddr(byte[] addr) throws UnknownHostException;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 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 sun.net.spi.nameservice;
|
||||
|
||||
public interface NameServiceDescriptor {
|
||||
/**
|
||||
* Create a new instance of the corresponding name service.
|
||||
*/
|
||||
public NameService createNameService () throws Exception ;
|
||||
|
||||
/**
|
||||
* Returns this service provider's name
|
||||
*
|
||||
*/
|
||||
public String getProviderName();
|
||||
|
||||
/**
|
||||
* Returns this name service type
|
||||
* "dns" "nis" etc
|
||||
*/
|
||||
public String getType();
|
||||
}
|
||||
505
jdkSrc/jdk8/sun/net/spi/nameservice/dns/DNSNameService.java
Normal file
505
jdkSrc/jdk8/sun/net/spi/nameservice/dns/DNSNameService.java
Normal file
@@ -0,0 +1,505 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 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 sun.net.spi.nameservice.dns;
|
||||
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import javax.naming.*;
|
||||
import javax.naming.directory.*;
|
||||
import javax.naming.spi.NamingManager;
|
||||
import java.util.*;
|
||||
import sun.net.util.IPAddressUtil;
|
||||
import sun.net.dns.ResolverConfiguration;
|
||||
import sun.net.spi.nameservice.*;
|
||||
import java.security.AccessController;
|
||||
import sun.security.action.*;
|
||||
|
||||
/*
|
||||
* A name service provider based on JNDI-DNS.
|
||||
*/
|
||||
|
||||
public final class DNSNameService implements NameService {
|
||||
|
||||
// List of domains specified by property
|
||||
private LinkedList<String> domainList = null;
|
||||
|
||||
// JNDI-DNS URL for name servers specified via property
|
||||
private String nameProviderUrl = null;
|
||||
|
||||
// Per-thread soft cache of the last temporary context
|
||||
private static ThreadLocal<SoftReference<ThreadContext>> contextRef =
|
||||
new ThreadLocal<>();
|
||||
|
||||
// Simple class to encapsulate the temporary context
|
||||
private static class ThreadContext {
|
||||
private DirContext dirCtxt;
|
||||
private List<String> nsList;
|
||||
|
||||
public ThreadContext(DirContext dirCtxt, List<String> nsList) {
|
||||
this.dirCtxt = dirCtxt;
|
||||
this.nsList = nsList;
|
||||
}
|
||||
|
||||
public DirContext dirContext() {
|
||||
return dirCtxt;
|
||||
}
|
||||
|
||||
public List<String> nameservers() {
|
||||
return nsList;
|
||||
}
|
||||
}
|
||||
|
||||
// Returns a per-thread DirContext
|
||||
private DirContext getTemporaryContext() throws NamingException {
|
||||
SoftReference<ThreadContext> ref = contextRef.get();
|
||||
ThreadContext thrCtxt = null;
|
||||
List<String> nsList = null;
|
||||
|
||||
// if no property specified we need to obtain the list of servers
|
||||
//
|
||||
if (nameProviderUrl == null)
|
||||
nsList = ResolverConfiguration.open().nameservers();
|
||||
|
||||
// if soft reference hasn't been gc'ed no property has been
|
||||
// specified then we need to check if the DNS configuration
|
||||
// has changed.
|
||||
//
|
||||
if ((ref != null) && ((thrCtxt = ref.get()) != null)) {
|
||||
if (nameProviderUrl == null) {
|
||||
if (!thrCtxt.nameservers().equals(nsList)) {
|
||||
// DNS configuration has changed
|
||||
thrCtxt = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// new thread context needs to be created
|
||||
if (thrCtxt == null) {
|
||||
final Hashtable<String,Object> env = new Hashtable<>();
|
||||
env.put("java.naming.factory.initial",
|
||||
"com.sun.jndi.dns.DnsContextFactory");
|
||||
|
||||
// If no nameservers property specified we create provider URL
|
||||
// based on system configured name servers
|
||||
//
|
||||
String provUrl = nameProviderUrl;
|
||||
if (provUrl == null) {
|
||||
provUrl = createProviderURL(nsList);
|
||||
if (provUrl.length() == 0) {
|
||||
throw new RuntimeException("bad nameserver configuration");
|
||||
}
|
||||
}
|
||||
env.put("java.naming.provider.url", provUrl);
|
||||
|
||||
// Need to create directory context in privileged block
|
||||
// as JNDI-DNS needs to resolve the name servers.
|
||||
//
|
||||
DirContext dirCtxt;
|
||||
try {
|
||||
dirCtxt = java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedExceptionAction<DirContext>() {
|
||||
public DirContext run() throws NamingException {
|
||||
// Create the DNS context using NamingManager rather than using
|
||||
// the initial context constructor. This avoids having the initial
|
||||
// context constructor call itself.
|
||||
Context ctx = NamingManager.getInitialContext(env);
|
||||
if (!(ctx instanceof DirContext)) {
|
||||
return null; // cannot create a DNS context
|
||||
}
|
||||
return (DirContext)ctx;
|
||||
}
|
||||
});
|
||||
} catch (java.security.PrivilegedActionException pae) {
|
||||
throw (NamingException)pae.getException();
|
||||
}
|
||||
|
||||
// create new soft reference to our thread context
|
||||
//
|
||||
thrCtxt = new ThreadContext(dirCtxt, nsList);
|
||||
contextRef.set(new SoftReference<ThreadContext>(thrCtxt));
|
||||
}
|
||||
|
||||
return thrCtxt.dirContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the specified entry in DNS.
|
||||
*
|
||||
* Canonical name records are recursively resolved (to a maximum
|
||||
* of 5 to avoid performance hit and potential CNAME loops).
|
||||
*
|
||||
* @param ctx JNDI directory context
|
||||
* @param name name to resolve
|
||||
* @param ids record types to search
|
||||
* @param depth call depth - pass as 0.
|
||||
*
|
||||
* @return array list with results (will have at least on entry)
|
||||
*
|
||||
* @throws UnknownHostException if lookup fails or other error.
|
||||
*/
|
||||
private ArrayList<String> resolve(final DirContext ctx, final String name,
|
||||
final String[] ids, int depth)
|
||||
throws UnknownHostException
|
||||
{
|
||||
ArrayList<String> results = new ArrayList<>();
|
||||
Attributes attrs;
|
||||
|
||||
// do the query
|
||||
try {
|
||||
attrs = java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedExceptionAction<Attributes>() {
|
||||
public Attributes run() throws NamingException {
|
||||
return ctx.getAttributes(name, ids);
|
||||
}
|
||||
});
|
||||
} catch (java.security.PrivilegedActionException pae) {
|
||||
throw new UnknownHostException(pae.getException().getMessage());
|
||||
}
|
||||
|
||||
// non-requested type returned so enumeration is empty
|
||||
NamingEnumeration<? extends Attribute> ne = attrs.getAll();
|
||||
if (!ne.hasMoreElements()) {
|
||||
throw new UnknownHostException("DNS record not found");
|
||||
}
|
||||
|
||||
// iterate through the returned attributes
|
||||
UnknownHostException uhe = null;
|
||||
try {
|
||||
while (ne.hasMoreElements()) {
|
||||
Attribute attr = ne.next();
|
||||
String attrID = attr.getID();
|
||||
|
||||
for (NamingEnumeration<?> e = attr.getAll(); e.hasMoreElements();) {
|
||||
String addr = (String)e.next();
|
||||
|
||||
// for canoncical name records do recursive lookup
|
||||
// - also check for CNAME loops to avoid stack overflow
|
||||
|
||||
if (attrID.equals("CNAME")) {
|
||||
if (depth > 4) {
|
||||
throw new UnknownHostException(name + ": possible CNAME loop");
|
||||
}
|
||||
try {
|
||||
results.addAll(resolve(ctx, addr, ids, depth+1));
|
||||
} catch (UnknownHostException x) {
|
||||
// canonical name can't be resolved.
|
||||
if (uhe == null)
|
||||
uhe = x;
|
||||
}
|
||||
} else {
|
||||
results.add(addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (NamingException nx) {
|
||||
throw new UnknownHostException(nx.getMessage());
|
||||
}
|
||||
|
||||
// pending exception as canonical name could not be resolved.
|
||||
if (results.isEmpty() && uhe != null) {
|
||||
throw uhe;
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
public DNSNameService() throws Exception {
|
||||
|
||||
// default domain
|
||||
String domain = AccessController.doPrivileged(
|
||||
new GetPropertyAction("sun.net.spi.nameservice.domain"));
|
||||
if (domain != null && domain.length() > 0) {
|
||||
domainList = new LinkedList<String>();
|
||||
domainList.add(domain);
|
||||
}
|
||||
|
||||
// name servers
|
||||
String nameservers = AccessController.doPrivileged(
|
||||
new GetPropertyAction("sun.net.spi.nameservice.nameservers"));
|
||||
if (nameservers != null && nameservers.length() > 0) {
|
||||
nameProviderUrl = createProviderURL(nameservers);
|
||||
if (nameProviderUrl.length() == 0) {
|
||||
throw new RuntimeException("malformed nameservers property");
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// no property specified so check host DNS resolver configured
|
||||
// with at least one nameserver in dotted notation.
|
||||
//
|
||||
List<String> nsList = ResolverConfiguration.open().nameservers();
|
||||
if (nsList.isEmpty()) {
|
||||
throw new RuntimeException("no nameservers provided");
|
||||
}
|
||||
boolean found = false;
|
||||
for (String addr: nsList) {
|
||||
if (IPAddressUtil.isIPv4LiteralAddress(addr) ||
|
||||
IPAddressUtil.isIPv6LiteralAddress(addr)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
throw new RuntimeException("bad nameserver configuration");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public InetAddress[] lookupAllHostAddr(String host) throws UnknownHostException {
|
||||
|
||||
// DNS records that we search for
|
||||
String[] ids = {"A", "AAAA", "CNAME"};
|
||||
|
||||
// first get directory context
|
||||
DirContext ctx;
|
||||
try {
|
||||
ctx = getTemporaryContext();
|
||||
} catch (NamingException nx) {
|
||||
throw new Error(nx);
|
||||
}
|
||||
|
||||
ArrayList<String> results = null;
|
||||
UnknownHostException uhe = null;
|
||||
|
||||
// If host already contains a domain name then just look it up
|
||||
if (host.indexOf('.') >= 0) {
|
||||
try {
|
||||
results = resolve(ctx, host, ids, 0);
|
||||
} catch (UnknownHostException x) {
|
||||
uhe = x;
|
||||
}
|
||||
}
|
||||
|
||||
// Here we try to resolve the host using the domain suffix or
|
||||
// the domain suffix search list. If the host cannot be resolved
|
||||
// using the domain suffix then we attempt devolution of
|
||||
// the suffix - eg: if we are searching for "foo" and our
|
||||
// domain suffix is "eng.sun.com" we will try to resolve
|
||||
// "foo.eng.sun.com" and "foo.sun.com".
|
||||
// It's not normal to attempt devolation with domains on the
|
||||
// domain suffix search list - however as ResolverConfiguration
|
||||
// doesn't distinguish domain or search list in the list it
|
||||
// returns we approximate by doing devolution on the domain
|
||||
// suffix if the list has one entry.
|
||||
|
||||
if (results == null) {
|
||||
List<String> searchList = null;
|
||||
Iterator<String> i;
|
||||
boolean usingSearchList = false;
|
||||
|
||||
if (domainList != null) {
|
||||
i = domainList.iterator();
|
||||
} else {
|
||||
searchList = ResolverConfiguration.open().searchlist();
|
||||
if (searchList.size() > 1) {
|
||||
usingSearchList = true;
|
||||
}
|
||||
i = searchList.iterator();
|
||||
}
|
||||
|
||||
// iterator through each domain suffix
|
||||
while (i.hasNext()) {
|
||||
String parentDomain = i.next();
|
||||
int start = 0;
|
||||
while ((start = parentDomain.indexOf(".")) != -1
|
||||
&& start < parentDomain.length() -1) {
|
||||
try {
|
||||
results = resolve(ctx, host+"."+parentDomain, ids, 0);
|
||||
break;
|
||||
} catch (UnknownHostException x) {
|
||||
uhe = x;
|
||||
if (usingSearchList) {
|
||||
break;
|
||||
}
|
||||
|
||||
// devolve
|
||||
parentDomain = parentDomain.substring(start+1);
|
||||
}
|
||||
}
|
||||
if (results != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// finally try the host if it doesn't have a domain name
|
||||
if (results == null && (host.indexOf('.') < 0)) {
|
||||
results = resolve(ctx, host, ids, 0);
|
||||
}
|
||||
|
||||
// if not found then throw the (last) exception thrown.
|
||||
if (results == null) {
|
||||
assert uhe != null;
|
||||
throw uhe;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the array list into a byte aray list - this
|
||||
* filters out any invalid IPv4/IPv6 addresses.
|
||||
*/
|
||||
assert results.size() > 0;
|
||||
InetAddress[] addrs = new InetAddress[results.size()];
|
||||
int count = 0;
|
||||
for (int i=0; i<results.size(); i++) {
|
||||
String addrString = results.get(i);
|
||||
byte[] addr = null;
|
||||
try {
|
||||
addr = IPAddressUtil.validateNumericFormatV4(addrString);
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
}
|
||||
if (addr == null) {
|
||||
addr = IPAddressUtil.textToNumericFormatV6(addrString);
|
||||
}
|
||||
if (addr != null) {
|
||||
addrs[count++] = InetAddress.getByAddress(host, addr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If addresses are filtered then we need to resize the
|
||||
* array. Additionally if all addresses are filtered then
|
||||
* we throw an exception.
|
||||
*/
|
||||
if (count == 0) {
|
||||
throw new UnknownHostException(host + ": no valid DNS records");
|
||||
}
|
||||
if (count < results.size()) {
|
||||
InetAddress[] tmp = new InetAddress[count];
|
||||
for (int i=0; i<count; i++) {
|
||||
tmp[i] = addrs[i];
|
||||
}
|
||||
addrs = tmp;
|
||||
}
|
||||
|
||||
return addrs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse lookup code. I.E: find a host name from an IP address.
|
||||
* IPv4 addresses are mapped in the IN-ADDR.ARPA. top domain, while
|
||||
* IPv6 addresses can be in IP6.ARPA or IP6.INT.
|
||||
* In both cases the address has to be converted into a dotted form.
|
||||
*/
|
||||
public String getHostByAddr(byte[] addr) throws UnknownHostException {
|
||||
String host = null;
|
||||
try {
|
||||
String literalip = "";
|
||||
String[] ids = { "PTR" };
|
||||
DirContext ctx;
|
||||
ArrayList<String> results = null;
|
||||
try {
|
||||
ctx = getTemporaryContext();
|
||||
} catch (NamingException nx) {
|
||||
throw new Error(nx);
|
||||
}
|
||||
if (addr.length == 4) { // IPv4 Address
|
||||
for (int i = addr.length-1; i >= 0; i--) {
|
||||
literalip += (addr[i] & 0xff) +".";
|
||||
}
|
||||
literalip += "IN-ADDR.ARPA.";
|
||||
|
||||
results = resolve(ctx, literalip, ids, 0);
|
||||
host = results.get(0);
|
||||
} else if (addr.length == 16) { // IPv6 Address
|
||||
/**
|
||||
* Because RFC 3152 changed the root domain name for reverse
|
||||
* lookups from IP6.INT. to IP6.ARPA., we need to check
|
||||
* both. I.E. first the new one, IP6.ARPA, then if it fails
|
||||
* the older one, IP6.INT
|
||||
*/
|
||||
|
||||
for (int i = addr.length-1; i >= 0; i--) {
|
||||
literalip += Integer.toHexString((addr[i] & 0x0f)) +"."
|
||||
+Integer.toHexString((addr[i] & 0xf0) >> 4) +".";
|
||||
}
|
||||
String ip6lit = literalip + "IP6.ARPA.";
|
||||
|
||||
try {
|
||||
results = resolve(ctx, ip6lit, ids, 0);
|
||||
host = results.get(0);
|
||||
} catch (UnknownHostException e) {
|
||||
host = null;
|
||||
}
|
||||
if (host == null) {
|
||||
// IP6.ARPA lookup failed, let's try the older IP6.INT
|
||||
ip6lit = literalip + "IP6.INT.";
|
||||
results = resolve(ctx, ip6lit, ids, 0);
|
||||
host = results.get(0);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new UnknownHostException(e.getMessage());
|
||||
}
|
||||
// Either we couldn't find it or the address was neither IPv4 or IPv6
|
||||
if (host == null)
|
||||
throw new UnknownHostException();
|
||||
// remove trailing dot
|
||||
if (host.endsWith(".")) {
|
||||
host = host.substring(0, host.length() - 1);
|
||||
}
|
||||
return host;
|
||||
}
|
||||
|
||||
|
||||
// ---------
|
||||
|
||||
private static void appendIfLiteralAddress(String addr, StringBuffer sb) {
|
||||
if (IPAddressUtil.isIPv4LiteralAddress(addr)) {
|
||||
sb.append("dns://" + addr + " ");
|
||||
} else {
|
||||
if (IPAddressUtil.isIPv6LiteralAddress(addr)) {
|
||||
sb.append("dns://[" + addr + "] ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @return String containing the JNDI-DNS provider URL
|
||||
* corresponding to the supplied List of nameservers.
|
||||
*/
|
||||
private static String createProviderURL(List<String> nsList) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (String s: nsList) {
|
||||
appendIfLiteralAddress(s, sb);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/*
|
||||
* @return String containing the JNDI-DNS provider URL
|
||||
* corresponding to the list of nameservers
|
||||
* contained in the provided str.
|
||||
*/
|
||||
private static String createProviderURL(String str) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
StringTokenizer st = new StringTokenizer(str, ",");
|
||||
while (st.hasMoreTokens()) {
|
||||
appendIfLiteralAddress(st.nextToken(), sb);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 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 sun.net.spi.nameservice.dns;
|
||||
|
||||
import sun.net.spi.nameservice.*;
|
||||
|
||||
public final class DNSNameServiceDescriptor implements NameServiceDescriptor {
|
||||
/**
|
||||
* Create a new instance of the corresponding name service.
|
||||
*/
|
||||
public NameService createNameService() throws Exception {
|
||||
return new DNSNameService();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this service provider's name
|
||||
*
|
||||
*/
|
||||
public String getProviderName() {
|
||||
return "sun";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this name service type
|
||||
* "dns" "nis" etc
|
||||
*/
|
||||
public String getType() {
|
||||
return "dns";
|
||||
}
|
||||
}
|
||||
741
jdkSrc/jdk8/sun/net/util/IPAddressUtil.java
Normal file
741
jdkSrc/jdk8/sun/net/util/IPAddressUtil.java
Normal file
@@ -0,0 +1,741 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 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 sun.net.util;
|
||||
|
||||
import java.net.URL;
|
||||
import java.nio.CharBuffer;
|
||||
import java.util.Arrays;
|
||||
|
||||
import sun.security.action.GetPropertyAction;
|
||||
|
||||
public class IPAddressUtil {
|
||||
private final static int INADDR4SZ = 4;
|
||||
private final static int INADDR16SZ = 16;
|
||||
private final static int INT16SZ = 2;
|
||||
|
||||
/*
|
||||
* Converts IPv4 address in its textual presentation form
|
||||
* into its numeric binary form.
|
||||
*
|
||||
* @param src a String representing an IPv4 address in standard format
|
||||
* @return a byte array representing the IPv4 numeric address
|
||||
*/
|
||||
@SuppressWarnings("fallthrough")
|
||||
public static byte[] textToNumericFormatV4(String src)
|
||||
{
|
||||
byte[] res = new byte[INADDR4SZ];
|
||||
|
||||
long tmpValue = 0;
|
||||
int currByte = 0;
|
||||
boolean newOctet = true;
|
||||
|
||||
int len = src.length();
|
||||
if (len == 0 || len > 15) {
|
||||
return null;
|
||||
}
|
||||
/*
|
||||
* When only one part is given, the value is stored directly in
|
||||
* the network address without any byte rearrangement.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* We determine and parse the leading parts, if any, as single
|
||||
* byte values in one pass directly into the resulting byte[],
|
||||
* then the remainder is treated as a 8-to-32-bit entity and
|
||||
* translated into the remaining bytes in the array.
|
||||
*/
|
||||
for (int i = 0; i < len; i++) {
|
||||
char c = src.charAt(i);
|
||||
if (c == '.') {
|
||||
if (newOctet || tmpValue < 0 || tmpValue > 0xff || currByte == 3) {
|
||||
return null;
|
||||
}
|
||||
res[currByte++] = (byte) (tmpValue & 0xff);
|
||||
tmpValue = 0;
|
||||
newOctet = true;
|
||||
} else {
|
||||
int digit = digit(c, 10);
|
||||
if (digit < 0) {
|
||||
return null;
|
||||
}
|
||||
tmpValue *= 10;
|
||||
tmpValue += digit;
|
||||
newOctet = false;
|
||||
}
|
||||
}
|
||||
if (newOctet || tmpValue < 0 || tmpValue >= (1L << ((4 - currByte) * 8))) {
|
||||
return null;
|
||||
}
|
||||
switch (currByte) {
|
||||
case 0:
|
||||
res[0] = (byte) ((tmpValue >> 24) & 0xff);
|
||||
case 1:
|
||||
res[1] = (byte) ((tmpValue >> 16) & 0xff);
|
||||
case 2:
|
||||
res[2] = (byte) ((tmpValue >> 8) & 0xff);
|
||||
case 3:
|
||||
res[3] = (byte) ((tmpValue >> 0) & 0xff);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates if input string is a valid IPv4 address literal.
|
||||
* If the "jdk.net.allowAmbiguousIPAddressLiterals" system property is set
|
||||
* to {@code false}, or is not set then validation of the address string is performed as follows:
|
||||
* If string can't be parsed by following IETF IPv4 address string literals
|
||||
* formatting style rules (default one), but can be parsed by following BSD formatting
|
||||
* style rules, the IPv4 address string content is treated as ambiguous and
|
||||
* {@code IllegalArgumentException} is thrown.
|
||||
*
|
||||
* @param src input string
|
||||
* @return bytes array if string is a valid IPv4 address string
|
||||
* @throws IllegalArgumentException if "jdk.net.allowAmbiguousIPAddressLiterals" SP is set to
|
||||
* "false" and IPv4 address string {@code "src"} is ambiguous
|
||||
*/
|
||||
public static byte[] validateNumericFormatV4(String src) {
|
||||
byte[] parsedBytes = textToNumericFormatV4(src);
|
||||
if (!ALLOW_AMBIGUOUS_IPADDRESS_LITERALS_SP_VALUE
|
||||
&& parsedBytes == null && isBsdParsableV4(src)) {
|
||||
throw new IllegalArgumentException("Invalid IP address literal: " + src);
|
||||
}
|
||||
return parsedBytes;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert IPv6 presentation level address to network order binary form.
|
||||
* credit:
|
||||
* Converted from C code from Solaris 8 (inet_pton)
|
||||
*
|
||||
* Any component of the string following a per-cent % is ignored.
|
||||
*
|
||||
* @param src a String representing an IPv6 address in textual format
|
||||
* @return a byte array representing the IPv6 numeric address
|
||||
*/
|
||||
public static byte[] textToNumericFormatV6(String src)
|
||||
{
|
||||
// Shortest valid string is "::", hence at least 2 chars
|
||||
if (src.length() < 2) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int colonp;
|
||||
char ch;
|
||||
boolean saw_xdigit;
|
||||
int val;
|
||||
char[] srcb = src.toCharArray();
|
||||
byte[] dst = new byte[INADDR16SZ];
|
||||
|
||||
int srcb_length = srcb.length;
|
||||
int pc = src.indexOf ("%");
|
||||
if (pc == srcb_length -1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (pc != -1) {
|
||||
srcb_length = pc;
|
||||
}
|
||||
|
||||
colonp = -1;
|
||||
int i = 0, j = 0;
|
||||
/* Leading :: requires some special handling. */
|
||||
if (srcb[i] == ':')
|
||||
if (srcb[++i] != ':')
|
||||
return null;
|
||||
int curtok = i;
|
||||
saw_xdigit = false;
|
||||
val = 0;
|
||||
while (i < srcb_length) {
|
||||
ch = srcb[i++];
|
||||
int chval = digit(ch, 16);
|
||||
if (chval != -1) {
|
||||
val <<= 4;
|
||||
val |= chval;
|
||||
if (val > 0xffff)
|
||||
return null;
|
||||
saw_xdigit = true;
|
||||
continue;
|
||||
}
|
||||
if (ch == ':') {
|
||||
curtok = i;
|
||||
if (!saw_xdigit) {
|
||||
if (colonp != -1)
|
||||
return null;
|
||||
colonp = j;
|
||||
continue;
|
||||
} else if (i == srcb_length) {
|
||||
return null;
|
||||
}
|
||||
if (j + INT16SZ > INADDR16SZ)
|
||||
return null;
|
||||
dst[j++] = (byte) ((val >> 8) & 0xff);
|
||||
dst[j++] = (byte) (val & 0xff);
|
||||
saw_xdigit = false;
|
||||
val = 0;
|
||||
continue;
|
||||
}
|
||||
if (ch == '.' && ((j + INADDR4SZ) <= INADDR16SZ)) {
|
||||
String ia4 = src.substring(curtok, srcb_length);
|
||||
/* check this IPv4 address has 3 dots, ie. A.B.C.D */
|
||||
int dot_count = 0, index=0;
|
||||
while ((index = ia4.indexOf ('.', index)) != -1) {
|
||||
dot_count ++;
|
||||
index ++;
|
||||
}
|
||||
if (dot_count != 3) {
|
||||
return null;
|
||||
}
|
||||
byte[] v4addr = textToNumericFormatV4(ia4);
|
||||
if (v4addr == null) {
|
||||
return null;
|
||||
}
|
||||
for (int k = 0; k < INADDR4SZ; k++) {
|
||||
dst[j++] = v4addr[k];
|
||||
}
|
||||
saw_xdigit = false;
|
||||
break; /* '\0' was seen by inet_pton4(). */
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (saw_xdigit) {
|
||||
if (j + INT16SZ > INADDR16SZ)
|
||||
return null;
|
||||
dst[j++] = (byte) ((val >> 8) & 0xff);
|
||||
dst[j++] = (byte) (val & 0xff);
|
||||
}
|
||||
|
||||
if (colonp != -1) {
|
||||
int n = j - colonp;
|
||||
|
||||
if (j == INADDR16SZ)
|
||||
return null;
|
||||
for (i = 1; i <= n; i++) {
|
||||
dst[INADDR16SZ - i] = dst[colonp + n - i];
|
||||
dst[colonp + n - i] = 0;
|
||||
}
|
||||
j = INADDR16SZ;
|
||||
}
|
||||
if (j != INADDR16SZ)
|
||||
return null;
|
||||
byte[] newdst = convertFromIPv4MappedAddress(dst);
|
||||
if (newdst != null) {
|
||||
return newdst;
|
||||
} else {
|
||||
return dst;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param src a String representing an IPv4 address in textual format
|
||||
* @return a boolean indicating whether src is an IPv4 literal address
|
||||
*/
|
||||
public static boolean isIPv4LiteralAddress(String src) {
|
||||
return textToNumericFormatV4(src) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param src a String representing an IPv6 address in textual format
|
||||
* @return a boolean indicating whether src is an IPv6 literal address
|
||||
*/
|
||||
public static boolean isIPv6LiteralAddress(String src) {
|
||||
return textToNumericFormatV6(src) != null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert IPv4-Mapped address to IPv4 address. Both input and
|
||||
* returned value are in network order binary form.
|
||||
*
|
||||
* @param src a String representing an IPv4-Mapped address in textual format
|
||||
* @return a byte array representing the IPv4 numeric address
|
||||
*/
|
||||
public static byte[] convertFromIPv4MappedAddress(byte[] addr) {
|
||||
if (isIPv4MappedAddress(addr)) {
|
||||
byte[] newAddr = new byte[INADDR4SZ];
|
||||
System.arraycopy(addr, 12, newAddr, 0, INADDR4SZ);
|
||||
return newAddr;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility routine to check if the InetAddress is an
|
||||
* IPv4 mapped IPv6 address.
|
||||
*
|
||||
* @return a <code>boolean</code> indicating if the InetAddress is
|
||||
* an IPv4 mapped IPv6 address; or false if address is IPv4 address.
|
||||
*/
|
||||
private static boolean isIPv4MappedAddress(byte[] addr) {
|
||||
if (addr.length < INADDR16SZ) {
|
||||
return false;
|
||||
}
|
||||
if ((addr[0] == 0x00) && (addr[1] == 0x00) &&
|
||||
(addr[2] == 0x00) && (addr[3] == 0x00) &&
|
||||
(addr[4] == 0x00) && (addr[5] == 0x00) &&
|
||||
(addr[6] == 0x00) && (addr[7] == 0x00) &&
|
||||
(addr[8] == 0x00) && (addr[9] == 0x00) &&
|
||||
(addr[10] == (byte)0xff) &&
|
||||
(addr[11] == (byte)0xff)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// See java.net.URI for more details on how to generate these
|
||||
// masks.
|
||||
//
|
||||
// square brackets
|
||||
private static final long L_IPV6_DELIMS = 0x0L; // "[]"
|
||||
private static final long H_IPV6_DELIMS = 0x28000000L; // "[]"
|
||||
// RFC 3986 gen-delims
|
||||
private static final long L_GEN_DELIMS = 0x8400800800000000L; // ":/?#[]@"
|
||||
private static final long H_GEN_DELIMS = 0x28000001L; // ":/?#[]@"
|
||||
// These gen-delims can appear in authority
|
||||
private static final long L_AUTH_DELIMS = 0x400000000000000L; // "@[]:"
|
||||
private static final long H_AUTH_DELIMS = 0x28000001L; // "@[]:"
|
||||
// colon is allowed in userinfo
|
||||
private static final long L_COLON = 0x400000000000000L; // ":"
|
||||
private static final long H_COLON = 0x0L; // ":"
|
||||
// slash should be encoded in authority
|
||||
private static final long L_SLASH = 0x800000000000L; // "/"
|
||||
private static final long H_SLASH = 0x0L; // "/"
|
||||
// backslash should always be encoded
|
||||
private static final long L_BACKSLASH = 0x0L; // "\"
|
||||
private static final long H_BACKSLASH = 0x10000000L; // "\"
|
||||
// ASCII chars 0-31 + 127 - various controls + CRLF + TAB
|
||||
private static final long L_NON_PRINTABLE = 0xffffffffL;
|
||||
private static final long H_NON_PRINTABLE = 0x8000000000000000L;
|
||||
// All of the above
|
||||
private static final long L_EXCLUDE = 0x84008008ffffffffL;
|
||||
private static final long H_EXCLUDE = 0x8000000038000001L;
|
||||
|
||||
private static final char[] OTHERS = {
|
||||
8263,8264,8265,8448,8449,8453,8454,10868,
|
||||
65109,65110,65119,65131,65283,65295,65306,65311,65312
|
||||
};
|
||||
|
||||
// Tell whether the given character is found by the given mask pair
|
||||
public static boolean match(char c, long lowMask, long highMask) {
|
||||
if (c < 64)
|
||||
return ((1L << c) & lowMask) != 0;
|
||||
if (c < 128)
|
||||
return ((1L << (c - 64)) & highMask) != 0;
|
||||
return false; // other non ASCII characters are not filtered
|
||||
}
|
||||
|
||||
// returns -1 if the string doesn't contain any characters
|
||||
// from the mask, the index of the first such character found
|
||||
// otherwise.
|
||||
public static int scan(String s, long lowMask, long highMask) {
|
||||
int i = -1, len;
|
||||
if (s == null || (len = s.length()) == 0) return -1;
|
||||
boolean match = false;
|
||||
while (++i < len && !(match = match(s.charAt(i), lowMask, highMask)));
|
||||
if (match) return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static int scan(String s, long lowMask, long highMask, char[] others) {
|
||||
int i = -1, len;
|
||||
if (s == null || (len = s.length()) == 0) return -1;
|
||||
boolean match = false;
|
||||
char c, c0 = others[0];
|
||||
while (++i < len && !(match = match((c=s.charAt(i)), lowMask, highMask))) {
|
||||
if (c >= c0 && (Arrays.binarySearch(others, c) > -1)) {
|
||||
match = true; break;
|
||||
}
|
||||
}
|
||||
if (match) return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static String describeChar(char c) {
|
||||
if (c < 32 || c == 127) {
|
||||
if (c == '\n') return "LF";
|
||||
if (c == '\r') return "CR";
|
||||
return "control char (code=" + (int)c + ")";
|
||||
}
|
||||
if (c == '\\') return "'\\'";
|
||||
return "'" + c + "'";
|
||||
}
|
||||
|
||||
private static String checkUserInfo(String str) {
|
||||
// colon is permitted in user info
|
||||
int index = scan(str, L_EXCLUDE & ~L_COLON,
|
||||
H_EXCLUDE & ~H_COLON);
|
||||
if (index >= 0) {
|
||||
return "Illegal character found in user-info: "
|
||||
+ describeChar(str.charAt(index));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String checkHost(String str) {
|
||||
int index;
|
||||
if (str.startsWith("[") && str.endsWith("]")) {
|
||||
str = str.substring(1, str.length() - 1);
|
||||
if (isIPv6LiteralAddress(str)) {
|
||||
index = str.indexOf('%');
|
||||
if (index >= 0) {
|
||||
index = scan(str = str.substring(index),
|
||||
L_NON_PRINTABLE | L_IPV6_DELIMS,
|
||||
H_NON_PRINTABLE | H_IPV6_DELIMS);
|
||||
if (index >= 0) {
|
||||
return "Illegal character found in IPv6 scoped address: "
|
||||
+ describeChar(str.charAt(index));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return "Unrecognized IPv6 address format";
|
||||
} else {
|
||||
index = scan(str, L_EXCLUDE, H_EXCLUDE);
|
||||
if (index >= 0) {
|
||||
return "Illegal character found in host: "
|
||||
+ describeChar(str.charAt(index));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String checkAuth(String str) {
|
||||
int index = scan(str,
|
||||
L_EXCLUDE & ~L_AUTH_DELIMS,
|
||||
H_EXCLUDE & ~H_AUTH_DELIMS);
|
||||
if (index >= 0) {
|
||||
return "Illegal character found in authority: "
|
||||
+ describeChar(str.charAt(index));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// check authority of hierarchical URL. Appropriate for
|
||||
// HTTP-like protocol handlers
|
||||
public static String checkAuthority(URL url) {
|
||||
String s, u, h;
|
||||
if (url == null) return null;
|
||||
if ((s = checkUserInfo(u = url.getUserInfo())) != null) {
|
||||
return s;
|
||||
}
|
||||
if ((s = checkHost(h = url.getHost())) != null) {
|
||||
return s;
|
||||
}
|
||||
if (h == null && u == null) {
|
||||
return checkAuth(url.getAuthority());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// minimal syntax checks - deeper check may be performed
|
||||
// by the appropriate protocol handler
|
||||
public static String checkExternalForm(URL url) {
|
||||
String s;
|
||||
if (url == null) return null;
|
||||
int index = scan(s = url.getUserInfo(),
|
||||
L_NON_PRINTABLE | L_SLASH,
|
||||
H_NON_PRINTABLE | H_SLASH);
|
||||
if (index >= 0) {
|
||||
return "Illegal character found in authority: "
|
||||
+ describeChar(s.charAt(index));
|
||||
}
|
||||
if ((s = checkHostString(url.getHost())) != null) {
|
||||
return s;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String checkHostString(String host) {
|
||||
if (host == null) return null;
|
||||
int index = scan(host,
|
||||
L_NON_PRINTABLE | L_SLASH,
|
||||
H_NON_PRINTABLE | H_SLASH,
|
||||
OTHERS);
|
||||
if (index >= 0) {
|
||||
return "Illegal character found in host: "
|
||||
+ describeChar(host.charAt(index));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the numeric value of the character {@code ch} in the
|
||||
* specified radix.
|
||||
*
|
||||
* @param ch the character to be converted.
|
||||
* @param radix the radix.
|
||||
* @return the numeric value represented by the character in the
|
||||
* specified radix.
|
||||
*/
|
||||
public static int digit(char ch, int radix) {
|
||||
if (ALLOW_AMBIGUOUS_IPADDRESS_LITERALS_SP_VALUE) {
|
||||
return Character.digit(ch, radix);
|
||||
} else {
|
||||
return parseAsciiDigit(ch, radix);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to parse String as IPv4 address literal by following
|
||||
* BSD-style formatting rules.
|
||||
*
|
||||
* @param input input string
|
||||
* @return {@code true} if input string is parsable as IPv4 address literal,
|
||||
* {@code false} otherwise.
|
||||
*/
|
||||
public static boolean isBsdParsableV4(String input) {
|
||||
char firstSymbol = input.charAt(0);
|
||||
// Check if first digit is not a decimal digit
|
||||
if (parseAsciiDigit(firstSymbol, DECIMAL) == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Last character is dot OR is not a supported digit: [0-9,A-F,a-f]
|
||||
char lastSymbol = input.charAt(input.length() - 1);
|
||||
if (lastSymbol == '.' || parseAsciiHexDigit(lastSymbol) == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Parse IP address fields
|
||||
CharBuffer charBuffer = CharBuffer.wrap(input);
|
||||
int fieldNumber = 0;
|
||||
while (charBuffer.hasRemaining()) {
|
||||
long fieldValue = -1L;
|
||||
// Try to parse fields in all supported radixes
|
||||
for (int radix : SUPPORTED_RADIXES) {
|
||||
fieldValue = parseV4FieldBsd(radix, charBuffer, fieldNumber);
|
||||
if (fieldValue >= 0) {
|
||||
fieldNumber++;
|
||||
break;
|
||||
} else if (fieldValue == TERMINAL_PARSE_ERROR) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// If field can't be parsed as one of supported radixes stop
|
||||
// parsing
|
||||
if (fieldValue < 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method tries to parse IP address field that starts from {@linkplain CharBuffer#position()
|
||||
* current position} of the provided character buffer.
|
||||
* <p>
|
||||
* This method supports three {@code "radix"} values to decode field values in
|
||||
* {@code "HEXADECIMAL (radix=16)"}, {@code "DECIMAL (radix=10)"} and
|
||||
* {@code "OCTAL (radix=8)"} radixes.
|
||||
* <p>
|
||||
* If {@code -1} value is returned the char buffer position is reset to the value
|
||||
* it was before it was called.
|
||||
* <p>
|
||||
* Method returns {@code -2} if formatting illegal for all supported {@code radix}
|
||||
* values is observed, and there is no point in checking other radix values.
|
||||
* That includes the following cases:<ul>
|
||||
* <li>Two subsequent dots are observer
|
||||
* <li>Number of dots more than 3
|
||||
* <li>Field value exceeds max allowed
|
||||
* <li>Character is not a valid digit for the requested {@code radix} value, given
|
||||
* that a field has the radix specific prefix
|
||||
* </ul>
|
||||
*
|
||||
* @param radix digits encoding radix to use for parsing. Valid values: 8, 10, 16.
|
||||
* @param buffer {@code CharBuffer} with position set to the field's fist character
|
||||
* @param fieldNumber parsed field number
|
||||
* @return {@code CANT_PARSE_IN_RADIX} if field can not be parsed in requested {@code radix}.
|
||||
* {@code TERMINAL_PARSE_ERROR} if field can't be parsed and the whole parse process should be terminated.
|
||||
* Parsed field value otherwise.
|
||||
*/
|
||||
private static long parseV4FieldBsd(int radix, CharBuffer buffer, int fieldNumber) {
|
||||
int initialPos = buffer.position();
|
||||
long val = 0;
|
||||
int digitsCount = 0;
|
||||
if (!checkPrefix(buffer, radix)) {
|
||||
val = CANT_PARSE_IN_RADIX;
|
||||
}
|
||||
boolean dotSeen = false;
|
||||
while (buffer.hasRemaining() && val != CANT_PARSE_IN_RADIX && !dotSeen) {
|
||||
char c = buffer.get();
|
||||
if (c == '.') {
|
||||
dotSeen = true;
|
||||
// Fail if 4 dots in IP address string.
|
||||
// fieldNumber counter starts from 0, therefore 3
|
||||
if (fieldNumber == 3) {
|
||||
// Terminal state, can stop parsing: too many fields
|
||||
return TERMINAL_PARSE_ERROR;
|
||||
}
|
||||
// Check for literals with two dots, like '1.2..3', '1.2.3..'
|
||||
if (digitsCount == 0) {
|
||||
// Terminal state, can stop parsing: dot with no digits
|
||||
return TERMINAL_PARSE_ERROR;
|
||||
}
|
||||
if (val > 255) {
|
||||
// Terminal state, can stop parsing: too big value for an octet
|
||||
return TERMINAL_PARSE_ERROR;
|
||||
}
|
||||
} else {
|
||||
int dv = parseAsciiDigit(c, radix);
|
||||
if (dv >= 0) {
|
||||
digitsCount++;
|
||||
val *= radix;
|
||||
val += dv;
|
||||
} else {
|
||||
// Spotted digit can't be parsed in the requested 'radix'.
|
||||
// The order in which radixes are checked - hex, octal, decimal:
|
||||
// - if symbol is not a valid digit in hex radix - terminal
|
||||
// - if symbol is not a valid digit in octal radix, and given
|
||||
// that octal prefix was observed before - terminal
|
||||
// - if symbol is not a valid digit in decimal radix - terminal
|
||||
return TERMINAL_PARSE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (val == CANT_PARSE_IN_RADIX) {
|
||||
buffer.position(initialPos);
|
||||
} else if (!dotSeen) {
|
||||
// It is the last field - check its value
|
||||
// This check will ensure that address strings with less
|
||||
// than 4 fields, i.e. A, A.B and A.B.C address types
|
||||
// contain value less then the allowed maximum for the last field.
|
||||
long maxValue = (1L << ((4 - fieldNumber) * 8)) - 1;
|
||||
if (val > maxValue) {
|
||||
// Terminal state, can stop parsing: last field value exceeds its
|
||||
// allowed value
|
||||
return TERMINAL_PARSE_ERROR;
|
||||
}
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
// This method moves the position of the supplied CharBuffer by analysing the digit prefix
|
||||
// symbols if any.
|
||||
// The caller should reset the position when method returns false.
|
||||
private static boolean checkPrefix(CharBuffer buffer, int radix) {
|
||||
switch (radix) {
|
||||
case OCTAL:
|
||||
return isOctalFieldStart(buffer);
|
||||
case DECIMAL:
|
||||
return isDecimalFieldStart(buffer);
|
||||
case HEXADECIMAL:
|
||||
return isHexFieldStart(buffer);
|
||||
default:
|
||||
throw new AssertionError("Not supported radix");
|
||||
}
|
||||
}
|
||||
|
||||
// This method always moves the position of the supplied CharBuffer
|
||||
// removing the octal prefix symbols '0'.
|
||||
// The caller should reset the position when method returns false.
|
||||
private static boolean isOctalFieldStart(CharBuffer cb) {
|
||||
// .0<EOS> is not treated as octal field
|
||||
if (cb.remaining() < 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Fetch two first characters
|
||||
int position = cb.position();
|
||||
char first = cb.get();
|
||||
char second = cb.get();
|
||||
|
||||
// Return false if the first char is not octal prefix '0' or second is a
|
||||
// field separator - parseV4FieldBsd will reset position to start of the field.
|
||||
// '.0.' fields will be successfully parsed in decimal radix.
|
||||
boolean isOctalPrefix = first == '0' && second != '.';
|
||||
|
||||
// If the prefix looks like octal - consume '0', otherwise 'false' is returned
|
||||
// and caller will reset the buffer position.
|
||||
if (isOctalPrefix) {
|
||||
cb.position(position + 1);
|
||||
}
|
||||
return isOctalPrefix;
|
||||
}
|
||||
|
||||
// This method doesn't move the position of the supplied CharBuffer
|
||||
private static boolean isDecimalFieldStart(CharBuffer cb) {
|
||||
return cb.hasRemaining();
|
||||
}
|
||||
|
||||
// This method always moves the position of the supplied CharBuffer
|
||||
// removing the hexadecimal prefix symbols '0x'.
|
||||
// The caller should reset the position when method returns false.
|
||||
private static boolean isHexFieldStart(CharBuffer cb) {
|
||||
if (cb.remaining() < 2) {
|
||||
return false;
|
||||
}
|
||||
char first = cb.get();
|
||||
char second = cb.get();
|
||||
return first == '0' && (second == 'x' || second == 'X');
|
||||
}
|
||||
|
||||
// Parse ASCII digit in given radix
|
||||
public static int parseAsciiDigit(char c, int radix) {
|
||||
assert radix == OCTAL || radix == DECIMAL || radix == HEXADECIMAL;
|
||||
if (radix == HEXADECIMAL) {
|
||||
return parseAsciiHexDigit(c);
|
||||
}
|
||||
int val = c - '0';
|
||||
return (val < 0 || val >= radix) ? -1 : val;
|
||||
}
|
||||
|
||||
// Parse ASCII digit in hexadecimal radix
|
||||
private static int parseAsciiHexDigit(char digit) {
|
||||
char c = Character.toLowerCase(digit);
|
||||
if (c >= 'a' && c <= 'f') {
|
||||
return c - 'a' + 10;
|
||||
}
|
||||
return parseAsciiDigit(c, DECIMAL);
|
||||
}
|
||||
|
||||
// Supported radixes
|
||||
private static final int HEXADECIMAL = 16;
|
||||
private static final int DECIMAL = 10;
|
||||
private static final int OCTAL = 8;
|
||||
// Order in which field formats are exercised to parse one IP address textual field
|
||||
private static final int[] SUPPORTED_RADIXES = new int[]{HEXADECIMAL, OCTAL, DECIMAL};
|
||||
|
||||
// BSD parser's return values
|
||||
private final static long CANT_PARSE_IN_RADIX = -1L;
|
||||
private final static long TERMINAL_PARSE_ERROR = -2L;
|
||||
|
||||
private static final String ALLOW_AMBIGUOUS_IPADDRESS_LITERALS_SP = "jdk.net.allowAmbiguousIPAddressLiterals";
|
||||
private static final boolean ALLOW_AMBIGUOUS_IPADDRESS_LITERALS_SP_VALUE = Boolean.valueOf(
|
||||
GetPropertyAction.privilegedGetProperty(ALLOW_AMBIGUOUS_IPADDRESS_LITERALS_SP, "false"));
|
||||
}
|
||||
49
jdkSrc/jdk8/sun/net/util/ProxyUtil.java
Normal file
49
jdkSrc/jdk8/sun/net/util/ProxyUtil.java
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2025, 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 sun.net.util;
|
||||
|
||||
import sun.net.ApplicationProxy;
|
||||
|
||||
import java.net.Proxy;
|
||||
|
||||
public final class ProxyUtil {
|
||||
|
||||
private ProxyUtil() {}
|
||||
|
||||
/**
|
||||
* Creates a new {@link Proxy} instance for the given proxy iff it is
|
||||
* neither null, {@link Proxy#NO_PROXY Proxy.NO_PROXY}, an
|
||||
* {@link ApplicationProxy} instance, nor already a {@code Proxy} instance.
|
||||
*/
|
||||
public static Proxy copyProxy(Proxy proxy) {
|
||||
return proxy == null
|
||||
|| proxy.getClass() == Proxy.class
|
||||
|| proxy instanceof ApplicationProxy
|
||||
? proxy
|
||||
: new Proxy(proxy.type(), proxy.address());
|
||||
}
|
||||
|
||||
}
|
||||
104
jdkSrc/jdk8/sun/net/util/URLUtil.java
Normal file
104
jdkSrc/jdk8/sun/net/util/URLUtil.java
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (c) 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 sun.net.util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.net.URLPermission;
|
||||
import java.security.Permission;
|
||||
|
||||
/**
|
||||
* URL Utility class.
|
||||
*/
|
||||
public class URLUtil {
|
||||
/**
|
||||
* Returns a string form of the url suitable for use as a key in HashMap/Sets.
|
||||
*
|
||||
* The string form should be behave in the same manner as the URL when
|
||||
* compared for equality in a HashMap/Set, except that no nameservice
|
||||
* lookup is done on the hostname (only string comparison), and the fragment
|
||||
* is not considered.
|
||||
*
|
||||
* @see java.net.URLStreamHandler.sameFile(java.net.URL)
|
||||
*/
|
||||
public static String urlNoFragString(URL url) {
|
||||
StringBuilder strForm = new StringBuilder();
|
||||
|
||||
String protocol = url.getProtocol();
|
||||
if (protocol != null) {
|
||||
/* protocol is compared case-insensitive, so convert to lowercase */
|
||||
protocol = protocol.toLowerCase();
|
||||
strForm.append(protocol);
|
||||
strForm.append("://");
|
||||
}
|
||||
|
||||
String host = url.getHost();
|
||||
if (host != null) {
|
||||
/* host is compared case-insensitive, so convert to lowercase */
|
||||
host = host.toLowerCase();
|
||||
strForm.append(host);
|
||||
|
||||
int port = url.getPort();
|
||||
if (port == -1) {
|
||||
/* if no port is specificed then use the protocols
|
||||
* default, if there is one */
|
||||
port = url.getDefaultPort();
|
||||
}
|
||||
if (port != -1) {
|
||||
strForm.append(":").append(port);
|
||||
}
|
||||
}
|
||||
|
||||
String file = url.getFile();
|
||||
if (file != null) {
|
||||
strForm.append(file);
|
||||
}
|
||||
|
||||
return strForm.toString();
|
||||
}
|
||||
|
||||
public static Permission getConnectPermission(URL url) throws IOException {
|
||||
String urlStringLowerCase = url.toString().toLowerCase();
|
||||
if (urlStringLowerCase.startsWith("http:") || urlStringLowerCase.startsWith("https:")) {
|
||||
return getURLConnectPermission(url);
|
||||
} else if (urlStringLowerCase.startsWith("jar:http:") || urlStringLowerCase.startsWith("jar:https:")) {
|
||||
String urlString = url.toString();
|
||||
int bangPos = urlString.indexOf("!/");
|
||||
urlString = urlString.substring(4, bangPos > -1 ? bangPos : urlString.length());
|
||||
URL u = new URL(urlString);
|
||||
return getURLConnectPermission(u);
|
||||
// If protocol is HTTP or HTTPS than use URLPermission object
|
||||
} else {
|
||||
return url.openConnection().getPermission();
|
||||
}
|
||||
}
|
||||
|
||||
private static Permission getURLConnectPermission(URL url) {
|
||||
String urlString = url.getProtocol() + "://" + url.getAuthority() + url.getPath();
|
||||
return new URLPermission(urlString);
|
||||
}
|
||||
}
|
||||
|
||||
41
jdkSrc/jdk8/sun/net/www/ApplicationLaunchException.java
Normal file
41
jdkSrc/jdk8/sun/net/www/ApplicationLaunchException.java
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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 sun.net.www;
|
||||
|
||||
/**
|
||||
* An exception thrown by the MimeLauncher when it is unable to launch
|
||||
* an external content viewer.
|
||||
*
|
||||
* @author Sunita Mani
|
||||
*/
|
||||
|
||||
public class ApplicationLaunchException extends Exception {
|
||||
private static final long serialVersionUID = -4782286141289536883L;
|
||||
|
||||
public ApplicationLaunchException(String reason) {
|
||||
super(reason);
|
||||
}
|
||||
}
|
||||
277
jdkSrc/jdk8/sun/net/www/HeaderParser.java
Normal file
277
jdkSrc/jdk8/sun/net/www/HeaderParser.java
Normal file
@@ -0,0 +1,277 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 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 sun.net.www;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.OptionalInt;
|
||||
|
||||
/* This is useful for the nightmare of parsing multi-part HTTP/RFC822 headers
|
||||
* sensibly:
|
||||
* From a String like: 'timeout=15, max=5'
|
||||
* create an array of Strings:
|
||||
* { {"timeout", "15"},
|
||||
* {"max", "5"}
|
||||
* }
|
||||
* From one like: 'Basic Realm="FuzzFace" Foo="Biz Bar Baz"'
|
||||
* create one like (no quotes in literal):
|
||||
* { {"basic", null},
|
||||
* {"realm", "FuzzFace"}
|
||||
* {"foo", "Biz Bar Baz"}
|
||||
* }
|
||||
* keys are converted to lower case, vals are left as is....
|
||||
*
|
||||
* @author Dave Brown
|
||||
*/
|
||||
|
||||
|
||||
public class HeaderParser {
|
||||
|
||||
/* table of key/val pairs */
|
||||
String raw;
|
||||
String[][] tab;
|
||||
int nkeys;
|
||||
int asize = 10; // initial size of array is 10
|
||||
|
||||
public HeaderParser(String raw) {
|
||||
this.raw = raw;
|
||||
tab = new String[asize][2];
|
||||
parse();
|
||||
}
|
||||
|
||||
private HeaderParser () {
|
||||
}
|
||||
|
||||
/**
|
||||
* create a new HeaderParser from this, whose keys (and corresponding values)
|
||||
* range from "start" to "end-1"
|
||||
*/
|
||||
public HeaderParser subsequence (int start, int end) {
|
||||
if (start == 0 && end == nkeys) {
|
||||
return this;
|
||||
}
|
||||
if (start < 0 || start >= end || end > nkeys)
|
||||
throw new IllegalArgumentException ("invalid start or end");
|
||||
HeaderParser n = new HeaderParser ();
|
||||
n.tab = new String [asize][2];
|
||||
n.asize = asize;
|
||||
System.arraycopy (tab, start, n.tab, 0, (end-start));
|
||||
n.nkeys= (end-start);
|
||||
return n;
|
||||
}
|
||||
|
||||
private void parse() {
|
||||
|
||||
if (raw != null) {
|
||||
raw = raw.trim();
|
||||
char[] ca = raw.toCharArray();
|
||||
int beg = 0, end = 0, i = 0;
|
||||
boolean inKey = true;
|
||||
boolean inQuote = false;
|
||||
int len = ca.length;
|
||||
while (end < len) {
|
||||
char c = ca[end];
|
||||
if ((c == '=') && !inQuote) { // end of a key
|
||||
tab[i][0] = new String(ca, beg, end-beg).toLowerCase();
|
||||
inKey = false;
|
||||
end++;
|
||||
beg = end;
|
||||
} else if (c == '\"') {
|
||||
if (inQuote) {
|
||||
tab[i++][1]= new String(ca, beg, end-beg);
|
||||
inQuote=false;
|
||||
do {
|
||||
end++;
|
||||
} while (end < len && (ca[end] == ' ' || ca[end] == ','));
|
||||
inKey=true;
|
||||
beg=end;
|
||||
} else {
|
||||
inQuote=true;
|
||||
end++;
|
||||
beg=end;
|
||||
}
|
||||
} else if (c == ' ' || c == ',') { // end key/val, of whatever we're in
|
||||
if (inQuote) {
|
||||
end++;
|
||||
continue;
|
||||
} else if (inKey) {
|
||||
tab[i++][0] = (new String(ca, beg, end-beg)).toLowerCase();
|
||||
} else {
|
||||
tab[i++][1] = (new String(ca, beg, end-beg));
|
||||
}
|
||||
while (end < len && (ca[end] == ' ' || ca[end] == ',')) {
|
||||
end++;
|
||||
}
|
||||
inKey = true;
|
||||
beg = end;
|
||||
} else {
|
||||
end++;
|
||||
}
|
||||
if (i == asize) {
|
||||
asize = asize * 2;
|
||||
String[][] ntab = new String[asize][2];
|
||||
System.arraycopy (tab, 0, ntab, 0, tab.length);
|
||||
tab = ntab;
|
||||
}
|
||||
}
|
||||
// get last key/val, if any
|
||||
if (--end > beg) {
|
||||
if (!inKey) {
|
||||
if (ca[end] == '\"') {
|
||||
tab[i++][1] = (new String(ca, beg, end-beg));
|
||||
} else {
|
||||
tab[i++][1] = (new String(ca, beg, end-beg+1));
|
||||
}
|
||||
} else {
|
||||
tab[i++][0] = (new String(ca, beg, end-beg+1)).toLowerCase();
|
||||
}
|
||||
} else if (end == beg) {
|
||||
if (!inKey) {
|
||||
if (ca[end] == '\"') {
|
||||
tab[i++][1] = String.valueOf(ca[end-1]);
|
||||
} else {
|
||||
tab[i++][1] = String.valueOf(ca[end]);
|
||||
}
|
||||
} else {
|
||||
tab[i++][0] = String.valueOf(ca[end]).toLowerCase();
|
||||
}
|
||||
}
|
||||
nkeys=i;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public String findKey(int i) {
|
||||
if (i < 0 || i > asize)
|
||||
return null;
|
||||
return tab[i][0];
|
||||
}
|
||||
|
||||
public String findValue(int i) {
|
||||
if (i < 0 || i > asize)
|
||||
return null;
|
||||
return tab[i][1];
|
||||
}
|
||||
|
||||
public String findValue(String key) {
|
||||
return findValue(key, null);
|
||||
}
|
||||
|
||||
public String findValue(String k, String Default) {
|
||||
if (k == null)
|
||||
return Default;
|
||||
k = k.toLowerCase();
|
||||
for (int i = 0; i < asize; ++i) {
|
||||
if (tab[i][0] == null) {
|
||||
return Default;
|
||||
} else if (k.equals(tab[i][0])) {
|
||||
return tab[i][1];
|
||||
}
|
||||
}
|
||||
return Default;
|
||||
}
|
||||
|
||||
class ParserIterator implements Iterator<String> {
|
||||
int index;
|
||||
boolean returnsValue; // or key
|
||||
|
||||
ParserIterator (boolean returnValue) {
|
||||
returnsValue = returnValue;
|
||||
}
|
||||
public boolean hasNext () {
|
||||
return index<nkeys;
|
||||
}
|
||||
public String next () {
|
||||
return tab[index++][returnsValue?1:0];
|
||||
}
|
||||
public void remove () {
|
||||
throw new UnsupportedOperationException ("remove not supported");
|
||||
}
|
||||
}
|
||||
|
||||
public Iterator<String> keys () {
|
||||
return new ParserIterator (false);
|
||||
}
|
||||
|
||||
public Iterator<String> values () {
|
||||
return new ParserIterator (true);
|
||||
}
|
||||
|
||||
public String toString () {
|
||||
Iterator<String> k = keys();
|
||||
StringBuffer sbuf = new StringBuffer();
|
||||
sbuf.append ("{size="+asize+" nkeys="+nkeys+" ");
|
||||
for (int i=0; k.hasNext(); i++) {
|
||||
String key = k.next();
|
||||
String val = findValue (i);
|
||||
if (val != null && "".equals (val)) {
|
||||
val = null;
|
||||
}
|
||||
sbuf.append (" {"+key+(val==null?"":","+val)+"}");
|
||||
if (k.hasNext()) {
|
||||
sbuf.append (",");
|
||||
}
|
||||
}
|
||||
sbuf.append (" }");
|
||||
return new String (sbuf);
|
||||
}
|
||||
|
||||
public int findInt(String k, int Default) {
|
||||
try {
|
||||
return Integer.parseInt(findValue(k, String.valueOf(Default)));
|
||||
} catch (Throwable t) {
|
||||
return Default;
|
||||
}
|
||||
}
|
||||
|
||||
public OptionalInt findInt(String k) {
|
||||
try {
|
||||
String s = findValue(k);
|
||||
if (s == null) {
|
||||
return OptionalInt.empty();
|
||||
}
|
||||
return OptionalInt.of(Integer.parseInt(s));
|
||||
} catch (Throwable t) {
|
||||
return OptionalInt.empty();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
public static void main(String[] a) throws Exception {
|
||||
System.out.print("enter line to parse> ");
|
||||
System.out.flush();
|
||||
DataInputStream dis = new DataInputStream(System.in);
|
||||
String line = dis.readLine();
|
||||
HeaderParser p = new HeaderParser(line);
|
||||
for (int i = 0; i < asize; ++i) {
|
||||
if (p.findKey(i) == null) break;
|
||||
String v = p.findValue(i);
|
||||
System.out.println(i + ") " +p.findKey(i) + "="+v);
|
||||
}
|
||||
System.out.println("Done!");
|
||||
|
||||
}
|
||||
*/
|
||||
}
|
||||
607
jdkSrc/jdk8/sun/net/www/MessageHeader.java
Normal file
607
jdkSrc/jdk8/sun/net/www/MessageHeader.java
Normal file
@@ -0,0 +1,607 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* news stream opener
|
||||
*/
|
||||
|
||||
package sun.net.www;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Array;
|
||||
import java.net.ProtocolException;
|
||||
import java.util.Collections;
|
||||
import java.util.*;
|
||||
|
||||
/** An RFC 844 or MIME message header. Includes methods
|
||||
for parsing headers from incoming streams, fetching
|
||||
values, setting values, and printing headers.
|
||||
Key values of null are legal: they indicate lines in
|
||||
the header that don't have a valid key, but do have
|
||||
a value (this isn't legal according to the standard,
|
||||
but lines like this are everywhere). */
|
||||
public
|
||||
class MessageHeader {
|
||||
private String keys[];
|
||||
private String values[];
|
||||
private int nkeys;
|
||||
|
||||
// max number of bytes for headers, <=0 means unlimited;
|
||||
// this corresponds to the length of the names, plus the length
|
||||
// of the values, plus an overhead of 32 bytes per name: value
|
||||
// pair.
|
||||
// Note: we use the same definition as HTTP/2 SETTINGS_MAX_HEADER_LIST_SIZE
|
||||
// see RFC 9113, section 6.5.2.
|
||||
// https://www.rfc-editor.org/rfc/rfc9113.html#SETTINGS_MAX_HEADER_LIST_SIZE
|
||||
private final int maxHeaderSize;
|
||||
|
||||
// Aggregate size of the field lines (name + value + 32) x N
|
||||
// that have been parsed and accepted so far.
|
||||
// This is defined as a long to force promotion to long
|
||||
// and avoid overflows; see checkNewSize;
|
||||
private long size;
|
||||
|
||||
public MessageHeader () {
|
||||
this(0);
|
||||
}
|
||||
|
||||
public MessageHeader (int maxHeaderSize) {
|
||||
this.maxHeaderSize = maxHeaderSize;
|
||||
grow();
|
||||
}
|
||||
|
||||
public MessageHeader (InputStream is) throws java.io.IOException {
|
||||
maxHeaderSize = 0;
|
||||
parseHeader(is);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of header names in a comma separated list
|
||||
*/
|
||||
public synchronized String getHeaderNamesInList() {
|
||||
StringJoiner joiner = new StringJoiner(",");
|
||||
for (int i=0; i<nkeys; i++) {
|
||||
joiner.add(keys[i]);
|
||||
}
|
||||
return joiner.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset a message header (all key/values removed)
|
||||
*/
|
||||
public synchronized void reset() {
|
||||
keys = null;
|
||||
values = null;
|
||||
nkeys = 0;
|
||||
grow();
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the value that corresponds to this key.
|
||||
* It finds only the first occurrence of the key.
|
||||
* @param k the key to find.
|
||||
* @return null if not found.
|
||||
*/
|
||||
public synchronized String findValue(String k) {
|
||||
if (k == null) {
|
||||
for (int i = nkeys; --i >= 0;)
|
||||
if (keys[i] == null)
|
||||
return values[i];
|
||||
} else
|
||||
for (int i = nkeys; --i >= 0;) {
|
||||
if (k.equalsIgnoreCase(keys[i]))
|
||||
return values[i];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// return the location of the key
|
||||
public synchronized int getKey(String k) {
|
||||
for (int i = nkeys; --i >= 0;)
|
||||
if ((keys[i] == k) ||
|
||||
(k != null && k.equalsIgnoreCase(keys[i])))
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
public synchronized String getKey(int n) {
|
||||
if (n < 0 || n >= nkeys) return null;
|
||||
return keys[n];
|
||||
}
|
||||
|
||||
public synchronized String getValue(int n) {
|
||||
if (n < 0 || n >= nkeys) return null;
|
||||
return values[n];
|
||||
}
|
||||
|
||||
/** Deprecated: Use multiValueIterator() instead.
|
||||
*
|
||||
* Find the next value that corresponds to this key.
|
||||
* It finds the first value that follows v. To iterate
|
||||
* over all the values of a key use:
|
||||
* <pre>
|
||||
* for(String v=h.findValue(k); v!=null; v=h.findNextValue(k, v)) {
|
||||
* ...
|
||||
* }
|
||||
* </pre>
|
||||
*/
|
||||
public synchronized String findNextValue(String k, String v) {
|
||||
boolean foundV = false;
|
||||
if (k == null) {
|
||||
for (int i = nkeys; --i >= 0;)
|
||||
if (keys[i] == null)
|
||||
if (foundV)
|
||||
return values[i];
|
||||
else if (values[i] == v)
|
||||
foundV = true;
|
||||
} else
|
||||
for (int i = nkeys; --i >= 0;)
|
||||
if (k.equalsIgnoreCase(keys[i]))
|
||||
if (foundV)
|
||||
return values[i];
|
||||
else if (values[i] == v)
|
||||
foundV = true;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes bare Negotiate and Kerberos headers when an "NTLM ..."
|
||||
* appears. All Performed on headers with key being k.
|
||||
* @return true if there is a change
|
||||
*/
|
||||
public boolean filterNTLMResponses(String k) {
|
||||
boolean found = false;
|
||||
for (int i=0; i<nkeys; i++) {
|
||||
if (k.equalsIgnoreCase(keys[i])
|
||||
&& values[i] != null && values[i].length() > 5
|
||||
&& values[i].substring(0, 5).equalsIgnoreCase("NTLM ")) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
int j = 0;
|
||||
for (int i=0; i<nkeys; i++) {
|
||||
if (k.equalsIgnoreCase(keys[i]) && (
|
||||
"Negotiate".equalsIgnoreCase(values[i]) ||
|
||||
"Kerberos".equalsIgnoreCase(values[i]))) {
|
||||
continue;
|
||||
}
|
||||
if (i != j) {
|
||||
keys[j] = keys[i];
|
||||
values[j] = values[i];
|
||||
}
|
||||
j++;
|
||||
}
|
||||
if (j != nkeys) {
|
||||
nkeys = j;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
class HeaderIterator implements Iterator<String> {
|
||||
int index = 0;
|
||||
int next = -1;
|
||||
String key;
|
||||
boolean haveNext = false;
|
||||
Object lock;
|
||||
|
||||
public HeaderIterator (String k, Object lock) {
|
||||
key = k;
|
||||
this.lock = lock;
|
||||
}
|
||||
public boolean hasNext () {
|
||||
synchronized (lock) {
|
||||
if (haveNext) {
|
||||
return true;
|
||||
}
|
||||
while (index < nkeys) {
|
||||
if (key.equalsIgnoreCase (keys[index])) {
|
||||
haveNext = true;
|
||||
next = index++;
|
||||
return true;
|
||||
}
|
||||
index ++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public String next() {
|
||||
synchronized (lock) {
|
||||
if (haveNext) {
|
||||
haveNext = false;
|
||||
return values [next];
|
||||
}
|
||||
if (hasNext()) {
|
||||
return next();
|
||||
} else {
|
||||
throw new NoSuchElementException ("No more elements");
|
||||
}
|
||||
}
|
||||
}
|
||||
public void remove () {
|
||||
throw new UnsupportedOperationException ("remove not allowed");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* return an Iterator that returns all values of a particular
|
||||
* key in sequence
|
||||
*/
|
||||
public Iterator<String> multiValueIterator (String k) {
|
||||
return new HeaderIterator (k, this);
|
||||
}
|
||||
|
||||
public synchronized Map<String, List<String>> getHeaders() {
|
||||
return getHeaders(null);
|
||||
}
|
||||
|
||||
public synchronized Map<String, List<String>> getHeaders(String[] excludeList) {
|
||||
return filterAndAddHeaders(excludeList, null);
|
||||
}
|
||||
|
||||
public synchronized Map<String, List<String>> filterAndAddHeaders(
|
||||
String[] excludeList, Map<String, List<String>> include) {
|
||||
boolean skipIt = false;
|
||||
Map<String, List<String>> m = new HashMap<String, List<String>>();
|
||||
for (int i = nkeys; --i >= 0;) {
|
||||
if (excludeList != null) {
|
||||
// check if the key is in the excludeList.
|
||||
// if so, don't include it in the Map.
|
||||
for (int j = 0; j < excludeList.length; j++) {
|
||||
if ((excludeList[j] != null) &&
|
||||
(excludeList[j].equalsIgnoreCase(keys[i]))) {
|
||||
skipIt = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!skipIt) {
|
||||
List<String> l = m.get(keys[i]);
|
||||
if (l == null) {
|
||||
l = new ArrayList<String>();
|
||||
m.put(keys[i], l);
|
||||
}
|
||||
l.add(values[i]);
|
||||
} else {
|
||||
// reset the flag
|
||||
skipIt = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (include != null) {
|
||||
for (Map.Entry<String,List<String>> entry: include.entrySet()) {
|
||||
List<String> l = m.get(entry.getKey());
|
||||
if (l == null) {
|
||||
l = new ArrayList<String>();
|
||||
m.put(entry.getKey(), l);
|
||||
}
|
||||
l.addAll(entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
for (String key : m.keySet()) {
|
||||
m.put(key, Collections.unmodifiableList(m.get(key)));
|
||||
}
|
||||
|
||||
return Collections.unmodifiableMap(m);
|
||||
}
|
||||
|
||||
/** Check if a line of message header looks like a request line.
|
||||
* This method does not perform a full validation but simply
|
||||
* returns false if the line does not end with 'HTTP/[1-9].[0-9]'
|
||||
* @param line the line to check.
|
||||
* @return true if the line might be a request line.
|
||||
*/
|
||||
private boolean isRequestline(String line) {
|
||||
String k = line.trim();
|
||||
int i = k.lastIndexOf(' ');
|
||||
if (i <= 0) return false;
|
||||
int len = k.length();
|
||||
if (len - i < 9) return false;
|
||||
|
||||
char c1 = k.charAt(len-3);
|
||||
char c2 = k.charAt(len-2);
|
||||
char c3 = k.charAt(len-1);
|
||||
if (c1 < '1' || c1 > '9') return false;
|
||||
if (c2 != '.') return false;
|
||||
if (c3 < '0' || c3 > '9') return false;
|
||||
|
||||
return (k.substring(i+1, len-3).equalsIgnoreCase("HTTP/"));
|
||||
}
|
||||
|
||||
|
||||
/** Prints the key-value pairs represented by this
|
||||
header. Also prints the RFC required blank line
|
||||
at the end. Omits pairs with a null key. Omits
|
||||
colon if key-value pair is the requestline. */
|
||||
public synchronized void print(PrintStream p) {
|
||||
for (int i = 0; i < nkeys; i++)
|
||||
if (keys[i] != null) {
|
||||
StringBuilder sb = new StringBuilder(keys[i]);
|
||||
if (values[i] != null) {
|
||||
sb.append(": " + values[i]);
|
||||
} else if (i != 0 || !isRequestline(keys[i])) {
|
||||
sb.append(":");
|
||||
}
|
||||
p.print(sb.append("\r\n"));
|
||||
}
|
||||
p.print("\r\n");
|
||||
p.flush();
|
||||
}
|
||||
|
||||
/** Adds a key value pair to the end of the
|
||||
header. Duplicates are allowed */
|
||||
public synchronized void add(String k, String v) {
|
||||
grow();
|
||||
keys[nkeys] = k;
|
||||
values[nkeys] = v;
|
||||
nkeys++;
|
||||
}
|
||||
|
||||
/** Prepends a key value pair to the beginning of the
|
||||
header. Duplicates are allowed */
|
||||
public synchronized void prepend(String k, String v) {
|
||||
grow();
|
||||
for (int i = nkeys; i > 0; i--) {
|
||||
keys[i] = keys[i-1];
|
||||
values[i] = values[i-1];
|
||||
}
|
||||
keys[0] = k;
|
||||
values[0] = v;
|
||||
nkeys++;
|
||||
}
|
||||
|
||||
/** Overwrite the previous key/val pair at location 'i'
|
||||
* with the new k/v. If the index didn't exist before
|
||||
* the key/val is simply tacked onto the end.
|
||||
*/
|
||||
|
||||
public synchronized void set(int i, String k, String v) {
|
||||
grow();
|
||||
if (i < 0) {
|
||||
return;
|
||||
} else if (i >= nkeys) {
|
||||
add(k, v);
|
||||
} else {
|
||||
keys[i] = k;
|
||||
values[i] = v;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** grow the key/value arrays as needed */
|
||||
|
||||
private void grow() {
|
||||
if (keys == null || nkeys >= keys.length) {
|
||||
String[] nk = new String[nkeys + 4];
|
||||
String[] nv = new String[nkeys + 4];
|
||||
if (keys != null)
|
||||
System.arraycopy(keys, 0, nk, 0, nkeys);
|
||||
if (values != null)
|
||||
System.arraycopy(values, 0, nv, 0, nkeys);
|
||||
keys = nk;
|
||||
values = nv;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the key from the header. If there are multiple values under
|
||||
* the same key, they are all removed.
|
||||
* Nothing is done if the key doesn't exist.
|
||||
* After a remove, the other pairs' order are not changed.
|
||||
* @param k the key to remove
|
||||
*/
|
||||
public synchronized void remove(String k) {
|
||||
if(k == null) {
|
||||
for (int i = 0; i < nkeys; i++) {
|
||||
while (keys[i] == null && i < nkeys) {
|
||||
for(int j=i; j<nkeys-1; j++) {
|
||||
keys[j] = keys[j+1];
|
||||
values[j] = values[j+1];
|
||||
}
|
||||
nkeys--;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < nkeys; i++) {
|
||||
while (k.equalsIgnoreCase(keys[i]) && i < nkeys) {
|
||||
for(int j=i; j<nkeys-1; j++) {
|
||||
keys[j] = keys[j+1];
|
||||
values[j] = values[j+1];
|
||||
}
|
||||
nkeys--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Sets the value of a key. If the key already
|
||||
exists in the header, it's value will be
|
||||
changed. Otherwise a new key/value pair will
|
||||
be added to the end of the header. */
|
||||
public synchronized void set(String k, String v) {
|
||||
for (int i = nkeys; --i >= 0;)
|
||||
if (k.equalsIgnoreCase(keys[i])) {
|
||||
values[i] = v;
|
||||
return;
|
||||
}
|
||||
add(k, v);
|
||||
}
|
||||
|
||||
/** Set's the value of a key only if there is no
|
||||
* key with that value already.
|
||||
*/
|
||||
|
||||
public synchronized void setIfNotSet(String k, String v) {
|
||||
if (findValue(k) == null) {
|
||||
add(k, v);
|
||||
}
|
||||
}
|
||||
|
||||
/** Convert a message-id string to canonical form (strips off
|
||||
leading and trailing <>s) */
|
||||
public static String canonicalID(String id) {
|
||||
if (id == null)
|
||||
return "";
|
||||
int st = 0;
|
||||
int len = id.length();
|
||||
boolean substr = false;
|
||||
int c;
|
||||
while (st < len && ((c = id.charAt(st)) == '<' ||
|
||||
c <= ' ')) {
|
||||
st++;
|
||||
substr = true;
|
||||
}
|
||||
while (st < len && ((c = id.charAt(len - 1)) == '>' ||
|
||||
c <= ' ')) {
|
||||
len--;
|
||||
substr = true;
|
||||
}
|
||||
return substr ? id.substring(st, len) : id;
|
||||
}
|
||||
|
||||
/** Parse a MIME header from an input stream. */
|
||||
public void parseHeader(InputStream is) throws java.io.IOException {
|
||||
synchronized (this) {
|
||||
nkeys = 0;
|
||||
size = 0;
|
||||
}
|
||||
mergeHeader(is);
|
||||
}
|
||||
|
||||
private void checkMaxHeaderSize(int sz) throws ProtocolException {
|
||||
if (maxHeaderSize > 0) checkNewSize(size, sz, 0);
|
||||
}
|
||||
|
||||
private long checkNewSize(long size, int name, int value) throws ProtocolException {
|
||||
// See SETTINGS_MAX_HEADER_LIST_SIZE, RFC 9113, section 6.5.2.
|
||||
long newSize = size + name + value + 32;
|
||||
if (maxHeaderSize > 0 && newSize > maxHeaderSize) {
|
||||
Arrays.fill(keys, 0, nkeys, null);
|
||||
Arrays.fill(values,0, nkeys, null);
|
||||
nkeys = 0;
|
||||
throw new ProtocolException(String.format("Header size too big: %s > %s",
|
||||
newSize, maxHeaderSize));
|
||||
}
|
||||
return newSize;
|
||||
}
|
||||
|
||||
/** Parse and merge a MIME header from an input stream. */
|
||||
@SuppressWarnings("fallthrough")
|
||||
public void mergeHeader(InputStream is) throws java.io.IOException {
|
||||
if (is == null)
|
||||
return;
|
||||
char s[] = new char[10];
|
||||
int firstc = is.read();
|
||||
while (firstc != '\n' && firstc != '\r' && firstc >= 0) {
|
||||
int len = 0;
|
||||
int keyend = -1;
|
||||
int c;
|
||||
boolean inKey = firstc > ' ';
|
||||
s[len++] = (char) firstc;
|
||||
checkMaxHeaderSize(len);
|
||||
parseloop:{
|
||||
// We start parsing for a new name value pair here.
|
||||
// The max header size includes an overhead of 32 bytes per
|
||||
// name value pair.
|
||||
// See SETTINGS_MAX_HEADER_LIST_SIZE, RFC 9113, section 6.5.2.
|
||||
long maxRemaining = maxHeaderSize > 0
|
||||
? maxHeaderSize - size - 32
|
||||
: Long.MAX_VALUE;
|
||||
while ((c = is.read()) >= 0) {
|
||||
switch (c) {
|
||||
case ':':
|
||||
if (inKey && len > 0)
|
||||
keyend = len;
|
||||
inKey = false;
|
||||
break;
|
||||
case '\t':
|
||||
c = ' ';
|
||||
/*fall through*/
|
||||
case ' ':
|
||||
inKey = false;
|
||||
break;
|
||||
case '\r':
|
||||
case '\n':
|
||||
firstc = is.read();
|
||||
if (c == '\r' && firstc == '\n') {
|
||||
firstc = is.read();
|
||||
if (firstc == '\r')
|
||||
firstc = is.read();
|
||||
}
|
||||
if (firstc == '\n' || firstc == '\r' || firstc > ' ')
|
||||
break parseloop;
|
||||
/* continuation */
|
||||
c = ' ';
|
||||
break;
|
||||
}
|
||||
if (len >= s.length) {
|
||||
char ns[] = new char[s.length * 2];
|
||||
System.arraycopy(s, 0, ns, 0, len);
|
||||
s = ns;
|
||||
}
|
||||
s[len++] = (char) c;
|
||||
if (maxHeaderSize > 0 && len > maxRemaining) {
|
||||
checkMaxHeaderSize(len);
|
||||
}
|
||||
}
|
||||
firstc = -1;
|
||||
}
|
||||
while (len > 0 && s[len - 1] <= ' ')
|
||||
len--;
|
||||
String k;
|
||||
if (keyend <= 0) {
|
||||
k = null;
|
||||
keyend = 0;
|
||||
} else {
|
||||
k = String.copyValueOf(s, 0, keyend);
|
||||
if (keyend < len && s[keyend] == ':')
|
||||
keyend++;
|
||||
while (keyend < len && s[keyend] <= ' ')
|
||||
keyend++;
|
||||
}
|
||||
String v;
|
||||
if (keyend >= len)
|
||||
v = new String();
|
||||
else
|
||||
v = String.copyValueOf(s, keyend, len - keyend);
|
||||
int klen = k == null ? 0 : k.length();
|
||||
|
||||
size = checkNewSize(size, klen, v.length());
|
||||
add(k, v);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized String toString() {
|
||||
String result = super.toString() + nkeys + " pairs: ";
|
||||
for (int i = 0; i < keys.length && i < nkeys; i++) {
|
||||
result += "{"+keys[i]+": "+values[i]+"}";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
217
jdkSrc/jdk8/sun/net/www/MeteredStream.java
Normal file
217
jdkSrc/jdk8/sun/net/www/MeteredStream.java
Normal file
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 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 sun.net.www;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
import sun.net.ProgressSource;
|
||||
import sun.net.www.http.ChunkedInputStream;
|
||||
|
||||
|
||||
public class MeteredStream extends FilterInputStream {
|
||||
|
||||
// Instance variables.
|
||||
/* if expected != -1, after we've read >= expected, we're "closed" and return -1
|
||||
* from subsequest read() 's
|
||||
*/
|
||||
protected boolean closed = false;
|
||||
protected long expected;
|
||||
protected long count = 0;
|
||||
protected long markedCount = 0;
|
||||
protected int markLimit = -1;
|
||||
protected ProgressSource pi;
|
||||
|
||||
public MeteredStream(InputStream is, ProgressSource pi, long expected)
|
||||
{
|
||||
super(is);
|
||||
|
||||
this.pi = pi;
|
||||
this.expected = expected;
|
||||
|
||||
if (pi != null) {
|
||||
pi.updateProgress(0, expected);
|
||||
}
|
||||
}
|
||||
|
||||
private final void justRead(long n) throws IOException {
|
||||
if (n == -1) {
|
||||
|
||||
/*
|
||||
* don't close automatically when mark is set and is valid;
|
||||
* cannot reset() after close()
|
||||
*/
|
||||
if (!isMarked()) {
|
||||
close();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
count += n;
|
||||
|
||||
/**
|
||||
* If read beyond the markLimit, invalidate the mark
|
||||
*/
|
||||
if (count - markedCount > markLimit) {
|
||||
markLimit = -1;
|
||||
}
|
||||
|
||||
if (pi != null)
|
||||
pi.updateProgress(count, expected);
|
||||
|
||||
if (isMarked()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// if expected length is known, we could determine if
|
||||
// read overrun.
|
||||
if (expected > 0) {
|
||||
if (count >= expected) {
|
||||
close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the mark is valid, false otherwise
|
||||
*/
|
||||
private boolean isMarked() {
|
||||
|
||||
if (markLimit < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// mark is set, but is not valid anymore
|
||||
if (count - markedCount > markLimit) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// mark still holds
|
||||
return true;
|
||||
}
|
||||
|
||||
public synchronized int read() throws java.io.IOException {
|
||||
if (closed) {
|
||||
return -1;
|
||||
}
|
||||
int c = in.read();
|
||||
if (c != -1) {
|
||||
justRead(1);
|
||||
} else {
|
||||
justRead(c);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
public synchronized int read(byte b[], int off, int len)
|
||||
throws java.io.IOException {
|
||||
if (closed) {
|
||||
return -1;
|
||||
}
|
||||
int n = in.read(b, off, len);
|
||||
justRead(n);
|
||||
return n;
|
||||
}
|
||||
|
||||
public synchronized long skip(long n) throws IOException {
|
||||
|
||||
// REMIND: what does skip do on EOF????
|
||||
if (closed) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (in instanceof ChunkedInputStream) {
|
||||
n = in.skip(n);
|
||||
}
|
||||
else {
|
||||
// just skip min(n, num_bytes_left)
|
||||
long min = (n > expected - count) ? expected - count: n;
|
||||
n = in.skip(min);
|
||||
}
|
||||
justRead(n);
|
||||
return n;
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
if (closed) {
|
||||
return;
|
||||
}
|
||||
if (pi != null)
|
||||
pi.finishTracking();
|
||||
|
||||
closed = true;
|
||||
in.close();
|
||||
}
|
||||
|
||||
public synchronized int available() throws IOException {
|
||||
return closed ? 0: in.available();
|
||||
}
|
||||
|
||||
public synchronized void mark(int readLimit) {
|
||||
if (closed) {
|
||||
return;
|
||||
}
|
||||
super.mark(readLimit);
|
||||
|
||||
/*
|
||||
* mark the count to restore upon reset
|
||||
*/
|
||||
markedCount = count;
|
||||
markLimit = readLimit;
|
||||
}
|
||||
|
||||
public synchronized void reset() throws IOException {
|
||||
if (closed) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isMarked()) {
|
||||
throw new IOException ("Resetting to an invalid mark");
|
||||
}
|
||||
|
||||
count = markedCount;
|
||||
super.reset();
|
||||
}
|
||||
|
||||
public boolean markSupported() {
|
||||
if (closed) {
|
||||
return false;
|
||||
}
|
||||
return super.markSupported();
|
||||
}
|
||||
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
close();
|
||||
if (pi != null)
|
||||
pi.close();
|
||||
}
|
||||
finally {
|
||||
// Call super class
|
||||
super.finalize();
|
||||
}
|
||||
}
|
||||
}
|
||||
340
jdkSrc/jdk8/sun/net/www/MimeEntry.java
Normal file
340
jdkSrc/jdk8/sun/net/www/MimeEntry.java
Normal file
@@ -0,0 +1,340 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2002, 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 sun.net.www;
|
||||
import java.net.URL;
|
||||
import java.io.*;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
public class MimeEntry implements Cloneable {
|
||||
private String typeName; // of the form: "type/subtype"
|
||||
private String tempFileNameTemplate;
|
||||
|
||||
private int action;
|
||||
private String command;
|
||||
private String description;
|
||||
private String imageFileName;
|
||||
private String fileExtensions[];
|
||||
|
||||
boolean starred;
|
||||
|
||||
// Actions
|
||||
public static final int UNKNOWN = 0;
|
||||
public static final int LOAD_INTO_BROWSER = 1;
|
||||
public static final int SAVE_TO_FILE = 2;
|
||||
public static final int LAUNCH_APPLICATION = 3;
|
||||
|
||||
static final String[] actionKeywords = {
|
||||
"unknown",
|
||||
"browser",
|
||||
"save",
|
||||
"application",
|
||||
};
|
||||
|
||||
/**
|
||||
* Construct an empty entry of the given type and subtype.
|
||||
*/
|
||||
public MimeEntry(String type) {
|
||||
// Default action is UNKNOWN so clients can decide what the default
|
||||
// should be, typically save to file or ask user.
|
||||
this(type, UNKNOWN, null, null, null);
|
||||
}
|
||||
|
||||
//
|
||||
// The next two constructors are used only by the deprecated
|
||||
// PlatformMimeTable classes or, in last case, is called by the public
|
||||
// constructor. They are kept here anticipating putting support for
|
||||
// mailcap formatted config files back in (so BOTH the properties format
|
||||
// and the mailcap formats are supported).
|
||||
//
|
||||
MimeEntry(String type, String imageFileName, String extensionString) {
|
||||
typeName = type.toLowerCase();
|
||||
action = UNKNOWN;
|
||||
command = null;
|
||||
this.imageFileName = imageFileName;
|
||||
setExtensions(extensionString);
|
||||
starred = isStarred(typeName);
|
||||
}
|
||||
|
||||
// For use with MimeTable::parseMailCap
|
||||
MimeEntry(String typeName, int action, String command,
|
||||
String tempFileNameTemplate) {
|
||||
this.typeName = typeName.toLowerCase();
|
||||
this.action = action;
|
||||
this.command = command;
|
||||
this.imageFileName = null;
|
||||
this.fileExtensions = null;
|
||||
|
||||
this.tempFileNameTemplate = tempFileNameTemplate;
|
||||
}
|
||||
|
||||
// This is the one called by the public constructor.
|
||||
MimeEntry(String typeName, int action, String command,
|
||||
String imageFileName, String fileExtensions[]) {
|
||||
|
||||
this.typeName = typeName.toLowerCase();
|
||||
this.action = action;
|
||||
this.command = command;
|
||||
this.imageFileName = imageFileName;
|
||||
this.fileExtensions = fileExtensions;
|
||||
|
||||
starred = isStarred(typeName);
|
||||
|
||||
}
|
||||
|
||||
public synchronized String getType() {
|
||||
return typeName;
|
||||
}
|
||||
|
||||
public synchronized void setType(String type) {
|
||||
typeName = type.toLowerCase();
|
||||
}
|
||||
|
||||
public synchronized int getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
public synchronized void setAction(int action, String command) {
|
||||
this.action = action;
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
public synchronized void setAction(int action) {
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
public synchronized String getLaunchString() {
|
||||
return command;
|
||||
}
|
||||
|
||||
public synchronized void setCommand(String command) {
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
public synchronized String getDescription() {
|
||||
return (description != null ? description : typeName);
|
||||
}
|
||||
|
||||
public synchronized void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
// ??? what to return for the image -- the file name or should this return
|
||||
// something more advanced like an image source or something?
|
||||
// returning the name has the least policy associated with it.
|
||||
// pro tempore, we'll use the name
|
||||
public String getImageFileName() {
|
||||
return imageFileName;
|
||||
}
|
||||
|
||||
public synchronized void setImageFileName(String filename) {
|
||||
File file = new File(filename);
|
||||
if (file.getParent() == null) {
|
||||
imageFileName = System.getProperty(
|
||||
"java.net.ftp.imagepath."+filename);
|
||||
}
|
||||
else {
|
||||
imageFileName = filename;
|
||||
}
|
||||
|
||||
if (filename.lastIndexOf('.') < 0) {
|
||||
imageFileName = imageFileName + ".gif";
|
||||
}
|
||||
}
|
||||
|
||||
public String getTempFileTemplate() {
|
||||
return tempFileNameTemplate;
|
||||
}
|
||||
|
||||
public synchronized String[] getExtensions() {
|
||||
return fileExtensions;
|
||||
}
|
||||
|
||||
public synchronized String getExtensionsAsList() {
|
||||
String extensionsAsString = "";
|
||||
if (fileExtensions != null) {
|
||||
for (int i = 0; i < fileExtensions.length; i++) {
|
||||
extensionsAsString += fileExtensions[i];
|
||||
if (i < (fileExtensions.length - 1)) {
|
||||
extensionsAsString += ",";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return extensionsAsString;
|
||||
}
|
||||
|
||||
public synchronized void setExtensions(String extensionString) {
|
||||
StringTokenizer extTokens = new StringTokenizer(extensionString, ",");
|
||||
int numExts = extTokens.countTokens();
|
||||
String extensionStrings[] = new String[numExts];
|
||||
|
||||
for (int i = 0; i < numExts; i++) {
|
||||
String ext = (String)extTokens.nextElement();
|
||||
extensionStrings[i] = ext.trim();
|
||||
}
|
||||
|
||||
fileExtensions = extensionStrings;
|
||||
}
|
||||
|
||||
private boolean isStarred(String typeName) {
|
||||
return (typeName != null)
|
||||
&& (typeName.length() > 0)
|
||||
&& (typeName.endsWith("/*"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke the MIME type specific behavior for this MIME type.
|
||||
* Returned value can be one of several types:
|
||||
* <ol>
|
||||
* <li>A thread -- the caller can choose when to launch this thread.
|
||||
* <li>A string -- the string is loaded into the browser directly.
|
||||
* <li>An input stream -- the caller can read from this byte stream and
|
||||
* will typically store the results in a file.
|
||||
* <li>A document (?) --
|
||||
* </ol>
|
||||
*/
|
||||
public Object launch(java.net.URLConnection urlc, InputStream is, MimeTable mt) throws ApplicationLaunchException {
|
||||
switch (action) {
|
||||
case SAVE_TO_FILE:
|
||||
// REMIND: is this really the right thing to do?
|
||||
try {
|
||||
return is;
|
||||
} catch(Exception e) {
|
||||
// I18N
|
||||
return "Load to file failed:\n" + e;
|
||||
}
|
||||
|
||||
case LOAD_INTO_BROWSER:
|
||||
// REMIND: invoke the content handler?
|
||||
// may be the right thing to do, may not be -- short term
|
||||
// where docs are not loaded asynch, loading and returning
|
||||
// the content is the right thing to do.
|
||||
try {
|
||||
return urlc.getContent();
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
case LAUNCH_APPLICATION:
|
||||
{
|
||||
String threadName = command;
|
||||
int fst = threadName.indexOf(' ');
|
||||
if (fst > 0) {
|
||||
threadName = threadName.substring(0, fst);
|
||||
}
|
||||
|
||||
return new MimeLauncher(this, urlc, is,
|
||||
mt.getTempFileTemplate(), threadName);
|
||||
}
|
||||
|
||||
case UNKNOWN:
|
||||
// REMIND: What do do here?
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean matches(String type) {
|
||||
if (starred) {
|
||||
// REMIND: is this the right thing or not?
|
||||
return type.startsWith(typeName);
|
||||
} else {
|
||||
return type.equals(typeName);
|
||||
}
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
// return a shallow copy of this.
|
||||
MimeEntry theClone = new MimeEntry(typeName);
|
||||
theClone.action = action;
|
||||
theClone.command = command;
|
||||
theClone.description = description;
|
||||
theClone.imageFileName = imageFileName;
|
||||
theClone.tempFileNameTemplate = tempFileNameTemplate;
|
||||
theClone.fileExtensions = fileExtensions;
|
||||
|
||||
return theClone;
|
||||
}
|
||||
|
||||
public synchronized String toProperty() {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
|
||||
String separator = "; ";
|
||||
boolean needSeparator = false;
|
||||
|
||||
int action = getAction();
|
||||
if (action != MimeEntry.UNKNOWN) {
|
||||
buf.append("action=" + actionKeywords[action]);
|
||||
needSeparator = true;
|
||||
}
|
||||
|
||||
String command = getLaunchString();
|
||||
if (command != null && command.length() > 0) {
|
||||
if (needSeparator) {
|
||||
buf.append(separator);
|
||||
}
|
||||
buf.append("application=" + command);
|
||||
needSeparator = true;
|
||||
}
|
||||
|
||||
if (getImageFileName() != null) {
|
||||
if (needSeparator) {
|
||||
buf.append(separator);
|
||||
}
|
||||
buf.append("icon=" + getImageFileName());
|
||||
needSeparator = true;
|
||||
}
|
||||
|
||||
String extensions = getExtensionsAsList();
|
||||
if (extensions.length() > 0) {
|
||||
if (needSeparator) {
|
||||
buf.append(separator);
|
||||
}
|
||||
buf.append("file_extensions=" + extensions);
|
||||
needSeparator = true;
|
||||
}
|
||||
|
||||
String description = getDescription();
|
||||
if (description != null && !description.equals(getType())) {
|
||||
if (needSeparator) {
|
||||
buf.append(separator);
|
||||
}
|
||||
buf.append("description=" + description);
|
||||
}
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "MimeEntry[contentType=" + typeName
|
||||
+ ", image=" + imageFileName
|
||||
+ ", action=" + action
|
||||
+ ", command=" + command
|
||||
+ ", extensions=" + getExtensionsAsList()
|
||||
+ "]";
|
||||
}
|
||||
}
|
||||
205
jdkSrc/jdk8/sun/net/www/MimeLauncher.java
Normal file
205
jdkSrc/jdk8/sun/net/www/MimeLauncher.java
Normal file
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 1998, 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 sun.net.www;
|
||||
import java.net.URL;
|
||||
import java.io.*;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
class MimeLauncher extends Thread {
|
||||
java.net.URLConnection uc;
|
||||
MimeEntry m;
|
||||
String genericTempFileTemplate;
|
||||
InputStream is;
|
||||
String execPath;
|
||||
|
||||
MimeLauncher (MimeEntry M, java.net.URLConnection uc,
|
||||
InputStream is, String tempFileTemplate, String threadName) throws ApplicationLaunchException {
|
||||
super(threadName);
|
||||
m = M;
|
||||
this.uc = uc;
|
||||
this.is = is;
|
||||
genericTempFileTemplate = tempFileTemplate;
|
||||
|
||||
/* get the application to launch */
|
||||
String launchString = m.getLaunchString();
|
||||
|
||||
/* get a valid path to launch application - sets
|
||||
the execPath instance variable with the correct path.
|
||||
*/
|
||||
if (!findExecutablePath(launchString)) {
|
||||
/* strip off parameters i.e %s */
|
||||
String appName;
|
||||
int index = launchString.indexOf(' ');
|
||||
if (index != -1) {
|
||||
appName = launchString.substring(0, index);
|
||||
}
|
||||
else {
|
||||
appName = launchString;
|
||||
}
|
||||
throw new ApplicationLaunchException(appName);
|
||||
}
|
||||
}
|
||||
|
||||
protected String getTempFileName(URL url, String template) {
|
||||
String tempFilename = template;
|
||||
|
||||
// Replace all but last occurrance of "%s" with timestamp to insure
|
||||
// uniqueness. There's a subtle behavior here: if there is anything
|
||||
// _after_ the last "%s" we need to append it so that unusual launch
|
||||
// strings that have the datafile in the middle can still be used.
|
||||
int wildcard = tempFilename.lastIndexOf("%s");
|
||||
String prefix = tempFilename.substring(0, wildcard);
|
||||
|
||||
String suffix = "";
|
||||
if (wildcard < tempFilename.length() - 2) {
|
||||
suffix = tempFilename.substring(wildcard + 2);
|
||||
}
|
||||
|
||||
long timestamp = System.currentTimeMillis()/1000;
|
||||
int argIndex = 0;
|
||||
while ((argIndex = prefix.indexOf("%s")) >= 0) {
|
||||
prefix = prefix.substring(0, argIndex)
|
||||
+ timestamp
|
||||
+ prefix.substring(argIndex + 2);
|
||||
}
|
||||
|
||||
// Add a file name and file-extension if known
|
||||
String filename = url.getFile();
|
||||
|
||||
String extension = "";
|
||||
int dot = filename.lastIndexOf('.');
|
||||
|
||||
// BugId 4084826: Temp MIME file names not always valid.
|
||||
// Fix: don't allow slashes in the file name or extension.
|
||||
if (dot >= 0 && dot > filename.lastIndexOf('/')) {
|
||||
extension = filename.substring(dot);
|
||||
}
|
||||
|
||||
filename = "HJ" + url.hashCode();
|
||||
|
||||
tempFilename = prefix + filename + timestamp + extension + suffix;
|
||||
|
||||
return tempFilename;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
String ofn = m.getTempFileTemplate();
|
||||
if (ofn == null) {
|
||||
ofn = genericTempFileTemplate;
|
||||
}
|
||||
|
||||
ofn = getTempFileName(uc.getURL(), ofn);
|
||||
try {
|
||||
OutputStream os = new FileOutputStream(ofn);
|
||||
byte buf[] = new byte[2048];
|
||||
int i = 0;
|
||||
try {
|
||||
while ((i = is.read(buf)) >= 0) {
|
||||
os.write(buf, 0, i);
|
||||
}
|
||||
} catch(IOException e) {
|
||||
//System.err.println("Exception in write loop " + i);
|
||||
//e.printStackTrace();
|
||||
} finally {
|
||||
os.close();
|
||||
is.close();
|
||||
}
|
||||
} catch(IOException e) {
|
||||
//System.err.println("Exception in input or output stream");
|
||||
//e.printStackTrace();
|
||||
}
|
||||
|
||||
int inx = 0;
|
||||
String c = execPath;
|
||||
while ((inx = c.indexOf("%t")) >= 0) {
|
||||
c = c.substring(0, inx) + uc.getContentType()
|
||||
+ c.substring(inx + 2);
|
||||
}
|
||||
|
||||
boolean substituted = false;
|
||||
while ((inx = c.indexOf("%s")) >= 0) {
|
||||
c = c.substring(0, inx) + ofn + c.substring(inx + 2);
|
||||
substituted = true;
|
||||
}
|
||||
if (!substituted)
|
||||
c = c + " <" + ofn;
|
||||
|
||||
// System.out.println("Execing " +c);
|
||||
|
||||
Runtime.getRuntime().exec(c);
|
||||
} catch(IOException e) {
|
||||
}
|
||||
}
|
||||
|
||||
/* This method determines the path for the launcher application
|
||||
and sets the execPath instance variable. It uses the exec.path
|
||||
property to obtain a list of paths that is in turn used to
|
||||
location the application. If a valid path is not found, it
|
||||
returns false else true. */
|
||||
private boolean findExecutablePath(String str) {
|
||||
if (str == null || str.length() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String command;
|
||||
int index = str.indexOf(' ');
|
||||
if (index != -1) {
|
||||
command = str.substring(0, index);
|
||||
}
|
||||
else {
|
||||
command = str;
|
||||
}
|
||||
|
||||
File f = new File(command);
|
||||
if (f.isFile()) {
|
||||
// Already executable as it is
|
||||
execPath = str;
|
||||
return true;
|
||||
}
|
||||
|
||||
String execPathList;
|
||||
execPathList = java.security.AccessController.doPrivileged(
|
||||
new sun.security.action.GetPropertyAction("exec.path"));
|
||||
if (execPathList == null) {
|
||||
// exec.path property not set
|
||||
return false;
|
||||
}
|
||||
|
||||
StringTokenizer iter = new StringTokenizer(execPathList, "|");
|
||||
while (iter.hasMoreElements()) {
|
||||
String prefix = (String)iter.nextElement();
|
||||
String fullCmd = prefix + File.separator + command;
|
||||
f = new File(fullCmd);
|
||||
if (f.isFile()) {
|
||||
execPath = prefix + File.separator + str;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false; // application not found in exec.path
|
||||
}
|
||||
}
|
||||
459
jdkSrc/jdk8/sun/net/www/MimeTable.java
Normal file
459
jdkSrc/jdk8/sun/net/www/MimeTable.java
Normal file
@@ -0,0 +1,459 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2011, 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 sun.net.www;
|
||||
import java.io.*;
|
||||
import java.net.FileNameMap;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Properties;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
public class MimeTable implements FileNameMap {
|
||||
/** Keyed by content type, returns MimeEntries */
|
||||
private Hashtable<String, MimeEntry> entries
|
||||
= new Hashtable<String, MimeEntry>();
|
||||
|
||||
/** Keyed by file extension (with the .), returns MimeEntries */
|
||||
private Hashtable<String, MimeEntry> extensionMap
|
||||
= new Hashtable<String, MimeEntry>();
|
||||
|
||||
// Will be reset if in the platform-specific data file
|
||||
private static String tempFileTemplate;
|
||||
|
||||
static {
|
||||
java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
tempFileTemplate =
|
||||
System.getProperty("content.types.temp.file.template",
|
||||
"/tmp/%s");
|
||||
|
||||
mailcapLocations = new String[] {
|
||||
System.getProperty("user.mailcap"),
|
||||
System.getProperty("user.home") + "/.mailcap",
|
||||
"/etc/mailcap",
|
||||
"/usr/etc/mailcap",
|
||||
"/usr/local/etc/mailcap",
|
||||
System.getProperty("hotjava.home",
|
||||
"/usr/local/hotjava")
|
||||
+ "/lib/mailcap",
|
||||
};
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private static final String filePreamble = "sun.net.www MIME content-types table";
|
||||
private static final String fileMagic = "#" + filePreamble;
|
||||
|
||||
MimeTable() {
|
||||
load();
|
||||
}
|
||||
|
||||
private static class DefaultInstanceHolder {
|
||||
static final MimeTable defaultInstance = getDefaultInstance();
|
||||
|
||||
static MimeTable getDefaultInstance() {
|
||||
return java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction<MimeTable>() {
|
||||
public MimeTable run() {
|
||||
MimeTable instance = new MimeTable();
|
||||
URLConnection.setFileNameMap(instance);
|
||||
return instance;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the single instance of this class. First use will load the
|
||||
* table from a data file.
|
||||
*/
|
||||
public static MimeTable getDefaultTable() {
|
||||
return DefaultInstanceHolder.defaultInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static FileNameMap loadTable() {
|
||||
MimeTable mt = getDefaultTable();
|
||||
return (FileNameMap)mt;
|
||||
}
|
||||
|
||||
public synchronized int getSize() {
|
||||
return entries.size();
|
||||
}
|
||||
|
||||
public synchronized String getContentTypeFor(String fileName) {
|
||||
MimeEntry entry = findByFileName(fileName);
|
||||
if (entry != null) {
|
||||
return entry.getType();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void add(MimeEntry m) {
|
||||
entries.put(m.getType(), m);
|
||||
|
||||
String exts[] = m.getExtensions();
|
||||
if (exts == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < exts.length; i++) {
|
||||
extensionMap.put(exts[i], m);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized MimeEntry remove(String type) {
|
||||
MimeEntry entry = entries.get(type);
|
||||
return remove(entry);
|
||||
}
|
||||
|
||||
public synchronized MimeEntry remove(MimeEntry entry) {
|
||||
String[] extensionKeys = entry.getExtensions();
|
||||
if (extensionKeys != null) {
|
||||
for (int i = 0; i < extensionKeys.length; i++) {
|
||||
extensionMap.remove(extensionKeys[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return entries.remove(entry.getType());
|
||||
}
|
||||
|
||||
public synchronized MimeEntry find(String type) {
|
||||
MimeEntry entry = entries.get(type);
|
||||
if (entry == null) {
|
||||
// try a wildcard lookup
|
||||
Enumeration<MimeEntry> e = entries.elements();
|
||||
while (e.hasMoreElements()) {
|
||||
MimeEntry wild = e.nextElement();
|
||||
if (wild.matches(type)) {
|
||||
return wild;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Locate a MimeEntry by the file extension that has been associated
|
||||
* with it. Parses general file names, and URLs.
|
||||
*/
|
||||
public MimeEntry findByFileName(String fname) {
|
||||
String ext = "";
|
||||
|
||||
int i = fname.lastIndexOf('#');
|
||||
|
||||
if (i > 0) {
|
||||
fname = fname.substring(0, i - 1);
|
||||
}
|
||||
|
||||
i = fname.lastIndexOf('.');
|
||||
// REMIND: OS specific delimters appear here
|
||||
i = Math.max(i, fname.lastIndexOf('/'));
|
||||
i = Math.max(i, fname.lastIndexOf('?'));
|
||||
|
||||
if (i != -1 && fname.charAt(i) == '.') {
|
||||
ext = fname.substring(i).toLowerCase();
|
||||
}
|
||||
|
||||
return findByExt(ext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Locate a MimeEntry by the file extension that has been associated
|
||||
* with it.
|
||||
*/
|
||||
public synchronized MimeEntry findByExt(String fileExtension) {
|
||||
return extensionMap.get(fileExtension);
|
||||
}
|
||||
|
||||
public synchronized MimeEntry findByDescription(String description) {
|
||||
Enumeration<MimeEntry> e = elements();
|
||||
while (e.hasMoreElements()) {
|
||||
MimeEntry entry = e.nextElement();
|
||||
if (description.equals(entry.getDescription())) {
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
|
||||
// We failed, now try treating description as type
|
||||
return find(description);
|
||||
}
|
||||
|
||||
String getTempFileTemplate() {
|
||||
return tempFileTemplate;
|
||||
}
|
||||
|
||||
public synchronized Enumeration<MimeEntry> elements() {
|
||||
return entries.elements();
|
||||
}
|
||||
|
||||
// For backward compatibility -- mailcap format files
|
||||
// This is not currently used, but may in the future when we add ability
|
||||
// to read BOTH the properties format and the mailcap format.
|
||||
protected static String[] mailcapLocations;
|
||||
|
||||
public synchronized void load() {
|
||||
Properties entries = new Properties();
|
||||
File file = null;
|
||||
try {
|
||||
InputStream is;
|
||||
// First try to load the user-specific table, if it exists
|
||||
String userTablePath =
|
||||
System.getProperty("content.types.user.table");
|
||||
if (userTablePath != null) {
|
||||
file = new File(userTablePath);
|
||||
if (!file.exists()) {
|
||||
// No user-table, try to load the default built-in table.
|
||||
file = new File(System.getProperty("java.home") +
|
||||
File.separator +
|
||||
"lib" +
|
||||
File.separator +
|
||||
"content-types.properties");
|
||||
}
|
||||
}
|
||||
else {
|
||||
// No user table, try to load the default built-in table.
|
||||
file = new File(System.getProperty("java.home") +
|
||||
File.separator +
|
||||
"lib" +
|
||||
File.separator +
|
||||
"content-types.properties");
|
||||
}
|
||||
|
||||
is = new BufferedInputStream(new FileInputStream(file));
|
||||
entries.load(is);
|
||||
is.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
System.err.println("Warning: default mime table not found: " +
|
||||
file.getPath());
|
||||
return;
|
||||
}
|
||||
parse(entries);
|
||||
}
|
||||
|
||||
void parse(Properties entries) {
|
||||
// first, strip out the platform-specific temp file template
|
||||
String tempFileTemplate = (String)entries.get("temp.file.template");
|
||||
if (tempFileTemplate != null) {
|
||||
entries.remove("temp.file.template");
|
||||
MimeTable.tempFileTemplate = tempFileTemplate;
|
||||
}
|
||||
|
||||
// now, parse the mime-type spec's
|
||||
Enumeration<?> types = entries.propertyNames();
|
||||
while (types.hasMoreElements()) {
|
||||
String type = (String)types.nextElement();
|
||||
String attrs = entries.getProperty(type);
|
||||
parse(type, attrs);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Table format:
|
||||
//
|
||||
// <entry> ::= <table_tag> | <type_entry>
|
||||
//
|
||||
// <table_tag> ::= <table_format_version> | <temp_file_template>
|
||||
//
|
||||
// <type_entry> ::= <type_subtype_pair> '=' <type_attrs_list>
|
||||
//
|
||||
// <type_subtype_pair> ::= <type> '/' <subtype>
|
||||
//
|
||||
// <type_attrs_list> ::= <attr_value_pair> [ ';' <attr_value_pair> ]*
|
||||
// | [ <attr_value_pair> ]+
|
||||
//
|
||||
// <attr_value_pair> ::= <attr_name> '=' <attr_value>
|
||||
//
|
||||
// <attr_name> ::= 'description' | 'action' | 'application'
|
||||
// | 'file_extensions' | 'icon'
|
||||
//
|
||||
// <attr_value> ::= <legal_char>*
|
||||
//
|
||||
// Embedded ';' in an <attr_value> are quoted with leading '\' .
|
||||
//
|
||||
// Interpretation of <attr_value> depends on the <attr_name> it is
|
||||
// associated with.
|
||||
//
|
||||
|
||||
void parse(String type, String attrs) {
|
||||
MimeEntry newEntry = new MimeEntry(type);
|
||||
|
||||
// REMIND handle embedded ';' and '|' and literal '"'
|
||||
StringTokenizer tokenizer = new StringTokenizer(attrs, ";");
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
String pair = tokenizer.nextToken();
|
||||
parse(pair, newEntry);
|
||||
}
|
||||
|
||||
add(newEntry);
|
||||
}
|
||||
|
||||
void parse(String pair, MimeEntry entry) {
|
||||
// REMIND add exception handling...
|
||||
String name = null;
|
||||
String value = null;
|
||||
|
||||
boolean gotName = false;
|
||||
StringTokenizer tokenizer = new StringTokenizer(pair, "=");
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
if (gotName) {
|
||||
value = tokenizer.nextToken().trim();
|
||||
}
|
||||
else {
|
||||
name = tokenizer.nextToken().trim();
|
||||
gotName = true;
|
||||
}
|
||||
}
|
||||
|
||||
fill(entry, name, value);
|
||||
}
|
||||
|
||||
void fill(MimeEntry entry, String name, String value) {
|
||||
if ("description".equalsIgnoreCase(name)) {
|
||||
entry.setDescription(value);
|
||||
}
|
||||
else if ("action".equalsIgnoreCase(name)) {
|
||||
entry.setAction(getActionCode(value));
|
||||
}
|
||||
else if ("application".equalsIgnoreCase(name)) {
|
||||
entry.setCommand(value);
|
||||
}
|
||||
else if ("icon".equalsIgnoreCase(name)) {
|
||||
entry.setImageFileName(value);
|
||||
}
|
||||
else if ("file_extensions".equalsIgnoreCase(name)) {
|
||||
entry.setExtensions(value);
|
||||
}
|
||||
|
||||
// else illegal name exception
|
||||
}
|
||||
|
||||
String[] getExtensions(String list) {
|
||||
StringTokenizer tokenizer = new StringTokenizer(list, ",");
|
||||
int n = tokenizer.countTokens();
|
||||
String[] extensions = new String[n];
|
||||
for (int i = 0; i < n; i++) {
|
||||
extensions[i] = tokenizer.nextToken();
|
||||
}
|
||||
|
||||
return extensions;
|
||||
}
|
||||
|
||||
int getActionCode(String action) {
|
||||
for (int i = 0; i < MimeEntry.actionKeywords.length; i++) {
|
||||
if (action.equalsIgnoreCase(MimeEntry.actionKeywords[i])) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return MimeEntry.UNKNOWN;
|
||||
}
|
||||
|
||||
public synchronized boolean save(String filename) {
|
||||
if (filename == null) {
|
||||
filename = System.getProperty("user.home" +
|
||||
File.separator +
|
||||
"lib" +
|
||||
File.separator +
|
||||
"content-types.properties");
|
||||
}
|
||||
|
||||
return saveAsProperties(new File(filename));
|
||||
}
|
||||
|
||||
public Properties getAsProperties() {
|
||||
Properties properties = new Properties();
|
||||
Enumeration<MimeEntry> e = elements();
|
||||
while (e.hasMoreElements()) {
|
||||
MimeEntry entry = e.nextElement();
|
||||
properties.put(entry.getType(), entry.toProperty());
|
||||
}
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
protected boolean saveAsProperties(File file) {
|
||||
FileOutputStream os = null;
|
||||
try {
|
||||
os = new FileOutputStream(file);
|
||||
Properties properties = getAsProperties();
|
||||
properties.put("temp.file.template", tempFileTemplate);
|
||||
String tag;
|
||||
String user = System.getProperty("user.name");
|
||||
if (user != null) {
|
||||
tag = "; customized for " + user;
|
||||
properties.store(os, filePreamble + tag);
|
||||
}
|
||||
else {
|
||||
properties.store(os, filePreamble);
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
finally {
|
||||
if (os != null) {
|
||||
try { os.close(); } catch (IOException e) {}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
/*
|
||||
* Debugging utilities
|
||||
*
|
||||
public void list(PrintStream out) {
|
||||
Enumeration keys = entries.keys();
|
||||
while (keys.hasMoreElements()) {
|
||||
String key = (String)keys.nextElement();
|
||||
MimeEntry entry = (MimeEntry)entries.get(key);
|
||||
out.println(key + ": " + entry);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
MimeTable testTable = MimeTable.getDefaultTable();
|
||||
|
||||
Enumeration e = testTable.elements();
|
||||
while (e.hasMoreElements()) {
|
||||
MimeEntry entry = (MimeEntry)e.nextElement();
|
||||
System.out.println(entry);
|
||||
}
|
||||
|
||||
testTable.save(File.separator + "tmp" +
|
||||
File.separator + "mime_table.save");
|
||||
}
|
||||
*/
|
||||
}
|
||||
680
jdkSrc/jdk8/sun/net/www/ParseUtil.java
Normal file
680
jdkSrc/jdk8/sun/net/www/ParseUtil.java
Normal file
@@ -0,0 +1,680 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2007, 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 sun.net.www;
|
||||
|
||||
import java.util.BitSet;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.CharBuffer;
|
||||
import java.nio.charset.CharacterCodingException;
|
||||
import sun.nio.cs.ThreadLocalCoders;
|
||||
import java.nio.charset.CharsetDecoder;
|
||||
import java.nio.charset.CoderResult;
|
||||
import java.nio.charset.CodingErrorAction;
|
||||
|
||||
/**
|
||||
* A class that contains useful routines common to sun.net.www
|
||||
* @author Mike McCloskey
|
||||
*/
|
||||
|
||||
public class ParseUtil {
|
||||
static BitSet encodedInPath;
|
||||
|
||||
static {
|
||||
encodedInPath = new BitSet(256);
|
||||
|
||||
// Set the bits corresponding to characters that are encoded in the
|
||||
// path component of a URI.
|
||||
|
||||
// These characters are reserved in the path segment as described in
|
||||
// RFC2396 section 3.3.
|
||||
encodedInPath.set('=');
|
||||
encodedInPath.set(';');
|
||||
encodedInPath.set('?');
|
||||
encodedInPath.set('/');
|
||||
|
||||
// These characters are defined as excluded in RFC2396 section 2.4.3
|
||||
// and must be escaped if they occur in the data part of a URI.
|
||||
encodedInPath.set('#');
|
||||
encodedInPath.set(' ');
|
||||
encodedInPath.set('<');
|
||||
encodedInPath.set('>');
|
||||
encodedInPath.set('%');
|
||||
encodedInPath.set('"');
|
||||
encodedInPath.set('{');
|
||||
encodedInPath.set('}');
|
||||
encodedInPath.set('|');
|
||||
encodedInPath.set('\\');
|
||||
encodedInPath.set('^');
|
||||
encodedInPath.set('[');
|
||||
encodedInPath.set(']');
|
||||
encodedInPath.set('`');
|
||||
|
||||
// US ASCII control characters 00-1F and 7F.
|
||||
for (int i=0; i<32; i++)
|
||||
encodedInPath.set(i);
|
||||
encodedInPath.set(127);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an encoded version of the specified path string suitable
|
||||
* for use in the construction of a URL.
|
||||
*
|
||||
* A path separator is replaced by a forward slash. The string is UTF8
|
||||
* encoded. The % escape sequence is used for characters that are above
|
||||
* 0x7F or those defined in RFC2396 as reserved or excluded in the path
|
||||
* component of a URL.
|
||||
*/
|
||||
public static String encodePath(String path) {
|
||||
return encodePath(path, true);
|
||||
}
|
||||
/*
|
||||
* flag indicates whether path uses platform dependent
|
||||
* File.separatorChar or not. True indicates path uses platform
|
||||
* dependent File.separatorChar.
|
||||
*/
|
||||
public static String encodePath(String path, boolean flag) {
|
||||
char[] retCC = new char[path.length() * 2 + 16];
|
||||
int retLen = 0;
|
||||
char[] pathCC = path.toCharArray();
|
||||
|
||||
int n = path.length();
|
||||
for (int i=0; i<n; i++) {
|
||||
char c = pathCC[i];
|
||||
if ((!flag && c == '/') || (flag && c == File.separatorChar))
|
||||
retCC[retLen++] = '/';
|
||||
else {
|
||||
if (c <= 0x007F) {
|
||||
if (c >= 'a' && c <= 'z' ||
|
||||
c >= 'A' && c <= 'Z' ||
|
||||
c >= '0' && c <= '9') {
|
||||
retCC[retLen++] = c;
|
||||
} else
|
||||
if (encodedInPath.get(c))
|
||||
retLen = escape(retCC, c, retLen);
|
||||
else
|
||||
retCC[retLen++] = c;
|
||||
} else if (c > 0x07FF) {
|
||||
retLen = escape(retCC, (char)(0xE0 | ((c >> 12) & 0x0F)), retLen);
|
||||
retLen = escape(retCC, (char)(0x80 | ((c >> 6) & 0x3F)), retLen);
|
||||
retLen = escape(retCC, (char)(0x80 | ((c >> 0) & 0x3F)), retLen);
|
||||
} else {
|
||||
retLen = escape(retCC, (char)(0xC0 | ((c >> 6) & 0x1F)), retLen);
|
||||
retLen = escape(retCC, (char)(0x80 | ((c >> 0) & 0x3F)), retLen);
|
||||
}
|
||||
}
|
||||
//worst case scenario for character [0x7ff-] every single
|
||||
//character will be encoded into 9 characters.
|
||||
if (retLen + 9 > retCC.length) {
|
||||
int newLen = retCC.length * 2 + 16;
|
||||
if (newLen < 0) {
|
||||
newLen = Integer.MAX_VALUE;
|
||||
}
|
||||
char[] buf = new char[newLen];
|
||||
System.arraycopy(retCC, 0, buf, 0, retLen);
|
||||
retCC = buf;
|
||||
}
|
||||
}
|
||||
return new String(retCC, 0, retLen);
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the URL escape sequence for the specified char to the
|
||||
* specified StringBuffer.
|
||||
*/
|
||||
private static int escape(char[] cc, char c, int index) {
|
||||
cc[index++] = '%';
|
||||
cc[index++] = Character.forDigit((c >> 4) & 0xF, 16);
|
||||
cc[index++] = Character.forDigit(c & 0xF, 16);
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Un-escape and return the character at position i in string s.
|
||||
*/
|
||||
private static byte unescape(String s, int i) {
|
||||
return (byte) Integer.parseInt(s.substring(i+1,i+3),16);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a new String constructed from the specified String by replacing
|
||||
* the URL escape sequences and UTF8 encoding with the characters they
|
||||
* represent.
|
||||
*/
|
||||
public static String decode(String s) {
|
||||
int n = s.length();
|
||||
if ((n == 0) || (s.indexOf('%') < 0))
|
||||
return s;
|
||||
|
||||
StringBuilder sb = new StringBuilder(n);
|
||||
ByteBuffer bb = ByteBuffer.allocate(n);
|
||||
CharBuffer cb = CharBuffer.allocate(n);
|
||||
CharsetDecoder dec = ThreadLocalCoders.decoderFor("UTF-8")
|
||||
.onMalformedInput(CodingErrorAction.REPORT)
|
||||
.onUnmappableCharacter(CodingErrorAction.REPORT);
|
||||
|
||||
char c = s.charAt(0);
|
||||
for (int i = 0; i < n;) {
|
||||
assert c == s.charAt(i);
|
||||
if (c != '%') {
|
||||
sb.append(c);
|
||||
if (++i >= n)
|
||||
break;
|
||||
c = s.charAt(i);
|
||||
continue;
|
||||
}
|
||||
bb.clear();
|
||||
int ui = i;
|
||||
for (;;) {
|
||||
assert (n - i >= 2);
|
||||
try {
|
||||
bb.put(unescape(s, i));
|
||||
} catch (NumberFormatException e) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
i += 3;
|
||||
if (i >= n)
|
||||
break;
|
||||
c = s.charAt(i);
|
||||
if (c != '%')
|
||||
break;
|
||||
}
|
||||
bb.flip();
|
||||
cb.clear();
|
||||
dec.reset();
|
||||
CoderResult cr = dec.decode(bb, cb, true);
|
||||
if (cr.isError())
|
||||
throw new IllegalArgumentException("Error decoding percent encoded characters");
|
||||
cr = dec.flush(cb);
|
||||
if (cr.isError())
|
||||
throw new IllegalArgumentException("Error decoding percent encoded characters");
|
||||
sb.append(cb.flip().toString());
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a canonical version of the specified string.
|
||||
*/
|
||||
public String canonizeString(String file) {
|
||||
int i = 0;
|
||||
int lim = file.length();
|
||||
|
||||
// Remove embedded /../
|
||||
while ((i = file.indexOf("/../")) >= 0) {
|
||||
if ((lim = file.lastIndexOf('/', i - 1)) >= 0) {
|
||||
file = file.substring(0, lim) + file.substring(i + 3);
|
||||
} else {
|
||||
file = file.substring(i + 3);
|
||||
}
|
||||
}
|
||||
// Remove embedded /./
|
||||
while ((i = file.indexOf("/./")) >= 0) {
|
||||
file = file.substring(0, i) + file.substring(i + 2);
|
||||
}
|
||||
// Remove trailing ..
|
||||
while (file.endsWith("/..")) {
|
||||
i = file.indexOf("/..");
|
||||
if ((lim = file.lastIndexOf('/', i - 1)) >= 0) {
|
||||
file = file.substring(0, lim+1);
|
||||
} else {
|
||||
file = file.substring(0, i);
|
||||
}
|
||||
}
|
||||
// Remove trailing .
|
||||
if (file.endsWith("/."))
|
||||
file = file.substring(0, file.length() -1);
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
public static URL fileToEncodedURL(File file)
|
||||
throws MalformedURLException
|
||||
{
|
||||
String path = file.getAbsolutePath();
|
||||
path = ParseUtil.encodePath(path);
|
||||
if (!path.startsWith("/")) {
|
||||
path = "/" + path;
|
||||
}
|
||||
if (!path.endsWith("/") && file.isDirectory()) {
|
||||
path = path + "/";
|
||||
}
|
||||
return new URL("file", "", path);
|
||||
}
|
||||
|
||||
public static java.net.URI toURI(URL url) {
|
||||
String protocol = url.getProtocol();
|
||||
String auth = url.getAuthority();
|
||||
String path = url.getPath();
|
||||
String query = url.getQuery();
|
||||
String ref = url.getRef();
|
||||
if (path != null && !(path.startsWith("/")))
|
||||
path = "/" + path;
|
||||
|
||||
//
|
||||
// In java.net.URI class, a port number of -1 implies the default
|
||||
// port number. So get it stripped off before creating URI instance.
|
||||
//
|
||||
if (auth != null && auth.endsWith(":-1"))
|
||||
auth = auth.substring(0, auth.length() - 3);
|
||||
|
||||
java.net.URI uri;
|
||||
try {
|
||||
uri = createURI(protocol, auth, path, query, ref);
|
||||
} catch (java.net.URISyntaxException e) {
|
||||
uri = null;
|
||||
}
|
||||
return uri;
|
||||
}
|
||||
|
||||
//
|
||||
// createURI() and its auxiliary code are cloned from java.net.URI.
|
||||
// Most of the code are just copy and paste, except that quote()
|
||||
// has been modified to avoid double-escape.
|
||||
//
|
||||
// Usually it is unacceptable, but we're forced to do it because
|
||||
// otherwise we need to change public API, namely java.net.URI's
|
||||
// multi-argument constructors. It turns out that the changes cause
|
||||
// incompatibilities so can't be done.
|
||||
//
|
||||
private static URI createURI(String scheme,
|
||||
String authority,
|
||||
String path,
|
||||
String query,
|
||||
String fragment) throws URISyntaxException
|
||||
{
|
||||
String s = toString(scheme, null,
|
||||
authority, null, null, -1,
|
||||
path, query, fragment);
|
||||
checkPath(s, scheme, path);
|
||||
return new URI(s);
|
||||
}
|
||||
|
||||
private static String toString(String scheme,
|
||||
String opaquePart,
|
||||
String authority,
|
||||
String userInfo,
|
||||
String host,
|
||||
int port,
|
||||
String path,
|
||||
String query,
|
||||
String fragment)
|
||||
{
|
||||
StringBuffer sb = new StringBuffer();
|
||||
if (scheme != null) {
|
||||
sb.append(scheme);
|
||||
sb.append(':');
|
||||
}
|
||||
appendSchemeSpecificPart(sb, opaquePart,
|
||||
authority, userInfo, host, port,
|
||||
path, query);
|
||||
appendFragment(sb, fragment);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static void appendSchemeSpecificPart(StringBuffer sb,
|
||||
String opaquePart,
|
||||
String authority,
|
||||
String userInfo,
|
||||
String host,
|
||||
int port,
|
||||
String path,
|
||||
String query)
|
||||
{
|
||||
if (opaquePart != null) {
|
||||
/* check if SSP begins with an IPv6 address
|
||||
* because we must not quote a literal IPv6 address
|
||||
*/
|
||||
if (opaquePart.startsWith("//[")) {
|
||||
int end = opaquePart.indexOf("]");
|
||||
if (end != -1 && opaquePart.indexOf(":")!=-1) {
|
||||
String doquote, dontquote;
|
||||
if (end == opaquePart.length()) {
|
||||
dontquote = opaquePart;
|
||||
doquote = "";
|
||||
} else {
|
||||
dontquote = opaquePart.substring(0,end+1);
|
||||
doquote = opaquePart.substring(end+1);
|
||||
}
|
||||
sb.append (dontquote);
|
||||
sb.append(quote(doquote, L_URIC, H_URIC));
|
||||
}
|
||||
} else {
|
||||
sb.append(quote(opaquePart, L_URIC, H_URIC));
|
||||
}
|
||||
} else {
|
||||
appendAuthority(sb, authority, userInfo, host, port);
|
||||
if (path != null)
|
||||
sb.append(quote(path, L_PATH, H_PATH));
|
||||
if (query != null) {
|
||||
sb.append('?');
|
||||
sb.append(quote(query, L_URIC, H_URIC));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void appendAuthority(StringBuffer sb,
|
||||
String authority,
|
||||
String userInfo,
|
||||
String host,
|
||||
int port)
|
||||
{
|
||||
if (host != null) {
|
||||
sb.append("//");
|
||||
if (userInfo != null) {
|
||||
sb.append(quote(userInfo, L_USERINFO, H_USERINFO));
|
||||
sb.append('@');
|
||||
}
|
||||
boolean needBrackets = ((host.indexOf(':') >= 0)
|
||||
&& !host.startsWith("[")
|
||||
&& !host.endsWith("]"));
|
||||
if (needBrackets) sb.append('[');
|
||||
sb.append(host);
|
||||
if (needBrackets) sb.append(']');
|
||||
if (port != -1) {
|
||||
sb.append(':');
|
||||
sb.append(port);
|
||||
}
|
||||
} else if (authority != null) {
|
||||
sb.append("//");
|
||||
if (authority.startsWith("[")) {
|
||||
int end = authority.indexOf("]");
|
||||
if (end != -1 && authority.indexOf(":")!=-1) {
|
||||
String doquote, dontquote;
|
||||
if (end == authority.length()) {
|
||||
dontquote = authority;
|
||||
doquote = "";
|
||||
} else {
|
||||
dontquote = authority.substring(0,end+1);
|
||||
doquote = authority.substring(end+1);
|
||||
}
|
||||
sb.append (dontquote);
|
||||
sb.append(quote(doquote,
|
||||
L_REG_NAME | L_SERVER,
|
||||
H_REG_NAME | H_SERVER));
|
||||
}
|
||||
} else {
|
||||
sb.append(quote(authority,
|
||||
L_REG_NAME | L_SERVER,
|
||||
H_REG_NAME | H_SERVER));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void appendFragment(StringBuffer sb, String fragment) {
|
||||
if (fragment != null) {
|
||||
sb.append('#');
|
||||
sb.append(quote(fragment, L_URIC, H_URIC));
|
||||
}
|
||||
}
|
||||
|
||||
// Quote any characters in s that are not permitted
|
||||
// by the given mask pair
|
||||
//
|
||||
private static String quote(String s, long lowMask, long highMask) {
|
||||
int n = s.length();
|
||||
StringBuffer sb = null;
|
||||
boolean allowNonASCII = ((lowMask & L_ESCAPED) != 0);
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
char c = s.charAt(i);
|
||||
if (c < '\u0080') {
|
||||
if (!match(c, lowMask, highMask) && !isEscaped(s, i)) {
|
||||
if (sb == null) {
|
||||
sb = new StringBuffer();
|
||||
sb.append(s.substring(0, i));
|
||||
}
|
||||
appendEscape(sb, (byte)c);
|
||||
} else {
|
||||
if (sb != null)
|
||||
sb.append(c);
|
||||
}
|
||||
} else if (allowNonASCII
|
||||
&& (Character.isSpaceChar(c)
|
||||
|| Character.isISOControl(c))) {
|
||||
if (sb == null) {
|
||||
sb = new StringBuffer();
|
||||
sb.append(s.substring(0, i));
|
||||
}
|
||||
appendEncoded(sb, c);
|
||||
} else {
|
||||
if (sb != null)
|
||||
sb.append(c);
|
||||
}
|
||||
}
|
||||
return (sb == null) ? s : sb.toString();
|
||||
}
|
||||
|
||||
//
|
||||
// To check if the given string has an escaped triplet
|
||||
// at the given position
|
||||
//
|
||||
private static boolean isEscaped(String s, int pos) {
|
||||
if (s == null || (s.length() <= (pos + 2)))
|
||||
return false;
|
||||
|
||||
return s.charAt(pos) == '%'
|
||||
&& match(s.charAt(pos + 1), L_HEX, H_HEX)
|
||||
&& match(s.charAt(pos + 2), L_HEX, H_HEX);
|
||||
}
|
||||
|
||||
private static void appendEncoded(StringBuffer sb, char c) {
|
||||
ByteBuffer bb = null;
|
||||
try {
|
||||
bb = ThreadLocalCoders.encoderFor("UTF-8")
|
||||
.encode(CharBuffer.wrap("" + c));
|
||||
} catch (CharacterCodingException x) {
|
||||
assert false;
|
||||
}
|
||||
while (bb.hasRemaining()) {
|
||||
int b = bb.get() & 0xff;
|
||||
if (b >= 0x80)
|
||||
appendEscape(sb, (byte)b);
|
||||
else
|
||||
sb.append((char)b);
|
||||
}
|
||||
}
|
||||
|
||||
private final static char[] hexDigits = {
|
||||
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
|
||||
};
|
||||
|
||||
private static void appendEscape(StringBuffer sb, byte b) {
|
||||
sb.append('%');
|
||||
sb.append(hexDigits[(b >> 4) & 0x0f]);
|
||||
sb.append(hexDigits[(b >> 0) & 0x0f]);
|
||||
}
|
||||
|
||||
// Tell whether the given character is permitted by the given mask pair
|
||||
private static boolean match(char c, long lowMask, long highMask) {
|
||||
if (c < 64)
|
||||
return ((1L << c) & lowMask) != 0;
|
||||
if (c < 128)
|
||||
return ((1L << (c - 64)) & highMask) != 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// If a scheme is given then the path, if given, must be absolute
|
||||
//
|
||||
private static void checkPath(String s, String scheme, String path)
|
||||
throws URISyntaxException
|
||||
{
|
||||
if (scheme != null) {
|
||||
if ((path != null)
|
||||
&& ((path.length() > 0) && (path.charAt(0) != '/')))
|
||||
throw new URISyntaxException(s,
|
||||
"Relative path in absolute URI");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// -- Character classes for parsing --
|
||||
|
||||
// Compute a low-order mask for the characters
|
||||
// between first and last, inclusive
|
||||
private static long lowMask(char first, char last) {
|
||||
long m = 0;
|
||||
int f = Math.max(Math.min(first, 63), 0);
|
||||
int l = Math.max(Math.min(last, 63), 0);
|
||||
for (int i = f; i <= l; i++)
|
||||
m |= 1L << i;
|
||||
return m;
|
||||
}
|
||||
|
||||
// Compute the low-order mask for the characters in the given string
|
||||
private static long lowMask(String chars) {
|
||||
int n = chars.length();
|
||||
long m = 0;
|
||||
for (int i = 0; i < n; i++) {
|
||||
char c = chars.charAt(i);
|
||||
if (c < 64)
|
||||
m |= (1L << c);
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
// Compute a high-order mask for the characters
|
||||
// between first and last, inclusive
|
||||
private static long highMask(char first, char last) {
|
||||
long m = 0;
|
||||
int f = Math.max(Math.min(first, 127), 64) - 64;
|
||||
int l = Math.max(Math.min(last, 127), 64) - 64;
|
||||
for (int i = f; i <= l; i++)
|
||||
m |= 1L << i;
|
||||
return m;
|
||||
}
|
||||
|
||||
// Compute the high-order mask for the characters in the given string
|
||||
private static long highMask(String chars) {
|
||||
int n = chars.length();
|
||||
long m = 0;
|
||||
for (int i = 0; i < n; i++) {
|
||||
char c = chars.charAt(i);
|
||||
if ((c >= 64) && (c < 128))
|
||||
m |= (1L << (c - 64));
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
// Character-class masks
|
||||
|
||||
// digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" |
|
||||
// "8" | "9"
|
||||
private static final long L_DIGIT = lowMask('0', '9');
|
||||
private static final long H_DIGIT = 0L;
|
||||
|
||||
// hex = digit | "A" | "B" | "C" | "D" | "E" | "F" |
|
||||
// "a" | "b" | "c" | "d" | "e" | "f"
|
||||
private static final long L_HEX = L_DIGIT;
|
||||
private static final long H_HEX = highMask('A', 'F') | highMask('a', 'f');
|
||||
|
||||
// upalpha = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" |
|
||||
// "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" |
|
||||
// "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z"
|
||||
private static final long L_UPALPHA = 0L;
|
||||
private static final long H_UPALPHA = highMask('A', 'Z');
|
||||
|
||||
// lowalpha = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" |
|
||||
// "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" |
|
||||
// "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z"
|
||||
private static final long L_LOWALPHA = 0L;
|
||||
private static final long H_LOWALPHA = highMask('a', 'z');
|
||||
|
||||
// alpha = lowalpha | upalpha
|
||||
private static final long L_ALPHA = L_LOWALPHA | L_UPALPHA;
|
||||
private static final long H_ALPHA = H_LOWALPHA | H_UPALPHA;
|
||||
|
||||
// alphanum = alpha | digit
|
||||
private static final long L_ALPHANUM = L_DIGIT | L_ALPHA;
|
||||
private static final long H_ALPHANUM = H_DIGIT | H_ALPHA;
|
||||
|
||||
// mark = "-" | "_" | "." | "!" | "~" | "*" | "'" |
|
||||
// "(" | ")"
|
||||
private static final long L_MARK = lowMask("-_.!~*'()");
|
||||
private static final long H_MARK = highMask("-_.!~*'()");
|
||||
|
||||
// unreserved = alphanum | mark
|
||||
private static final long L_UNRESERVED = L_ALPHANUM | L_MARK;
|
||||
private static final long H_UNRESERVED = H_ALPHANUM | H_MARK;
|
||||
|
||||
// reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
|
||||
// "$" | "," | "[" | "]"
|
||||
// Added per RFC2732: "[", "]"
|
||||
private static final long L_RESERVED = lowMask(";/?:@&=+$,[]");
|
||||
private static final long H_RESERVED = highMask(";/?:@&=+$,[]");
|
||||
|
||||
// The zero'th bit is used to indicate that escape pairs and non-US-ASCII
|
||||
// characters are allowed; this is handled by the scanEscape method below.
|
||||
private static final long L_ESCAPED = 1L;
|
||||
private static final long H_ESCAPED = 0L;
|
||||
|
||||
// Dash, for use in domainlabel and toplabel
|
||||
private static final long L_DASH = lowMask("-");
|
||||
private static final long H_DASH = highMask("-");
|
||||
|
||||
// uric = reserved | unreserved | escaped
|
||||
private static final long L_URIC = L_RESERVED | L_UNRESERVED | L_ESCAPED;
|
||||
private static final long H_URIC = H_RESERVED | H_UNRESERVED | H_ESCAPED;
|
||||
|
||||
// pchar = unreserved | escaped |
|
||||
// ":" | "@" | "&" | "=" | "+" | "$" | ","
|
||||
private static final long L_PCHAR
|
||||
= L_UNRESERVED | L_ESCAPED | lowMask(":@&=+$,");
|
||||
private static final long H_PCHAR
|
||||
= H_UNRESERVED | H_ESCAPED | highMask(":@&=+$,");
|
||||
|
||||
// All valid path characters
|
||||
private static final long L_PATH = L_PCHAR | lowMask(";/");
|
||||
private static final long H_PATH = H_PCHAR | highMask(";/");
|
||||
|
||||
// userinfo = *( unreserved | escaped |
|
||||
// ";" | ":" | "&" | "=" | "+" | "$" | "," )
|
||||
private static final long L_USERINFO
|
||||
= L_UNRESERVED | L_ESCAPED | lowMask(";:&=+$,");
|
||||
private static final long H_USERINFO
|
||||
= H_UNRESERVED | H_ESCAPED | highMask(";:&=+$,");
|
||||
|
||||
// reg_name = 1*( unreserved | escaped | "$" | "," |
|
||||
// ";" | ":" | "@" | "&" | "=" | "+" )
|
||||
private static final long L_REG_NAME
|
||||
= L_UNRESERVED | L_ESCAPED | lowMask("$,;:@&=+");
|
||||
private static final long H_REG_NAME
|
||||
= H_UNRESERVED | H_ESCAPED | highMask("$,;:@&=+");
|
||||
|
||||
// All valid characters for server-based authorities
|
||||
private static final long L_SERVER
|
||||
= L_USERINFO | L_ALPHANUM | L_DASH | lowMask(".:@[]");
|
||||
private static final long H_SERVER
|
||||
= H_USERINFO | H_ALPHANUM | H_DASH | highMask(".:@[]");
|
||||
}
|
||||
246
jdkSrc/jdk8/sun/net/www/URLConnection.java
Normal file
246
jdkSrc/jdk8/sun/net/www/URLConnection.java
Normal file
@@ -0,0 +1,246 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2011, 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 sun.net.www;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* A class to represent an active connection to an object
|
||||
* represented by a URL.
|
||||
* @author James Gosling
|
||||
*/
|
||||
|
||||
abstract public class URLConnection extends java.net.URLConnection {
|
||||
|
||||
/** The URL that it is connected to */
|
||||
|
||||
private String contentType;
|
||||
private int contentLength = -1;
|
||||
|
||||
protected MessageHeader properties;
|
||||
|
||||
/** Create a URLConnection object. These should not be created directly:
|
||||
instead they should be created by protocol handers in response to
|
||||
URL.openConnection.
|
||||
@param u The URL that this connects to.
|
||||
*/
|
||||
public URLConnection (URL u) {
|
||||
super(u);
|
||||
properties = new MessageHeader();
|
||||
}
|
||||
|
||||
/** Call this routine to get the property list for this object.
|
||||
* Properties (like content-type) that have explicit getXX() methods
|
||||
* associated with them should be accessed using those methods. */
|
||||
public MessageHeader getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
/** Call this routine to set the property list for this object. */
|
||||
public void setProperties(MessageHeader properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
public void setRequestProperty(String key, String value) {
|
||||
if(connected)
|
||||
throw new IllegalAccessError("Already connected");
|
||||
if (key == null)
|
||||
throw new NullPointerException ("key cannot be null");
|
||||
properties.set(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* The following three methods addRequestProperty, getRequestProperty,
|
||||
* and getRequestProperties were copied from the superclass implementation
|
||||
* before it was changed by CR:6230836, to maintain backward compatibility.
|
||||
*/
|
||||
public void addRequestProperty(String key, String value) {
|
||||
if (connected)
|
||||
throw new IllegalStateException("Already connected");
|
||||
if (key == null)
|
||||
throw new NullPointerException ("key is null");
|
||||
}
|
||||
|
||||
public String getRequestProperty(String key) {
|
||||
if (connected)
|
||||
throw new IllegalStateException("Already connected");
|
||||
return null;
|
||||
}
|
||||
|
||||
public Map<String,List<String>> getRequestProperties() {
|
||||
if (connected)
|
||||
throw new IllegalStateException("Already connected");
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
public String getHeaderField(String name) {
|
||||
try {
|
||||
getInputStream();
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
return properties == null ? null : properties.findValue(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the key for the nth header field. Returns null if
|
||||
* there are fewer than n fields. This can be used to iterate
|
||||
* through all the headers in the message.
|
||||
*/
|
||||
public String getHeaderFieldKey(int n) {
|
||||
try {
|
||||
getInputStream();
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
MessageHeader props = properties;
|
||||
return props == null ? null : props.getKey(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value for the nth header field. Returns null if
|
||||
* there are fewer than n fields. This can be used in conjunction
|
||||
* with getHeaderFieldKey to iterate through all the headers in the message.
|
||||
*/
|
||||
public String getHeaderField(int n) {
|
||||
try {
|
||||
getInputStream();
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
MessageHeader props = properties;
|
||||
return props == null ? null : props.getValue(n);
|
||||
}
|
||||
|
||||
/** Call this routine to get the content-type associated with this
|
||||
* object.
|
||||
*/
|
||||
public String getContentType() {
|
||||
if (contentType == null)
|
||||
contentType = getHeaderField("content-type");
|
||||
if (contentType == null) {
|
||||
String ct = null;
|
||||
try {
|
||||
ct = guessContentTypeFromStream(getInputStream());
|
||||
} catch(java.io.IOException e) {
|
||||
}
|
||||
String ce = properties.findValue("content-encoding");
|
||||
if (ct == null) {
|
||||
ct = properties.findValue("content-type");
|
||||
|
||||
if (ct == null)
|
||||
if (url.getFile().endsWith("/"))
|
||||
ct = "text/html";
|
||||
else
|
||||
ct = guessContentTypeFromName(url.getFile());
|
||||
}
|
||||
|
||||
/*
|
||||
* If the Mime header had a Content-encoding field and its value
|
||||
* was not one of the values that essentially indicate no
|
||||
* encoding, we force the content type to be unknown. This will
|
||||
* cause a save dialog to be presented to the user. It is not
|
||||
* ideal but is better than what we were previously doing, namely
|
||||
* bringing up an image tool for compressed tar files.
|
||||
*/
|
||||
|
||||
if (ct == null || ce != null &&
|
||||
!(ce.equalsIgnoreCase("7bit")
|
||||
|| ce.equalsIgnoreCase("8bit")
|
||||
|| ce.equalsIgnoreCase("binary")))
|
||||
ct = "content/unknown";
|
||||
setContentType(ct);
|
||||
}
|
||||
return contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the content type of this URL to a specific value.
|
||||
* @param type The content type to use. One of the
|
||||
* content_* static variables in this
|
||||
* class should be used.
|
||||
* eg. setType(URL.content_html);
|
||||
*/
|
||||
public void setContentType(String type) {
|
||||
contentType = type;
|
||||
properties.set("content-type", type);
|
||||
}
|
||||
|
||||
/** Call this routine to get the content-length associated with this
|
||||
* object.
|
||||
*/
|
||||
public int getContentLength() {
|
||||
try {
|
||||
getInputStream();
|
||||
} catch (Exception e) {
|
||||
return -1;
|
||||
}
|
||||
int l = contentLength;
|
||||
if (l < 0) {
|
||||
try {
|
||||
l = Integer.parseInt(properties.findValue("content-length"));
|
||||
setContentLength(l);
|
||||
} catch(Exception e) {
|
||||
}
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
/** Call this routine to set the content-length associated with this
|
||||
* object.
|
||||
*/
|
||||
protected void setContentLength(int length) {
|
||||
contentLength = length;
|
||||
properties.set("content-length", String.valueOf(length));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the data associated with this URL can be cached.
|
||||
*/
|
||||
public boolean canCache() {
|
||||
return url.getFile().indexOf('?') < 0 /* && url.postData == null
|
||||
REMIND */ ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this to close the connection and flush any remaining data.
|
||||
* Overriders must remember to call super.close()
|
||||
*/
|
||||
public void close() {
|
||||
url = null;
|
||||
}
|
||||
|
||||
private static HashMap<String,Void> proxiedHosts = new HashMap<>();
|
||||
|
||||
public synchronized static void setProxiedHost(String host) {
|
||||
proxiedHosts.put(host.toLowerCase(), null);
|
||||
}
|
||||
|
||||
public synchronized static boolean isProxiedHost(String host) {
|
||||
return proxiedHosts.containsKey(host.toLowerCase());
|
||||
}
|
||||
}
|
||||
43
jdkSrc/jdk8/sun/net/www/content/audio/aiff.java
Normal file
43
jdkSrc/jdk8/sun/net/www/content/audio/aiff.java
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Basic .aiff audio handler.
|
||||
* @author Jeff Nisewanger
|
||||
*/
|
||||
package sun.net.www.content.audio;
|
||||
|
||||
import java.net.*;
|
||||
import java.io.IOException;
|
||||
import sun.applet.AppletAudioClip;
|
||||
|
||||
/**
|
||||
* Returns an AppletAudioClip object.
|
||||
*/
|
||||
public class aiff extends ContentHandler {
|
||||
public Object getContent(URLConnection uc) throws IOException {
|
||||
return new AppletAudioClip(uc);
|
||||
}
|
||||
}
|
||||
45
jdkSrc/jdk8/sun/net/www/content/audio/basic.java
Normal file
45
jdkSrc/jdk8/sun/net/www/content/audio/basic.java
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Basic .au and .snd audio handler.
|
||||
* @author Jeff Nisewanger
|
||||
*/
|
||||
package sun.net.www.content.audio;
|
||||
|
||||
import java.net.*;
|
||||
import java.io.IOException;
|
||||
import sun.applet.AppletAudioClip;
|
||||
|
||||
/**
|
||||
* Returns an AppletAudioClip object.
|
||||
* This provides backwards compatibility with the behavior
|
||||
* of ClassLoader.getResource().getContent() on JDK1.1.
|
||||
*/
|
||||
public class basic extends ContentHandler {
|
||||
public Object getContent(URLConnection uc) throws IOException {
|
||||
return new AppletAudioClip(uc);
|
||||
}
|
||||
}
|
||||
43
jdkSrc/jdk8/sun/net/www/content/audio/wav.java
Normal file
43
jdkSrc/jdk8/sun/net/www/content/audio/wav.java
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Basic .wav audio handler.
|
||||
* @author Jeff Nisewanger
|
||||
*/
|
||||
package sun.net.www.content.audio;
|
||||
|
||||
import java.net.*;
|
||||
import java.io.IOException;
|
||||
import sun.applet.AppletAudioClip;
|
||||
|
||||
/**
|
||||
* Returns an AppletAudioClip object.
|
||||
*/
|
||||
public class wav extends ContentHandler {
|
||||
public Object getContent(URLConnection uc) throws IOException {
|
||||
return new AppletAudioClip(uc);
|
||||
}
|
||||
}
|
||||
43
jdkSrc/jdk8/sun/net/www/content/audio/x_aiff.java
Normal file
43
jdkSrc/jdk8/sun/net/www/content/audio/x_aiff.java
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Basic .aiff audio handler.
|
||||
* @author Jeff Nisewanger
|
||||
*/
|
||||
package sun.net.www.content.audio;
|
||||
|
||||
import java.net.*;
|
||||
import java.io.IOException;
|
||||
import sun.applet.AppletAudioClip;
|
||||
|
||||
/**
|
||||
* Returns an AppletAudioClip object.
|
||||
*/
|
||||
public class x_aiff extends ContentHandler {
|
||||
public Object getContent(URLConnection uc) throws IOException {
|
||||
return new AppletAudioClip(uc);
|
||||
}
|
||||
}
|
||||
43
jdkSrc/jdk8/sun/net/www/content/audio/x_wav.java
Normal file
43
jdkSrc/jdk8/sun/net/www/content/audio/x_wav.java
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Basic .wav audio handler.
|
||||
* @author Jeff Nisewanger
|
||||
*/
|
||||
package sun.net.www.content.audio;
|
||||
|
||||
import java.net.*;
|
||||
import java.io.IOException;
|
||||
import sun.applet.AppletAudioClip;
|
||||
|
||||
/**
|
||||
* Returns an AppletAudioClip object.
|
||||
*/
|
||||
public class x_wav extends ContentHandler {
|
||||
public Object getContent(URLConnection uc) throws IOException {
|
||||
return new AppletAudioClip(uc);
|
||||
}
|
||||
}
|
||||
54
jdkSrc/jdk8/sun/net/www/content/image/gif.java
Normal file
54
jdkSrc/jdk8/sun/net/www/content/image/gif.java
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 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 sun.net.www.content.image;
|
||||
|
||||
import java.net.*;
|
||||
import sun.awt.image.*;
|
||||
import java.io.IOException;
|
||||
import java.awt.Image;
|
||||
import java.awt.Toolkit;
|
||||
|
||||
|
||||
public class gif extends ContentHandler {
|
||||
public Object getContent(URLConnection urlc) throws java.io.IOException {
|
||||
return new URLImageSource(urlc);
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public Object getContent(URLConnection urlc, Class[] classes) throws IOException {
|
||||
Class<?>[] cls = classes;
|
||||
for (int i = 0; i < cls.length; i++) {
|
||||
if (cls[i].isAssignableFrom(URLImageSource.class)) {
|
||||
return new URLImageSource(urlc);
|
||||
}
|
||||
if (cls[i].isAssignableFrom(Image.class)) {
|
||||
Toolkit tk = Toolkit.getDefaultToolkit();
|
||||
return tk.createImage(new URLImageSource(urlc));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
53
jdkSrc/jdk8/sun/net/www/content/image/jpeg.java
Normal file
53
jdkSrc/jdk8/sun/net/www/content/image/jpeg.java
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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 sun.net.www.content.image;
|
||||
|
||||
import java.net.*;
|
||||
import sun.awt.image.*;
|
||||
import java.io.IOException;
|
||||
import java.awt.Image;
|
||||
import java.awt.Toolkit;
|
||||
|
||||
public class jpeg extends ContentHandler {
|
||||
public Object getContent(URLConnection urlc) throws java.io.IOException {
|
||||
return new URLImageSource(urlc);
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public Object getContent(URLConnection urlc, Class[] classes) throws IOException {
|
||||
Class<?>[] cls = classes;
|
||||
for (int i = 0; i < cls.length; i++) {
|
||||
if (cls[i].isAssignableFrom(URLImageSource.class)) {
|
||||
return new URLImageSource(urlc);
|
||||
}
|
||||
if (cls[i].isAssignableFrom(Image.class)) {
|
||||
Toolkit tk = Toolkit.getDefaultToolkit();
|
||||
return tk.createImage(new URLImageSource(urlc));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
53
jdkSrc/jdk8/sun/net/www/content/image/png.java
Normal file
53
jdkSrc/jdk8/sun/net/www/content/image/png.java
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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 sun.net.www.content.image;
|
||||
|
||||
import java.net.*;
|
||||
import java.io.IOException;
|
||||
import sun.awt.image.*;
|
||||
import java.awt.Image;
|
||||
import java.awt.Toolkit;
|
||||
|
||||
public class png extends ContentHandler {
|
||||
public Object getContent(URLConnection urlc) throws java.io.IOException {
|
||||
return new URLImageSource(urlc);
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public Object getContent(URLConnection urlc, Class[] classes) throws IOException {
|
||||
Class<?>[] cls = classes;
|
||||
for (int i = 0; i < cls.length; i++) {
|
||||
if (cls[i].isAssignableFrom(URLImageSource.class)) {
|
||||
return new URLImageSource(urlc);
|
||||
}
|
||||
if (cls[i].isAssignableFrom(Image.class)) {
|
||||
Toolkit tk = Toolkit.getDefaultToolkit();
|
||||
return tk.createImage(new URLImageSource(urlc));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
52
jdkSrc/jdk8/sun/net/www/content/image/x_xbitmap.java
Normal file
52
jdkSrc/jdk8/sun/net/www/content/image/x_xbitmap.java
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 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 sun.net.www.content.image;
|
||||
|
||||
import java.net.*;
|
||||
import sun.awt.image.*;
|
||||
import java.awt.Image;
|
||||
import java.awt.Toolkit;
|
||||
|
||||
public class x_xbitmap extends ContentHandler {
|
||||
public Object getContent(URLConnection urlc) throws java.io.IOException {
|
||||
return new URLImageSource(urlc);
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public Object getContent(URLConnection urlc, Class[] classes) throws java.io.IOException {
|
||||
Class<?>[] cls = classes;
|
||||
for (int i = 0; i < cls.length; i++) {
|
||||
if (cls[i].isAssignableFrom(URLImageSource.class)) {
|
||||
return new URLImageSource(urlc);
|
||||
}
|
||||
if (cls[i].isAssignableFrom(Image.class)) {
|
||||
Toolkit tk = Toolkit.getDefaultToolkit();
|
||||
return tk.createImage(new URLImageSource(urlc));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
52
jdkSrc/jdk8/sun/net/www/content/image/x_xpixmap.java
Normal file
52
jdkSrc/jdk8/sun/net/www/content/image/x_xpixmap.java
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 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 sun.net.www.content.image;
|
||||
|
||||
import java.net.*;
|
||||
import sun.awt.image.*;
|
||||
import java.awt.Image;
|
||||
import java.awt.Toolkit;
|
||||
|
||||
public class x_xpixmap extends ContentHandler {
|
||||
public Object getContent(URLConnection urlc) throws java.io.IOException {
|
||||
return new URLImageSource(urlc);
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public Object getContent(URLConnection urlc, Class[] classes) throws java.io.IOException {
|
||||
Class<?>[] cls = classes;
|
||||
for (int i = 0; i < cls.length; i++) {
|
||||
if (cls[i].isAssignableFrom(URLImageSource.class)) {
|
||||
return new URLImageSource(urlc);
|
||||
}
|
||||
if (cls[i].isAssignableFrom(Image.class)) {
|
||||
Toolkit tk = Toolkit.getDefaultToolkit();
|
||||
return tk.createImage(new URLImageSource(urlc));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
33
jdkSrc/jdk8/sun/net/www/content/text/Generic.java
Normal file
33
jdkSrc/jdk8/sun/net/www/content/text/Generic.java
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 1995, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Generic text file handler
|
||||
*/
|
||||
package sun.net.www.content.text;
|
||||
|
||||
public class Generic extends plain {
|
||||
/* nothing to do since Generic is identical to plain! */
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 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 sun.net.www.content.text;
|
||||
import java.io.InputStream;
|
||||
import java.io.FilterInputStream;
|
||||
|
||||
/**
|
||||
* PlainTextInputStream class extends the FilterInputStream class.
|
||||
* Currently all calls to the PlainTextInputStream object will call
|
||||
* the corresponding methods in the FilterInputStream class. Hence
|
||||
* for now its use is more semantic.
|
||||
*
|
||||
* @author Sunita Mani
|
||||
*/
|
||||
public class PlainTextInputStream extends FilterInputStream {
|
||||
|
||||
/**
|
||||
* Calls FilterInputStream's constructor.
|
||||
* @param an InputStream
|
||||
*/
|
||||
PlainTextInputStream(InputStream is) {
|
||||
super(is);
|
||||
}
|
||||
}
|
||||
48
jdkSrc/jdk8/sun/net/www/content/text/plain.java
Normal file
48
jdkSrc/jdk8/sun/net/www/content/text/plain.java
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 1996, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Plain text file handler.
|
||||
* @author Steven B. Byrne
|
||||
*/
|
||||
package sun.net.www.content.text;
|
||||
import java.net.*;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class plain extends ContentHandler {
|
||||
/**
|
||||
* Returns a PlainTextInputStream object from which data
|
||||
* can be read.
|
||||
*/
|
||||
public Object getContent(URLConnection uc) {
|
||||
try {
|
||||
InputStream is = uc.getInputStream();
|
||||
return new PlainTextInputStream(uc.getInputStream());
|
||||
} catch (IOException e) {
|
||||
return "Error reading document:\n" + e.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
780
jdkSrc/jdk8/sun/net/www/http/ChunkedInputStream.java
Normal file
780
jdkSrc/jdk8/sun/net/www/http/ChunkedInputStream.java
Normal file
@@ -0,0 +1,780 @@
|
||||
/*
|
||||
* 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 sun.net.www.http;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
import sun.net.*;
|
||||
import sun.net.www.*;
|
||||
|
||||
/**
|
||||
* A <code>ChunkedInputStream</code> provides a stream for reading a body of
|
||||
* a http message that can be sent as a series of chunks, each with its own
|
||||
* size indicator. Optionally the last chunk can be followed by trailers
|
||||
* containing entity-header fields.
|
||||
* <p>
|
||||
* A <code>ChunkedInputStream</code> is also <code>Hurryable</code> so it
|
||||
* can be hurried to the end of the stream if the bytes are available on
|
||||
* the underlying stream.
|
||||
*/
|
||||
public
|
||||
class ChunkedInputStream extends InputStream implements Hurryable {
|
||||
|
||||
/**
|
||||
* The underlying stream
|
||||
*/
|
||||
private InputStream in;
|
||||
|
||||
/**
|
||||
* The <code>HttpClient</code> that should be notified when the chunked stream has
|
||||
* completed.
|
||||
*/
|
||||
private HttpClient hc;
|
||||
|
||||
/**
|
||||
* The <code>MessageHeader</code> that is populated with any optional trailer
|
||||
* that appear after the last chunk.
|
||||
*/
|
||||
private MessageHeader responses;
|
||||
|
||||
/**
|
||||
* The size, in bytes, of the chunk that is currently being read.
|
||||
* This size is only valid if the current position in the underlying
|
||||
* input stream is inside a chunk (ie: state == STATE_READING_CHUNK).
|
||||
*/
|
||||
private int chunkSize;
|
||||
|
||||
/**
|
||||
* The number of bytes read from the underlying stream for the current
|
||||
* chunk. This value is always in the range <code>0</code> through to
|
||||
* <code>chunkSize</code>
|
||||
*/
|
||||
private int chunkRead;
|
||||
|
||||
/**
|
||||
* The internal buffer array where chunk data is available for the
|
||||
* application to read.
|
||||
*/
|
||||
private byte chunkData[] = new byte[4096];
|
||||
|
||||
/**
|
||||
* The current position in the buffer. It contains the index
|
||||
* of the next byte to read from <code>chunkData</code>
|
||||
*/
|
||||
private int chunkPos;
|
||||
|
||||
/**
|
||||
* The index one greater than the index of the last valid byte in the
|
||||
* buffer. This value is always in the range <code>0</code> through
|
||||
* <code>chunkData.length</code>.
|
||||
*/
|
||||
private int chunkCount;
|
||||
|
||||
/**
|
||||
* The internal buffer where bytes from the underlying stream can be
|
||||
* read. It may contain bytes representing chunk-size, chunk-data, or
|
||||
* trailer fields.
|
||||
*/
|
||||
private byte rawData[] = new byte[32];
|
||||
|
||||
/**
|
||||
* The current position in the buffer. It contains the index
|
||||
* of the next byte to read from <code>rawData</code>
|
||||
*/
|
||||
private int rawPos;
|
||||
|
||||
/**
|
||||
* The index one greater than the index of the last valid byte in the
|
||||
* buffer. This value is always in the range <code>0</code> through
|
||||
* <code>rawData.length</code>.
|
||||
*/
|
||||
private int rawCount;
|
||||
|
||||
/**
|
||||
* Indicates if an error was encountered when processing the chunked
|
||||
* stream.
|
||||
*/
|
||||
private boolean error;
|
||||
|
||||
/**
|
||||
* Indicates if the chunked stream has been closed using the
|
||||
* <code>close</code> method.
|
||||
*/
|
||||
private boolean closed;
|
||||
|
||||
/*
|
||||
* Maximum chunk header size of 2KB + 2 bytes for CRLF
|
||||
*/
|
||||
private final static int MAX_CHUNK_HEADER_SIZE = 2050;
|
||||
|
||||
/**
|
||||
* State to indicate that next field should be :-
|
||||
* chunk-size [ chunk-extension ] CRLF
|
||||
*/
|
||||
static final int STATE_AWAITING_CHUNK_HEADER = 1;
|
||||
|
||||
/**
|
||||
* State to indicate that we are currently reading the chunk-data.
|
||||
*/
|
||||
static final int STATE_READING_CHUNK = 2;
|
||||
|
||||
/**
|
||||
* Indicates that a chunk has been completely read and the next
|
||||
* fields to be examine should be CRLF
|
||||
*/
|
||||
static final int STATE_AWAITING_CHUNK_EOL = 3;
|
||||
|
||||
/**
|
||||
* Indicates that all chunks have been read and the next field
|
||||
* should be optional trailers or an indication that the chunked
|
||||
* stream is complete.
|
||||
*/
|
||||
static final int STATE_AWAITING_TRAILERS = 4;
|
||||
|
||||
/**
|
||||
* State to indicate that the chunked stream is complete and
|
||||
* no further bytes should be read from the underlying stream.
|
||||
*/
|
||||
static final int STATE_DONE = 5;
|
||||
|
||||
/**
|
||||
* Indicates the current state.
|
||||
*/
|
||||
private int state;
|
||||
|
||||
|
||||
/**
|
||||
* Check to make sure that this stream has not been closed.
|
||||
*/
|
||||
private void ensureOpen() throws IOException {
|
||||
if (closed) {
|
||||
throw new IOException("stream is closed");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Ensures there is <code>size</code> bytes available in
|
||||
* <code>rawData</code>. This requires that we either
|
||||
* shift the bytes in use to the begining of the buffer
|
||||
* or allocate a large buffer with sufficient space available.
|
||||
*/
|
||||
private void ensureRawAvailable(int size) {
|
||||
if (rawCount + size > rawData.length) {
|
||||
int used = rawCount - rawPos;
|
||||
if (used + size > rawData.length) {
|
||||
byte tmp[] = new byte[used + size];
|
||||
if (used > 0) {
|
||||
System.arraycopy(rawData, rawPos, tmp, 0, used);
|
||||
}
|
||||
rawData = tmp;
|
||||
} else {
|
||||
if (used > 0) {
|
||||
System.arraycopy(rawData, rawPos, rawData, 0, used);
|
||||
}
|
||||
}
|
||||
rawCount = used;
|
||||
rawPos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Close the underlying input stream by either returning it to the
|
||||
* keep alive cache or closing the stream.
|
||||
* <p>
|
||||
* As a chunked stream is inheritly persistent (see HTTP 1.1 RFC) the
|
||||
* underlying stream can be returned to the keep alive cache if the
|
||||
* stream can be completely read without error.
|
||||
*/
|
||||
private void closeUnderlying() throws IOException {
|
||||
if (in == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!error && state == STATE_DONE) {
|
||||
hc.finished();
|
||||
} else {
|
||||
if (!hurry()) {
|
||||
hc.closeServer();
|
||||
}
|
||||
}
|
||||
|
||||
in = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to read the remainder of a chunk directly into the
|
||||
* caller's buffer.
|
||||
* <p>
|
||||
* Return the number of bytes read.
|
||||
*/
|
||||
private int fastRead(byte[] b, int off, int len) throws IOException {
|
||||
|
||||
// assert state == STATE_READING_CHUNKS;
|
||||
|
||||
int remaining = chunkSize - chunkRead;
|
||||
int cnt = (remaining < len) ? remaining : len;
|
||||
if (cnt > 0) {
|
||||
int nread;
|
||||
try {
|
||||
nread = in.read(b, off, cnt);
|
||||
} catch (IOException e) {
|
||||
error = true;
|
||||
throw e;
|
||||
}
|
||||
if (nread > 0) {
|
||||
chunkRead += nread;
|
||||
if (chunkRead >= chunkSize) {
|
||||
state = STATE_AWAITING_CHUNK_EOL;
|
||||
}
|
||||
return nread;
|
||||
}
|
||||
error = true;
|
||||
throw new IOException("Premature EOF");
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process any outstanding bytes that have already been read into
|
||||
* <code>rawData</code>.
|
||||
* <p>
|
||||
* The parsing of the chunked stream is performed as a state machine with
|
||||
* <code>state</code> representing the current state of the processing.
|
||||
* <p>
|
||||
* Returns when either all the outstanding bytes in rawData have been
|
||||
* processed or there is insufficient bytes available to continue
|
||||
* processing. When the latter occurs <code>rawPos</code> will not have
|
||||
* been updated and thus the processing can be restarted once further
|
||||
* bytes have been read into <code>rawData</code>.
|
||||
*/
|
||||
private void processRaw() throws IOException {
|
||||
int pos;
|
||||
int i;
|
||||
|
||||
while (state != STATE_DONE) {
|
||||
|
||||
switch (state) {
|
||||
|
||||
/**
|
||||
* We are awaiting a line with a chunk header
|
||||
*/
|
||||
case STATE_AWAITING_CHUNK_HEADER:
|
||||
/*
|
||||
* Find \n to indicate end of chunk header. If not found when there is
|
||||
* insufficient bytes in the raw buffer to parse a chunk header.
|
||||
*/
|
||||
pos = rawPos;
|
||||
while (pos < rawCount) {
|
||||
if (rawData[pos] == '\n') {
|
||||
break;
|
||||
}
|
||||
pos++;
|
||||
if ((pos - rawPos) >= MAX_CHUNK_HEADER_SIZE) {
|
||||
error = true;
|
||||
throw new IOException("Chunk header too long");
|
||||
}
|
||||
}
|
||||
if (pos >= rawCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Extract the chunk size from the header (ignoring extensions).
|
||||
*/
|
||||
String header = new String(rawData, rawPos, pos-rawPos+1, "US-ASCII");
|
||||
for (i=0; i < header.length(); i++) {
|
||||
if (Character.digit(header.charAt(i), 16) == -1)
|
||||
break;
|
||||
}
|
||||
try {
|
||||
chunkSize = Integer.parseInt(header.substring(0, i), 16);
|
||||
} catch (NumberFormatException e) {
|
||||
error = true;
|
||||
throw new IOException("Bogus chunk size");
|
||||
}
|
||||
|
||||
/*
|
||||
* Chunk has been parsed so move rawPos to first byte of chunk
|
||||
* data.
|
||||
*/
|
||||
rawPos = pos + 1;
|
||||
chunkRead = 0;
|
||||
|
||||
/*
|
||||
* A chunk size of 0 means EOF.
|
||||
*/
|
||||
if (chunkSize > 0) {
|
||||
state = STATE_READING_CHUNK;
|
||||
} else {
|
||||
state = STATE_AWAITING_TRAILERS;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
/**
|
||||
* We are awaiting raw entity data (some may have already been
|
||||
* read). chunkSize is the size of the chunk; chunkRead is the
|
||||
* total read from the underlying stream to date.
|
||||
*/
|
||||
case STATE_READING_CHUNK :
|
||||
/* no data available yet */
|
||||
if (rawPos >= rawCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute the number of bytes of chunk data available in the
|
||||
* raw buffer.
|
||||
*/
|
||||
int copyLen = Math.min( chunkSize-chunkRead, rawCount-rawPos );
|
||||
|
||||
/*
|
||||
* Expand or compact chunkData if needed.
|
||||
*/
|
||||
if (chunkData.length < chunkCount + copyLen) {
|
||||
int cnt = chunkCount - chunkPos;
|
||||
if (chunkData.length < cnt + copyLen) {
|
||||
byte tmp[] = new byte[cnt + copyLen];
|
||||
System.arraycopy(chunkData, chunkPos, tmp, 0, cnt);
|
||||
chunkData = tmp;
|
||||
} else {
|
||||
System.arraycopy(chunkData, chunkPos, chunkData, 0, cnt);
|
||||
}
|
||||
chunkPos = 0;
|
||||
chunkCount = cnt;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy the chunk data into chunkData so that it's available
|
||||
* to the read methods.
|
||||
*/
|
||||
System.arraycopy(rawData, rawPos, chunkData, chunkCount, copyLen);
|
||||
rawPos += copyLen;
|
||||
chunkCount += copyLen;
|
||||
chunkRead += copyLen;
|
||||
|
||||
/*
|
||||
* If all the chunk has been copied into chunkData then the next
|
||||
* token should be CRLF.
|
||||
*/
|
||||
if (chunkSize - chunkRead <= 0) {
|
||||
state = STATE_AWAITING_CHUNK_EOL;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
/**
|
||||
* Awaiting CRLF after the chunk
|
||||
*/
|
||||
case STATE_AWAITING_CHUNK_EOL:
|
||||
/* not available yet */
|
||||
if (rawPos + 1 >= rawCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (rawData[rawPos] != '\r') {
|
||||
error = true;
|
||||
throw new IOException("missing CR");
|
||||
}
|
||||
if (rawData[rawPos+1] != '\n') {
|
||||
error = true;
|
||||
throw new IOException("missing LF");
|
||||
}
|
||||
rawPos += 2;
|
||||
|
||||
/*
|
||||
* Move onto the next chunk
|
||||
*/
|
||||
state = STATE_AWAITING_CHUNK_HEADER;
|
||||
break;
|
||||
|
||||
|
||||
/**
|
||||
* Last chunk has been read so not we're waiting for optional
|
||||
* trailers.
|
||||
*/
|
||||
case STATE_AWAITING_TRAILERS:
|
||||
|
||||
/*
|
||||
* Do we have an entire line in the raw buffer?
|
||||
*/
|
||||
pos = rawPos;
|
||||
while (pos < rawCount) {
|
||||
if (rawData[pos] == '\n') {
|
||||
break;
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
if (pos >= rawCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pos == rawPos) {
|
||||
error = true;
|
||||
throw new IOException("LF should be proceeded by CR");
|
||||
}
|
||||
if (rawData[pos-1] != '\r') {
|
||||
error = true;
|
||||
throw new IOException("LF should be proceeded by CR");
|
||||
}
|
||||
|
||||
/*
|
||||
* Stream done so close underlying stream.
|
||||
*/
|
||||
if (pos == (rawPos + 1)) {
|
||||
|
||||
state = STATE_DONE;
|
||||
closeUnderlying();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Extract any tailers and append them to the message
|
||||
* headers.
|
||||
*/
|
||||
String trailer = new String(rawData, rawPos, pos-rawPos, "US-ASCII");
|
||||
i = trailer.indexOf(':');
|
||||
if (i == -1) {
|
||||
throw new IOException("Malformed tailer - format should be key:value");
|
||||
}
|
||||
String key = (trailer.substring(0, i)).trim();
|
||||
String value = (trailer.substring(i+1, trailer.length())).trim();
|
||||
|
||||
responses.add(key, value);
|
||||
|
||||
/*
|
||||
* Move onto the next trailer.
|
||||
*/
|
||||
rawPos = pos+1;
|
||||
break;
|
||||
|
||||
} /* switch */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads any available bytes from the underlying stream into
|
||||
* <code>rawData</code> and returns the number of bytes of
|
||||
* chunk data available in <code>chunkData</code> that the
|
||||
* application can read.
|
||||
*/
|
||||
private int readAheadNonBlocking() throws IOException {
|
||||
|
||||
/*
|
||||
* If there's anything available on the underlying stream then we read
|
||||
* it into the raw buffer and process it. Processing ensures that any
|
||||
* available chunk data is made available in chunkData.
|
||||
*/
|
||||
int avail = in.available();
|
||||
if (avail > 0) {
|
||||
|
||||
/* ensure that there is space in rawData to read the available */
|
||||
ensureRawAvailable(avail);
|
||||
|
||||
int nread;
|
||||
try {
|
||||
nread = in.read(rawData, rawCount, avail);
|
||||
} catch (IOException e) {
|
||||
error = true;
|
||||
throw e;
|
||||
}
|
||||
if (nread < 0) {
|
||||
error = true; /* premature EOF ? */
|
||||
return -1;
|
||||
}
|
||||
rawCount += nread;
|
||||
|
||||
/*
|
||||
* Process the raw bytes that have been read.
|
||||
*/
|
||||
processRaw();
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the number of chunked bytes available to read
|
||||
*/
|
||||
return chunkCount - chunkPos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads from the underlying stream until there is chunk data
|
||||
* available in <code>chunkData</code> for the application to
|
||||
* read.
|
||||
*/
|
||||
private int readAheadBlocking() throws IOException {
|
||||
|
||||
do {
|
||||
/*
|
||||
* All of chunked response has been read to return EOF.
|
||||
*/
|
||||
if (state == STATE_DONE) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* We must read into the raw buffer so make sure there is space
|
||||
* available. We use a size of 32 to avoid too much chunk data
|
||||
* being read into the raw buffer.
|
||||
*/
|
||||
ensureRawAvailable(32);
|
||||
int nread;
|
||||
try {
|
||||
nread = in.read(rawData, rawCount, rawData.length-rawCount);
|
||||
} catch (IOException e) {
|
||||
error = true;
|
||||
throw e;
|
||||
}
|
||||
|
||||
/**
|
||||
* If we hit EOF it means there's a problem as we should never
|
||||
* attempt to read once the last chunk and trailers have been
|
||||
* received.
|
||||
*/
|
||||
if (nread < 0) {
|
||||
error = true;
|
||||
throw new IOException("Premature EOF");
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the bytes from the underlying stream
|
||||
*/
|
||||
rawCount += nread;
|
||||
processRaw();
|
||||
|
||||
} while (chunkCount <= 0);
|
||||
|
||||
/*
|
||||
* Return the number of chunked bytes available to read
|
||||
*/
|
||||
return chunkCount - chunkPos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read ahead in either blocking or non-blocking mode. This method
|
||||
* is typically used when we run out of available bytes in
|
||||
* <code>chunkData</code> or we need to determine how many bytes
|
||||
* are available on the input stream.
|
||||
*/
|
||||
private int readAhead(boolean allowBlocking) throws IOException {
|
||||
|
||||
/*
|
||||
* Last chunk already received - return EOF
|
||||
*/
|
||||
if (state == STATE_DONE) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset position/count if data in chunkData is exhausted.
|
||||
*/
|
||||
if (chunkPos >= chunkCount) {
|
||||
chunkCount = 0;
|
||||
chunkPos = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read ahead blocking or non-blocking
|
||||
*/
|
||||
if (allowBlocking) {
|
||||
return readAheadBlocking();
|
||||
} else {
|
||||
return readAheadNonBlocking();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a <code>ChunkedInputStream</code> and saves its arguments, for
|
||||
* later use.
|
||||
*
|
||||
* @param in the underlying input stream.
|
||||
* @param hc the HttpClient
|
||||
* @param responses the MessageHeader that should be populated with optional
|
||||
* trailers.
|
||||
*/
|
||||
public ChunkedInputStream(InputStream in, HttpClient hc, MessageHeader responses) throws IOException {
|
||||
|
||||
/* save arguments */
|
||||
this.in = in;
|
||||
this.responses = responses;
|
||||
this.hc = hc;
|
||||
|
||||
/*
|
||||
* Set our initial state to indicate that we are first starting to
|
||||
* look for a chunk header.
|
||||
*/
|
||||
state = STATE_AWAITING_CHUNK_HEADER;
|
||||
}
|
||||
|
||||
/**
|
||||
* See
|
||||
* the general contract of the <code>read</code>
|
||||
* method of <code>InputStream</code>.
|
||||
*
|
||||
* @return the next byte of data, or <code>-1</code> if the end of the
|
||||
* stream is reached.
|
||||
* @exception IOException if an I/O error occurs.
|
||||
* @see java.io.FilterInputStream#in
|
||||
*/
|
||||
public synchronized int read() throws IOException {
|
||||
ensureOpen();
|
||||
if (chunkPos >= chunkCount) {
|
||||
if (readAhead(true) <= 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return chunkData[chunkPos++] & 0xff;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads bytes from this stream into the specified byte array, starting at
|
||||
* the given offset.
|
||||
*
|
||||
* @param b destination buffer.
|
||||
* @param off offset at which to start storing bytes.
|
||||
* @param len maximum number of bytes to read.
|
||||
* @return the number of bytes read, or <code>-1</code> if the end of
|
||||
* the stream has been reached.
|
||||
* @exception IOException if an I/O error occurs.
|
||||
*/
|
||||
public synchronized int read(byte b[], int off, int len)
|
||||
throws IOException
|
||||
{
|
||||
ensureOpen();
|
||||
if ((off < 0) || (off > b.length) || (len < 0) ||
|
||||
((off + len) > b.length) || ((off + len) < 0)) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
} else if (len == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int avail = chunkCount - chunkPos;
|
||||
if (avail <= 0) {
|
||||
/*
|
||||
* Optimization: if we're in the middle of the chunk read
|
||||
* directly from the underlying stream into the caller's
|
||||
* buffer
|
||||
*/
|
||||
if (state == STATE_READING_CHUNK) {
|
||||
return fastRead( b, off, len );
|
||||
}
|
||||
|
||||
/*
|
||||
* We're not in the middle of a chunk so we must read ahead
|
||||
* until there is some chunk data available.
|
||||
*/
|
||||
avail = readAhead(true);
|
||||
if (avail < 0) {
|
||||
return -1; /* EOF */
|
||||
}
|
||||
}
|
||||
int cnt = (avail < len) ? avail : len;
|
||||
System.arraycopy(chunkData, chunkPos, b, off, cnt);
|
||||
chunkPos += cnt;
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of bytes that can be read from this input
|
||||
* stream without blocking.
|
||||
*
|
||||
* @return the number of bytes that can be read from this input
|
||||
* stream without blocking.
|
||||
* @exception IOException if an I/O error occurs.
|
||||
* @see java.io.FilterInputStream#in
|
||||
*/
|
||||
public synchronized int available() throws IOException {
|
||||
ensureOpen();
|
||||
|
||||
int avail = chunkCount - chunkPos;
|
||||
if(avail > 0) {
|
||||
return avail;
|
||||
}
|
||||
|
||||
avail = readAhead(false);
|
||||
|
||||
if (avail < 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return avail;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the stream by either returning the connection to the
|
||||
* keep alive cache or closing the underlying stream.
|
||||
* <p>
|
||||
* If the chunked response hasn't been completely read we
|
||||
* try to "hurry" to the end of the response. If this is
|
||||
* possible (without blocking) then the connection can be
|
||||
* returned to the keep alive cache.
|
||||
*
|
||||
* @exception IOException if an I/O error occurs.
|
||||
*/
|
||||
public synchronized void close() throws IOException {
|
||||
if (closed) {
|
||||
return;
|
||||
}
|
||||
closeUnderlying();
|
||||
closed = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hurry the input stream by reading everything from the underlying
|
||||
* stream. If the last chunk (and optional trailers) can be read without
|
||||
* blocking then the stream is considered hurried.
|
||||
* <p>
|
||||
* Note that if an error has occurred or we can't get to last chunk
|
||||
* without blocking then this stream can't be hurried and should be
|
||||
* closed.
|
||||
*/
|
||||
public synchronized boolean hurry() {
|
||||
if (in == null || error) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
readAhead(false);
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (state == STATE_DONE);
|
||||
}
|
||||
|
||||
}
|
||||
300
jdkSrc/jdk8/sun/net/www/http/ChunkedOutputStream.java
Normal file
300
jdkSrc/jdk8/sun/net/www/http/ChunkedOutputStream.java
Normal file
@@ -0,0 +1,300 @@
|
||||
/*
|
||||
* 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 sun.net.www.http;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* OutputStream that sends the output to the underlying stream using chunked
|
||||
* encoding as specified in RFC 2068.
|
||||
*/
|
||||
public class ChunkedOutputStream extends PrintStream {
|
||||
|
||||
/* Default chunk size (including chunk header) if not specified */
|
||||
static final int DEFAULT_CHUNK_SIZE = 4096;
|
||||
private static final byte[] CRLF = {'\r', '\n'};
|
||||
private static final int CRLF_SIZE = CRLF.length;
|
||||
private static final byte[] FOOTER = CRLF;
|
||||
private static final int FOOTER_SIZE = CRLF_SIZE;
|
||||
private static final byte[] EMPTY_CHUNK_HEADER = getHeader(0);
|
||||
private static final int EMPTY_CHUNK_HEADER_SIZE = getHeaderSize(0);
|
||||
|
||||
/* internal buffer */
|
||||
private byte buf[];
|
||||
/* size of data (excluding footers and headers) already stored in buf */
|
||||
private int size;
|
||||
/* current index in buf (i.e. buf[count] */
|
||||
private int count;
|
||||
/* number of bytes to be filled up to complete a data chunk
|
||||
* currently being built */
|
||||
private int spaceInCurrentChunk;
|
||||
|
||||
/* underlying stream */
|
||||
private PrintStream out;
|
||||
|
||||
/* the chunk size we use */
|
||||
private int preferredChunkDataSize;
|
||||
private int preferedHeaderSize;
|
||||
private int preferredChunkGrossSize;
|
||||
/* header for a complete Chunk */
|
||||
private byte[] completeHeader;
|
||||
|
||||
/* return the size of the header for a particular chunk size */
|
||||
private static int getHeaderSize(int size) {
|
||||
return (Integer.toHexString(size)).length() + CRLF_SIZE;
|
||||
}
|
||||
|
||||
/* return a header for a particular chunk size */
|
||||
private static byte[] getHeader(int size){
|
||||
try {
|
||||
String hexStr = Integer.toHexString(size);
|
||||
byte[] hexBytes = hexStr.getBytes("US-ASCII");
|
||||
byte[] header = new byte[getHeaderSize(size)];
|
||||
for (int i=0; i<hexBytes.length; i++)
|
||||
header[i] = hexBytes[i];
|
||||
header[hexBytes.length] = CRLF[0];
|
||||
header[hexBytes.length+1] = CRLF[1];
|
||||
return header;
|
||||
} catch (java.io.UnsupportedEncodingException e) {
|
||||
/* This should never happen */
|
||||
throw new InternalError(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public ChunkedOutputStream(PrintStream o) {
|
||||
this(o, DEFAULT_CHUNK_SIZE);
|
||||
}
|
||||
|
||||
public ChunkedOutputStream(PrintStream o, int size) {
|
||||
super(o);
|
||||
out = o;
|
||||
|
||||
if (size <= 0) {
|
||||
size = DEFAULT_CHUNK_SIZE;
|
||||
}
|
||||
|
||||
/* Adjust the size to cater for the chunk header - eg: if the
|
||||
* preferred chunk size is 1k this means the chunk size should
|
||||
* be 1017 bytes (differs by 7 from preferred size because of
|
||||
* 3 bytes for chunk size in hex and CRLF (header) and CRLF (footer)).
|
||||
*
|
||||
* If headerSize(adjusted_size) is shorter then headerSize(size)
|
||||
* then try to use the extra byte unless headerSize(adjusted_size+1)
|
||||
* increases back to headerSize(size)
|
||||
*/
|
||||
if (size > 0) {
|
||||
int adjusted_size = size - getHeaderSize(size) - FOOTER_SIZE;
|
||||
if (getHeaderSize(adjusted_size+1) < getHeaderSize(size)){
|
||||
adjusted_size++;
|
||||
}
|
||||
size = adjusted_size;
|
||||
}
|
||||
|
||||
if (size > 0) {
|
||||
preferredChunkDataSize = size;
|
||||
} else {
|
||||
preferredChunkDataSize = DEFAULT_CHUNK_SIZE -
|
||||
getHeaderSize(DEFAULT_CHUNK_SIZE) - FOOTER_SIZE;
|
||||
}
|
||||
|
||||
preferedHeaderSize = getHeaderSize(preferredChunkDataSize);
|
||||
preferredChunkGrossSize = preferedHeaderSize + preferredChunkDataSize
|
||||
+ FOOTER_SIZE;
|
||||
completeHeader = getHeader(preferredChunkDataSize);
|
||||
|
||||
/* start with an initial buffer */
|
||||
buf = new byte[preferredChunkGrossSize];
|
||||
reset();
|
||||
}
|
||||
|
||||
/*
|
||||
* Flush a buffered, completed chunk to an underlying stream. If the data in
|
||||
* the buffer is insufficient to build up a chunk of "preferredChunkSize"
|
||||
* then the data do not get flushed unless flushAll is true. If flushAll is
|
||||
* true then the remaining data builds up a last chunk which size is smaller
|
||||
* than preferredChunkSize, and then the last chunk gets flushed to
|
||||
* underlying stream. If flushAll is true and there is no data in a buffer
|
||||
* at all then an empty chunk (containing a header only) gets flushed to
|
||||
* underlying stream.
|
||||
*/
|
||||
private void flush(boolean flushAll) {
|
||||
if (spaceInCurrentChunk == 0) {
|
||||
/* flush a completed chunk to underlying stream */
|
||||
out.write(buf, 0, preferredChunkGrossSize);
|
||||
out.flush();
|
||||
reset();
|
||||
} else if (flushAll){
|
||||
/* complete the last chunk and flush it to underlying stream */
|
||||
if (size > 0){
|
||||
/* adjust a header start index in case the header of the last
|
||||
* chunk is shorter then preferedHeaderSize */
|
||||
|
||||
int adjustedHeaderStartIndex = preferedHeaderSize -
|
||||
getHeaderSize(size);
|
||||
|
||||
/* write header */
|
||||
System.arraycopy(getHeader(size), 0, buf,
|
||||
adjustedHeaderStartIndex, getHeaderSize(size));
|
||||
|
||||
/* write footer */
|
||||
buf[count++] = FOOTER[0];
|
||||
buf[count++] = FOOTER[1];
|
||||
|
||||
//send the last chunk to underlying stream
|
||||
out.write(buf, adjustedHeaderStartIndex, count - adjustedHeaderStartIndex);
|
||||
} else {
|
||||
//send an empty chunk (containing just a header) to underlying stream
|
||||
out.write(EMPTY_CHUNK_HEADER, 0, EMPTY_CHUNK_HEADER_SIZE);
|
||||
}
|
||||
|
||||
out.flush();
|
||||
reset();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkError() {
|
||||
return out.checkError();
|
||||
}
|
||||
|
||||
/* Check that the output stream is still open */
|
||||
private void ensureOpen() {
|
||||
if (out == null)
|
||||
setError();
|
||||
}
|
||||
|
||||
/*
|
||||
* Writes data from b[] to an internal buffer and stores the data as data
|
||||
* chunks of a following format: {Data length in Hex}{CRLF}{data}{CRLF}
|
||||
* The size of the data is preferredChunkSize. As soon as a completed chunk
|
||||
* is read from b[] a process of reading from b[] suspends, the chunk gets
|
||||
* flushed to the underlying stream and then the reading process from b[]
|
||||
* continues. When there is no more sufficient data in b[] to build up a
|
||||
* chunk of preferredChunkSize size the data get stored as an incomplete
|
||||
* chunk of a following format: {space for data length}{CRLF}{data}
|
||||
* The size of the data is of course smaller than preferredChunkSize.
|
||||
*/
|
||||
@Override
|
||||
public synchronized void write(byte b[], int off, int len) {
|
||||
ensureOpen();
|
||||
if ((off < 0) || (off > b.length) || (len < 0) ||
|
||||
((off + len) > b.length) || ((off + len) < 0)) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
} else if (len == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* if b[] contains enough data then one loop cycle creates one complete
|
||||
* data chunk with a header, body and a footer, and then flushes the
|
||||
* chunk to the underlying stream. Otherwise, the last loop cycle
|
||||
* creates incomplete data chunk with empty header and with no footer
|
||||
* and stores this incomplete chunk in an internal buffer buf[]
|
||||
*/
|
||||
int bytesToWrite = len;
|
||||
int inputIndex = off; /* the index of the byte[] currently being written */
|
||||
|
||||
do {
|
||||
/* enough data to complete a chunk */
|
||||
if (bytesToWrite >= spaceInCurrentChunk) {
|
||||
|
||||
/* header */
|
||||
for (int i=0; i<completeHeader.length; i++)
|
||||
buf[i] = completeHeader[i];
|
||||
|
||||
/* data */
|
||||
System.arraycopy(b, inputIndex, buf, count, spaceInCurrentChunk);
|
||||
inputIndex += spaceInCurrentChunk;
|
||||
bytesToWrite -= spaceInCurrentChunk;
|
||||
count += spaceInCurrentChunk;
|
||||
|
||||
/* footer */
|
||||
buf[count++] = FOOTER[0];
|
||||
buf[count++] = FOOTER[1];
|
||||
spaceInCurrentChunk = 0; //chunk is complete
|
||||
|
||||
flush(false);
|
||||
if (checkError()){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* not enough data to build a chunk */
|
||||
else {
|
||||
/* header */
|
||||
/* do not write header if not enough bytes to build a chunk yet */
|
||||
|
||||
/* data */
|
||||
System.arraycopy(b, inputIndex, buf, count, bytesToWrite);
|
||||
count += bytesToWrite;
|
||||
size += bytesToWrite;
|
||||
spaceInCurrentChunk -= bytesToWrite;
|
||||
bytesToWrite = 0;
|
||||
|
||||
/* footer */
|
||||
/* do not write header if not enough bytes to build a chunk yet */
|
||||
}
|
||||
} while (bytesToWrite > 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void write(int _b) {
|
||||
byte b[] = {(byte)_b};
|
||||
write(b, 0, 1);
|
||||
}
|
||||
|
||||
public synchronized void reset() {
|
||||
count = preferedHeaderSize;
|
||||
size = 0;
|
||||
spaceInCurrentChunk = preferredChunkDataSize;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void close() {
|
||||
ensureOpen();
|
||||
|
||||
/* if we have buffer a chunked send it */
|
||||
if (size > 0) {
|
||||
flush(true);
|
||||
}
|
||||
|
||||
/* send a zero length chunk */
|
||||
flush(true);
|
||||
|
||||
/* don't close the underlying stream */
|
||||
out = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void flush() {
|
||||
ensureOpen();
|
||||
if (size > 0) {
|
||||
flush(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user