Adds FTP upload support 92837. r=bbaetz, sr=darin

This commit is contained in:
dougt%netscape.com 2001-08-02 01:30:00 +00:00
Родитель bd468c0dde
Коммит 5959e028cf
5 изменённых файлов: 88 добавлений и 43 удалений

Просмотреть файл

@ -21,6 +21,7 @@
*/
#include "nsIChannel.idl"
interface nsIRequestObserver;
// this interface provides a way for the FTP connection to
// synchronize with the owning channel.
@ -28,6 +29,10 @@
[scriptable, uuid(3476df52-1dd2-11b2-b928-925d89b33bc0)]
interface nsIFTPChannel : nsIChannel
{
/**
* Set the stream to be uploaded by this channel.
*/
attribute nsIInputStream uploadStream;
};
[scriptable, uuid(455d4234-0330-43d2-bbfb-99afbecbfeb0)]

Просмотреть файл

@ -291,7 +291,7 @@ nsFTPChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *ctxt)
}
PRBool offline;
if (mCacheSession) {
if (mCacheSession && !mUploadStream) {
mIOService->GetOffline(&offline);
// Set the desired cache access mode accordingly...
@ -329,6 +329,8 @@ nsFTPChannel::SetupState()
mCacheEntry);
if (NS_FAILED(rv)) return rv;
(void) mFTPState->SetWriteStream(mUploadStream);
rv = mFTPState->Connect();
if (NS_FAILED(rv)) return rv;
@ -572,10 +574,6 @@ nsFTPChannel::OnStopRequest(nsIRequest *request, nsISupports* aContext,
mStatus = aStatus;
if (mObserver) {
(void) mObserver->OnStopRequest(this, mUserContext, aStatus);
}
if (mListener) {
(void) mListener->OnStopRequest(this, mUserContext, aStatus);
}
@ -595,6 +593,9 @@ nsFTPChannel::OnStopRequest(nsIRequest *request, nsISupports* aContext,
mCacheEntry = 0;
}
if (mUploadStream)
mUploadStream->Close();
mIsPending = PR_FALSE;
return rv;
}
@ -608,10 +609,6 @@ nsFTPChannel::OnStartRequest(nsIRequest *request, nsISupports *aContext)
this, request));
nsresult rv = NS_OK;
if (mObserver) {
rv = mObserver->OnStartRequest(this, mUserContext);
if (NS_FAILED(rv)) return rv;
}
if (mListener) {
rv = mListener->OnStartRequest(this, mUserContext);
@ -658,3 +655,19 @@ nsFTPChannel::OnCacheEntryAvailable(nsICacheEntryDescriptor *entry,
}
return NS_OK;
}
NS_IMETHODIMP
nsFTPChannel::SetUploadStream(nsIInputStream *stream)
{
mUploadStream = stream;
return NS_OK;
}
NS_IMETHODIMP
nsFTPChannel::GetUploadStream(nsIInputStream **stream)
{
NS_IF_ADDREF(*stream = mUploadStream);
return NS_OK;
}

Просмотреть файл

@ -91,6 +91,8 @@ public:
protected:
nsCOMPtr<nsIURI> mOriginalURI;
nsCOMPtr<nsIURI> mURL;
nsCOMPtr<nsIInputStream> mUploadStream;
// various callback interfaces
nsCOMPtr<nsIProgressEventSink> mEventSink;
@ -110,7 +112,6 @@ protected:
nsCOMPtr<nsISupports> mOwner;
nsCOMPtr<nsIStreamListener> mListener;
nsCOMPtr<nsIRequestObserver> mObserver;
nsFtpState* mFTPState;

Просмотреть файл

@ -86,6 +86,8 @@ public:
NS_FORWARD_NSIFTPCHANNEL(mFTPChannel->)
PRUint32 GetBytesTransfered() {return mBytesTransfered;} ;
void Uploading(PRBool value);
protected:
@ -95,9 +97,11 @@ protected:
nsCOMPtr<nsIProgressEventSink> mEventSink;
nsCOMPtr<nsICacheEntryDescriptor> mCacheEntry;
nsresult DelayedOnStartRequest(nsIRequest *request, nsISupports *ctxt);
PRBool mDelayedOnStartFired;
PRUint32 mBytesTransfered;
PRPackedBool mDelayedOnStartFired;
PRPackedBool mUploading;
nsresult DelayedOnStartRequest(nsIRequest *request, nsISupports *ctxt);
};
@ -119,8 +123,8 @@ DataRequestForwarder::DataRequestForwarder()
{
PR_LOG(gFTPLog, PR_LOG_DEBUG, ("(%x) DataRequestForwarder CREATED\n", this));
mDelayedOnStartFired = PR_FALSE;
mBytesTransfered = 0;
mUploading = mDelayedOnStartFired = PR_FALSE;
NS_INIT_ISUPPORTS();
}
@ -161,6 +165,11 @@ DataRequestForwarder::Init(nsIRequest *request)
return NS_OK;
}
void
DataRequestForwarder::Uploading(PRBool value)
{
mUploading = value;
}
nsresult
DataRequestForwarder::SetCacheEntry(nsICacheEntryDescriptor *cacheEntry, PRBool writing)
@ -216,7 +225,14 @@ DataRequestForwarder::DelayedOnStartRequest(nsIRequest *request, nsISupports *ct
NS_IMETHODIMP
DataRequestForwarder::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
{
NS_ASSERTION(mListener, "No Listener Set.");
PR_LOG(gFTPLog, PR_LOG_DEBUG, ("(%x) DataRequestForwarder OnStartRequest \n", this));
if (!mListener)
return NS_ERROR_NOT_INITIALIZED;
if (mUploading)
return mListener->OnStartRequest(this, ctxt);
return NS_OK;
}
@ -234,10 +250,10 @@ DataRequestForwarder::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsre
if (sTrans)
sTrans->SetReuseConnection(PR_FALSE);
}
if (mListener)
return mListener->OnStopRequest(this, ctxt, statusCode);
return NS_OK;
if (!mListener)
return NS_ERROR_NOT_INITIALIZED;
return mListener->OnStopRequest(this, ctxt, statusCode);
}
NS_IMETHODIMP
@ -245,6 +261,8 @@ DataRequestForwarder::OnDataAvailable(nsIRequest *request, nsISupports *ctxt, ns
{
nsresult rv;
NS_ASSERTION(mListener, "No Listener Set.");
NS_ASSERTION(!mUploading, "Since we are uploading, we should never get a ODA");
if (!mListener)
return NS_ERROR_NOT_INITIALIZED;
@ -277,8 +295,9 @@ DataRequestForwarder::OnProgress(nsIRequest *request, nsISupports* aContext,
PRUint32 aProgress, PRUint32 aProgressMax) {
if (!mEventSink)
return NS_OK;
return mEventSink->OnProgress(this, nsnull, mBytesTransfered, 0);
PRUint32 count = mUploading ? aProgress : mBytesTransfered;
PRUint32 max = mUploading ? aProgressMax : 0;
return mEventSink->OnProgress(this, nsnull, count, max);
}
@ -304,8 +323,6 @@ nsFtpState::nsFtpState() {
mSuspendCount = 0;
mPort = 21;
mWriteCount = 0;
mReceivedControlData = PR_FALSE;
mControlStatus = NS_OK;
mControlReadContinue = PR_FALSE;
@ -830,8 +847,6 @@ nsFtpState::Process()
if (FTP_ERROR == mState)
mInternalError = NS_ERROR_FAILURE;
//(DONE)
mNextState = FTP_COMPLETE;
break;
// PASV
@ -1284,30 +1299,38 @@ nsFtpState::R_rest() {
nsresult
nsFtpState::S_stor() {
nsresult rv = NS_OK;
nsCAutoString retrStr("STOR ");
retrStr.Append(mPath);
retrStr.Append(CRLF);
nsCAutoString storStr("STOR ");
storStr.Append(mPath.get());
storStr.Append(CRLF);
rv = SendFTPCommand(retrStr);
rv = SendFTPCommand(storStr);
if (NS_FAILED(rv)) return rv;
NS_ASSERTION(mWriteStream, "we're trying to upload without any data");
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIRequestObserver> observer = do_QueryInterface(mChannel, &rv);
if (NS_FAILED(rv)) return rv;
if (!mWriteStream)
return NS_ERROR_FAILURE;
PRUint32 len;
mWriteStream->Available(&len);
PR_LOG(gFTPLog, PR_LOG_DEBUG, ("(%x) writing on Data Transport\n", this));
return NS_AsyncWriteFromStream(getter_AddRefs(mDPipeRequest), mDPipe, mWriteStream,
0, mWriteCount, 0, observer, nsnull);
return NS_AsyncWriteFromStream(getter_AddRefs(mDPipeRequest),
mDPipe,
mWriteStream, 0, len, 0, mDRequestForwarder);
}
FTP_STATE
nsFtpState::R_stor() {
if (mResponseCode/100 == 1) {
return FTP_READ_BUF;
if (mResponseCode/100 == 2) {
//(DONE)
mNextState = FTP_COMPLETE;
return FTP_COMPLETE;
}
return FTP_ERROR;
if (mResponseCode/100 == 1) {
return FTP_READ_BUF;
}
return FTP_ERROR;
}
@ -1465,6 +1488,11 @@ nsFtpState::R_pasv() {
return FTP_ERROR;
}
if (mAction == PUT) {
mDRequestForwarder->Uploading(PR_TRUE);
return FTP_S_STOR;
}
rv = mDPipe->AsyncRead(mDRequestForwarder, nsnull, 0, PRUint32(-1), 0, getter_AddRefs(mDPipeRequest));
if (NS_FAILED(rv)){
PR_LOG(gFTPLog, PR_LOG_DEBUG, ("(%x) forwarder->AsyncRead failed (rv=%x)\n", this, rv));
@ -1472,9 +1500,6 @@ nsFtpState::R_pasv() {
}
if (mAction == PUT)
return FTP_S_CWD;
return FTP_S_SIZE;
}
@ -1766,10 +1791,12 @@ nsFtpState::Connect()
return rv;
}
nsresult
nsFtpState::SetWriteStream(nsIInputStream* aInStream, PRUint32 aWriteCount) {
nsFtpState::SetWriteStream(nsIInputStream* aInStream) {
if (!aInStream)
return NS_OK;
mAction = PUT;
mWriteStream = aInStream;
mWriteCount = aWriteCount; // The is the amount of data to write.
return NS_OK;
}

Просмотреть файл

@ -101,7 +101,7 @@ public:
nsICacheEntryDescriptor* cacheEntry);
// use this to provide a stream to be written to the server.
nsresult SetWriteStream(nsIInputStream* aInStream, PRUint32 aWriteCount);
nsresult SetWriteStream(nsIInputStream* aInStream);
nsresult Connect();
@ -192,7 +192,6 @@ private:
PRUint32 mBufferMaxSize;
PRLock *mLock;
nsCOMPtr<nsIInputStream> mWriteStream; // This stream is written to the server.
PRUint32 mWriteCount; // The amount of data to write to the server.
PRPackedBool mFireCallbacks; // Fire the listener callback.
PRPackedBool mIPv6Checked;
PRBool mGenerateHTMLContent;