You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by se...@apache.org on 2014/12/12 01:57:16 UTC
svn commit: r1644802 - in /commons/proper/net/trunk/src: changes/
main/java/examples/ftp/ main/java/examples/telnet/
main/java/org/apache/commons/net/ftp/ test/java/org/apache/commons/net/ftp/
Author: sebb
Date: Fri Dec 12 00:57:15 2014
New Revision: 1644802
URL: http://svn.apache.org/r1644802
Log:
NET-528 FTPListParseEngine does not provide access to raw responses
Added:
commons/proper/net/trunk/src/main/java/examples/telnet/TelnetClientScript.java
Modified:
commons/proper/net/trunk/src/changes/changes.xml
commons/proper/net/trunk/src/main/java/examples/ftp/FTPClientExample.java
commons/proper/net/trunk/src/main/java/org/apache/commons/net/ftp/FTPClient.java
commons/proper/net/trunk/src/main/java/org/apache/commons/net/ftp/FTPClientConfig.java
commons/proper/net/trunk/src/main/java/org/apache/commons/net/ftp/FTPFile.java
commons/proper/net/trunk/src/main/java/org/apache/commons/net/ftp/FTPListParseEngine.java
commons/proper/net/trunk/src/test/java/org/apache/commons/net/ftp/FTPClientTest.java
Modified: commons/proper/net/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/changes/changes.xml?rev=1644802&r1=1644801&r2=1644802&view=diff
==============================================================================
--- commons/proper/net/trunk/src/changes/changes.xml [utf-8] (original)
+++ commons/proper/net/trunk/src/changes/changes.xml [utf-8] Fri Dec 12 00:57:15 2014
@@ -68,7 +68,10 @@ This is mainly a bug-fix release. See fu
IMAPExportMbox (example app) allows IMAP folders to be exported into an mbox file.
This is the inverse of the IMAPImportMbox example added previously
">
- <action issue="NET-565" type="update" dev="sebb">
+ <action issue="NET-528" type="add" dev="sebb">
+ FTPListParseEngine does not provide access to raw responses
+ </action>
+ <action issue="NET-565" type="add" dev="sebb">
Add FTPClient method to return an FTPFile from an MDTM command
</action>
<action issue="NET-564" type="update" dev="sebb">
Modified: commons/proper/net/trunk/src/main/java/examples/ftp/FTPClientExample.java
URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/main/java/examples/ftp/FTPClientExample.java?rev=1644802&r1=1644801&r2=1644802&view=diff
==============================================================================
--- commons/proper/net/trunk/src/main/java/examples/ftp/FTPClientExample.java (original)
+++ commons/proper/net/trunk/src/main/java/examples/ftp/FTPClientExample.java Fri Dec 12 00:57:15 2014
@@ -70,7 +70,9 @@ public final class FTPClientExample
"\t-n - list file names using NLST (remote is used as the pathname if provided)\n" +
"\t-p true|false|protocol[,true|false] - use FTPSClient with the specified protocol and/or isImplicit setting\n" +
"\t-s - store file on server (upload)\n" +
+ "\t-S - systemType set server system type (e.g. UNIX VMS WINDOWS)\n" +
"\t-t - list file details using MLST (remote is used as the pathname if provided)\n" +
+ "\t-U - save unparseable responses\n" +
"\t-w msec - wait time for keep-alive reply (setControlKeepAliveReplyTimeout)\n" +
"\t-T all|valid|none - use one of the built-in TrustManager implementations (none = JVM default)\n" +
"\t-Z timezone - set the server timezone for parsing LIST responses\n" +
@@ -84,7 +86,7 @@ public final class FTPClientExample
{
boolean storeFile = false, binaryTransfer = false, error = false, listFiles = false, listNames = false, hidden = false;
boolean localActive = false, useEpsvWithIPv4 = false, feat = false, printHash = false;
- boolean mlst = false, mlsd = false, mdtm = false;
+ boolean mlst = false, mlsd = false, mdtm = false, saveUnparseable = false;
boolean lenient = false;
long keepAliveTimeout = -1;
int controlKeepAliveReplyTimeout = -1;
@@ -101,6 +103,7 @@ public final class FTPClientExample
String encoding = null;
String serverTimeZoneId = null;
String displayTimeZoneId = null;
+ String serverType = null;
int base = 0;
@@ -161,10 +164,16 @@ public final class FTPClientExample
else if (args[base].equals("-p")) {
protocol = args[++base];
}
+ else if (args[base].equals("-S")) {
+ serverType = args[++base];
+ }
else if (args[base].equals("-t")) {
mlst = true;
minParams = 3;
}
+ else if (args[base].equals("-U")) {
+ saveUnparseable = true;
+ }
else if (args[base].equals("-w")) {
controlKeepAliveReplyTimeout = Integer.parseInt(args[++base]);
}
@@ -281,6 +290,15 @@ public final class FTPClientExample
// suppress login details
ftp.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out), true));
+ final FTPClientConfig config;
+ if (serverType != null) {
+ config = new FTPClientConfig(serverType);
+ } else {
+ config = new FTPClientConfig();
+ }
+ config.setUnparseableEntries(saveUnparseable);
+ ftp.configure(config);
+
try
{
int reply;
@@ -388,17 +406,20 @@ __main:
// Do this last because it changes the client
if (listFiles) {
if (lenient || serverTimeZoneId != null) {
- FTPClientConfig config = new FTPClientConfig();
config.setLenientFutureDates(lenient);
if (serverTimeZoneId != null) {
config.setServerTimeZoneId(serverTimeZoneId);
}
ftp.configure(config );
}
-
+
for (FTPFile f : ftp.listFiles(remote)) {
System.out.println(f.getRawListing());
- System.out.println(f.toFormattedString(displayTimeZoneId));
+ if (f.isValid()) {
+ System.out.println(f.toFormattedString(displayTimeZoneId));
+ } else {
+ System.out.println("[Unparseable]");
+ }
}
}
}
Added: commons/proper/net/trunk/src/main/java/examples/telnet/TelnetClientScript.java
URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/main/java/examples/telnet/TelnetClientScript.java?rev=1644802&view=auto
==============================================================================
--- commons/proper/net/trunk/src/main/java/examples/telnet/TelnetClientScript.java (added)
+++ commons/proper/net/trunk/src/main/java/examples/telnet/TelnetClientScript.java Fri Dec 12 00:57:15 2014
@@ -0,0 +1,75 @@
+package examples.telnet;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.SocketTimeoutException;
+
+import org.apache.commons.net.telnet.TelnetClient;
+
+public class TelnetClientScript {
+
+ private final InputStream in;
+ private final OutputStream out;
+ private final TelnetClient telnet = new TelnetClient();
+ TelnetClientScript(String host, int port) throws IOException {
+ telnet.connect(host, port);
+ telnet.setSoTimeout(1000);
+ this.in=telnet.getInputStream();
+ this.out=telnet.getOutputStream();
+ }
+
+ void login() {
+
+ }
+ void write(String command) throws IOException {
+ out.write(command.getBytes());
+ out.write('\r');
+ out.write('\n');
+ }
+
+ void readResponse() {
+ int i;
+ try {
+ while((i=in.read()) != -1){
+ System.out.print((char) i);
+ }
+ } catch (SocketTimeoutException e) {
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ public static void main(String [] args) throws IOException{
+ if(args.length < 1)
+ {
+ System.err.println("Usage: TelnetClientScriptExample <remote-ip> [<remote-port>]");
+ System.exit(1);
+ }
+
+ String remoteip = args[0];
+
+ int remoteport;
+
+ if (args.length > 1)
+ {
+ remoteport = (new Integer(args[1])).intValue();
+ }
+ else
+ {
+ remoteport = 23;
+ }
+
+ TelnetClientScript script = new TelnetClientScript(remoteip, remoteport);
+
+ script.login();
+ script.write("INFORMATION");
+ script.readResponse();
+ System.out.println("--------------------");
+
+ script.write("INFORMATION");
+ script.readResponse();
+ System.out.println("--------------------");
+ }
+
+}
Modified: commons/proper/net/trunk/src/main/java/org/apache/commons/net/ftp/FTPClient.java
URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/main/java/org/apache/commons/net/ftp/FTPClient.java?rev=1644802&r1=1644801&r2=1644802&view=diff
==============================================================================
--- commons/proper/net/trunk/src/main/java/org/apache/commons/net/ftp/FTPClient.java (original)
+++ commons/proper/net/trunk/src/main/java/org/apache/commons/net/ftp/FTPClient.java Fri Dec 12 00:57:15 2014
@@ -3361,7 +3361,7 @@ implements Configurable
{
Socket socket = _openDataConnection_(FTPCmd.LIST, getListArguments(pathname));
- FTPListParseEngine engine = new FTPListParseEngine(parser);
+ FTPListParseEngine engine = new FTPListParseEngine(parser, __configuration);
if (socket == null)
{
return engine;
@@ -3388,7 +3388,7 @@ implements Configurable
private FTPListParseEngine initiateMListParsing(String pathname) throws IOException
{
Socket socket = _openDataConnection_(FTPCmd.MLSD, pathname);
- FTPListParseEngine engine = new FTPListParseEngine(MLSxEntryParser.getInstance());
+ FTPListParseEngine engine = new FTPListParseEngine(MLSxEntryParser.getInstance(), __configuration);
if (socket == null)
{
return engine;
Modified: commons/proper/net/trunk/src/main/java/org/apache/commons/net/ftp/FTPClientConfig.java
URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/main/java/org/apache/commons/net/ftp/FTPClientConfig.java?rev=1644802&r1=1644801&r2=1644802&view=diff
==============================================================================
--- commons/proper/net/trunk/src/main/java/org/apache/commons/net/ftp/FTPClientConfig.java (original)
+++ commons/proper/net/trunk/src/main/java/org/apache/commons/net/ftp/FTPClientConfig.java Fri Dec 12 00:57:15 2014
@@ -217,6 +217,7 @@ public class FTPClientConfig
private String serverLanguageCode = null;
private String shortMonthNames = null;
private String serverTimeZoneId = null;
+ private boolean saveUnparseableEntries = false;
/**
@@ -583,5 +584,21 @@ public class FTPClientConfig
return LANGUAGE_CODE_MAP.keySet();
}
+ /**
+ * Allow list parsing methods to create basic FTPFile entries if parsing fails
+ * @param saveUnparseable if true, then create FTPFile entries if parsing fails
+ * @since 3.4
+ */
+ public void setUnparseableEntries(boolean saveUnparseable) {
+ this.saveUnparseableEntries = saveUnparseable;
+ }
+
+ /**
+ * @return true if list parsing should return FTPFile entries even for unparseable response lines
+ * @since 3.4
+ */
+ public boolean getUnparseableEntries() {
+ return this.saveUnparseableEntries;
+ }
}
Modified: commons/proper/net/trunk/src/main/java/org/apache/commons/net/ftp/FTPFile.java
URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/main/java/org/apache/commons/net/ftp/FTPFile.java?rev=1644802&r1=1644801&r2=1644802&view=diff
==============================================================================
--- commons/proper/net/trunk/src/main/java/org/apache/commons/net/ftp/FTPFile.java (original)
+++ commons/proper/net/trunk/src/main/java/org/apache/commons/net/ftp/FTPFile.java Fri Dec 12 00:57:15 2014
@@ -65,13 +65,34 @@ public class FTPFile implements Serializ
private long _size;
private String _rawListing, _user, _group, _name, _link;
private Calendar _date;
+ // If this is null, then list entry parsing failed
private final boolean[] _permissions[]; // e.g. _permissions[USER_ACCESS][READ_PERMISSION]
/*** Creates an empty FTPFile. ***/
public FTPFile()
{
_permissions = new boolean[3][3];
- _rawListing = null;
+ _type = UNKNOWN_TYPE;
+ // init these to values that do not occur in listings
+ // so can distinguish which fields are unset
+ _hardLinkCount = 0; // 0 is invalid as a link count
+ _size = -1; // 0 is valid, so use -1
+ _user = "";
+ _group = "";
+ _date = null;
+ _name = null;
+ }
+
+ /**
+ * Constructor for use by {@link FTPListParseEngine} only.
+ * Used to create FTPFile entries for failed parses
+ * @param rawListing line that could not be parsed.
+ * @since 3.4
+ */
+ FTPFile(String rawListing)
+ {
+ _permissions = null; // flag that entry is invalid
+ _rawListing = rawListing;
_type = UNKNOWN_TYPE;
// init these to values that do not occur in listings
// so can distinguish which fields are unset
@@ -151,6 +172,18 @@ public class FTPFile implements Serializ
return (_type == UNKNOWN_TYPE);
}
+ /**
+ * Used to indicate whether an entry is valid or not.
+ * If the entry is invalid, only the {@link #getRawListing()} method will be useful.
+ * Other methods may fail.
+ *
+ * Used in conjunction with list parsing that preseverves entries that failed to parse.
+ * @return true if the entry is valid
+ * @since 3.4
+ */
+ public boolean isValid() {
+ return (_permissions != null);
+ }
/***
* Set the type of the file (<code>DIRECTORY_TYPE</code>,
@@ -410,6 +443,10 @@ public class FTPFile implements Serializ
*/
public String toFormattedString(final String timezone)
{
+
+ if (!isValid()) {
+ return getRawListing();
+ }
StringBuilder sb = new StringBuilder();
Formatter fmt = new Formatter(sb);
sb.append(formatType());
Modified: commons/proper/net/trunk/src/main/java/org/apache/commons/net/ftp/FTPListParseEngine.java
URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/main/java/org/apache/commons/net/ftp/FTPListParseEngine.java?rev=1644802&r1=1644801&r2=1644802&view=diff
==============================================================================
--- commons/proper/net/trunk/src/main/java/org/apache/commons/net/ftp/FTPListParseEngine.java (original)
+++ commons/proper/net/trunk/src/main/java/org/apache/commons/net/ftp/FTPListParseEngine.java Fri Dec 12 00:57:15 2014
@@ -80,9 +80,24 @@ public class FTPListParseEngine {
private ListIterator<String> _internalIterator = entries.listIterator();
private final FTPFileEntryParser parser;
+ // Should invalid files (parse failures) be allowed?
+ private final boolean saveUnparseableEntries;
public FTPListParseEngine(FTPFileEntryParser parser) {
+ this(parser, null);
+ }
+
+ /**
+ * Intended for use by FTPClient only
+ * @since 3.4
+ */
+ FTPListParseEngine(FTPFileEntryParser parser, FTPClientConfig configuration) {
this.parser = parser;
+ if (configuration != null) {
+ this.saveUnparseableEntries = configuration.getUnparseableEntries();
+ } else {
+ this.saveUnparseableEntries = false;
+ }
}
/**
@@ -164,6 +179,9 @@ public class FTPListParseEngine {
while (count > 0 && this._internalIterator.hasNext()) {
String entry = this._internalIterator.next();
FTPFile temp = this.parser.parseFTPEntry(entry);
+ if (temp == null && saveUnparseableEntries) {
+ temp = new FTPFile(entry);
+ }
tmpResults.add(temp);
count--;
}
@@ -203,6 +221,9 @@ public class FTPListParseEngine {
while (count > 0 && this._internalIterator.hasPrevious()) {
String entry = this._internalIterator.previous();
FTPFile temp = this.parser.parseFTPEntry(entry);
+ if (temp == null && saveUnparseableEntries) {
+ temp = new FTPFile(entry);
+ }
tmpResults.add(0,temp);
count--;
}
@@ -250,6 +271,9 @@ public class FTPListParseEngine {
while (iter.hasNext()) {
String entry = iter.next();
FTPFile temp = this.parser.parseFTPEntry(entry);
+ if (temp == null && saveUnparseableEntries) {
+ temp = new FTPFile(entry);
+ }
if (filter.accept(temp)){
tmpResults.add(temp);
}
Modified: commons/proper/net/trunk/src/test/java/org/apache/commons/net/ftp/FTPClientTest.java
URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/test/java/org/apache/commons/net/ftp/FTPClientTest.java?rev=1644802&r1=1644801&r2=1644802&view=diff
==============================================================================
--- commons/proper/net/trunk/src/test/java/org/apache/commons/net/ftp/FTPClientTest.java (original)
+++ commons/proper/net/trunk/src/test/java/org/apache/commons/net/ftp/FTPClientTest.java Fri Dec 12 00:57:15 2014
@@ -18,8 +18,12 @@
package org.apache.commons.net.ftp;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import org.apache.commons.net.ftp.parser.UnixFTPEntryParser;
+
import junit.framework.TestCase;
public class FTPClientTest extends TestCase {
@@ -100,4 +104,25 @@ public class FTPClientTest extends TestC
client.__createParser(null);
assertSame(entryParser, client.getEntryParser()); // parser was cached
}
+ public void testUnparseableFiles() throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ baos.write("-rwxr-xr-x 2 root root 4096 Mar 2 15:13 zxbox".getBytes());
+ baos.write(new byte[]{'\r','\n'});
+ baos.write("zrwxr-xr-x 2 root root 4096 Mar 2 15:13 zxbox".getBytes());
+ baos.write(new byte[]{'\r','\n'});
+ FTPFileEntryParser parser = new UnixFTPEntryParser();
+ FTPClientConfig config = new FTPClientConfig();
+ FTPListParseEngine engine = new FTPListParseEngine(parser, config);
+ config.setUnparseableEntries(false);
+ engine.readServerList(new ByteArrayInputStream(baos.toByteArray()), null); // use default encoding
+ FTPFile[] files = engine.getFiles();
+ assertEquals(1, files.length);
+ config.setUnparseableEntries(true);
+ engine = new FTPListParseEngine(parser, config );
+ engine.readServerList(new ByteArrayInputStream(baos.toByteArray()), null); // use default encoding
+ files = engine.getFiles();
+ assertEquals(2, files.length);
+ }
+
+
}