6893702: Overhaul of Ftp Client internal code
Major reorg of internal FTP client code Reviewed-by: chegar
This commit is contained in:
parent
48792ee40c
commit
196a0c5cf8
@ -45,8 +45,14 @@ FILES_java = \
|
|||||||
sun/net/dns/ResolverConfiguration.java \
|
sun/net/dns/ResolverConfiguration.java \
|
||||||
sun/net/dns/ResolverConfigurationImpl.java \
|
sun/net/dns/ResolverConfigurationImpl.java \
|
||||||
sun/net/ftp/FtpClient.java \
|
sun/net/ftp/FtpClient.java \
|
||||||
|
sun/net/ftp/FtpClientProvider.java \
|
||||||
|
sun/net/ftp/FtpDirEntry.java \
|
||||||
|
sun/net/ftp/FtpReplyCode.java \
|
||||||
|
sun/net/ftp/FtpDirParser.java \
|
||||||
sun/net/ftp/FtpLoginException.java \
|
sun/net/ftp/FtpLoginException.java \
|
||||||
sun/net/ftp/FtpProtocolException.java \
|
sun/net/ftp/FtpProtocolException.java \
|
||||||
|
sun/net/ftp/impl/FtpClient.java \
|
||||||
|
sun/net/ftp/impl/DefaultFtpClientProvider.java \
|
||||||
sun/net/spi/DefaultProxySelector.java \
|
sun/net/spi/DefaultProxySelector.java \
|
||||||
sun/net/spi/nameservice/NameServiceDescriptor.java \
|
sun/net/spi/nameservice/NameServiceDescriptor.java \
|
||||||
sun/net/spi/nameservice/NameService.java \
|
sun/net/spi/nameservice/NameService.java \
|
||||||
|
File diff suppressed because it is too large
Load Diff
158
jdk/src/share/classes/sun/net/ftp/FtpClientProvider.java
Normal file
158
jdk/src/share/classes/sun/net/ftp/FtpClientProvider.java
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||||
|
* CA 95054 USA or visit www.sun.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 sun.misc.Service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 x) {
|
||||||
|
throw new ServiceConfigurationError(x.toString());
|
||||||
|
} catch (IllegalAccessException x) {
|
||||||
|
throw new ServiceConfigurationError(x.toString());
|
||||||
|
} catch (InstantiationException x) {
|
||||||
|
throw new ServiceConfigurationError(x.toString());
|
||||||
|
} catch (SecurityException x) {
|
||||||
|
throw new ServiceConfigurationError(x.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean loadProviderAsService() {
|
||||||
|
// Iterator i = Service.providers(FtpClientProvider.class,
|
||||||
|
// ClassLoader.getSystemClassLoader());
|
||||||
|
// while (i.hasNext()) {
|
||||||
|
// try {
|
||||||
|
// provider = (FtpClientProvider) 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
jdk/src/share/classes/sun/net/ftp/FtpDirEntry.java
Normal file
331
jdk/src/share/classes/sun/net/ftp/FtpDirEntry.java
Normal file
@ -0,0 +1,331 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||||
|
* CA 95054 USA or visit www.sun.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
jdk/src/share/classes/sun/net/ftp/FtpDirParser.java
Normal file
49
jdk/src/share/classes/sun/net/ftp/FtpDirParser.java
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||||
|
* CA 95054 USA or visit www.sun.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);
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 1994-2008 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 1994-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
package sun.net.ftp;
|
package sun.net.ftp;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This exception is thrown when an error is encountered during an
|
* This exception is thrown when an error is encountered during an
|
||||||
@ -33,10 +33,10 @@ import java.io.*;
|
|||||||
*
|
*
|
||||||
* @author Jonathan Payne
|
* @author Jonathan Payne
|
||||||
*/
|
*/
|
||||||
public class FtpLoginException extends FtpProtocolException {
|
public class FtpLoginException extends IOException {
|
||||||
private static final long serialVersionUID = 2218162403237941536L;
|
private static final long serialVersionUID = 2218162403237941536L;
|
||||||
|
|
||||||
FtpLoginException(String s) {
|
public FtpLoginException(String s) {
|
||||||
super(s);
|
super(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 1994-2008 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 1994-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -22,21 +22,49 @@
|
|||||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||||
* have any questions.
|
* have any questions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package sun.net.ftp;
|
package sun.net.ftp;
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This exeception is thrown when unexpected results are returned during
|
* Thrown to indicate that the FTP server reported an error.
|
||||||
* an FTP session.
|
* 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
|
* @author Jonathan Payne
|
||||||
*/
|
*/
|
||||||
public class FtpProtocolException extends IOException {
|
public class FtpProtocolException extends Exception {
|
||||||
private static final long serialVersionUID = 5978077070276545054L;
|
private static final long serialVersionUID = 5978077070276545054L;
|
||||||
|
private final FtpReplyCode code;
|
||||||
|
|
||||||
FtpProtocolException(String s) {
|
/**
|
||||||
super(s);
|
* 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
jdk/src/share/classes/sun/net/ftp/FtpReplyCode.java
Normal file
248
jdk/src/share/classes/sun/net/ftp/FtpReplyCode.java
Normal file
@ -0,0 +1,248 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||||
|
* CA 95054 USA or visit www.sun.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;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||||
|
* CA 95054 USA or visit www.sun.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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
2191
jdk/src/share/classes/sun/net/ftp/impl/FtpClient.java
Normal file
2191
jdk/src/share/classes/sun/net/ftp/impl/FtpClient.java
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 1994-2008 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 1994-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -37,10 +37,8 @@ import java.io.FilterInputStream;
|
|||||||
import java.io.FilterOutputStream;
|
import java.io.FilterOutputStream;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLStreamHandler;
|
|
||||||
import java.net.SocketPermission;
|
import java.net.SocketPermission;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.net.MalformedURLException;
|
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.Proxy;
|
import java.net.Proxy;
|
||||||
@ -84,7 +82,6 @@ public class FtpURLConnection extends URLConnection {
|
|||||||
// In case we have to use proxies, we use HttpURLConnection
|
// In case we have to use proxies, we use HttpURLConnection
|
||||||
HttpURLConnection http = null;
|
HttpURLConnection http = null;
|
||||||
private Proxy instProxy;
|
private Proxy instProxy;
|
||||||
Proxy proxy = null;
|
|
||||||
|
|
||||||
InputStream is = null;
|
InputStream is = null;
|
||||||
OutputStream os = null;
|
OutputStream os = null;
|
||||||
@ -125,12 +122,11 @@ public class FtpURLConnection extends URLConnection {
|
|||||||
ftp = cl;
|
ftp = cl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
super.close();
|
super.close();
|
||||||
try {
|
if (ftp != null) {
|
||||||
if (ftp != null)
|
ftp.close();
|
||||||
ftp.closeServer();
|
|
||||||
} catch (IOException ex) {
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -149,12 +145,11 @@ public class FtpURLConnection extends URLConnection {
|
|||||||
ftp = cl;
|
ftp = cl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
super.close();
|
super.close();
|
||||||
try {
|
if (ftp != null) {
|
||||||
if (ftp != null)
|
ftp.close();
|
||||||
ftp.closeServer();
|
|
||||||
} catch (IOException ex) {
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -192,10 +187,12 @@ public class FtpURLConnection extends URLConnection {
|
|||||||
|
|
||||||
private void setTimeouts() {
|
private void setTimeouts() {
|
||||||
if (ftp != null) {
|
if (ftp != null) {
|
||||||
if (connectTimeout >= 0)
|
if (connectTimeout >= 0) {
|
||||||
ftp.setConnectTimeout(connectTimeout);
|
ftp.setConnectTimeout(connectTimeout);
|
||||||
if (readTimeout >= 0)
|
}
|
||||||
|
if (readTimeout >= 0) {
|
||||||
ftp.setReadTimeout(readTimeout);
|
ftp.setReadTimeout(readTimeout);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,21 +215,22 @@ public class FtpURLConnection extends URLConnection {
|
|||||||
* Do we have to use a proxy?
|
* Do we have to use a proxy?
|
||||||
*/
|
*/
|
||||||
ProxySelector sel = java.security.AccessController.doPrivileged(
|
ProxySelector sel = java.security.AccessController.doPrivileged(
|
||||||
new java.security.PrivilegedAction<ProxySelector>() {
|
new java.security.PrivilegedAction<ProxySelector>() {
|
||||||
public ProxySelector run() {
|
public ProxySelector run() {
|
||||||
return ProxySelector.getDefault();
|
return ProxySelector.getDefault();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (sel != null) {
|
if (sel != null) {
|
||||||
URI uri = sun.net.www.ParseUtil.toURI(url);
|
URI uri = sun.net.www.ParseUtil.toURI(url);
|
||||||
Iterator<Proxy> it = sel.select(uri).iterator();
|
Iterator<Proxy> it = sel.select(uri).iterator();
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
p = it.next();
|
p = it.next();
|
||||||
if (p == null || p == Proxy.NO_PROXY ||
|
if (p == null || p == Proxy.NO_PROXY ||
|
||||||
p.type() == Proxy.Type.SOCKS)
|
p.type() == Proxy.Type.SOCKS) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
if (p.type() != Proxy.Type.HTTP ||
|
if (p.type() != Proxy.Type.HTTP ||
|
||||||
!(p.address() instanceof InetSocketAddress)) {
|
!(p.address() instanceof InetSocketAddress)) {
|
||||||
sel.connectFailed(uri, p.address(), new IOException("Wrong proxy type"));
|
sel.connectFailed(uri, p.address(), new IOException("Wrong proxy type"));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -240,10 +238,14 @@ public class FtpURLConnection extends URLConnection {
|
|||||||
InetSocketAddress paddr = (InetSocketAddress) p.address();
|
InetSocketAddress paddr = (InetSocketAddress) p.address();
|
||||||
try {
|
try {
|
||||||
http = new HttpURLConnection(url, p);
|
http = new HttpURLConnection(url, p);
|
||||||
if (connectTimeout >= 0)
|
http.setDoInput(getDoInput());
|
||||||
|
http.setDoOutput(getDoOutput());
|
||||||
|
if (connectTimeout >= 0) {
|
||||||
http.setConnectTimeout(connectTimeout);
|
http.setConnectTimeout(connectTimeout);
|
||||||
if (readTimeout >= 0)
|
}
|
||||||
|
if (readTimeout >= 0) {
|
||||||
http.setReadTimeout(readTimeout);
|
http.setReadTimeout(readTimeout);
|
||||||
|
}
|
||||||
http.connect();
|
http.connect();
|
||||||
connected = true;
|
connected = true;
|
||||||
return;
|
return;
|
||||||
@ -257,10 +259,14 @@ public class FtpURLConnection extends URLConnection {
|
|||||||
p = instProxy;
|
p = instProxy;
|
||||||
if (p.type() == Proxy.Type.HTTP) {
|
if (p.type() == Proxy.Type.HTTP) {
|
||||||
http = new HttpURLConnection(url, instProxy);
|
http = new HttpURLConnection(url, instProxy);
|
||||||
if (connectTimeout >= 0)
|
http.setDoInput(getDoInput());
|
||||||
|
http.setDoOutput(getDoOutput());
|
||||||
|
if (connectTimeout >= 0) {
|
||||||
http.setConnectTimeout(connectTimeout);
|
http.setConnectTimeout(connectTimeout);
|
||||||
if (readTimeout >= 0)
|
}
|
||||||
|
if (readTimeout >= 0) {
|
||||||
http.setReadTimeout(readTimeout);
|
http.setReadTimeout(readTimeout);
|
||||||
|
}
|
||||||
http.connect();
|
http.connect();
|
||||||
connected = true;
|
connected = true;
|
||||||
return;
|
return;
|
||||||
@ -270,31 +276,35 @@ public class FtpURLConnection extends URLConnection {
|
|||||||
if (user == null) {
|
if (user == null) {
|
||||||
user = "anonymous";
|
user = "anonymous";
|
||||||
String vers = java.security.AccessController.doPrivileged(
|
String vers = java.security.AccessController.doPrivileged(
|
||||||
new GetPropertyAction("java.version"));
|
new GetPropertyAction("java.version"));
|
||||||
password = java.security.AccessController.doPrivileged(
|
password = java.security.AccessController.doPrivileged(
|
||||||
new GetPropertyAction("ftp.protocol.user",
|
new GetPropertyAction("ftp.protocol.user",
|
||||||
"Java" + vers +"@"));
|
"Java" + vers + "@"));
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
if (p != null)
|
ftp = FtpClient.create();
|
||||||
ftp = new FtpClient(p);
|
if (p != null) {
|
||||||
else
|
ftp.setProxy(p);
|
||||||
ftp = new FtpClient();
|
}
|
||||||
setTimeouts();
|
setTimeouts();
|
||||||
if (port != -1)
|
if (port != -1) {
|
||||||
ftp.openServer(host, port);
|
ftp.connect(new InetSocketAddress(host, port));
|
||||||
else
|
} else {
|
||||||
ftp.openServer(host);
|
ftp.connect(new InetSocketAddress(host, FtpClient.defaultPort()));
|
||||||
|
}
|
||||||
} catch (UnknownHostException e) {
|
} catch (UnknownHostException e) {
|
||||||
// Maybe do something smart here, like use a proxy like iftp.
|
// Maybe do something smart here, like use a proxy like iftp.
|
||||||
// Just keep throwing for now.
|
// Just keep throwing for now.
|
||||||
throw e;
|
throw e;
|
||||||
|
} catch (FtpProtocolException fe) {
|
||||||
|
throw new IOException(fe);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
ftp.login(user, password);
|
ftp.login(user, password.toCharArray());
|
||||||
} catch (sun.net.ftp.FtpLoginException e) {
|
} catch (sun.net.ftp.FtpProtocolException e) {
|
||||||
ftp.closeServer();
|
ftp.close();
|
||||||
throw e;
|
// Backward compatibility
|
||||||
|
throw new sun.net.ftp.FtpLoginException("Invalid username/password");
|
||||||
}
|
}
|
||||||
connected = true;
|
connected = true;
|
||||||
}
|
}
|
||||||
@ -306,24 +316,29 @@ public class FtpURLConnection extends URLConnection {
|
|||||||
private void decodePath(String path) {
|
private void decodePath(String path) {
|
||||||
int i = path.indexOf(";type=");
|
int i = path.indexOf(";type=");
|
||||||
if (i >= 0) {
|
if (i >= 0) {
|
||||||
String s1 = path.substring(i+6, path.length());
|
String s1 = path.substring(i + 6, path.length());
|
||||||
if ("i".equalsIgnoreCase(s1))
|
if ("i".equalsIgnoreCase(s1)) {
|
||||||
type = BIN;
|
type = BIN;
|
||||||
if ("a".equalsIgnoreCase(s1))
|
}
|
||||||
|
if ("a".equalsIgnoreCase(s1)) {
|
||||||
type = ASCII;
|
type = ASCII;
|
||||||
if ("d".equalsIgnoreCase(s1))
|
}
|
||||||
|
if ("d".equalsIgnoreCase(s1)) {
|
||||||
type = DIR;
|
type = DIR;
|
||||||
|
}
|
||||||
path = path.substring(0, i);
|
path = path.substring(0, i);
|
||||||
}
|
}
|
||||||
if (path != null && path.length() > 1 &&
|
if (path != null && path.length() > 1 &&
|
||||||
path.charAt(0) == '/')
|
path.charAt(0) == '/') {
|
||||||
path = path.substring(1);
|
path = path.substring(1);
|
||||||
if (path == null || path.length() == 0)
|
}
|
||||||
|
if (path == null || path.length() == 0) {
|
||||||
path = "./";
|
path = "./";
|
||||||
|
}
|
||||||
if (!path.endsWith("/")) {
|
if (!path.endsWith("/")) {
|
||||||
i = path.lastIndexOf('/');
|
i = path.lastIndexOf('/');
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
filename = path.substring(i+1, path.length());
|
filename = path.substring(i + 1, path.length());
|
||||||
filename = ParseUtil.decode(filename);
|
filename = ParseUtil.decode(filename);
|
||||||
pathname = path.substring(0, i);
|
pathname = path.substring(0, i);
|
||||||
} else {
|
} else {
|
||||||
@ -334,10 +349,11 @@ public class FtpURLConnection extends URLConnection {
|
|||||||
pathname = path.substring(0, path.length() - 1);
|
pathname = path.substring(0, path.length() - 1);
|
||||||
filename = null;
|
filename = null;
|
||||||
}
|
}
|
||||||
if (pathname != null)
|
if (pathname != null) {
|
||||||
fullpath = pathname + "/" + (filename != null ? filename : "");
|
fullpath = pathname + "/" + (filename != null ? filename : "");
|
||||||
else
|
} else {
|
||||||
fullpath = filename;
|
fullpath = filename;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -346,18 +362,19 @@ public class FtpURLConnection extends URLConnection {
|
|||||||
* This is because, '/' is not necessarly the directory delimiter
|
* This is because, '/' is not necessarly the directory delimiter
|
||||||
* on every systems.
|
* on every systems.
|
||||||
*/
|
*/
|
||||||
|
private void cd(String path) throws FtpProtocolException, IOException {
|
||||||
private void cd(String path) throws IOException {
|
if (path == null || path.isEmpty()) {
|
||||||
if (path == null || "".equals(path))
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
if (path.indexOf('/') == -1) {
|
if (path.indexOf('/') == -1) {
|
||||||
ftp.cd(ParseUtil.decode(path));
|
ftp.changeDirectory(ParseUtil.decode(path));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
StringTokenizer token = new StringTokenizer(path,"/");
|
StringTokenizer token = new StringTokenizer(path, "/");
|
||||||
while (token.hasMoreTokens())
|
while (token.hasMoreTokens()) {
|
||||||
ftp.cd(ParseUtil.decode(token.nextToken()));
|
ftp.changeDirectory(ParseUtil.decode(token.nextToken()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -369,16 +386,19 @@ public class FtpURLConnection extends URLConnection {
|
|||||||
* @throws IOException if already opened for output
|
* @throws IOException if already opened for output
|
||||||
* @throws FtpProtocolException if errors occur during the transfert.
|
* @throws FtpProtocolException if errors occur during the transfert.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public InputStream getInputStream() throws IOException {
|
public InputStream getInputStream() throws IOException {
|
||||||
if (!connected) {
|
if (!connected) {
|
||||||
connect();
|
connect();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (http != null)
|
if (http != null) {
|
||||||
return http.getInputStream();
|
return http.getInputStream();
|
||||||
|
}
|
||||||
|
|
||||||
if (os != null)
|
if (os != null) {
|
||||||
throw new IOException("Already opened for output");
|
throw new IOException("Already opened for output");
|
||||||
|
}
|
||||||
|
|
||||||
if (is != null) {
|
if (is != null) {
|
||||||
return is;
|
return is;
|
||||||
@ -386,82 +406,85 @@ public class FtpURLConnection extends URLConnection {
|
|||||||
|
|
||||||
MessageHeader msgh = new MessageHeader();
|
MessageHeader msgh = new MessageHeader();
|
||||||
|
|
||||||
|
boolean isAdir = false;
|
||||||
try {
|
try {
|
||||||
decodePath(url.getPath());
|
decodePath(url.getPath());
|
||||||
if (filename == null || type == DIR) {
|
if (filename == null || type == DIR) {
|
||||||
ftp.ascii();
|
ftp.setAsciiType();
|
||||||
cd(pathname);
|
cd(pathname);
|
||||||
if (filename == null)
|
if (filename == null) {
|
||||||
is = new FtpInputStream(ftp, ftp.list());
|
is = new FtpInputStream(ftp, ftp.list(null));
|
||||||
else
|
} else {
|
||||||
is = new FtpInputStream(ftp, ftp.nameList(filename));
|
is = new FtpInputStream(ftp, ftp.nameList(filename));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (type == ASCII)
|
if (type == ASCII) {
|
||||||
ftp.ascii();
|
ftp.setAsciiType();
|
||||||
else
|
} else {
|
||||||
ftp.binary();
|
ftp.setBinaryType();
|
||||||
|
}
|
||||||
cd(pathname);
|
cd(pathname);
|
||||||
is = new FtpInputStream(ftp, ftp.get(filename));
|
is = new FtpInputStream(ftp, ftp.getFileStream(filename));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Try to get the size of the file in bytes. If that is
|
/* Try to get the size of the file in bytes. If that is
|
||||||
successful, then create a MeteredStream. */
|
successful, then create a MeteredStream. */
|
||||||
try {
|
try {
|
||||||
String response = ftp.getResponseString();
|
long l = ftp.getLastTransferSize();
|
||||||
int offset;
|
msgh.add("content-length", Long.toString(l));
|
||||||
|
if (l > 0) {
|
||||||
|
|
||||||
if ((offset = response.indexOf(" bytes)")) != -1) {
|
// Wrap input stream with MeteredStream to ensure read() will always return -1
|
||||||
int i = offset;
|
// at expected length.
|
||||||
int c;
|
|
||||||
|
|
||||||
while (--i >= 0 && ((c = response.charAt(i)) >= '0'
|
// Check if URL should be metered
|
||||||
&& c <= '9'))
|
boolean meteredInput = ProgressMonitor.getDefault().shouldMeterInput(url, "GET");
|
||||||
;
|
ProgressSource pi = null;
|
||||||
long l = Long.parseLong(response.substring(i + 1, offset));
|
|
||||||
msgh.add("content-length", Long.toString(l));
|
|
||||||
if (l > 0) {
|
|
||||||
|
|
||||||
// Wrap input stream with MeteredStream to ensure read() will always return -1
|
if (meteredInput) {
|
||||||
// at expected length.
|
pi = new ProgressSource(url, "GET", l);
|
||||||
|
pi.beginTracking();
|
||||||
// Check if URL should be metered
|
|
||||||
boolean meteredInput = ProgressMonitor.getDefault().shouldMeterInput(url, "GET");
|
|
||||||
ProgressSource pi = null;
|
|
||||||
|
|
||||||
if (meteredInput) {
|
|
||||||
pi = new ProgressSource(url, "GET", l);
|
|
||||||
pi.beginTracking();
|
|
||||||
}
|
|
||||||
|
|
||||||
is = new MeteredStream(is, pi, l);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is = new MeteredStream(is, pi, l);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
/* do nothing, since all we were doing was trying to
|
/* do nothing, since all we were doing was trying to
|
||||||
get the size in bytes of the file */
|
get the size in bytes of the file */
|
||||||
}
|
}
|
||||||
|
|
||||||
String type = guessContentTypeFromName(fullpath);
|
if (isAdir) {
|
||||||
if (type == null && is.markSupported()) {
|
msgh.add("content-type", "text/plain");
|
||||||
type = guessContentTypeFromStream(is);
|
msgh.add("access-type", "directory");
|
||||||
}
|
} else {
|
||||||
if (type != null) {
|
msgh.add("access-type", "file");
|
||||||
msgh.add("content-type", type);
|
String ftype = guessContentTypeFromName(fullpath);
|
||||||
|
if (ftype == null && is.markSupported()) {
|
||||||
|
ftype = guessContentTypeFromStream(is);
|
||||||
|
}
|
||||||
|
if (ftype != null) {
|
||||||
|
msgh.add("content-type", ftype);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
try {
|
try {
|
||||||
cd(fullpath);
|
cd(fullpath);
|
||||||
/* if that worked, then make a directory listing
|
/* if that worked, then make a directory listing
|
||||||
and build an html stream with all the files in
|
and build an html stream with all the files in
|
||||||
the directory */
|
the directory */
|
||||||
ftp.ascii();
|
ftp.setAsciiType();
|
||||||
|
|
||||||
is = new FtpInputStream(ftp, ftp.list());
|
is = new FtpInputStream(ftp, ftp.list(null));
|
||||||
msgh.add("content-type", "text/plain");
|
msgh.add("content-type", "text/plain");
|
||||||
|
msgh.add("access-type", "directory");
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
throw new FileNotFoundException(fullpath);
|
throw new FileNotFoundException(fullpath);
|
||||||
|
} catch (FtpProtocolException ex2) {
|
||||||
|
throw new FileNotFoundException(fullpath);
|
||||||
}
|
}
|
||||||
|
} catch (FtpProtocolException ftpe) {
|
||||||
|
throw new IOException(ftpe);
|
||||||
}
|
}
|
||||||
setProperties(msgh);
|
setProperties(msgh);
|
||||||
return is;
|
return is;
|
||||||
@ -477,31 +500,45 @@ public class FtpURLConnection extends URLConnection {
|
|||||||
* points to a directory
|
* points to a directory
|
||||||
* @throws FtpProtocolException if errors occur during the transfert.
|
* @throws FtpProtocolException if errors occur during the transfert.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public OutputStream getOutputStream() throws IOException {
|
public OutputStream getOutputStream() throws IOException {
|
||||||
if (!connected) {
|
if (!connected) {
|
||||||
connect();
|
connect();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (http != null)
|
if (http != null) {
|
||||||
return http.getOutputStream();
|
OutputStream out = http.getOutputStream();
|
||||||
|
// getInputStream() is neccessary to force a writeRequests()
|
||||||
|
// on the http client.
|
||||||
|
http.getInputStream();
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
if (is != null)
|
if (is != null) {
|
||||||
throw new IOException("Already opened for input");
|
throw new IOException("Already opened for input");
|
||||||
|
}
|
||||||
|
|
||||||
if (os != null) {
|
if (os != null) {
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
decodePath(url.getPath());
|
decodePath(url.getPath());
|
||||||
if (filename == null || filename.length() == 0)
|
if (filename == null || filename.length() == 0) {
|
||||||
throw new IOException("illegal filename for a PUT");
|
throw new IOException("illegal filename for a PUT");
|
||||||
if (pathname != null)
|
}
|
||||||
cd(pathname);
|
try {
|
||||||
if (type == ASCII)
|
if (pathname != null) {
|
||||||
ftp.ascii();
|
cd(pathname);
|
||||||
else
|
}
|
||||||
ftp.binary();
|
if (type == ASCII) {
|
||||||
os = new FtpOutputStream(ftp, ftp.put(filename));
|
ftp.setAsciiType();
|
||||||
|
} else {
|
||||||
|
ftp.setBinaryType();
|
||||||
|
}
|
||||||
|
os = new FtpOutputStream(ftp, ftp.putFileStream(filename, false));
|
||||||
|
} catch (FtpProtocolException e) {
|
||||||
|
throw new IOException(e);
|
||||||
|
}
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -514,12 +551,13 @@ public class FtpURLConnection extends URLConnection {
|
|||||||
*
|
*
|
||||||
* @return The <code>Permission</code> object.
|
* @return The <code>Permission</code> object.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public Permission getPermission() {
|
public Permission getPermission() {
|
||||||
if (permission == null) {
|
if (permission == null) {
|
||||||
int port = url.getPort();
|
int urlport = url.getPort();
|
||||||
port = port < 0 ? FtpClient.FTP_PORT : port;
|
urlport = urlport < 0 ? FtpClient.defaultPort() : urlport;
|
||||||
String host = this.host + ":" + port;
|
String urlhost = this.host + ":" + urlport;
|
||||||
permission = new SocketPermission(host, "connect");
|
permission = new SocketPermission(urlhost, "connect");
|
||||||
}
|
}
|
||||||
return permission;
|
return permission;
|
||||||
}
|
}
|
||||||
@ -534,21 +572,22 @@ public class FtpURLConnection extends URLConnection {
|
|||||||
* @throws IllegalStateException if already connected
|
* @throws IllegalStateException if already connected
|
||||||
* @see #getRequestProperty(java.lang.String)
|
* @see #getRequestProperty(java.lang.String)
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void setRequestProperty(String key, String value) {
|
public void setRequestProperty(String key, String value) {
|
||||||
super.setRequestProperty (key, value);
|
super.setRequestProperty(key, value);
|
||||||
if ("type".equals (key)) {
|
if ("type".equals(key)) {
|
||||||
if ("i".equalsIgnoreCase(value))
|
if ("i".equalsIgnoreCase(value)) {
|
||||||
type = BIN;
|
type = BIN;
|
||||||
else if ("a".equalsIgnoreCase(value))
|
} else if ("a".equalsIgnoreCase(value)) {
|
||||||
type = ASCII;
|
type = ASCII;
|
||||||
else
|
} else if ("d".equalsIgnoreCase(value)) {
|
||||||
if ("d".equalsIgnoreCase(value))
|
type = DIR;
|
||||||
type = DIR;
|
} else {
|
||||||
else
|
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Value of '" + key +
|
"Value of '" + key +
|
||||||
"' request property was '" + value +
|
"' request property was '" + value +
|
||||||
"' when it must be either 'i', 'a' or 'd'");
|
"' when it must be either 'i', 'a' or 'd'");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -562,33 +601,41 @@ public class FtpURLConnection extends URLConnection {
|
|||||||
* @throws IllegalStateException if already connected
|
* @throws IllegalStateException if already connected
|
||||||
* @see #setRequestProperty(java.lang.String, java.lang.String)
|
* @see #setRequestProperty(java.lang.String, java.lang.String)
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public String getRequestProperty(String key) {
|
public String getRequestProperty(String key) {
|
||||||
String value = super.getRequestProperty (key);
|
String value = super.getRequestProperty(key);
|
||||||
|
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
if ("type".equals (key))
|
if ("type".equals(key)) {
|
||||||
value = (type == ASCII ? "a" : type == DIR ? "d" : "i");
|
value = (type == ASCII ? "a" : type == DIR ? "d" : "i");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setConnectTimeout(int timeout) {
|
public void setConnectTimeout(int timeout) {
|
||||||
if (timeout < 0)
|
if (timeout < 0) {
|
||||||
throw new IllegalArgumentException("timeouts can't be negative");
|
throw new IllegalArgumentException("timeouts can't be negative");
|
||||||
|
}
|
||||||
connectTimeout = timeout;
|
connectTimeout = timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int getConnectTimeout() {
|
public int getConnectTimeout() {
|
||||||
return (connectTimeout < 0 ? 0 : connectTimeout);
|
return (connectTimeout < 0 ? 0 : connectTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setReadTimeout(int timeout) {
|
public void setReadTimeout(int timeout) {
|
||||||
if (timeout < 0)
|
if (timeout < 0) {
|
||||||
throw new IllegalArgumentException("timeouts can't be negative");
|
throw new IllegalArgumentException("timeouts can't be negative");
|
||||||
|
}
|
||||||
readTimeout = timeout;
|
readTimeout = timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int getReadTimeout() {
|
public int getReadTimeout() {
|
||||||
return readTimeout < 0 ? 0 : readTimeout;
|
return readTimeout < 0 ? 0 : readTimeout;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user