/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set sw=2 ts=8 et tw=80 : */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is * The Mozilla Foundation * Portions created by the Initial Developer are Copyright (C) 2010 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Alon Zakai * Josh Matthews * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #include "mozilla/net/FTPChannelParent.h" #include "nsFTPChannel.h" #include "nsNetUtil.h" #include "nsISupportsPriority.h" #include "nsIRedirectChannelRegistrar.h" #include "nsFtpProtocolHandler.h" #undef LOG #define LOG(args) PR_LOG(gFTPLog, PR_LOG_DEBUG, args) namespace mozilla { namespace net { FTPChannelParent::FTPChannelParent() : mIPCClosed(false) { nsIProtocolHandler* handler; CallGetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "ftp", &handler); NS_ASSERTION(handler, "no ftp handler"); } FTPChannelParent::~FTPChannelParent() { gFtpHandler->Release(); } void FTPChannelParent::ActorDestroy(ActorDestroyReason why) { // We may still have refcount>0 if the channel hasn't called OnStopRequest // yet, but we must not send any more msgs to child. mIPCClosed = true; } //----------------------------------------------------------------------------- // FTPChannelParent::nsISupports //----------------------------------------------------------------------------- NS_IMPL_ISUPPORTS4(FTPChannelParent, nsIStreamListener, nsIParentChannel, nsIInterfaceRequestor, nsIRequestObserver); //----------------------------------------------------------------------------- // FTPChannelParent::PFTPChannelParent //----------------------------------------------------------------------------- bool FTPChannelParent::RecvAsyncOpen(const IPC::URI& aURI, const PRUint64& aStartPos, const nsCString& aEntityID, const IPC::InputStream& aUploadStream) { nsCOMPtr uri(aURI); #ifdef DEBUG nsCString uriSpec; uri->GetSpec(uriSpec); LOG(("FTPChannelParent RecvAsyncOpen [this=%x uri=%s]\n", this, uriSpec.get())); #endif nsresult rv; nsCOMPtr ios(do_GetIOService(&rv)); if (NS_FAILED(rv)) return SendFailedAsyncOpen(rv); nsCOMPtr chan; rv = NS_NewChannel(getter_AddRefs(chan), uri, ios); if (NS_FAILED(rv)) return SendFailedAsyncOpen(rv); mChannel = static_cast(chan.get()); nsCOMPtr upload(aUploadStream); if (upload) { // contentType and contentLength are ignored rv = mChannel->SetUploadStream(upload, EmptyCString(), 0); if (NS_FAILED(rv)) return SendFailedAsyncOpen(rv); } rv = mChannel->ResumeAt(aStartPos, aEntityID); if (NS_FAILED(rv)) return SendFailedAsyncOpen(rv); rv = mChannel->AsyncOpen(this, nsnull); if (NS_FAILED(rv)) return SendFailedAsyncOpen(rv); return true; } bool FTPChannelParent::RecvConnectChannel(const PRUint32& channelId) { nsresult rv; LOG(("Looking for a registered channel [this=%p, id=%d]", this, channelId)); nsCOMPtr channel; rv = NS_LinkRedirectChannels(channelId, this, getter_AddRefs(channel)); if (NS_SUCCEEDED(rv)) mChannel = static_cast(channel.get()); LOG((" found channel %p, rv=%08x", mChannel.get(), rv)); return true; } bool FTPChannelParent::RecvCancel(const nsresult& status) { if (mChannel) mChannel->Cancel(status); return true; } bool FTPChannelParent::RecvSuspend() { if (mChannel) mChannel->Suspend(); return true; } bool FTPChannelParent::RecvResume() { if (mChannel) mChannel->Resume(); return true; } //----------------------------------------------------------------------------- // FTPChannelParent::nsIRequestObserver //----------------------------------------------------------------------------- NS_IMETHODIMP FTPChannelParent::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext) { LOG(("FTPChannelParent::OnStartRequest [this=%x]\n", this)); nsFtpChannel* chan = static_cast(aRequest); PRInt32 aContentLength; chan->GetContentLength(&aContentLength); nsCString contentType; chan->GetContentType(contentType); nsCString entityID; chan->GetEntityID(entityID); PRTime lastModified; chan->GetLastModifiedTime(&lastModified); if (mIPCClosed || !SendOnStartRequest(aContentLength, contentType, lastModified, entityID, chan->URI())) { return NS_ERROR_UNEXPECTED; } return NS_OK; } NS_IMETHODIMP FTPChannelParent::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext, nsresult aStatusCode) { LOG(("FTPChannelParent::OnStopRequest: [this=%x status=%ul]\n", this, aStatusCode)); if (mIPCClosed || !SendOnStopRequest(aStatusCode)) { return NS_ERROR_UNEXPECTED; } return NS_OK; } //----------------------------------------------------------------------------- // FTPChannelParent::nsIStreamListener //----------------------------------------------------------------------------- NS_IMETHODIMP FTPChannelParent::OnDataAvailable(nsIRequest* aRequest, nsISupports* aContext, nsIInputStream* aInputStream, PRUint32 aOffset, PRUint32 aCount) { LOG(("FTPChannelParent::OnDataAvailable [this=%x]\n", this)); nsCString data; nsresult rv = NS_ReadInputStreamToString(aInputStream, data, aCount); if (NS_FAILED(rv)) return rv; if (mIPCClosed || !SendOnDataAvailable(data, aOffset, aCount)) return NS_ERROR_UNEXPECTED; return NS_OK; } //----------------------------------------------------------------------------- // FTPChannelParent::nsIParentChannel //----------------------------------------------------------------------------- NS_IMETHODIMP FTPChannelParent::Delete() { if (mIPCClosed || !SendDeleteSelf()) return NS_ERROR_UNEXPECTED; return NS_OK; } //----------------------------------------------------------------------------- // FTPChannelParent::nsIInterfaceRequestor //----------------------------------------------------------------------------- NS_IMETHODIMP FTPChannelParent::GetInterface(const nsIID& uuid, void** result) { return QueryInterface(uuid, result); } } // namespace net } // namespace mozilla