51 import sun.net.www.MeteredStream;
52 import sun.net.www.URLConnection;
53 import sun.net.www.protocol.http.HttpURLConnection;
54 import sun.net.ftp.FtpClient;
55 import sun.net.ftp.FtpProtocolException;
56 import sun.net.ProgressSource;
57 import sun.net.ProgressMonitor;
58 import sun.net.www.ParseUtil;
59 import sun.security.action.GetPropertyAction;
60
61
62 /**
63 * This class Opens an FTP input (or output) stream given a URL.
64 * It works as a one shot FTP transfer :
65 * <UL>
66 * <LI>Login</LI>
67 * <LI>Get (or Put) the file</LI>
68 * <LI>Disconnect</LI>
69 * </UL>
70 * You should not have to use it directly in most cases because all will be handled
71 * in a abstract layer. Here is an example of how to use the class :
72 * <P>
73 * <code>URL url = new URL("ftp://ftp.sun.com/pub/test.txt");<p>
74 * UrlConnection con = url.openConnection();<p>
75 * InputStream is = con.getInputStream();<p>
76 * ...<p>
77 * is.close();</code>
78 *
79 * @see sun.net.ftp.FtpClient
80 */
81 public class FtpURLConnection extends URLConnection {
82
83 // In case we have to use proxies, we use HttpURLConnection
84 HttpURLConnection http = null;
85 private Proxy instProxy;
86
87 InputStream is = null;
88 OutputStream os = null;
89
90 FtpClient ftp = null;
91 Permission permission;
92
93 String password;
94 String user;
95
96 String host;
97 String pathname;
141 */
142 protected class FtpOutputStream extends FilterOutputStream {
143 FtpClient ftp;
144 FtpOutputStream(FtpClient cl, OutputStream fd) {
145 super(fd);
146 ftp = cl;
147 }
148
149 @Override
150 public void close() throws IOException {
151 super.close();
152 if (ftp != null) {
153 ftp.close();
154 }
155 }
156 }
157
158 /**
159 * Creates an FtpURLConnection from a URL.
160 *
161 * @param url The <code>URL</code> to retrieve or store.
162 */
163 public FtpURLConnection(URL url) {
164 this(url, null);
165 }
166
167 /**
168 * Same as FtpURLconnection(URL) with a per connection proxy specified
169 */
170 FtpURLConnection(URL url, Proxy p) {
171 super(url);
172 instProxy = p;
173 host = url.getHost();
174 port = url.getPort();
175 String userInfo = url.getUserInfo();
176
177 if (userInfo != null) { // get the user and password
178 int delimiter = userInfo.indexOf(':');
179 if (delimiter == -1) {
180 user = ParseUtil.decode(userInfo);
181 password = null;
365 */
366 private void cd(String path) throws FtpProtocolException, IOException {
367 if (path == null || path.isEmpty()) {
368 return;
369 }
370 if (path.indexOf('/') == -1) {
371 ftp.changeDirectory(ParseUtil.decode(path));
372 return;
373 }
374
375 StringTokenizer token = new StringTokenizer(path, "/");
376 while (token.hasMoreTokens()) {
377 ftp.changeDirectory(ParseUtil.decode(token.nextToken()));
378 }
379 }
380
381 /**
382 * Get the InputStream to retreive the remote file. It will issue the
383 * "get" (or "dir") command to the ftp server.
384 *
385 * @return the <code>InputStream</code> to the connection.
386 *
387 * @throws IOException if already opened for output
388 * @throws FtpProtocolException if errors occur during the transfert.
389 */
390 @Override
391 public InputStream getInputStream() throws IOException {
392 if (!connected) {
393 connect();
394 }
395
396 if (http != null) {
397 return http.getInputStream();
398 }
399
400 if (os != null) {
401 throw new IOException("Already opened for output");
402 }
403
404 if (is != null) {
405 return is;
478
479 is = new FtpInputStream(ftp, ftp.list(null));
480 msgh.add("content-type", "text/plain");
481 msgh.add("access-type", "directory");
482 } catch (IOException ex) {
483 throw new FileNotFoundException(fullpath);
484 } catch (FtpProtocolException ex2) {
485 throw new FileNotFoundException(fullpath);
486 }
487 } catch (FtpProtocolException ftpe) {
488 throw new IOException(ftpe);
489 }
490 setProperties(msgh);
491 return is;
492 }
493
494 /**
495 * Get the OutputStream to store the remote file. It will issue the
496 * "put" command to the ftp server.
497 *
498 * @return the <code>OutputStream</code> to the connection.
499 *
500 * @throws IOException if already opened for input or the URL
501 * points to a directory
502 * @throws FtpProtocolException if errors occur during the transfert.
503 */
504 @Override
505 public OutputStream getOutputStream() throws IOException {
506 if (!connected) {
507 connect();
508 }
509
510 if (http != null) {
511 OutputStream out = http.getOutputStream();
512 // getInputStream() is neccessary to force a writeRequests()
513 // on the http client.
514 http.getInputStream();
515 return out;
516 }
517
518 if (is != null) {
531 if (pathname != null) {
532 cd(pathname);
533 }
534 if (type == ASCII) {
535 ftp.setAsciiType();
536 } else {
537 ftp.setBinaryType();
538 }
539 os = new FtpOutputStream(ftp, ftp.putFileStream(filename, false));
540 } catch (FtpProtocolException e) {
541 throw new IOException(e);
542 }
543 return os;
544 }
545
546 String guessContentTypeFromFilename(String fname) {
547 return guessContentTypeFromName(fname);
548 }
549
550 /**
551 * Gets the <code>Permission</code> associated with the host & port.
552 *
553 * @return The <code>Permission</code> object.
554 */
555 @Override
556 public Permission getPermission() {
557 if (permission == null) {
558 int urlport = url.getPort();
559 urlport = urlport < 0 ? FtpClient.defaultPort() : urlport;
560 String urlhost = this.host + ":" + urlport;
561 permission = new SocketPermission(urlhost, "connect");
562 }
563 return permission;
564 }
565
566 /**
567 * Sets the general request property. If a property with the key already
568 * exists, overwrite its value with the new value.
569 *
570 * @param key the keyword by which the request is known
571 * (e.g., "<code>accept</code>").
572 * @param value the value associated with it.
573 * @throws IllegalStateException if already connected
574 * @see #getRequestProperty(java.lang.String)
575 */
576 @Override
577 public void setRequestProperty(String key, String value) {
578 super.setRequestProperty(key, value);
579 if ("type".equals(key)) {
580 if ("i".equalsIgnoreCase(value)) {
581 type = BIN;
582 } else if ("a".equalsIgnoreCase(value)) {
583 type = ASCII;
584 } else if ("d".equalsIgnoreCase(value)) {
585 type = DIR;
586 } else {
587 throw new IllegalArgumentException(
588 "Value of '" + key +
589 "' request property was '" + value +
590 "' when it must be either 'i', 'a' or 'd'");
591 }
|
51 import sun.net.www.MeteredStream;
52 import sun.net.www.URLConnection;
53 import sun.net.www.protocol.http.HttpURLConnection;
54 import sun.net.ftp.FtpClient;
55 import sun.net.ftp.FtpProtocolException;
56 import sun.net.ProgressSource;
57 import sun.net.ProgressMonitor;
58 import sun.net.www.ParseUtil;
59 import sun.security.action.GetPropertyAction;
60
61
62 /**
63 * This class Opens an FTP input (or output) stream given a URL.
64 * It works as a one shot FTP transfer :
65 * <UL>
66 * <LI>Login</LI>
67 * <LI>Get (or Put) the file</LI>
68 * <LI>Disconnect</LI>
69 * </UL>
70 * You should not have to use it directly in most cases because all will be handled
71 * in a abstract layer. Here is an example of how to use the class:
72 * <pre>{@code
73 * URL url = new URL("ftp://ftp.sun.com/pub/test.txt");
74 * UrlConnection con = url.openConnection();
75 * InputStream is = con.getInputStream();
76 * ...
77 * is.close();
78 * }</pre>
79 *
80 * @see sun.net.ftp.FtpClient
81 */
82 public class FtpURLConnection extends URLConnection {
83
84 // In case we have to use proxies, we use HttpURLConnection
85 HttpURLConnection http = null;
86 private Proxy instProxy;
87
88 InputStream is = null;
89 OutputStream os = null;
90
91 FtpClient ftp = null;
92 Permission permission;
93
94 String password;
95 String user;
96
97 String host;
98 String pathname;
142 */
143 protected class FtpOutputStream extends FilterOutputStream {
144 FtpClient ftp;
145 FtpOutputStream(FtpClient cl, OutputStream fd) {
146 super(fd);
147 ftp = cl;
148 }
149
150 @Override
151 public void close() throws IOException {
152 super.close();
153 if (ftp != null) {
154 ftp.close();
155 }
156 }
157 }
158
159 /**
160 * Creates an FtpURLConnection from a URL.
161 *
162 * @param url The {@code URL} to retrieve or store.
163 */
164 public FtpURLConnection(URL url) {
165 this(url, null);
166 }
167
168 /**
169 * Same as FtpURLconnection(URL) with a per connection proxy specified
170 */
171 FtpURLConnection(URL url, Proxy p) {
172 super(url);
173 instProxy = p;
174 host = url.getHost();
175 port = url.getPort();
176 String userInfo = url.getUserInfo();
177
178 if (userInfo != null) { // get the user and password
179 int delimiter = userInfo.indexOf(':');
180 if (delimiter == -1) {
181 user = ParseUtil.decode(userInfo);
182 password = null;
366 */
367 private void cd(String path) throws FtpProtocolException, IOException {
368 if (path == null || path.isEmpty()) {
369 return;
370 }
371 if (path.indexOf('/') == -1) {
372 ftp.changeDirectory(ParseUtil.decode(path));
373 return;
374 }
375
376 StringTokenizer token = new StringTokenizer(path, "/");
377 while (token.hasMoreTokens()) {
378 ftp.changeDirectory(ParseUtil.decode(token.nextToken()));
379 }
380 }
381
382 /**
383 * Get the InputStream to retreive the remote file. It will issue the
384 * "get" (or "dir") command to the ftp server.
385 *
386 * @return the {@code InputStream} to the connection.
387 *
388 * @throws IOException if already opened for output
389 * @throws FtpProtocolException if errors occur during the transfert.
390 */
391 @Override
392 public InputStream getInputStream() throws IOException {
393 if (!connected) {
394 connect();
395 }
396
397 if (http != null) {
398 return http.getInputStream();
399 }
400
401 if (os != null) {
402 throw new IOException("Already opened for output");
403 }
404
405 if (is != null) {
406 return is;
479
480 is = new FtpInputStream(ftp, ftp.list(null));
481 msgh.add("content-type", "text/plain");
482 msgh.add("access-type", "directory");
483 } catch (IOException ex) {
484 throw new FileNotFoundException(fullpath);
485 } catch (FtpProtocolException ex2) {
486 throw new FileNotFoundException(fullpath);
487 }
488 } catch (FtpProtocolException ftpe) {
489 throw new IOException(ftpe);
490 }
491 setProperties(msgh);
492 return is;
493 }
494
495 /**
496 * Get the OutputStream to store the remote file. It will issue the
497 * "put" command to the ftp server.
498 *
499 * @return the {@code OutputStream} to the connection.
500 *
501 * @throws IOException if already opened for input or the URL
502 * points to a directory
503 * @throws FtpProtocolException if errors occur during the transfert.
504 */
505 @Override
506 public OutputStream getOutputStream() throws IOException {
507 if (!connected) {
508 connect();
509 }
510
511 if (http != null) {
512 OutputStream out = http.getOutputStream();
513 // getInputStream() is neccessary to force a writeRequests()
514 // on the http client.
515 http.getInputStream();
516 return out;
517 }
518
519 if (is != null) {
532 if (pathname != null) {
533 cd(pathname);
534 }
535 if (type == ASCII) {
536 ftp.setAsciiType();
537 } else {
538 ftp.setBinaryType();
539 }
540 os = new FtpOutputStream(ftp, ftp.putFileStream(filename, false));
541 } catch (FtpProtocolException e) {
542 throw new IOException(e);
543 }
544 return os;
545 }
546
547 String guessContentTypeFromFilename(String fname) {
548 return guessContentTypeFromName(fname);
549 }
550
551 /**
552 * Gets the {@code Permission} associated with the host and port.
553 *
554 * @return The {@code Permission} object.
555 */
556 @Override
557 public Permission getPermission() {
558 if (permission == null) {
559 int urlport = url.getPort();
560 urlport = urlport < 0 ? FtpClient.defaultPort() : urlport;
561 String urlhost = this.host + ":" + urlport;
562 permission = new SocketPermission(urlhost, "connect");
563 }
564 return permission;
565 }
566
567 /**
568 * Sets the general request property. If a property with the key already
569 * exists, overwrite its value with the new value.
570 *
571 * @param key the keyword by which the request is known
572 * (e.g., "{@code accept}").
573 * @param value the value associated with it.
574 * @throws IllegalStateException if already connected
575 * @see #getRequestProperty(java.lang.String)
576 */
577 @Override
578 public void setRequestProperty(String key, String value) {
579 super.setRequestProperty(key, value);
580 if ("type".equals(key)) {
581 if ("i".equalsIgnoreCase(value)) {
582 type = BIN;
583 } else if ("a".equalsIgnoreCase(value)) {
584 type = ASCII;
585 } else if ("d".equalsIgnoreCase(value)) {
586 type = DIR;
587 } else {
588 throw new IllegalArgumentException(
589 "Value of '" + key +
590 "' request property was '" + value +
591 "' when it must be either 'i', 'a' or 'd'");
592 }
|