mirror of
https://github.com/roytam1/UXP.git
synced 2026-05-26 14:54:25 +00:00
Issue #1349 - Stop 2xx FTP responses from causing browser to hang.
LIST and RETR still appear to work as intended on ftp:// URLs after my changes. I wasn't able to test STOR because the browser doesn't appear to support FTP uploads at this time (although our FTP implementation appears perfectly capable of doing an FTP upload.) If I understood the issue correctly, though, what we're doing is ensuring that we receive a preliminary 100 response from the FTP server for a given action before jumping to the 200 code describing what we do if the action was completed. Even though it makes no logical sense for a server to say an action was completed before it was initiated, someone could write a really annoying FTP server that takes advantage of this fact to crash the browser if they wanted.
This commit is contained in:
@@ -82,6 +82,9 @@ nsFtpState::nsFtpState()
|
||||
, mAnonymous(true)
|
||||
, mRetryPass(false)
|
||||
, mStorReplyReceived(false)
|
||||
, mRlist1xxReceived(false)
|
||||
, mRstor1xxReceived(false)
|
||||
, mRretr1xxReceived(false)
|
||||
, mInternalError(NS_OK)
|
||||
, mReconnectAndLoginAgain(false)
|
||||
, mCacheConnection(true)
|
||||
@@ -1153,15 +1156,18 @@ nsFtpState::S_list() {
|
||||
FTP_STATE
|
||||
nsFtpState::R_list() {
|
||||
if (mResponseCode/100 == 1) {
|
||||
mRlist1xxReceived = true;
|
||||
|
||||
// OK, time to start reading from the data connection.
|
||||
if (mDataStream && HasPendingCallback())
|
||||
mDataStream->AsyncWait(this, 0, 0, CallbackTarget());
|
||||
return FTP_READ_BUF;
|
||||
}
|
||||
|
||||
if (mResponseCode/100 == 2) {
|
||||
if (mResponseCode/100 == 2 && mRlist1xxReceived) {
|
||||
//(DONE)
|
||||
mNextState = FTP_COMPLETE;
|
||||
mRlist1xxReceived = false;
|
||||
return FTP_COMPLETE;
|
||||
}
|
||||
return FTP_ERROR;
|
||||
@@ -1181,13 +1187,16 @@ nsFtpState::S_retr() {
|
||||
|
||||
FTP_STATE
|
||||
nsFtpState::R_retr() {
|
||||
if (mResponseCode/100 == 2) {
|
||||
if (mResponseCode/100 == 2 && mRretr1xxReceived) {
|
||||
//(DONE)
|
||||
mNextState = FTP_COMPLETE;
|
||||
mRretr1xxReceived = false;
|
||||
return FTP_COMPLETE;
|
||||
}
|
||||
|
||||
if (mResponseCode/100 == 1) {
|
||||
mRretr1xxReceived = true;
|
||||
|
||||
if (mDataStream && HasPendingCallback())
|
||||
mDataStream->AsyncWait(this, 0, 0, CallbackTarget());
|
||||
return FTP_READ_BUF;
|
||||
@@ -1262,7 +1271,7 @@ nsFtpState::S_stor() {
|
||||
|
||||
FTP_STATE
|
||||
nsFtpState::R_stor() {
|
||||
if (mResponseCode/100 == 2) {
|
||||
if (mResponseCode/100 == 2 && mRstor1xxReceived) {
|
||||
//(DONE)
|
||||
mNextState = FTP_COMPLETE;
|
||||
mStorReplyReceived = true;
|
||||
@@ -1270,11 +1279,12 @@ nsFtpState::R_stor() {
|
||||
// Call Close() if it was not called in nsFtpState::OnStoprequest()
|
||||
if (!mUploadRequest && !IsClosed())
|
||||
Close();
|
||||
|
||||
mRstor1xxReceived = false;
|
||||
return FTP_COMPLETE;
|
||||
}
|
||||
|
||||
if (mResponseCode/100 == 1) {
|
||||
mRstor1xxReceived = true;
|
||||
LOG(("FTP:(%x) writing on DT\n", this));
|
||||
return FTP_READ_BUF;
|
||||
}
|
||||
|
||||
@@ -180,6 +180,12 @@ private:
|
||||
bool mRetryPass; // retrying the password
|
||||
bool mStorReplyReceived; // FALSE if waiting for STOR
|
||||
// completion status from server
|
||||
bool mRlist1xxReceived; // TRUE if the server has sent a
|
||||
// LIST 1xx response.
|
||||
bool mRstor1xxReceived; // TRUE if the server has sent a
|
||||
// STOR 1xx response.
|
||||
bool mRretr1xxReceived; // TRUE if the server has sent a
|
||||
// RETR 1xx response.
|
||||
nsresult mInternalError; // represents internal state errors
|
||||
bool mReconnectAndLoginAgain;
|
||||
bool mCacheConnection;
|
||||
|
||||
Reference in New Issue
Block a user