#include "ftpcontrolconnection.h"
#include "ftplistcommand.h"
#include "ftpretrcommand.h"
#include "ftpstorcommand.h"
#include "dataconnection.h"
#include <QFileInfo>
#include <QDateTime>
#include <QDir>
#include <QStringList>
#include <QEventLoop>
#include <QDebug>
#include <QTimer>
#include <QTcpSocket>
#include <QHostAddress>
FtpControlConnection::FtpControlConnection(QObject *parent, QTcpSocket *socket, const QString &rootPath, const QString &userName, const QString &password, bool readOnly) :
QObject(parent)
{
this->socket = socket;
this->userName = userName;
this->password = password;
this->rootPath = rootPath;
this->readOnly = readOnly;
isLoggedIn = false;
encryptDataConnection = false;
socket->setParent(this);
connect(socket, SIGNAL(readyRead()), this, SLOT(acceptNewData()));
connect(socket, SIGNAL(disconnected()), this, SLOT(deleteLater()));
currentDirectory = "/";
dataConnection = new DataConnection(this);
reply("220 Welcome to QFtpServer.");
}
FtpControlConnection::~FtpControlConnection()
{
}
void FtpControlConnection::acceptNewData()
{
if (!socket->canReadLine()) {
return;
}
// Note how we execute only one line, and use QTimer::singleShot, instead
// of using a for-loop until no more lines are available. This is done
// so we don't block the event loop for a long time.
processCommand(QString::fromUtf8(socket->readLine()).trimmed());
QTimer::singleShot(0, this, SLOT(acceptNewData()));
}
void FtpControlConnection::disconnectFromHost()
{
socket->disconnectFromHost();
}
bool FtpControlConnection::verifyAuthentication(const QString &command)
{
if (isLoggedIn) {
return true;
}
const char *commandsRequiringAuth[] = {
"PWD", "CWD", "TYPE", "PORT", "PASV", "LIST", "RETR", "REST",
"NLST", "SIZE", "SYST", "PROT", "CDUP", "OPTS", "PBSZ", "NOOP",
"STOR", "MKD", "RMD", "DELE", "RNFR", "RNTO", "APPE"
};
for (size_t ii = 0; ii < sizeof(commandsRequiringAuth)/sizeof(commandsRequiringAuth[0]); ++ii) {
if (command == commandsRequiringAuth[ii]) {
reply("530 You must log in first.");
return false;
}
}
return true;
}
bool FtpControlConnection::verifyWritePermission(const QString &command)
{
if (!readOnly) {
return true;
}
const char *commandsRequiringWritePermission[] = {
"STOR", "MKD", "RMD", "DELE", "RNFR", "RNTO", "APPE"
};
for (size_t ii = 0; ii < sizeof(commandsRequiringWritePermission)/sizeof(commandsRequiringWritePermission[0]); ++ii) {
if (command == commandsRequiringWritePermission[ii]) {
reply("550 Can't do that in read-only mode.");
return false;
}
}
return true;
}
QString FtpControlConnection::stripFlagL(const QString &fileName)
{
QString a = fileName.toUpper();
if (a == "-L") {
return "";
}
if (a.startsWith("-L ")) {
return fileName.mid(3);
}
return fileName;
}
void FtpControlConnection::parseCommand(const QString &entireCommand, QString *command, QString *commandParameters)
{
// Split parameters and command.
int pos = entireCommand.indexOf(' ');
if (-1 != pos) {
*command = entireCommand.left(pos).trimmed().toUpper();
*commandParameters = entireCommand.mid(pos+1).trimmed();
} else {
*command = entireCommand.trimmed().toUpper();
}
}
QString FtpControlConnection::toLocalPath(const QString &fileName) const
{
QString localPath = fileName;
// Some FTP clients send backslashes.
localPath.replace('\\', '/');
// If this is a relative path, we prepend the current directory.
if (!localPath.startsWith('/')) {
localPath = currentDirectory + '/' + localPath;
}
// Evaluate all the ".." and ".", "/path/././to/dir/../.." becomes "/path".
// Note we do this **before** prepending the root path, in order to avoid
// "jailbreaking" out of the "chroot".
QStringList components;
foreach (const QString &component, localPath.split('/', QString::SkipEmptyParts)) {
if (component == "..") {
if (!components.isEmpty()) {
components.pop_back();
}
} else if (component != ".") {
components += component;
}
}
// Prepend the root path.
localPath = QDir::cleanPath(rootPath + '/' + components.join("/"));
qDebug() << "to local path" << fileName << "->" << localPath;
return localPath;
}
void FtpControlConnection::reply(const QString &replyCode)
{
qDebug() << "reply" << replyCode;
socket->write((replyCode + "\r\n").toUtf8());
}
void FtpControlConnection::processCommand(const QString &entireCommand)
{
qDebug() << "command" << entireCommand;
QString command;
QString commandParameters;
parseCommand(entireCommand, &command, &commandParameters);
if (!verifyAuthentication(command)) {
return;
}
if (!verifyWritePermission(command)) {
return;
}
if ("USER" == command) {
reply("331 User name OK, need password.");
} else if ("PASS" == command) {
pass(commandParameters);
} else if ("QUIT" == command) {
quit();
} else if ("AUTH" == command && "TLS" == commandParameters.toUpper()) {
auth();
} else if ("FEAT" == command) {
feat();
} else if ("PWD" == command) {
reply(QString("257 \"%1\"").arg(currentDirectory));
} else if ("CWD" == command) {
cwd(commandParameters);
} else if ("TYPE" == command) {
reply("200 Command okay.");
} else if ("PORT" == command) {
port(commandParameters);
} else if ("PASV" == command) {
pasv();
} else if ("LIST" == command) {
list(toLocalPath(stripFlagL(commandParameters)), false);
} else if ("RETR" == command) {
retr(toLocalPath(commandParameters));
} else if ("REST" == command) {
reply("350 Requested file action pending further information.");
} else if ("NLST" == command) {
list(toLocalPath(stripFlagL(commandParameters)), true);
} else if ("SIZE" == command) {
size(toLocalPath(commandParameters));
} else if ("SYST" == command) {
reply("215 UNIX");
} else if ("PROT" == command) {
prot(commandParameters.toUpper());
} else if ("CDUP" == command) {
cdup();
} else if ("OPTS" == command && "UTF8 ON" == commandParameters.toUpper()) {
reply("200 Command okay.");
} else if ("PBSZ" == command && "0" == commandParameters.toUpper()) {
reply("200 Command okay.");
} else if ("NOOP" == command) {
reply("200 Command okay.");
} else if ("STOR" == command) {
stor(toLocalPath(commandParameters));
} else if ("MKD" == command) {
mkd(toLocalPath(commandParameters));
} else if ("RMD" == command) {
rmd(toLocalPath(commandParameters));
} else if ("DELE" == command) {
dele(toLocalPath(commandParameters));
} else if ("RNFR" == command) {
reply("350 Requested file action pending further information.");
} else if ("RNTO" == command) {
rnto(toLocalPath(commandParameters));
} else if ("APPE" == command) {
stor(toLocalPath(commandParameters), true);
} else {
reply("502 Command not implemented.");
}
lastProcessedCommand = entireCommand;
}
void FtpControlConnection::startOrScheduleCommand(FtpCommand *ftpCommand)
{
connect(ftpCommand, SIGNAL(reply(QString)), this, SLOT(reply(QString)));
if (!dataConnection->setFtpCommand(ftpCommand)) {
delete ftpCommand;
reply("425 Can't open data connection.");
re
没有合适的资源?快使用搜索试试~ 我知道了~
QT实现FTPServer和FTPClient.zip
共63个文件
cpp:21个
o:19个
h:10个
需积分: 50 18 下载量 58 浏览量
2020-12-14
14:51:18
上传
评论 2
收藏 7.82MB ZIP 举报
温馨提示
使用Qt实现的FTP服务器,支持文件的上传和下载 ,内涵代码和常用ftp工具,QT5编译完美实现,使用Qt实现的FTP服务器,支持文件的上传和下载 ,内涵代码和常用ftp工具,QT5编译完美实现,
资源推荐
资源详情
资源评论
收起资源包目录
QT实现FTPServer和FTPClient.zip (63个子文件)
QT实现FTPServer和FTPClient
CXTools
CXTools.pro.user 22KB
mainwindow.ui 2KB
mainwindow.cpp 3KB
FtpManager.h 1KB
main.cpp 183B
mainwindow.h 764B
FtpManager.cpp 2KB
CXTools.pro 1KB
HA_FileZilla_Server_v0933.rar 3.5MB
FileZilla_Server-0_9_60_2.exe 2.14MB
FtpServer
build-FtpServer-Desktop_Qt_5_5_0_MinGW_32bit-Debug
object_script.FtpServer.Release 506B
release
debug
moc_ftpserver.cpp 4KB
ftpserver.o 248KB
ftpcontrolconnection.o 301KB
main.o 325KB
moc_ftpstorcommand.cpp 3KB
ftpstorcommand.o 171KB
moc_sslserver.o 165KB
FtpServer.exe 3.25MB
dataconnection.o 183KB
moc_ftpserver.o 191KB
ftpcommand.o 152KB
moc_ftplistcommand.cpp 3KB
moc_ftpstorcommand.o 170KB
ftpretrcommand.o 171KB
ftplistcommand.o 273KB
moc_ftpcommand.o 170KB
moc_ftpretrcommand.cpp 4KB
moc_sslserver.cpp 3KB
moc_ftpcommand.cpp 4KB
moc_ftpcontrolconnection.cpp 4KB
moc_ftpcontrolconnection.o 172KB
sslserver.o 169KB
moc_dataconnection.cpp 4KB
moc_ftplistcommand.o 170KB
moc_ftpretrcommand.o 170KB
moc_ftpserverdialog.cpp 4KB
moc_dataconnection.o 183KB
ftpserverdialog.o 464KB
moc_ftpserverdialog.o 183KB
Makefile 21KB
Makefile.Debug 123KB
Makefile.Release 124KB
object_script.FtpServer.Debug 472B
FtpServer
ftpretrcommand.h 565B
ftpcontrolconnection.cpp 13KB
FtpServer.pro.user 18KB
dataconnection.h 2KB
ftpcontrolconnection.h 5KB
FtpServer.pro 743B
ftpretrcommand.cpp 1KB
ftplistcommand.h 788B
ftplistcommand.cpp 4KB
ftpserverdialog.h 1KB
ftpstorcommand.h 624B
ftpserver.h 2KB
ftpserverdialog.cpp 3KB
main.cpp 193B
ftpcommand.h 502B
dataconnection.cpp 2KB
ftpserver.cpp 2KB
ftpstorcommand.cpp 1KB
ftpcommand.cpp 374B
共 63 条
- 1
资源评论
Create_Joy
- 粉丝: 90
- 资源: 83
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功