mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-11 04:15:43 +00:00
fix bug 84242 [FTP URL parsing broken] and bug 95277 [ftp: URL w/o path
should redirect to home dir] This will change the way we parse ftp urls, a ftp url like ftp://user@host/path will go to path under the users home directory not the root directory. With most anonymous ftp servers there is no change since root is the home, but if you want to access /path from a users directory you have to use ftp://user@host//path instead. This will bring us closer to the ftp urls outlined in rfc 1738. r=bbaetzcs.@mcgill.ca, sr=darin@netscape.com
This commit is contained in:
parent
e2f4401c73
commit
b2ce2eae99
@ -52,6 +52,9 @@
|
||||
#define NS_ERROR_FTP_PASV \
|
||||
NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 23)
|
||||
|
||||
#define NS_ERROR_FTP_PWD \
|
||||
NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 24)
|
||||
|
||||
/**
|
||||
* Status nsresult codes: used with nsINotification objects
|
||||
*/
|
||||
|
@ -569,7 +569,7 @@ nsFtpState::EstablishControlConnection()
|
||||
// read cached variables into us.
|
||||
mServerType = mControlConnection->mServerType;
|
||||
mPassword = mControlConnection->mPassword;
|
||||
|
||||
mPwd = mControlConnection->mPwd;
|
||||
mTryingCachedControl = PR_TRUE;
|
||||
|
||||
// we're already connected to this server, skip login.
|
||||
@ -897,6 +897,24 @@ nsFtpState::Process()
|
||||
|
||||
break;
|
||||
|
||||
// PWD
|
||||
case FTP_S_PWD:
|
||||
rv = S_pwd();
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
mInternalError = NS_ERROR_FTP_PWD;
|
||||
|
||||
MoveToNextState(FTP_R_PWD);
|
||||
break;
|
||||
|
||||
case FTP_R_PWD:
|
||||
mState = R_pwd();
|
||||
|
||||
if (FTP_ERROR == mState)
|
||||
mInternalError = NS_ERROR_FTP_PWD;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
;
|
||||
|
||||
@ -1097,6 +1115,31 @@ nsFtpState::R_pass() {
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFtpState::S_pwd() {
|
||||
nsCString pwdStr("PWD" CRLF);
|
||||
return SendFTPCommand(pwdStr);
|
||||
}
|
||||
|
||||
FTP_STATE
|
||||
nsFtpState::R_pwd() {
|
||||
if (mResponseCode/100 != 2)
|
||||
return FTP_ERROR;
|
||||
nsCAutoString respStr(mResponseMsg);
|
||||
PRInt32 pos = respStr.FindChar('"');
|
||||
if (pos > -1) {
|
||||
respStr.Cut(0,pos+1);
|
||||
pos = respStr.FindChar('"');
|
||||
if (pos > -1) {
|
||||
respStr.Truncate(pos);
|
||||
if (respStr.Last() != '/')
|
||||
respStr.Append("/");
|
||||
mPwd = respStr;
|
||||
}
|
||||
}
|
||||
return FTP_S_TYPE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFtpState::S_syst() {
|
||||
nsCString systString("SYST" CRLF);
|
||||
@ -1131,7 +1174,7 @@ nsFtpState::R_syst() {
|
||||
return FTP_ERROR;
|
||||
}
|
||||
|
||||
return FTP_S_TYPE;
|
||||
return FTP_S_PWD;
|
||||
}
|
||||
|
||||
if (mResponseCode/100 == 5) {
|
||||
@ -1139,7 +1182,7 @@ nsFtpState::R_syst() {
|
||||
// No clue. We will just hope it is UNIX type server.
|
||||
mServerType = FTP_UNIX_TYPE;
|
||||
|
||||
return FTP_S_TYPE;
|
||||
return FTP_S_PWD;
|
||||
}
|
||||
return FTP_ERROR;
|
||||
}
|
||||
@ -1174,8 +1217,10 @@ nsFtpState::R_type() {
|
||||
|
||||
nsresult
|
||||
nsFtpState::S_cwd() {
|
||||
nsCAutoString cwdStr("CWD ");
|
||||
cwdStr.Append(mPath);
|
||||
nsCAutoString cwdStr(mPath);
|
||||
if (cwdStr.First() != '/')
|
||||
cwdStr.Insert(mPwd,0);
|
||||
cwdStr.Insert("CWD ",0);
|
||||
cwdStr.Append(CRLF);
|
||||
|
||||
return SendFTPCommand(cwdStr);
|
||||
@ -1195,8 +1240,10 @@ nsFtpState::R_cwd() {
|
||||
|
||||
nsresult
|
||||
nsFtpState::S_size() {
|
||||
nsCAutoString sizeBuf("SIZE ");
|
||||
sizeBuf.Append(mPath);
|
||||
nsCAutoString sizeBuf(mPath);
|
||||
if (sizeBuf.First() != '/')
|
||||
sizeBuf.Insert(mPwd,0);
|
||||
sizeBuf.Insert("SIZE ",0);
|
||||
sizeBuf.Append(CRLF);
|
||||
|
||||
return SendFTPCommand(sizeBuf);
|
||||
@ -1293,8 +1340,10 @@ nsFtpState::R_list() {
|
||||
nsresult
|
||||
nsFtpState::S_retr() {
|
||||
nsresult rv = NS_OK;
|
||||
nsCAutoString retrStr("RETR ");
|
||||
retrStr.Append(mPath);
|
||||
nsCAutoString retrStr(mPath);
|
||||
if (retrStr.First() != '/')
|
||||
retrStr.Insert(mPwd,0);
|
||||
retrStr.Insert("RETR ",0);
|
||||
retrStr.Append(CRLF);
|
||||
|
||||
if (!mDRequestForwarder)
|
||||
@ -1360,8 +1409,10 @@ nsFtpState::R_rest() {
|
||||
nsresult
|
||||
nsFtpState::S_stor() {
|
||||
nsresult rv = NS_OK;
|
||||
nsCAutoString storStr("STOR ");
|
||||
storStr.Append(mPath.get());
|
||||
nsCAutoString storStr(mPath.get());
|
||||
if (storStr.First() != '/')
|
||||
storStr.Insert(mPwd,0);
|
||||
storStr.Insert("STOR ",0);
|
||||
storStr.Append(CRLF);
|
||||
|
||||
rv = SendFTPCommand(storStr);
|
||||
@ -1800,7 +1851,20 @@ nsFtpState::Init(nsIFTPChannel* aChannel,
|
||||
rv = mURL->GetPath(&path);
|
||||
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
mPath.Adopt(nsUnescape(path));
|
||||
// Skip leading slash
|
||||
char* fwdPtr= NS_CONST_CAST(char*, path);
|
||||
if (fwdPtr && (*fwdPtr == '/'))
|
||||
fwdPtr++;
|
||||
if (*fwdPtr == '\0') {
|
||||
// make it at least a dot
|
||||
mPath.Adopt(".");
|
||||
} else {
|
||||
// now unescape it
|
||||
char *unescPath = nsnull;
|
||||
nsStdUnescape(fwdPtr,&unescPath);
|
||||
nsMemory::Free(path);
|
||||
mPath.Adopt(unescPath);
|
||||
}
|
||||
|
||||
// pull any username and/or password out of the uri
|
||||
nsXPIDLCString uname;
|
||||
@ -1907,6 +1971,7 @@ nsFtpState::KillControlConnection() {
|
||||
// Store connection persistant data
|
||||
mControlConnection->mServerType = mServerType;
|
||||
mControlConnection->mPassword = mPassword;
|
||||
mControlConnection->mPwd = mPwd;
|
||||
nsresult rv = nsFtpProtocolHandler::InsertConnection(mURL,
|
||||
NS_STATIC_CAST(nsISupports*, (nsIStreamListener*)mControlConnection));
|
||||
// Can't cache it? Kill it then.
|
||||
|
@ -92,7 +92,8 @@ typedef enum _FTP_STATE {
|
||||
FTP_S_RETR, FTP_R_RETR,
|
||||
FTP_S_STOR, FTP_R_STOR,
|
||||
FTP_S_LIST, FTP_R_LIST,
|
||||
FTP_S_PASV, FTP_R_PASV
|
||||
FTP_S_PASV, FTP_R_PASV,
|
||||
FTP_S_PWD, FTP_R_PWD
|
||||
} FTP_STATE;
|
||||
|
||||
// higher level ftp actions
|
||||
@ -142,7 +143,8 @@ private:
|
||||
nsresult S_rest(); FTP_STATE R_rest();
|
||||
nsresult S_retr(); FTP_STATE R_retr();
|
||||
nsresult S_stor(); FTP_STATE R_stor();
|
||||
nsresult S_pasv(); FTP_STATE R_pasv();
|
||||
nsresult S_pasv(); FTP_STATE R_pasv();
|
||||
nsresult S_pwd(); FTP_STATE R_pwd();
|
||||
// END: STATE METHODS
|
||||
///////////////////////////////////
|
||||
|
||||
@ -200,6 +202,7 @@ private:
|
||||
PRInt32 mPort; // the port to connect to
|
||||
nsAutoString mFilename; // url filename (if any)
|
||||
nsXPIDLCString mPath; // the url's path
|
||||
nsCString mPwd; // login Path
|
||||
|
||||
// ****** other vars
|
||||
PRUint8 mSuspendCount;// number of times we've been suspended.
|
||||
|
@ -75,6 +75,7 @@ public:
|
||||
PRUint32 mServerType; // what kind of server is it.
|
||||
nsString mPassword;
|
||||
PRInt32 mSuspendedWrite;
|
||||
nsCString mPwd;
|
||||
|
||||
private:
|
||||
PRLock* mLock; // protects mListener.
|
||||
|
Loading…
Reference in New Issue
Block a user