--- a/jdk/src/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java Wed Oct 21 13:42:39 2009 +0200
+++ b/jdk/src/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java Wed Oct 21 16:28:57 2009 +0200
@@ -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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -37,10 +37,8 @@
import java.io.FilterOutputStream;
import java.io.FileNotFoundException;
import java.net.URL;
-import java.net.URLStreamHandler;
import java.net.SocketPermission;
import java.net.UnknownHostException;
-import java.net.MalformedURLException;
import java.net.InetSocketAddress;
import java.net.URI;
import java.net.Proxy;
@@ -84,7 +82,6 @@
// In case we have to use proxies, we use HttpURLConnection
HttpURLConnection http = null;
private Proxy instProxy;
- Proxy proxy = null;
InputStream is = null;
OutputStream os = null;
@@ -125,12 +122,11 @@
ftp = cl;
}
+ @Override
public void close() throws IOException {
super.close();
- try {
- if (ftp != null)
- ftp.closeServer();
- } catch (IOException ex) {
+ if (ftp != null) {
+ ftp.close();
}
}
}
@@ -149,12 +145,11 @@
ftp = cl;
}
+ @Override
public void close() throws IOException {
super.close();
- try {
- if (ftp != null)
- ftp.closeServer();
- } catch (IOException ex) {
+ if (ftp != null) {
+ ftp.close();
}
}
}
@@ -192,10 +187,12 @@
private void setTimeouts() {
if (ftp != null) {
- if (connectTimeout >= 0)
+ if (connectTimeout >= 0) {
ftp.setConnectTimeout(connectTimeout);
- if (readTimeout >= 0)
+ }
+ if (readTimeout >= 0) {
ftp.setReadTimeout(readTimeout);
+ }
}
}
@@ -218,21 +215,22 @@
* Do we have to use a proxy?
*/
ProxySelector sel = java.security.AccessController.doPrivileged(
- new java.security.PrivilegedAction<ProxySelector>() {
- public ProxySelector run() {
- return ProxySelector.getDefault();
- }
- });
+ new java.security.PrivilegedAction<ProxySelector>() {
+ public ProxySelector run() {
+ return ProxySelector.getDefault();
+ }
+ });
if (sel != null) {
URI uri = sun.net.www.ParseUtil.toURI(url);
Iterator<Proxy> it = sel.select(uri).iterator();
while (it.hasNext()) {
p = it.next();
if (p == null || p == Proxy.NO_PROXY ||
- p.type() == Proxy.Type.SOCKS)
+ p.type() == Proxy.Type.SOCKS) {
break;
+ }
if (p.type() != Proxy.Type.HTTP ||
- !(p.address() instanceof InetSocketAddress)) {
+ !(p.address() instanceof InetSocketAddress)) {
sel.connectFailed(uri, p.address(), new IOException("Wrong proxy type"));
continue;
}
@@ -240,10 +238,14 @@
InetSocketAddress paddr = (InetSocketAddress) p.address();
try {
http = new HttpURLConnection(url, p);
- if (connectTimeout >= 0)
+ http.setDoInput(getDoInput());
+ http.setDoOutput(getDoOutput());
+ if (connectTimeout >= 0) {
http.setConnectTimeout(connectTimeout);
- if (readTimeout >= 0)
+ }
+ if (readTimeout >= 0) {
http.setReadTimeout(readTimeout);
+ }
http.connect();
connected = true;
return;
@@ -257,10 +259,14 @@
p = instProxy;
if (p.type() == Proxy.Type.HTTP) {
http = new HttpURLConnection(url, instProxy);
- if (connectTimeout >= 0)
+ http.setDoInput(getDoInput());
+ http.setDoOutput(getDoOutput());
+ if (connectTimeout >= 0) {
http.setConnectTimeout(connectTimeout);
- if (readTimeout >= 0)
+ }
+ if (readTimeout >= 0) {
http.setReadTimeout(readTimeout);
+ }
http.connect();
connected = true;
return;
@@ -270,31 +276,35 @@
if (user == null) {
user = "anonymous";
String vers = java.security.AccessController.doPrivileged(
- new GetPropertyAction("java.version"));
+ new GetPropertyAction("java.version"));
password = java.security.AccessController.doPrivileged(
- new GetPropertyAction("ftp.protocol.user",
- "Java" + vers +"@"));
+ new GetPropertyAction("ftp.protocol.user",
+ "Java" + vers + "@"));
}
try {
- if (p != null)
- ftp = new FtpClient(p);
- else
- ftp = new FtpClient();
+ ftp = FtpClient.create();
+ if (p != null) {
+ ftp.setProxy(p);
+ }
setTimeouts();
- if (port != -1)
- ftp.openServer(host, port);
- else
- ftp.openServer(host);
+ if (port != -1) {
+ ftp.connect(new InetSocketAddress(host, port));
+ } else {
+ ftp.connect(new InetSocketAddress(host, FtpClient.defaultPort()));
+ }
} catch (UnknownHostException e) {
// Maybe do something smart here, like use a proxy like iftp.
// Just keep throwing for now.
throw e;
+ } catch (FtpProtocolException fe) {
+ throw new IOException(fe);
}
try {
- ftp.login(user, password);
- } catch (sun.net.ftp.FtpLoginException e) {
- ftp.closeServer();
- throw e;
+ ftp.login(user, password.toCharArray());
+ } catch (sun.net.ftp.FtpProtocolException e) {
+ ftp.close();
+ // Backward compatibility
+ throw new sun.net.ftp.FtpLoginException("Invalid username/password");
}
connected = true;
}
@@ -306,24 +316,29 @@
private void decodePath(String path) {
int i = path.indexOf(";type=");
if (i >= 0) {
- String s1 = path.substring(i+6, path.length());
- if ("i".equalsIgnoreCase(s1))
+ String s1 = path.substring(i + 6, path.length());
+ if ("i".equalsIgnoreCase(s1)) {
type = BIN;
- if ("a".equalsIgnoreCase(s1))
+ }
+ if ("a".equalsIgnoreCase(s1)) {
type = ASCII;
- if ("d".equalsIgnoreCase(s1))
+ }
+ if ("d".equalsIgnoreCase(s1)) {
type = DIR;
+ }
path = path.substring(0, i);
}
if (path != null && path.length() > 1 &&
- path.charAt(0) == '/')
+ path.charAt(0) == '/') {
path = path.substring(1);
- if (path == null || path.length() == 0)
+ }
+ if (path == null || path.length() == 0) {
path = "./";
+ }
if (!path.endsWith("/")) {
i = path.lastIndexOf('/');
if (i > 0) {
- filename = path.substring(i+1, path.length());
+ filename = path.substring(i + 1, path.length());
filename = ParseUtil.decode(filename);
pathname = path.substring(0, i);
} else {
@@ -334,10 +349,11 @@
pathname = path.substring(0, path.length() - 1);
filename = null;
}
- if (pathname != null)
+ if (pathname != null) {
fullpath = pathname + "/" + (filename != null ? filename : "");
- else
+ } else {
fullpath = filename;
+ }
}
/*
@@ -346,18 +362,19 @@
* This is because, '/' is not necessarly the directory delimiter
* on every systems.
*/
-
- private void cd(String path) throws IOException {
- if (path == null || "".equals(path))
+ private void cd(String path) throws FtpProtocolException, IOException {
+ if (path == null || path.isEmpty()) {
return;
+ }
if (path.indexOf('/') == -1) {
- ftp.cd(ParseUtil.decode(path));
+ ftp.changeDirectory(ParseUtil.decode(path));
return;
}
- StringTokenizer token = new StringTokenizer(path,"/");
- while (token.hasMoreTokens())
- ftp.cd(ParseUtil.decode(token.nextToken()));
+ StringTokenizer token = new StringTokenizer(path, "/");
+ while (token.hasMoreTokens()) {
+ ftp.changeDirectory(ParseUtil.decode(token.nextToken()));
+ }
}
/**
@@ -369,16 +386,19 @@
* @throws IOException if already opened for output
* @throws FtpProtocolException if errors occur during the transfert.
*/
+ @Override
public InputStream getInputStream() throws IOException {
if (!connected) {
connect();
}
- if (http != null)
+ if (http != null) {
return http.getInputStream();
+ }
- if (os != null)
+ if (os != null) {
throw new IOException("Already opened for output");
+ }
if (is != null) {
return is;
@@ -386,82 +406,85 @@
MessageHeader msgh = new MessageHeader();
+ boolean isAdir = false;
try {
decodePath(url.getPath());
if (filename == null || type == DIR) {
- ftp.ascii();
+ ftp.setAsciiType();
cd(pathname);
- if (filename == null)
- is = new FtpInputStream(ftp, ftp.list());
- else
+ if (filename == null) {
+ is = new FtpInputStream(ftp, ftp.list(null));
+ } else {
is = new FtpInputStream(ftp, ftp.nameList(filename));
+ }
} else {
- if (type == ASCII)
- ftp.ascii();
- else
- ftp.binary();
+ if (type == ASCII) {
+ ftp.setAsciiType();
+ } else {
+ ftp.setBinaryType();
+ }
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
- successful, then create a MeteredStream. */
+ successful, then create a MeteredStream. */
try {
- String response = ftp.getResponseString();
- int offset;
+ long l = ftp.getLastTransferSize();
+ msgh.add("content-length", Long.toString(l));
+ if (l > 0) {
- if ((offset = response.indexOf(" bytes)")) != -1) {
- int i = offset;
- int c;
+ // Wrap input stream with MeteredStream to ensure read() will always return -1
+ // at expected length.
- while (--i >= 0 && ((c = response.charAt(i)) >= '0'
- && c <= '9'))
- ;
- 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
- // at expected length.
+ // Check if URL should be metered
+ boolean meteredInput = ProgressMonitor.getDefault().shouldMeterInput(url, "GET");
+ ProgressSource pi = null;
- // 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();
+ }
- 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) {
e.printStackTrace();
- /* do nothing, since all we were doing was trying to
- get the size in bytes of the file */
+ /* do nothing, since all we were doing was trying to
+ get the size in bytes of the file */
}
- String type = guessContentTypeFromName(fullpath);
- if (type == null && is.markSupported()) {
- type = guessContentTypeFromStream(is);
- }
- if (type != null) {
- msgh.add("content-type", type);
+ if (isAdir) {
+ msgh.add("content-type", "text/plain");
+ msgh.add("access-type", "directory");
+ } else {
+ msgh.add("access-type", "file");
+ String ftype = guessContentTypeFromName(fullpath);
+ if (ftype == null && is.markSupported()) {
+ ftype = guessContentTypeFromStream(is);
+ }
+ if (ftype != null) {
+ msgh.add("content-type", ftype);
+ }
}
} catch (FileNotFoundException e) {
try {
cd(fullpath);
/* if that worked, then make a directory listing
- and build an html stream with all the files in
- the directory */
- ftp.ascii();
+ and build an html stream with all the files in
+ the directory */
+ ftp.setAsciiType();
- is = new FtpInputStream(ftp, ftp.list());
+ is = new FtpInputStream(ftp, ftp.list(null));
msgh.add("content-type", "text/plain");
+ msgh.add("access-type", "directory");
} catch (IOException ex) {
throw new FileNotFoundException(fullpath);
+ } catch (FtpProtocolException ex2) {
+ throw new FileNotFoundException(fullpath);
}
+ } catch (FtpProtocolException ftpe) {
+ throw new IOException(ftpe);
}
setProperties(msgh);
return is;
@@ -477,31 +500,45 @@
* points to a directory
* @throws FtpProtocolException if errors occur during the transfert.
*/
+ @Override
public OutputStream getOutputStream() throws IOException {
if (!connected) {
connect();
}
- if (http != null)
- return http.getOutputStream();
+ if (http != null) {
+ 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");
+ }
if (os != null) {
return os;
}
decodePath(url.getPath());
- if (filename == null || filename.length() == 0)
+ if (filename == null || filename.length() == 0) {
throw new IOException("illegal filename for a PUT");
- if (pathname != null)
- cd(pathname);
- if (type == ASCII)
- ftp.ascii();
- else
- ftp.binary();
- os = new FtpOutputStream(ftp, ftp.put(filename));
+ }
+ try {
+ if (pathname != null) {
+ cd(pathname);
+ }
+ if (type == ASCII) {
+ ftp.setAsciiType();
+ } else {
+ ftp.setBinaryType();
+ }
+ os = new FtpOutputStream(ftp, ftp.putFileStream(filename, false));
+ } catch (FtpProtocolException e) {
+ throw new IOException(e);
+ }
return os;
}
@@ -514,12 +551,13 @@
*
* @return The <code>Permission</code> object.
*/
+ @Override
public Permission getPermission() {
if (permission == null) {
- int port = url.getPort();
- port = port < 0 ? FtpClient.FTP_PORT : port;
- String host = this.host + ":" + port;
- permission = new SocketPermission(host, "connect");
+ int urlport = url.getPort();
+ urlport = urlport < 0 ? FtpClient.defaultPort() : urlport;
+ String urlhost = this.host + ":" + urlport;
+ permission = new SocketPermission(urlhost, "connect");
}
return permission;
}
@@ -534,21 +572,22 @@
* @throws IllegalStateException if already connected
* @see #getRequestProperty(java.lang.String)
*/
+ @Override
public void setRequestProperty(String key, String value) {
- super.setRequestProperty (key, value);
- if ("type".equals (key)) {
- if ("i".equalsIgnoreCase(value))
+ super.setRequestProperty(key, value);
+ if ("type".equals(key)) {
+ if ("i".equalsIgnoreCase(value)) {
type = BIN;
- else if ("a".equalsIgnoreCase(value))
+ } else if ("a".equalsIgnoreCase(value)) {
type = ASCII;
- else
- if ("d".equalsIgnoreCase(value))
- type = DIR;
- else
+ } else if ("d".equalsIgnoreCase(value)) {
+ type = DIR;
+ } else {
throw new IllegalArgumentException(
- "Value of '" + key +
- "' request property was '" + value +
- "' when it must be either 'i', 'a' or 'd'");
+ "Value of '" + key +
+ "' request property was '" + value +
+ "' when it must be either 'i', 'a' or 'd'");
+ }
}
}
@@ -562,33 +601,41 @@
* @throws IllegalStateException if already connected
* @see #setRequestProperty(java.lang.String, java.lang.String)
*/
+ @Override
public String getRequestProperty(String key) {
- String value = super.getRequestProperty (key);
+ String value = super.getRequestProperty(key);
if (value == null) {
- if ("type".equals (key))
+ if ("type".equals(key)) {
value = (type == ASCII ? "a" : type == DIR ? "d" : "i");
+ }
}
return value;
}
+ @Override
public void setConnectTimeout(int timeout) {
- if (timeout < 0)
+ if (timeout < 0) {
throw new IllegalArgumentException("timeouts can't be negative");
+ }
connectTimeout = timeout;
}
+ @Override
public int getConnectTimeout() {
return (connectTimeout < 0 ? 0 : connectTimeout);
}
+ @Override
public void setReadTimeout(int timeout) {
- if (timeout < 0)
+ if (timeout < 0) {
throw new IllegalArgumentException("timeouts can't be negative");
+ }
readTimeout = timeout;
}
+ @Override
public int getReadTimeout() {
return readTimeout < 0 ? 0 : readTimeout;
}