pull/1/head
Tatsuhiro Tsujikawa 2006-02-21 12:28:42 +00:00
parent 5a8710676d
commit e0aa767f94
14 changed files with 1161 additions and 0 deletions

207
src/FtpConnection.cc Normal file
View File

@ -0,0 +1,207 @@
/* <!-- copyright */
/*
* aria2 - a simple utility for downloading files faster
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* copyright --> */
#include "FtpConnection.h"
#include "Util.h"
#include "DlAbortEx.h"
#include "message.h"
FtpConnection::FtpConnection(int cuid, const Socket* socket, const Request* req, const Option* op, const Logger* logger):cuid(cuid), socket(socket), req(req), option(op), logger(logger) {}
FtpConnection::~FtpConnection() {}
void FtpConnection::sendUser() const {
string request = "USER "+option->get("ftp_user")+"\r\n";
logger->info(MSG_SENDING_FTP_REQUEST, cuid, request.c_str());
socket->writeData(request);
}
void FtpConnection::sendPass() const {
string request = "PASS "+option->get("ftp_passwd")+"\r\n";
logger->info(MSG_SENDING_FTP_REQUEST, cuid, "PASS ********");
socket->writeData(request);
}
void FtpConnection::sendType() const {
string request = "TYPE "+option->get("ftp_type")+"\r\n";
logger->info(MSG_SENDING_FTP_REQUEST, cuid, request.c_str());
socket->writeData(request);
}
void FtpConnection::sendCwd() const {
string request = "CWD "+req->getDir()+"\r\n";
logger->info(MSG_SENDING_FTP_REQUEST, cuid, request.c_str());
socket->writeData(request);
}
void FtpConnection::sendSize() const {
string request = "SIZE "+req->getFile()+"\r\n";
logger->info(MSG_SENDING_FTP_REQUEST, cuid, request.c_str());
socket->writeData(request);
}
void FtpConnection::sendPasv() const {
string request = "PASV\r\n";
logger->info(MSG_SENDING_FTP_REQUEST, cuid, request.c_str());
socket->writeData(request);
}
Socket* FtpConnection::sendPort() const {
Socket* serverSocket = new Socket();
try {
serverSocket->beginListen();
pair<string, int> addrinfo;
socket->getAddrInfo(addrinfo);
int ipaddr[4];
sscanf(addrinfo.first.c_str(), "%d.%d.%d.%d",
&ipaddr[0], &ipaddr[1], &ipaddr[2], &ipaddr[3]);
serverSocket->getAddrInfo(addrinfo);
string request = "PORT "+
Util::itos(ipaddr[0])+","+Util::itos(ipaddr[1])+","+
Util::itos(ipaddr[2])+","+Util::itos(ipaddr[3])+","+
Util::itos(addrinfo.second/256)+","+Util::itos(addrinfo.second%256)+"\r\n";
logger->info(MSG_SENDING_FTP_REQUEST, cuid, request.c_str());
socket->writeData(request);
} catch (Exception* ex) {
delete serverSocket;
throw;
}
return serverSocket;
}
void FtpConnection::sendRest(const Segment& segment) const {
string request = "REST "+Util::llitos(segment.sp+segment.ds)+"\r\n";
logger->info(MSG_SENDING_FTP_REQUEST, cuid, request.c_str());
socket->writeData(request);
}
void FtpConnection::sendRetr() const {
string request = "RETR "+req->getFile()+"\r\n";
logger->info(MSG_SENDING_FTP_REQUEST, cuid, request.c_str());
socket->writeData(request);
}
int FtpConnection::getStatus(string response) const {
int status;
// TODO we must handle when the response is not like "%d %*s"
// In this case, we return 0
if(sscanf(response.c_str(), "%d %*s", &status) == 1) {
return status;
} else {
return 0;
}
}
bool FtpConnection::isEndOfResponse(int status, string response) const {
if(response.size() <= 4) {
return false;
}
// if forth character of buf is '-', then multi line response is expected.
if(response.at(3) == '-') {
// multi line response
string::size_type p;
p = response.find("\r\n"+Util::itos(status)+" ");
if(p == string::npos) {
return false;
}
}
if(Util::endsWith(response, "\r\n")) {
return true;
} else {
return false;
}
}
bool FtpConnection::bulkReceiveResponse(pair<int, string>& response) {
char buf[1024];
while(socket->isReadable(0)) {
int size = sizeof(buf)-1;
socket->readData(buf, size);
buf[size] = '\0';
strbuf += buf;
}
int status;
if(strbuf.size() >= 4) {
status = getStatus(strbuf);
if(status == 0) {
throw new DlAbortEx(EX_INVALID_RESPONSE);
}
} else {
return false;
}
if(isEndOfResponse(status, strbuf)) {
logger->info(MSG_RECEIVE_RESPONSE, cuid, strbuf.c_str());
response.first = status;
response.second = strbuf;
strbuf.erase();
return true;
} else {
// didn't receive response fully.
return false;
}
}
int FtpConnection::receiveResponse() {
pair<int, string> response;
if(bulkReceiveResponse(response)) {
return response.first;
} else {
return 0;
}
}
int FtpConnection::receiveSizeResponse(long long int& size) {
pair<int, string> response;
if(bulkReceiveResponse(response)) {
if(response.first == 213) {
sscanf(response.second.c_str(), "%*d %Ld", &size);
}
return response.first;
} else {
return 0;
}
}
int FtpConnection::receivePasvResponse(pair<string, int>& dest) {
pair<int, string> response;
if(bulkReceiveResponse(response)) {
if(response.first == 227) {
// we assume the format of response is "227 Entering Passive Mode (h1,h2,h3,h4,p1,p2)."
int h1, h2, h3, h4, p1, p2;
string::size_type p = response.second.find("(");
if(p >= 4) {
sscanf(response.second.substr(response.second.find("(")).c_str(),
"(%d,%d,%d,%d,%d,%d).",
&h1, &h2, &h3, &h4, &p1, &p2);
// ip address
dest.first = Util::itos(h1)+"."+Util::itos(h2)+"."+Util::itos(h3)+"."+Util::itos(h4);
// port number
dest.second = 256*p1+p2;
} else {
throw new DlAbortEx(EX_INVALID_RESPONSE);
}
}
return response.first;
} else {
return 0;
}
}

65
src/FtpConnection.h Normal file
View File

@ -0,0 +1,65 @@
/* <!-- copyright */
/*
* aria2 - a simple utility for downloading files faster
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* copyright --> */
#ifndef _D_FTP_CONNECTION_H_
#define _D_FTP_CONNECTION_H_
#include "Socket.h"
#include "Option.h"
#include "Logger.h"
#include "Segment.h"
#include "Request.h"
#include <utility>
using namespace std;
class FtpConnection {
private:
int cuid;
const Socket* socket;
const Request* req;
const Option* option;
const Logger* logger;
string strbuf;
int getStatus(string response) const;
bool isEndOfResponse(int status, string response) const;
bool bulkReceiveResponse(pair<int, string>& response);
public:
FtpConnection(int cuid, const Socket* socket, const Request* req, const Option* op, const Logger* logger);
~FtpConnection();
void sendUser() const;
void sendPass() const;
void sendType() const;
void sendCwd() const;
void sendSize() const;
void sendPasv() const;
Socket* sendPort() const;
void sendRest(const Segment& segment) const;
void sendRetr() const;
int receiveResponse();
int receiveSizeResponse(long long int& size);
int receivePasvResponse(pair<string, int>& dest);
};
#endif // _D_FTP_CONNECTION_H_

38
src/FtpDownloadCommand.cc Normal file
View File

@ -0,0 +1,38 @@
/* <!-- copyright */
/*
* aria2 - a simple utility for downloading files faster
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* copyright --> */
#include "FtpDownloadCommand.h"
FtpDownloadCommand::FtpDownloadCommand(int cuid, Request* req, DownloadEngine* e, Socket* dataSocket, Socket* ctrlSocket):
DownloadCommand(cuid, req, e, dataSocket)
{
this->ctrlSocket = new Socket(*ctrlSocket);
}
FtpDownloadCommand::~FtpDownloadCommand() {
if(ctrlSocket != NULL) {
delete ctrlSocket;
}
}
TransferEncoding* FtpDownloadCommand::getTransferEncoding(string name) {
return NULL;
}

37
src/FtpDownloadCommand.h Normal file
View File

@ -0,0 +1,37 @@
/* <!-- copyright */
/*
* aria2 - a simple utility for downloading files faster
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* copyright --> */
#ifndef _D_FTP_DOWNLOAD_COMMAND_H_
#define _D_FTP_DOWNLOAD_COMMAND_H_
#include "DownloadCommand.h"
class FtpDownloadCommand : public DownloadCommand {
private:
Socket* ctrlSocket;
public:
FtpDownloadCommand(int cuid, Request* req, DownloadEngine* e, Socket* dataSocket, Socket* ctrlSocket);
~FtpDownloadCommand();
TransferEncoding* getTransferEncoding(string name);
};
#endif // _D_FTP_DOWNLOAD_COMMAND_H_

View File

@ -0,0 +1,84 @@
/* <!-- copyright */
/*
* aria2 - a simple utility for downloading files faster
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* copyright --> */
#include "FtpInitiateConnectionCommand.h"
#include "FtpNegotiationCommand.h"
#include "HttpRequestCommand.h"
#include "FtpTunnelRequestCommand.h"
#include "DlAbortEx.h"
#include "message.h"
FtpInitiateConnectionCommand::FtpInitiateConnectionCommand(int cuid, Request* req, DownloadEngine* e):AbstractCommand(cuid, req, e) {}
FtpInitiateConnectionCommand::~FtpInitiateConnectionCommand() {}
bool FtpInitiateConnectionCommand::executeInternal(Segment segment) {
if(!e->segmentMan->downloadStarted) {
e->segmentMan->filename = req->getFile();
bool segFileExists = e->segmentMan->segmentFileExists();
if(segFileExists) {
e->segmentMan->load();
e->diskWriter->openExistingFile(e->segmentMan->getFilePath());
e->segmentMan->downloadStarted = true;
} else {
e->diskWriter->initAndOpenFile(e->segmentMan->getFilePath());
}
}
socket = new Socket();
Command* command;
if(useHttpProxy()) {
e->logger->info(MSG_CONNECTING_TO_SERVER, cuid,
e->option->get("http_proxy_host").c_str(),
e->option->getAsInt("http_proxy_port"));
socket->establishConnection(e->option->get("http_proxy_host"),
e->option->getAsInt("http_proxy_port"));
if(useHttpProxyGet()) {
command = new HttpRequestCommand(cuid, req, e, socket);
} else if(useHttpProxyConnect()) {
command = new FtpTunnelRequestCommand(cuid, req, e, socket);
} else {
// TODO
throw new DlAbortEx("ERROR");
}
} else {
e->logger->info(MSG_CONNECTING_TO_SERVER, cuid, req->getHost().c_str(),
req->getPort());
socket->establishConnection(req->getHost(), req->getPort());
command = new FtpNegotiationCommand(cuid, req, e, socket);
}
e->commands.push(command);
return true;
}
bool FtpInitiateConnectionCommand::useHttpProxy() const {
return e->option->defined("http_proxy_enabled") &&
e->option->get("http_proxy_enabled") == "true";
}
bool FtpInitiateConnectionCommand::useHttpProxyGet() const {
return useHttpProxy() && e->option->get("ftp_via_http_proxy") == "get";
}
bool FtpInitiateConnectionCommand::useHttpProxyConnect() const {
return useHttpProxy() && e->option->get("ftp_via_http_proxy") == "tunnel";
}

View File

@ -0,0 +1,39 @@
/* <!-- copyright */
/*
* aria2 - a simple utility for downloading files faster
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* copyright --> */
#ifndef _D_FTP_INITIATE_CONNECTION_COMMAND_H_
#define _D_FTP_INITIATE_CONNECTION_COMMAND_H_
#include "AbstractCommand.h"
class FtpInitiateConnectionCommand : public AbstractCommand {
private:
bool useHttpProxy() const;
bool useHttpProxyGet() const;
bool useHttpProxyConnect() const;
protected:
bool executeInternal(Segment segment);
public:
FtpInitiateConnectionCommand(int cuid, Request* req, DownloadEngine* e);
~FtpInitiateConnectionCommand();
};
#endif // _D_FTP_INITIATE_CONNECTION_COMMAND_H_

View File

@ -0,0 +1,328 @@
/* <!-- copyright */
/*
* aria2 - a simple utility for downloading files faster
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* copyright --> */
#include "FtpNegotiationCommand.h"
#include "FtpDownloadCommand.h"
#include "DlAbortEx.h"
#include "message.h"
FtpNegotiationCommand::FtpNegotiationCommand(int cuid, Request* req, DownloadEngine* e, Socket* s):
AbstractCommand(cuid, req, e, s),
dataSocket(NULL), serverSocket(NULL), sequence(SEQ_RECV_GREETING)
{
ftp = new FtpConnection(cuid, socket, req, e->option, e->logger);
setReadCheckSocket(NULL);
setWriteCheckSocket(socket);
}
FtpNegotiationCommand::~FtpNegotiationCommand() {
if(dataSocket != NULL) {
delete dataSocket;
}
if(serverSocket != NULL) {
delete serverSocket;
}
delete ftp;
}
bool FtpNegotiationCommand::executeInternal(Segment segment) {
while(processSequence(segment));
if(sequence == SEQ_RETRY) {
return prepareForRetry(0);
} else if(sequence == SEQ_NEGOTIATION_COMPLETED) {
FtpDownloadCommand* command = new FtpDownloadCommand(cuid, req, e, dataSocket, socket);
e->commands.push(command);
return true;
} else {
e->commands.push(this);
return false;
}
}
bool FtpNegotiationCommand::recvGreeting() {
socket->setBlockingMode();
int status = ftp->receiveResponse();
if(status == 0) {
return false;
}
if(status != 220) {
throw new DlAbortEx(EX_CONNECTION_FAILED);
}
sequence = SEQ_SEND_USER;
setReadCheckSocket(socket);
setWriteCheckSocket(NULL);
return true;
}
bool FtpNegotiationCommand::sendUser() {
ftp->sendUser();
sequence = SEQ_RECV_USER;
return false;
}
bool FtpNegotiationCommand::recvUser() {
int status = ftp->receiveResponse();
switch(status) {
case 0:
return false;
case 230:
sequence = SEQ_SEND_TYPE;
break;
case 331:
sequence = SEQ_SEND_PASS;
break;
default:
throw new DlAbortEx(EX_BAD_STATUS, status);
}
return true;
}
bool FtpNegotiationCommand::sendPass() {
ftp->sendPass();
sequence = SEQ_RECV_PASS;
return false;
}
bool FtpNegotiationCommand::recvPass() {
int status = ftp->receiveResponse();
if(status == 0) {
return false;
}
if(status != 230) {
throw new DlAbortEx(EX_BAD_STATUS, status);
}
sequence = SEQ_SEND_TYPE;
return true;
}
bool FtpNegotiationCommand::sendType() {
ftp->sendType();
sequence = SEQ_RECV_TYPE;
return false;
}
bool FtpNegotiationCommand::recvType() {
int status = ftp->receiveResponse();
if(status == 0) {
return false;
}
if(status != 200) {
throw new DlAbortEx(EX_BAD_STATUS, status);
}
sequence = SEQ_SEND_CWD;
return true;
}
bool FtpNegotiationCommand::sendCwd() {
ftp->sendCwd();
sequence = SEQ_RECV_CWD;
return false;
}
bool FtpNegotiationCommand::recvCwd() {
int status = ftp->receiveResponse();
if(status == 0) {
return false;
}
if(status != 250) {
throw new DlAbortEx(EX_BAD_STATUS, status);
}
sequence = SEQ_SEND_SIZE;
return true;
}
bool FtpNegotiationCommand::sendSize() {
ftp->sendSize();
sequence = SEQ_RECV_SIZE;
return false;
}
bool FtpNegotiationCommand::recvSize() {
long long int size = 0;
int status = ftp->receiveSizeResponse(size);
if(status == 0) {
return false;
}
if(status != 213) {
throw new DlAbortEx(EX_BAD_STATUS, status);
}
// TODO check the value of size
if(!e->segmentMan->downloadStarted) {
e->segmentMan->downloadStarted = true;
e->segmentMan->totalSize = size;
} else if(e->segmentMan->totalSize != size) {
throw new DlAbortEx(EX_SIZE_MISMATCH, e->segmentMan->totalSize, size);
}
if(e->option->get("ftp_pasv_enabled") == "true") {
sequence = SEQ_SEND_PASV;
} else {
sequence = SEQ_SEND_PORT;
}
return true;
}
bool FtpNegotiationCommand::sendPort() {
serverSocket = ftp->sendPort();
sequence = SEQ_RECV_PORT;
return false;
}
bool FtpNegotiationCommand::recvPort() {
int status = ftp->receiveResponse();
if(status == 0) {
return false;
}
if(status != 200) {
throw new DlAbortEx(EX_BAD_STATUS, status);
}
sequence = SEQ_SEND_REST;
return true;
}
bool FtpNegotiationCommand::sendPasv() {
ftp->sendPasv();
sequence = SEQ_RECV_PASV;
return false;
}
bool FtpNegotiationCommand::recvPasv() {
pair<string, int> dest;
int status = ftp->receivePasvResponse(dest);
if(status == 0) {
return false;
}
if(status != 227) {
throw new DlAbortEx(EX_BAD_STATUS, status);
}
// make a data connection to the server.
dataSocket = new Socket();
e->logger->info(MSG_CONNECTING_TO_SERVER, cuid,
dest.first.c_str(),
dest.second);
dataSocket->establishConnection(dest.first, dest.second);
setReadCheckSocket(NULL);
setWriteCheckSocket(dataSocket);
sequence = SEQ_SEND_REST_PASV;
return false;
}
bool FtpNegotiationCommand::sendRestPasv(const Segment& segment) {
dataSocket->setBlockingMode();
setReadCheckSocket(socket);
setWriteCheckSocket(NULL);
return sendRest(segment);
}
bool FtpNegotiationCommand::sendRest(const Segment& segment) {
ftp->sendRest(segment);
sequence = SEQ_RECV_REST;
return false;
}
bool FtpNegotiationCommand::recvRest() {
int status = ftp->receiveResponse();
if(status == 0) {
return false;
}
// TODO if we recieve negative response, then we set e->segmentMan->splittable = false, and continue.
if(status != 350) {
throw new DlAbortEx(EX_BAD_STATUS, status);
}
sequence = SEQ_SEND_RETR;
return true;
}
bool FtpNegotiationCommand::sendRetr() {
ftp->sendRetr();
sequence = SEQ_RECV_RETR;
return false;
}
bool FtpNegotiationCommand::recvRetr() {
int status = ftp->receiveResponse();
if(status == 0) {
return false;
}
if(status != 150) {
throw new DlAbortEx(EX_BAD_STATUS, status);
}
if(e->option->get("ftp_pasv_enabled") != "true") {
assert(serverSocket);
dataSocket = serverSocket->acceptConnection();
}
sequence = SEQ_NEGOTIATION_COMPLETED;
return false;
}
bool FtpNegotiationCommand::processSequence(const Segment& segment) {
bool doNextSequence = true;
switch(sequence) {
case SEQ_RECV_GREETING:
return recvGreeting();
case SEQ_SEND_USER:
return sendUser();
case SEQ_RECV_USER:
return recvUser();
case SEQ_SEND_PASS:
return sendPass();
case SEQ_RECV_PASS:
return recvPass();
case SEQ_SEND_TYPE:
return sendType();
case SEQ_RECV_TYPE:
return recvType();
case SEQ_SEND_CWD:
return sendCwd();
case SEQ_RECV_CWD:
return recvCwd();
case SEQ_SEND_SIZE:
return sendSize();
case SEQ_RECV_SIZE:
return recvSize();
case SEQ_SEND_PORT:
return sendPort();
case SEQ_RECV_PORT:
return recvPort();
case SEQ_SEND_PASV:
return sendPasv();
case SEQ_RECV_PASV:
return recvPasv();
case SEQ_SEND_REST_PASV:
return sendRestPasv(segment);
case SEQ_SEND_REST:
return sendRest(segment);
case SEQ_RECV_REST:
return recvRest();
case SEQ_SEND_RETR:
return sendRetr();
case SEQ_RECV_RETR:
return recvRetr();
default:
abort();
}
return doNextSequence;
}

View File

@ -0,0 +1,87 @@
/* <!-- copyright */
/*
* aria2 - a simple utility for downloading files faster
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* copyright --> */
#ifndef _D_FTP_NEGOTIATION_COMMAND_H_
#define _D_FTP_NEGOTIATION_COMMAND_H_
#include "AbstractCommand.h"
#include "FtpConnection.h"
class FtpNegotiationCommand : public AbstractCommand {
private:
enum Seq {
SEQ_RECV_GREETING,
SEQ_SEND_USER,
SEQ_RECV_USER,
SEQ_SEND_PASS,
SEQ_RECV_PASS,
SEQ_SEND_TYPE,
SEQ_RECV_TYPE,
SEQ_SEND_CWD,
SEQ_RECV_CWD,
SEQ_SEND_SIZE,
SEQ_RECV_SIZE,
SEQ_SEND_PORT,
SEQ_RECV_PORT,
SEQ_SEND_PASV,
SEQ_RECV_PASV,
SEQ_SEND_REST_PASV,
SEQ_SEND_REST,
SEQ_RECV_REST,
SEQ_SEND_RETR,
SEQ_RECV_RETR,
SEQ_NEGOTIATION_COMPLETED,
SEQ_RETRY
};
bool recvGreeting();
bool sendUser();
bool recvUser();
bool sendPass();
bool recvPass();
bool sendType();
bool recvType();
bool sendCwd();
bool recvCwd();
bool sendSize();
bool recvSize();
bool sendPort();
bool recvPort();
bool sendPasv();
bool recvPasv();
bool sendRest(const Segment& segment);
bool sendRestPasv(const Segment& segment);
bool recvRest();
bool sendRetr();
bool recvRetr();
bool processSequence(const Segment& segment);
Socket* dataSocket;
Socket* serverSocket;
int sequence;
FtpConnection* ftp;
protected:
bool executeInternal(Segment segment);
public:
FtpNegotiationCommand(int cuid, Request* req, DownloadEngine* e, Socket* s);
~FtpNegotiationCommand();
};
#endif // _D_FTP_NEGOTIATION_COMMAND_H_

View File

@ -0,0 +1,41 @@
/* <!-- copyright */
/*
* aria2 - a simple utility for downloading files faster
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* copyright --> */
#include "FtpTunnelRequestCommand.h"
#include "FtpTunnelResponseCommand.h"
#include "HttpConnection.h"
FtpTunnelRequestCommand::FtpTunnelRequestCommand(int cuid, Request* req, DownloadEngine* e, Socket* s):AbstractCommand(cuid, req, e, s) {
setReadCheckSocket(NULL);
setWriteCheckSocket(NULL);
}
FtpTunnelRequestCommand::~FtpTunnelRequestCommand() {}
bool FtpTunnelRequestCommand::executeInternal(Segment segment) {
socket->setBlockingMode();
HttpConnection httpConnection(cuid, socket, req, e->option, e->logger);
httpConnection.sendProxyRequest();
FtpTunnelResponseCommand* command = new FtpTunnelResponseCommand(cuid, req, e, socket);
e->commands.push(command);
return true;
}

View File

@ -0,0 +1,35 @@
/* <!-- copyright */
/*
* aria2 - a simple utility for downloading files faster
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* copyright --> */
#ifndef _D_FTP_TUNNEL_REQUEST_COMMAND_H_
#define _D_FTP_TUNNEL_REQUEST_COMMAND_H_
#include "AbstractCommand.h"
class FtpTunnelRequestCommand : public AbstractCommand {
protected:
bool executeInternal(Segment segment);
public:
FtpTunnelRequestCommand(int cuid, Request* req, DownloadEngine* e, Socket* s);
~FtpTunnelRequestCommand();
};
#endif // _D_FTP_TUNNEL_REQUEST_COMMAND_H_

View File

@ -0,0 +1,49 @@
/* <!-- copyright */
/*
* aria2 - a simple utility for downloading files faster
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* copyright --> */
#include "FtpTunnelResponseCommand.h"
#include "FtpNegotiationCommand.h"
#include "DlRetryEx.h"
#include "message.h"
FtpTunnelResponseCommand::FtpTunnelResponseCommand(int cuid, Request* req, DownloadEngine* e, Socket* s):AbstractCommand(cuid, req, e, s) {
http = new HttpConnection(cuid, socket, req, e->option, e->logger);
}
FtpTunnelResponseCommand::~FtpTunnelResponseCommand() {
delete http;
}
bool FtpTunnelResponseCommand::executeInternal(Segment segment) {
HttpHeader headers;
int status = http->receiveResponse(headers);
if(status == 0) {
// we didn't receive all of headers yet.
e->commands.push(this);
return false;
}
if(status != 200) {
throw new DlRetryEx(EX_PROXY_CONNECTION_FAILED);
}
FtpNegotiationCommand* command = new FtpNegotiationCommand(cuid, req, e, socket);
e->commands.push(command);
return true;
}

View File

@ -0,0 +1,39 @@
/* <!-- copyright */
/*
* aria2 - a simple utility for downloading files faster
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* copyright --> */
#ifndef _D_FTP_TUNNEL_RESPONSE_COMMAND_H_
#define _D_FTP_TUNNEL_RESPONSE_COMMAND_H_
#include "AbstractCommand.h"
#include "HttpConnection.h"
class FtpTunnelResponseCommand : public AbstractCommand {
private:
HttpConnection* http;
protected:
bool executeInternal(Segment segment);
public:
FtpTunnelResponseCommand(int cuid, Request* req, DownloadEngine* e, Socket* s);
~FtpTunnelResponseCommand();
};
#endif // _D_FTP_TUNNEL_RESPONSE_COMMAND_H_

66
src/HttpHeader.cc Normal file
View File

@ -0,0 +1,66 @@
/* <!-- copyright */
/*
* aria2 - a simple utility for downloading files faster
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* copyright --> */
#include "HttpHeader.h"
void HttpHeader::put(const string& name, const string& value) {
multimap<string, string>::value_type vt(name, value);
table.insert(vt);
}
bool HttpHeader::defined(const string& name) const {
return table.count(name) == 1;
}
string HttpHeader::getFirst(const string& name) const {
multimap<string, string>::const_iterator itr = table.find(name);
if(itr == table.end()) {
return "";
} else {
return (*itr).second;
}
}
vector<string> HttpHeader::get(const string& name) const {
vector<string> v;
for(multimap<string, string>::const_iterator itr = table.find(name); itr != table.end(); itr++) {
v.push_back((*itr).second);
}
return v;
}
int HttpHeader::getFirstAsInt(const string& name) const {
multimap<string, string>::const_iterator itr = table.find(name);
if(itr == table.end()) {
return 0;
} else {
return (int)strtol((*itr).second.c_str(), NULL, 10);
}
}
long long int HttpHeader::getFirstAsLLInt(const string& name) const {
multimap<string, string>::const_iterator itr = table.find(name);
if(itr == table.end()) {
return 0;
} else {
return strtoll((*itr).second.c_str(), NULL, 10);
}
}

46
src/HttpHeader.h Normal file
View File

@ -0,0 +1,46 @@
/* <!-- copyright */
/*
* aria2 - a simple utility for downloading files faster
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* copyright --> */
#ifndef _D_HTTP_HEADER_H_
#define _D_HTTP_HEADER_H_
#include <map>
#include <vector>
#include <string>
using namespace std;
class HttpHeader {
private:
multimap<string, string> table;
public:
HttpHeader() {}
~HttpHeader() {}
void put(const string& name, const string& value);
bool defined(const string& name) const;
string getFirst(const string& name) const;
vector<string> get(const string& name) const;
int getFirstAsInt(const string& name) const;
long long int getFirstAsLLInt(const string& name) const;
};
#endif // _D_HTTP_HEADER_H_