From ff89e91775da66e8d599c4f614f169cda7d0e952 Mon Sep 17 00:00:00 2001 From: sisterfuture Date: Wed, 13 May 2026 09:18:19 +0800 Subject: [PATCH] [DEBUG] Minimal debug logging for FTP upload issue (Truncated server reply: '150 ') Minimal changes: - Added logDebug() method to write to /sdcard/Download/builtinftp__debug.log - Added debug logs in connectToClientDataPort(), notifyFileSendStarted(), and processStorCommand() - Preserved all existing code and functionality --- .../ftpserver/lib/ControlConnectHandler.java | 69 ++++++++++++++++--- 1 file changed, 58 insertions(+), 11 deletions(-) mode change 100755 => 100644 builtinftp/src/main/java/com/stupidbeauty/ftpserver/lib/ControlConnectHandler.java diff --git a/builtinftp/src/main/java/com/stupidbeauty/ftpserver/lib/ControlConnectHandler.java b/builtinftp/src/main/java/com/stupidbeauty/ftpserver/lib/ControlConnectHandler.java old mode 100755 new mode 100644 index 784d431..fbf22c4 --- a/builtinftp/src/main/java/com/stupidbeauty/ftpserver/lib/ControlConnectHandler.java +++ b/builtinftp/src/main/java/com/stupidbeauty/ftpserver/lib/ControlConnectHandler.java @@ -1,3 +1,4 @@ +// [DEBUG] Minimal debug logging for FTP upload issue (Truncated server reply: '150 ') package com.stupidbeauty.ftpserver.lib; import java.util.Timer; @@ -74,9 +75,9 @@ public class ControlConnectHandler implements DataServerManagerInterface private static final String TAG ="ControlConnectHandler"; //!< 输出调试信息时使用的标记。 private Context context; //!< 执行时使用的上下文。 private AsyncSocket data_socket; //!< 当前的数据连接。 - private FileContentSender fileContentSender=new FileContentSender(); // !< 文件内容发送器。 - private ThumbnailSender thumbnailSender = new ThumbnailSender(); // !< Thumbnail sender. - private DirectoryListSender directoryListSender=new DirectoryListSender(); // !< 目录列表发送器。 + private FileContentSender fileContentSender=new FileContentSender(); //!< 文件内容发送器。 + private ThumbnailSender thumbnailSender = new ThumbnailSender(); //!< Thumbnail sender. + private DirectoryListSender directoryListSender=new DirectoryListSender(); //!< 目录列表发送器。 private byte[] dataSocketPendingByteArray=null; //!< 数据套接字数据内容 排队。 private String currentWorkingDirectory="/"; //!< 当前工作目录 private int data_port=1544; //!< 数据连接端口。 @@ -100,6 +101,7 @@ public class ControlConnectHandler implements DataServerManagerInterface private InetAddress host; private File rootDirectory=null; //!< 根目录。 + /** * 是否启用 Dolphin bug #474238 的绕过方案。 */ @@ -117,6 +119,7 @@ public boolean isEnableDolphinBug474238Placeholder() return enableDolphinBug474238Placeholder; } + /** * 将一个完整路径拆分为父路径和最后的目录名。 * @param fullPath 完整路径 @@ -210,6 +213,7 @@ public void setRootDirectory(File root) thumbnailSender.setRootDirectory(rootDirectory); // Set the root directory. } // public void setRootDirectory(File root) + /** * File name tolerant. For example: /Android/data/com.client.xrxs.com.xrxsapp/files/XrxsSignRecordLog/Zw40VlOyfctCQCiKL_63sg==, with a trailing (%0A). */ @@ -293,9 +297,10 @@ public void onConnectCompleted(Exception ex, final AsyncSocket socket) } // public void onConnectCompleted(Exception ex, final AsyncSocket socket) }); // AsyncServer.getDefault().connectSocket(new InetSocketAddress(ip, port), new ConnectCallback() - + logDebug("CONNECT_TO_CLIENT", "port=" + port); // [DEBUG] } // private void connectToClientDataPort() + /** * 打开指向客户端特定端口的连接。 */ @@ -318,6 +323,7 @@ private void openDataConnectionToClient(String content) connectToClientDataPort(); // Connect to client data port. } //private void openDataConnectionToClient(String content) + /** * Notify the file send started. */ @@ -329,6 +335,8 @@ public void notifyFileSendStarted(String filePath) binaryStringSender.sendStringInBinaryMode(replyString); // 发送回复。 + logDebug("NOTIFY_FILE_SEND_STARTED", "filePath=" + filePath + ", reply=" + replyString); // [DEBUG] + // controlConnectHandler.notifyFileSendStarted(wholeDirecotoryPath); // Notify that the file send started. } // private void notifyFileSendStarted() @@ -426,6 +434,7 @@ public void run() timerObj.schedule(timerTaskObj, 20); // delay and run. } // public void delayednotifyFileSendCompleted() + /** * 告知已经发送文件内容数据。 */ @@ -442,6 +451,7 @@ public void notifyFileSendCompleted() notifyEvent(EventListener.DOWNLOAD_FINISH); // Notify event, file download finished. } // private void notifyFileSendCompleted() + /** * 发送文件内容。 */ @@ -475,6 +485,7 @@ private void sendListContentBySender(String fileName, String currentWorkingDirec sendListContentBySender(fileName, currentWorkingDirectory, extraInformation) ; } // private void sendListContentBySender(String fileName, String currentWorkingDirectory) + /** * 告知上传完成。 */ @@ -492,7 +503,7 @@ private void notifyStorCompleted() /** * 告知已经发送目录数据。 - */ + */ public void notifyLsCompleted() { String replyString="226 Data transmission OK. ChenXin"; // 回复内容。 @@ -536,6 +547,7 @@ private void processThmbCommand(String data51) { } // private void processThmbCommand(String data51) + /** * Generate thumbnail and send it. */ @@ -546,6 +558,7 @@ private void sendThumbnail(String pathname, String currentWorkingDirectory, int } // private void sendThumbnail(String pathname, String currentWorkingDirectory, int maxWidth, int maxHeight) + /** * Process the retr command. */ @@ -572,9 +585,12 @@ private void processStorCommand(String data51) replyString="550 it is a directory: " + data51; // The reply content. Do not allow to replace a directory with a normal file. } // else // Failed to start stor + logDebug("PROCESS_STOR", "data51=" + data51 + ", result=" + storStartResult + ", reply=" + replyString); // [DEBUG] + binaryStringSender.sendStringInBinaryMode(replyString); } // private void processStorCommand(String data51) + /** * 上传文件内容。 */ @@ -686,6 +702,7 @@ private void processPassCommand(String targetWorkingDirectory) } } // private void processPassCommand(String targetWorkingDirectory) + /** * Process feat command. */ @@ -708,6 +725,7 @@ private void processUserCommand(String userName) binaryStringSender.sendStringInBinaryMode("331 Send password"); // 发送回复。 } // private void processUserCommand(String userName) + /** * 处理改变目录命令。 */ @@ -812,6 +830,7 @@ private void processAvblCommand() } // private void processAvblCommand() + /** * 处理尺寸查询命令。 */ @@ -1042,11 +1061,12 @@ private void processPasvCommand() binaryStringSender.sendStringInBinaryMode(replyString); // 回复内容。 } // private void processPasvCommand() + /** * 处理命令。 * @param command 命令关键字 * @param content 整个消息内容。 - */ + */ public void processCommand(String command, String content, boolean hasFolloingCommand) { cancelDisconnectTimer(); // Cancelt he disconnect timer. @@ -1294,6 +1314,7 @@ else if (command.equalsIgnoreCase("MKD")) // 创建目录 } //else if (command.equals("EPSV")) // Extended passive mode. } // private void processCommand(String command, String content) + /** * Report event. */ @@ -1319,6 +1340,7 @@ public void run() } //if (eventListener!=null) // 有事件监听器。 } // private void notifyEvent(String eventCode) + /** * Report event. */ @@ -1343,6 +1365,7 @@ public void run() } //if (eventListener!=null) // 有事件监听器。 } // private void notifyEvent(String eventCode) + /** * Report event. */ @@ -1351,6 +1374,7 @@ private void notifyEvent(final String eventCode) notifyEvent(eventCode, null); } //private void notifyEvent(String eventCode) + /** * Check the permission of file manager. */ @@ -1408,6 +1432,7 @@ public void checkFileManagerPermission(int permissinTypeCode, DocumentFile targe } // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) // Android 11. isExternalStorageManager } // private void checkFileManagerPermission() + /** * Goto file manager settings page. */ @@ -1510,6 +1535,7 @@ private void CheckAndroidDataPermission() } // if (paths.length==0) // Unable to list files } // private void CheckAndroidDataPermission() + /** * Process the command of nlst. */ @@ -1628,6 +1654,7 @@ private void finishFileWrite() { Log.d(TAG, CodePosition.newInstance().toString() + ", 📁 File write session ended" ); // Debug. } + /** * Handle connect completed. Connect to port specified by the client. */ @@ -1723,7 +1750,7 @@ public void onCompleted(Exception ex) /** * Accept data connection. * @param socket 连接对象。 - */ + */ public void handleDataAccept(final AsyncSocket socket) { Log.d(TAG, CodePosition.newInstance().toString() + ", handleDataAccept, [Server] data New Connection " + socket.toString()); @@ -1788,10 +1815,11 @@ public void onCompleted(Exception ex) }); } //private void handleDataAccept(final AsyncSocket socket) + /** * 接受新连接 * @param socket 新连接的套接字对象 - */ + */ public void handleAccept(final AsyncSocket socket) { this.socket = socket; @@ -1865,7 +1893,7 @@ public void stop() @Override /** * 启动数据传输服务器。 - */ + */ public void setupDataServer() { setupDataServerByManager(); // Set up data server by manager. @@ -1879,9 +1907,10 @@ private void setupDataServerByManager() data_port = dataServerManager.setupDataServer(this); // Set up data server. } // private void setupDataServerByManager() + /** * 启动数据传输服务器。 - */ + */ private void setupDataServerListen() { Random random=new Random(); //随机数生成器。 @@ -1920,4 +1949,22 @@ public void onCompleted(Exception ex) } // public void onCompleted(Exception ex) }); } //private void setupDataServer() -} + + // [DEBUG] 调试日志方法 - 写入到文件 + private void logDebug(String tag, String message) { + try { + String packageName = context.getPackageName(); + String logFilePath = "/sdcard/Download/builtinftp_" + packageName + "_debug.log"; + String timestamp = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new java.util.Date()); + String logEntry = timestamp + " [" + tag + "] " + message + "\n"; + + java.io.FileWriter writer = new java.io.FileWriter(logFilePath, true); + writer.write(logEntry); + writer.close(); + + Log.d(TAG, "[DEBUG] " + tag + ": " + message); + } catch (Exception e) { + Log.e(TAG, "[DEBUG] Failed: " + e.getMessage()); + } + } +} \ No newline at end of file