mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 26767 - FTP client detects UTF-8 if server returns UTF8 on FEAT. r=michal.novotny
This commit is contained in:
parent
375ca3ec4c
commit
a3c69f7ea9
@ -92,6 +92,7 @@ nsFtpState::nsFtpState()
|
||||
, mPort(21)
|
||||
, mAddressChecked(false)
|
||||
, mServerIsIPv6(false)
|
||||
, mUseUTF8(false)
|
||||
, mControlStatus(NS_OK)
|
||||
, mDeferredCallbackPending(false)
|
||||
{
|
||||
@ -276,7 +277,12 @@ nsFtpState::EstablishControlConnection()
|
||||
mServerType = mControlConnection->mServerType;
|
||||
mPassword = mControlConnection->mPassword;
|
||||
mPwd = mControlConnection->mPwd;
|
||||
mUseUTF8 = mControlConnection->mUseUTF8;
|
||||
mTryingCachedControl = true;
|
||||
|
||||
// we have to set charset to connection if server supports utf-8
|
||||
if (mUseUTF8)
|
||||
mChannel->SetContentCharset(NS_LITERAL_CSTRING("UTF-8"));
|
||||
|
||||
// we're already connected to this server, skip login.
|
||||
mState = FTP_S_PASV;
|
||||
@ -646,7 +652,43 @@ nsFtpState::Process()
|
||||
mInternalError = NS_ERROR_FTP_PWD;
|
||||
|
||||
break;
|
||||
|
||||
|
||||
// FEAT for RFC2640 support
|
||||
case FTP_S_FEAT:
|
||||
rv = S_feat();
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
mInternalError = rv;
|
||||
|
||||
MoveToNextState(FTP_R_FEAT);
|
||||
break;
|
||||
|
||||
case FTP_R_FEAT:
|
||||
mState = R_feat();
|
||||
|
||||
// Don't want to overwrite a more explicit status code
|
||||
if (FTP_ERROR == mState && NS_SUCCEEDED(mInternalError))
|
||||
mInternalError = NS_ERROR_FAILURE;
|
||||
break;
|
||||
|
||||
// OPTS for some non-RFC2640-compliant servers support
|
||||
case FTP_S_OPTS:
|
||||
rv = S_opts();
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
mInternalError = rv;
|
||||
|
||||
MoveToNextState(FTP_R_OPTS);
|
||||
break;
|
||||
|
||||
case FTP_R_OPTS:
|
||||
mState = R_opts();
|
||||
|
||||
// Don't want to overwrite a more explicit status code
|
||||
if (FTP_ERROR == mState && NS_SUCCEEDED(mInternalError))
|
||||
mInternalError = NS_ERROR_FAILURE;
|
||||
break;
|
||||
|
||||
default:
|
||||
;
|
||||
|
||||
@ -923,7 +965,7 @@ nsFtpState::R_syst() {
|
||||
return FTP_ERROR;
|
||||
}
|
||||
|
||||
return FTP_S_PWD;
|
||||
return FTP_S_FEAT;
|
||||
}
|
||||
|
||||
if (mResponseCode/100 == 5) {
|
||||
@ -931,7 +973,7 @@ nsFtpState::R_syst() {
|
||||
// No clue. We will just hope it is UNIX type server.
|
||||
mServerType = FTP_UNIX_TYPE;
|
||||
|
||||
return FTP_S_PWD;
|
||||
return FTP_S_FEAT;
|
||||
}
|
||||
return FTP_ERROR;
|
||||
}
|
||||
@ -1135,6 +1177,10 @@ nsFtpState::S_list() {
|
||||
serverType.AppendInt(mServerType);
|
||||
mCacheEntry->SetMetaDataElement("servertype", serverType.get());
|
||||
|
||||
nsAutoCString useUTF8;
|
||||
useUTF8.AppendInt(mUseUTF8);
|
||||
mCacheEntry->SetMetaDataElement("useUTF8", useUTF8.get());
|
||||
|
||||
// open cache entry for writing, and configure it to receive data.
|
||||
if (NS_FAILED(InstallCacheListener())) {
|
||||
mCacheEntry->AsyncDoom(nullptr);
|
||||
@ -1551,6 +1597,39 @@ nsFtpState::R_pasv() {
|
||||
return FTP_S_SIZE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFtpState::S_feat() {
|
||||
return SendFTPCommand(NS_LITERAL_CSTRING("FEAT" CRLF));
|
||||
}
|
||||
|
||||
FTP_STATE
|
||||
nsFtpState::R_feat() {
|
||||
if (mResponseCode/100 == 2) {
|
||||
if (mResponseMsg.Find(NS_LITERAL_CSTRING(CRLF " UTF8" CRLF), true) > -1) {
|
||||
// This FTP server supports UTF-8 encoding
|
||||
mChannel->SetContentCharset(NS_LITERAL_CSTRING("UTF-8"));
|
||||
mUseUTF8 = true;
|
||||
return FTP_S_OPTS;
|
||||
}
|
||||
}
|
||||
|
||||
mUseUTF8 = false;
|
||||
return FTP_S_PWD;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFtpState::S_opts() {
|
||||
// This command is for compatibility of old FTP spec (IETF Draft)
|
||||
return SendFTPCommand(NS_LITERAL_CSTRING("OPTS UTF8 ON" CRLF));
|
||||
}
|
||||
|
||||
FTP_STATE
|
||||
nsFtpState::R_opts() {
|
||||
// Ignore error code because "OPTS UTF8 ON" is for compatibility of
|
||||
// FTP server using IETF draft
|
||||
return FTP_S_PWD;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIRequest methods:
|
||||
|
||||
@ -1847,6 +1926,7 @@ nsFtpState::KillControlConnection()
|
||||
mControlConnection->mServerType = mServerType;
|
||||
mControlConnection->mPassword = mPassword;
|
||||
mControlConnection->mPwd = mPwd;
|
||||
mControlConnection->mUseUTF8 = mUseUTF8;
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
// Don't cache controlconnection if anonymous (bug #473371)
|
||||
@ -1865,7 +1945,7 @@ nsFtpState::KillControlConnection()
|
||||
class nsFtpAsyncAlert : public nsRunnable
|
||||
{
|
||||
public:
|
||||
nsFtpAsyncAlert(nsIPrompt *aPrompter, nsACString& aResponseMsg)
|
||||
nsFtpAsyncAlert(nsIPrompt *aPrompter, nsString aResponseMsg)
|
||||
: mPrompter(aPrompter)
|
||||
, mResponseMsg(aResponseMsg)
|
||||
{
|
||||
@ -1878,15 +1958,15 @@ public:
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
if (mPrompter) {
|
||||
mPrompter->Alert(nullptr, NS_ConvertASCIItoUTF16(mResponseMsg).get());
|
||||
mPrompter->Alert(nullptr, mResponseMsg.get());
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
private:
|
||||
nsCOMPtr<nsIPrompt> mPrompter;
|
||||
nsCString mResponseMsg;
|
||||
nsString mResponseMsg;
|
||||
};
|
||||
|
||||
|
||||
|
||||
nsresult
|
||||
nsFtpState::StopProcessing()
|
||||
@ -1910,8 +1990,14 @@ nsFtpState::StopProcessing()
|
||||
nsCOMPtr<nsIPrompt> prompter;
|
||||
mChannel->GetCallback(prompter);
|
||||
if (prompter) {
|
||||
nsCOMPtr<nsIRunnable> alertEvent =
|
||||
new nsFtpAsyncAlert(prompter, mResponseMsg);
|
||||
nsCOMPtr<nsIRunnable> alertEvent;
|
||||
if (mUseUTF8) {
|
||||
alertEvent = new nsFtpAsyncAlert(prompter,
|
||||
NS_ConvertUTF8toUTF16(mResponseMsg));
|
||||
} else {
|
||||
alertEvent = new nsFtpAsyncAlert(prompter,
|
||||
NS_ConvertASCIItoUTF16(mResponseMsg));
|
||||
}
|
||||
NS_DispatchToMainThread(alertEvent, NS_DISPATCH_NORMAL);
|
||||
}
|
||||
}
|
||||
@ -2372,6 +2458,12 @@ nsFtpState::ReadCacheEntry()
|
||||
nsAutoCString serverNum(serverType.get());
|
||||
nsresult err;
|
||||
mServerType = serverNum.ToInteger(&err);
|
||||
|
||||
nsXPIDLCString charset;
|
||||
mCacheEntry->GetMetaDataElement("useUTF8", getter_Copies(charset));
|
||||
const char *useUTF8 = charset.get();
|
||||
if (useUTF8 && atoi(useUTF8) == 1)
|
||||
mChannel->SetContentCharset(NS_LITERAL_CSTRING("UTF-8"));
|
||||
|
||||
mChannel->PushStreamConverter("text/ftp-dir",
|
||||
APPLICATION_HTTP_INDEX_FORMAT);
|
||||
|
@ -57,7 +57,9 @@ typedef enum _FTP_STATE {
|
||||
FTP_S_STOR, FTP_R_STOR,
|
||||
FTP_S_LIST, FTP_R_LIST,
|
||||
FTP_S_PASV, FTP_R_PASV,
|
||||
FTP_S_PWD, FTP_R_PWD
|
||||
FTP_S_PWD, FTP_R_PWD,
|
||||
FTP_S_FEAT, FTP_R_FEAT,
|
||||
FTP_S_OPTS, FTP_R_OPTS
|
||||
} FTP_STATE;
|
||||
|
||||
// higher level ftp actions
|
||||
@ -129,6 +131,8 @@ private:
|
||||
nsresult S_stor(); FTP_STATE R_stor();
|
||||
nsresult S_pasv(); FTP_STATE R_pasv();
|
||||
nsresult S_pwd(); FTP_STATE R_pwd();
|
||||
nsresult S_feat(); FTP_STATE R_feat();
|
||||
nsresult S_opts(); FTP_STATE R_opts();
|
||||
// END: STATE METHODS
|
||||
///////////////////////////////////
|
||||
|
||||
@ -243,6 +247,7 @@ private:
|
||||
nsCOMPtr<nsIRequest> mUploadRequest;
|
||||
bool mAddressChecked;
|
||||
bool mServerIsIPv6;
|
||||
bool mUseUTF8;
|
||||
|
||||
static uint32_t mSessionStartTime;
|
||||
|
||||
|
@ -65,8 +65,8 @@ nsFtpControlConnection::OnInputStreamReady(nsIAsyncInputStream *stream)
|
||||
|
||||
nsFtpControlConnection::nsFtpControlConnection(const nsCSubstring& host,
|
||||
uint32_t port)
|
||||
: mServerType(0), mSessionId(gFtpHandler->GetSessionId()), mHost(host)
|
||||
, mPort(port)
|
||||
: mServerType(0), mSessionId(gFtpHandler->GetSessionId())
|
||||
, mUseUTF8(false), mHost(host), mPort(port)
|
||||
{
|
||||
LOG_ALWAYS(("FTP:CC created @%p", this));
|
||||
}
|
||||
|
@ -68,6 +68,7 @@ public:
|
||||
int32_t mSuspendedWrite;
|
||||
nsCString mPwd;
|
||||
uint32_t mSessionId;
|
||||
bool mUseUTF8;
|
||||
|
||||
private:
|
||||
nsCString mHost;
|
||||
|
Loading…
Reference in New Issue
Block a user