From 0a2fcf9a4514597d6cedfcedf9310fa164cde854 Mon Sep 17 00:00:00 2001 From: "radha%netscape.com" Date: Thu, 31 Jan 2002 19:35:33 +0000 Subject: [PATCH] Initial checkin for wyciwyg protocol implementation. bug=35340 r/sr by nisheeth, darin, jst git-svn-id: svn://10.0.0.236/trunk@113336 18797224-902f-48f8-a5cc-f745e15eee43 --- .../html/document/src/nsWyciwygChannel.cpp | 633 ++++++++++++++++++ .../html/document/src/nsWyciwygChannel.h | 99 +++ .../document/src/nsWyciwygProtocolHandler.cpp | 121 ++++ .../document/src/nsWyciwygProtocolHandler.h | 43 ++ 4 files changed, 896 insertions(+) create mode 100644 mozilla/content/html/document/src/nsWyciwygChannel.cpp create mode 100644 mozilla/content/html/document/src/nsWyciwygChannel.h create mode 100644 mozilla/content/html/document/src/nsWyciwygProtocolHandler.cpp create mode 100644 mozilla/content/html/document/src/nsWyciwygProtocolHandler.h diff --git a/mozilla/content/html/document/src/nsWyciwygChannel.cpp b/mozilla/content/html/document/src/nsWyciwygChannel.cpp new file mode 100644 index 00000000000..067174aa38f --- /dev/null +++ b/mozilla/content/html/document/src/nsWyciwygChannel.cpp @@ -0,0 +1,633 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape 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/NPL/ + * + * 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 Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): Radha Kulkarni(radha@netscape.com) + */ + +#include "nsWyciwygChannel.h" +#include "nsIServiceManager.h" +#include "nsILoadGroup.h" +#include "nsIScriptSecurityManager.h" +#include "nsNetUtil.h" +#include "nsICacheService.h" +#include "nsICacheSession.h" + + +PRLogModuleInfo * gWyciwygLog = nsnull; + +#define wyciwyg_TYPE "text/html" + +// nsWyciwygChannel methods +nsWyciwygChannel::nsWyciwygChannel() + : mStatus(NS_OK), + mIsPending(PR_FALSE), + mLoadFlags(LOAD_NORMAL) +{ + NS_INIT_ISUPPORTS(); +} + +nsWyciwygChannel::~nsWyciwygChannel() +{ +} + +NS_IMPL_THREADSAFE_ISUPPORTS8(nsWyciwygChannel, nsIChannel, nsIRequest, + nsIStreamListener, nsICacheListener, + nsIInterfaceRequestor, nsIWyciwygChannel, + nsIRequestObserver, nsIProgressEventSink) + +nsresult +nsWyciwygChannel::Init(nsIURI* uri) +{ + if (!uri) + return NS_ERROR_NULL_POINTER; + mURI = uri; + return NS_OK; +} + +//----------------------------------------------------------------------------- +// nsHttpChannel::nsIInterfaceRequestor +//----------------------------------------------------------------------------- + +NS_IMETHODIMP +nsWyciwygChannel::GetInterface(const nsIID &aIID, void **aResult) +{ + + if (aIID.Equals(NS_GET_IID(nsIProgressEventSink))) { + // + // we return ourselves as the progress event sink so we can intercept + // notifications and set the correct request and context parameters. + // but, if we don't have a progress sink to forward those messages + // to, then there's no point in handing out a reference to ourselves. + // + if (!mProgressSink) + return NS_ERROR_NO_INTERFACE; + + return QueryInterface(aIID, aResult); + } + + if (mCallbacks) + return mCallbacks->GetInterface(aIID, aResult); + + return NS_ERROR_NO_INTERFACE; +} + +/////////////////////////////////////////////////////////////////////////////// +// nsIRequest methods: +/////////////////////////////////////////////////////////////////////////////// + +NS_IMETHODIMP +nsWyciwygChannel::GetName(PRUnichar**aName) +{ + NS_ENSURE_ARG_POINTER(aName); + nsXPIDLCString spec; + mURI->GetSpec(getter_Copies(spec)); + *aName = ToNewUnicode(spec); + return NS_OK; +} + +NS_IMETHODIMP +nsWyciwygChannel::IsPending(PRBool *aIsPending) +{ + *aIsPending = mIsPending; + return NS_OK; +} + +NS_IMETHODIMP +nsWyciwygChannel::GetStatus(nsresult *aStatus) +{ + *aStatus = mStatus; + return NS_OK; +} + +NS_IMETHODIMP +nsWyciwygChannel::Cancel(nsresult aStatus) +{ + LOG(("nsWyciwygChannel::Cancel [this=%x status=%x]\n", this, aStatus)); + NS_ASSERTION(NS_FAILED(aStatus), "shouldn't cancel with a success code"); + + if (NS_FAILED(aStatus)) + printf("status is failure\n"); + mStatus = aStatus; + if (mCacheReadRequest) + mCacheReadRequest->Cancel(aStatus); + // Clear out all cache handles. + CloseCacheEntry(); + return NS_OK; +} + +NS_IMETHODIMP +nsWyciwygChannel::Suspend(void) +{ + LOG(("nsWyciwygChannel::Suspend [this=%x]\n", this)); + if (mCacheReadRequest) + return mCacheReadRequest->Suspend(); + return NS_OK; +} + +NS_IMETHODIMP +nsWyciwygChannel::Resume(void) +{ + LOG(("nsWyciwygChannel::Resume [this=%x]\n", this)); + if (mCacheReadRequest) + return mCacheReadRequest->Resume(); + return NS_OK; +} + +NS_IMETHODIMP +nsWyciwygChannel::GetLoadGroup(nsILoadGroup* *aLoadGroup) +{ + NS_ENSURE_ARG_POINTER(aLoadGroup); + *aLoadGroup = mLoadGroup; + NS_IF_ADDREF(*aLoadGroup); + return NS_OK; +} + +NS_IMETHODIMP +nsWyciwygChannel::SetLoadGroup(nsILoadGroup* aLoadGroup) +{ + mLoadGroup = aLoadGroup; + return NS_OK; +} + +NS_IMETHODIMP +nsWyciwygChannel::SetLoadFlags(PRUint32 aLoadFlags) +{ + mLoadFlags = aLoadFlags; + return NS_OK; +} + +NS_IMETHODIMP +nsWyciwygChannel::GetLoadFlags(PRUint32 * aLoadFlags) +{ + NS_ENSURE_ARG_POINTER(aLoadFlags); + *aLoadFlags = mLoadFlags; + return NS_OK; +} + +//////////////////////////////////////////////////////////////////////////////// +// nsIChannel methods: +/////////////////////////////////////////////////////////////////////////////// +NS_IMETHODIMP +nsWyciwygChannel::GetOriginalURI(nsIURI* *aURI) +{ + // Let's hope this isn't called before mOriginalURI is set or we will + // return the full wyciwyg URI for our originalURI :S + NS_ASSERTION(mOriginalURI, "nsWyciwygChannel::GetOriginalURI - mOriginalURI not set!\n"); + + *aURI = mOriginalURI ? mOriginalURI : mURI; + NS_IF_ADDREF(*aURI); + return NS_OK; +} + +NS_IMETHODIMP +nsWyciwygChannel::SetOriginalURI(nsIURI* aURI) +{ + mOriginalURI = aURI; + return NS_OK; +} + +NS_IMETHODIMP +nsWyciwygChannel::GetURI(nsIURI* *aURI) +{ + NS_ENSURE_ARG_POINTER(aURI); + *aURI = mURI; + NS_IF_ADDREF(*aURI); + return NS_OK; +} + +NS_IMETHODIMP +nsWyciwygChannel::GetOwner(nsISupports* *aOwner) +{ + nsresult rv = NS_OK; + if (!mOwner) { + // Create codebase principal with URI of original document, not our URI + NS_ASSERTION(mOriginalURI, + "nsWyciwygChannel::GetOwner without an owner or an original URI!"); + if (mOriginalURI) { + nsIPrincipal* pIPrincipal = nsnull; + nsCOMPtr secMan(do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv)); + if (secMan) { + rv = secMan->GetCodebasePrincipal(mOriginalURI, &pIPrincipal); + if (NS_SUCCEEDED(rv)) { + mOwner = pIPrincipal; + NS_RELEASE(pIPrincipal); + } + } + } else { + // Uh oh, must set originalURI before we can return an owner! + return NS_ERROR_FAILURE; + } + } + NS_ASSERTION(mOriginalURI, + "nsWyciwygChannel::GetOwner unable to get owner!"); + if (mOwner) { + *aOwner = mOwner.get(); + NS_IF_ADDREF(*aOwner); + } else { + *aOwner = nsnull; + } + return rv; +} + +NS_IMETHODIMP +nsWyciwygChannel::SetOwner(nsISupports* aOwner) +{ + mOwner = aOwner; + return NS_OK; +} + +NS_IMETHODIMP +nsWyciwygChannel::GetNotificationCallbacks(nsIInterfaceRequestor* *aCallbacks) +{ + *aCallbacks = mCallbacks.get(); + NS_IF_ADDREF(*aCallbacks); + return NS_OK; +} + +NS_IMETHODIMP +nsWyciwygChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks) +{ + mCallbacks = aNotificationCallbacks; + mProgressSink = do_GetInterface(mCallbacks); + return NS_OK; +} + +NS_IMETHODIMP +nsWyciwygChannel::GetSecurityInfo(nsISupports * *aSecurityInfo) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsWyciwygChannel::GetContentType(char* *aContentType) +{ + NS_ENSURE_ARG_POINTER(aContentType); + *aContentType = nsCRT::strdup(wyciwyg_TYPE); + return NS_OK; +} + +NS_IMETHODIMP +nsWyciwygChannel::SetContentType(const char *aContentType) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsWyciwygChannel::GetContentLength(PRInt32 *aContentLength) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsWyciwygChannel::SetContentLength(PRInt32 aContentLength) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsWyciwygChannel::Open(nsIInputStream ** aReturn) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsWyciwygChannel::AsyncOpen(nsIStreamListener * aListener, nsISupports * aContext) +{ + LOG(("nsWyciwygChannel::AsyncOpen [this=%x]\n", this)); + + NS_ENSURE_ARG_POINTER(aListener); + NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS); + + //XXX Should I worry about Port safety? + + mIsPending = PR_TRUE; + mListener = aListener; + mListenerContext = aContext; + + // add ourselves to the load group. From this point forward, we'll report + // all failures asynchronously. + if (mLoadGroup) + mLoadGroup->AddRequest(this, nsnull); + + nsresult rv = Connect(PR_TRUE); + if (NS_FAILED(rv)) { + LOG(("nsWyciwygChannel::AsyncOpen Connect failed [rv=%x]\n", rv)); + CloseCacheEntry(); + AsyncAbort(rv); + } + return NS_OK; +} + +////////////////////////////////////////////////////////////////////////////// +// nsIWyciwygChannel +////////////////////////////////////////////////////////////////////////////// + +NS_IMETHODIMP +nsWyciwygChannel::CreateCacheEntry(const char * aCacheKey) +{ + return OpenCacheEntry(aCacheKey, nsICache::ACCESS_WRITE); +} + +NS_IMETHODIMP +nsWyciwygChannel::WriteToCache(const char * aScript) +{ + if (!mCacheEntry) + return NS_ERROR_FAILURE; + PRUint32 len = nsCRT::strlen(aScript); + nsresult rv; + PRUint32 out; + + if (!mCacheTransport && !mCacheOutputStream) { + //Get the transport from cache + rv = mCacheEntry->GetTransport(getter_AddRefs(mCacheTransport)); + + // Get the outputstream from the transport. + if (mCacheTransport) + rv = mCacheTransport->OpenOutputStream(0, -1, 0, getter_AddRefs(mCacheOutputStream)); + } + + if (mCacheOutputStream) + rv = mCacheOutputStream->Write(aScript, len, &out); + return rv; +} + + +NS_IMETHODIMP +nsWyciwygChannel::CloseCacheEntry() +{ + nsresult rv = NS_OK; + if (mCacheEntry) { + LOG(("nsWyciwygChannel::CloseCacheEntry [this=%x ]", this)); + // make sure the cache transport isn't holding a reference back to us + if (mCacheTransport) + mCacheTransport->SetNotificationCallbacks(nsnull, 0); + mCacheReadRequest = 0; + mCacheTransport = 0; + mCacheOutputStream = 0; + mCacheEntry = 0; + } + return rv; +} + +////////////////////////////////////////////////////////////////////////////// +// nsICachelistener +////////////////////////////////////////////////////////////////////////////// +NS_IMETHODIMP +nsWyciwygChannel::OnCacheEntryAvailable(nsICacheEntryDescriptor * aCacheEntry, nsCacheAccessMode aMode, nsresult aStatus) +{ + LOG(("nsWyciwygChannel::OnCacheEntryAvailable [this=%x entry=%x " + "access=%x status=%x]\n", this, aCacheEntry, aMode, aStatus)); + + // if the channel's already fired onStopRequest, + // then we should ignore this event. + if (!mIsPending) + return NS_OK; + + // otherwise, we have to handle this event. + if (NS_SUCCEEDED(aStatus)) { + mCacheEntry = aCacheEntry; + } + + nsresult rv; + + if (NS_FAILED(mStatus)) { + LOG(("channel was canceled [this=%x status=%x]\n", this, mStatus)); + rv = mStatus; + } + else // advance to the next state... + rv = Connect(PR_FALSE); + + // a failure from Connect means that we have to abort the channel. + if (NS_FAILED(rv)) { + CloseCacheEntry(); + AsyncAbort(rv); + } + + return rv; +} + +//----------------------------------------------------------------------------- +// nsWyciwygChannel::nsIStreamListener +//----------------------------------------------------------------------------- + +NS_IMETHODIMP +nsWyciwygChannel::OnDataAvailable(nsIRequest *aRequest, nsISupports *aCtxt, + nsIInputStream *aInput, + PRUint32 aOffset, PRUint32 aCount) +{ + LOG(("nsWyciwygChannel::OnDataAvailable [this=%x request=%x offset=%u count=%u]\n", + this, aRequest, aOffset, aCount)); + + // if the request is for something we no longer reference, then simply + // drop this event. + if (aRequest != mCacheReadRequest) { + NS_WARNING("nsWyciwygChannel::OnDataAvailable got stale request... why wasn't it cancelled?"); + return NS_BASE_STREAM_CLOSED; + } + + if (mListener) + return mListener->OnDataAvailable((nsIRequest *)this, mListenerContext, aInput, aOffset, aCount); + + return NS_BASE_STREAM_CLOSED; +} + +////////////////////////////////////////////////////////////////////////////// +// nsIRequestObserver +////////////////////////////////////////////////////////////////////////////// + +NS_IMETHODIMP +nsWyciwygChannel::OnStartRequest(nsIRequest *aRequest, nsISupports *aCtxt) +{ + nsresult rv = NS_ERROR_FAILURE; + LOG(("nsWyciwygChannel::OnStartRequest [this=%x request=%x\n", + this, aRequest)); + + // capture the request's status, so our consumers will know ASAP of any + // connection failures, etc. + aRequest->GetStatus(&mStatus); + if (mListener) + rv = mListener->OnStartRequest(this, mListenerContext); + return rv; +} + + +NS_IMETHODIMP +nsWyciwygChannel::OnStopRequest(nsIRequest *aRequest, nsISupports *aCtxt, nsresult aStatus) +{ + LOG(("nsWyciwygChannel::OnStopRequest [this=%x request=%x status=%d\n", + this, aRequest, (PRUint32)aStatus)); + + mIsPending = PR_FALSE; + mStatus = aStatus; + CloseCacheEntry(); + if (mListener) { + mListener->OnStopRequest(this, mListenerContext, aStatus); + mListener = 0; + mListenerContext = 0; + } + + if (mLoadGroup) + mLoadGroup->RemoveRequest(this, nsnull, aStatus); + + return NS_OK; +} + +////////////////////////////////////////////////////////////////////////////// +// nsIProgressEventSink +////////////////////////////////////////////////////////////////////////////// + +NS_IMETHODIMP +nsWyciwygChannel::OnStatus(nsIRequest *aRequest, nsISupports *aContext, nsresult aStatus, + const PRUnichar *aStatusText) +{ + if (mProgressSink) + mProgressSink->OnStatus(this, mListenerContext, aStatus, aStatusText); + + return NS_OK; +} + +NS_IMETHODIMP +nsWyciwygChannel::OnProgress(nsIRequest *aRequest, nsISupports *aContext, + PRUint32 aProgress, PRUint32 aProgressMax) +{ + if (mProgressSink) + mProgressSink->OnProgress(this, mListenerContext, aProgress, aProgressMax); + + return NS_OK; +} + + +////////////////////////////////////////////////////////////////////////////// +// Helper functions +////////////////////////////////////////////////////////////////////////////// +nsresult +nsWyciwygChannel::OpenCacheEntry(const char * aCacheKey, nsCacheAccessMode aAccessMode, PRBool * aDelayFlag ) +{ + nsresult rv; + // Get cache service + nsCOMPtr cacheService(do_GetService(NS_CACHESERVICE_CONTRACTID, &rv)); + + if (NS_SUCCEEDED(rv) && cacheService) { + nsXPIDLCString spec; + nsAutoString newURIString; + nsCOMPtr cacheSession; + + // Open a stream based cache session. + rv = cacheService->CreateSession("wyciwyg", nsICache::STORE_ANYWHERE, PR_TRUE, getter_AddRefs(cacheSession)); + if (!cacheSession) + return NS_ERROR_FAILURE; + + /* we'll try to synchronously open the cache entry... however, it may be + * in use and not yet validated, in which case we'll try asynchronously + * opening the cache entry. + */ + + rv = cacheSession->OpenCacheEntry(aCacheKey, aAccessMode, PR_FALSE, + getter_AddRefs(mCacheEntry)); + + if (rv == NS_ERROR_CACHE_WAIT_FOR_VALIDATION) { + // access to the cache entry has been denied. Let's try + // opening it async. + rv = cacheSession->AsyncOpenCacheEntry(aCacheKey, aAccessMode, this); + if (NS_FAILED(rv)) + return rv; + if (aDelayFlag) + *aDelayFlag = PR_TRUE; + } + else if (rv == NS_OK) { + LOG(("nsWyciwygChannel::OpenCacheEntry got cache entry \n")); + } + } + return rv; +} + +nsresult +nsWyciwygChannel::Connect(PRBool aFirstTime) +{ + nsresult rv; + + LOG(("nsWyciwygChannel::Connect [this=%x]\n", this)); + + // true when called from AsyncOpen + if (aFirstTime) { + PRBool delayed = PR_FALSE; + + nsXPIDLCString spec; + mURI->GetSpec(getter_Copies(spec)); + // open a cache entry for this channel... + rv = OpenCacheEntry(spec.get(), nsICache::ACCESS_READ, &delayed); + + if (NS_FAILED(rv)) { + LOG(("nsWyciwygChannel::Connect OpenCacheEntry failed [rv=%x]\n", rv)); + return rv; + } + + if (NS_SUCCEEDED(rv) && delayed) + return NS_OK; + } + + // Read the script from cache. + if (mCacheEntry) + return ReadFromCache(); + return rv; +} + +nsresult +nsWyciwygChannel::ReadFromCache() +{ + nsresult rv; + + NS_ENSURE_TRUE(mCacheEntry, NS_ERROR_FAILURE); + LOG(("nsWyciwygChannel::ReadFromCache [this=%x] ", this)); + + // Get a transport to the cached data... + rv = mCacheEntry->GetTransport(getter_AddRefs(mCacheTransport)); + if (NS_FAILED(rv) || !mCacheTransport) + return rv; + + // Hookup the notification callbacks interface to the new transport... + mCacheTransport->SetNotificationCallbacks(this, + ((mLoadFlags & nsIRequest::LOAD_BACKGROUND) + ? nsITransport::DONT_REPORT_PROGRESS + : 0)); + + // Pump the cache data downstream + return mCacheTransport->AsyncRead(this, nsnull, + 0, PRUint32(-1), 0, + getter_AddRefs(mCacheReadRequest)); +} + + + + +// called when Connect fails +nsresult +nsWyciwygChannel::AsyncAbort(nsresult aStatus) +{ + LOG(("nsWyciwygChannel::AsyncAbort [this=%x status=%x]\n", this, aStatus)); + + mStatus = aStatus; + mIsPending = PR_FALSE; + + // Remove ourselves from the load group. + if (mLoadGroup) + mLoadGroup->RemoveRequest((nsIRequest *)this, nsnull, aStatus); + + return NS_OK; +} \ No newline at end of file diff --git a/mozilla/content/html/document/src/nsWyciwygChannel.h b/mozilla/content/html/document/src/nsWyciwygChannel.h new file mode 100644 index 00000000000..be4969e6581 --- /dev/null +++ b/mozilla/content/html/document/src/nsWyciwygChannel.h @@ -0,0 +1,99 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape 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/NPL/ + * + * 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 Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + */ + +#ifndef nsWyciwygChannel_h___ +#define nsWyciwygChannel_h___ + +#include "nsIWyciwygChannel.h" +#include "nsString.h" +#include "nsILoadGroup.h" +#include "nsIInputStream.h" +#include "nsIInterfaceRequestor.h" +#include "nsCOMPtr.h" +#include "nsXPIDLString.h" +#include "nsIChannel.h" +#include "nsIURI.h" +#include "nsWyciwygProtocolHandler.h" +#include "nsIStreamListener.h" +#include "nsICacheListener.h" +#include "nsITransport.h" +#include "nsICacheEntryDescriptor.h" +#include "nsIOutputStream.h" +#include "nsIProgressEventSink.h" +#include "prlog.h" + +extern PRLogModuleInfo * gWyciwygLog; + +#define LOG(args) PR_LOG(gWyciwygLog, 4, args) + +class nsWyciwygChannel: public nsIWyciwygChannel, + public nsIStreamListener, + public nsIInterfaceRequestor, + public nsICacheListener, + public nsIProgressEventSink +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIREQUEST + NS_DECL_NSICHANNEL + NS_DECL_NSIWYCIWYGCHANNEL + NS_DECL_NSISTREAMLISTENER + NS_DECL_NSICACHELISTENER + NS_DECL_NSIINTERFACEREQUESTOR + NS_DECL_NSIREQUESTOBSERVER + NS_DECL_NSIPROGRESSEVENTSINK + + // nsWyciwygChannel methods: + nsWyciwygChannel(); + virtual ~nsWyciwygChannel(); + + nsresult Init(nsIURI* uri); + +protected: + nsresult AsyncAbort(nsresult rv); + nsresult Connect(PRBool firstTime); + nsresult ReadFromCache(); + nsresult OpenCacheEntry(const char * aCacheKey, nsCacheAccessMode aWriteAccess, PRBool * aDelayFlag = nsnull); + + nsCOMPtr mCallbacks; + nsCOMPtr mLoadGroup; + nsCOMPtr mOriginalURI; + nsCOMPtr mOwner; + nsCOMPtr mListener; + nsCOMPtr mListenerContext; + nsCOMPtr mURI; + nsCOMPtr mProgressSink; + + // Cache related stuff + nsCOMPtr mCacheTransport; + nsCOMPtr mCacheReadRequest; + nsCOMPtr mCacheEntry; + nsCOMPtr mCacheOutputStream; + + // flags + PRUint32 mStatus; + PRUint32 mLoadFlags; + PRPackedBool mIsPending; + +}; + +#endif /* nsWyciwygChannel_h___ */ \ No newline at end of file diff --git a/mozilla/content/html/document/src/nsWyciwygProtocolHandler.cpp b/mozilla/content/html/document/src/nsWyciwygProtocolHandler.cpp new file mode 100644 index 00000000000..27959083c05 --- /dev/null +++ b/mozilla/content/html/document/src/nsWyciwygProtocolHandler.cpp @@ -0,0 +1,121 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape 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/NPL/ + * + * 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 Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): Radha Kulkarni(radha@netscape.com) + */ + +#include "nsWyciwygChannel.h" +#include "nsWyciwygProtocolHandler.h" +#include "nsIURL.h" +#include "nsIComponentManager.h" +#include "nsNetCID.h" + +static NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID); + +//////////////////////////////////////////////////////////////////////////////// + +nsWyciwygProtocolHandler::nsWyciwygProtocolHandler() +{ + NS_INIT_ISUPPORTS(); + +#if defined(PR_LOGGING) + gWyciwygLog = PR_NewLogModule("nsWyciwygChannel"); +#endif +} + +nsWyciwygProtocolHandler::~nsWyciwygProtocolHandler() +{ +} + +NS_IMPL_ISUPPORTS1(nsWyciwygProtocolHandler, nsIProtocolHandler); + +//////////////////////////////////////////////////////////////////////////////// +// nsIProtocolHandler methods: +//////////////////////////////////////////////////////////////////////////////// + +NS_IMETHODIMP +nsWyciwygProtocolHandler::GetScheme(char* *result) +{ + *result = nsCRT::strdup("wyciwyg"); + return *result ? NS_OK : NS_ERROR_OUT_OF_MEMORY; +} + +NS_IMETHODIMP +nsWyciwygProtocolHandler::GetDefaultPort(PRInt32 *result) +{ + return NS_ERROR_NOT_AVAILABLE; +} + +NS_IMETHODIMP +nsWyciwygProtocolHandler::AllowPort(PRInt32 port, const char *scheme, PRBool *_retval) +{ + // don't override anything. + *_retval = PR_FALSE; + return NS_OK; +} + +NS_IMETHODIMP +nsWyciwygProtocolHandler::NewURI(const char *aSpec, nsIURI *aBaseURI, + nsIURI **result) +{ + nsresult rv; + + // no concept of a relative wyciwyg url + NS_ASSERTION(!aBaseURI, "base url passed into wyciwyg protocol handler"); + + nsIURI* url; + rv = nsComponentManager::CreateInstance(kSimpleURICID, nsnull, + NS_GET_IID(nsIURI), + (void**)&url); + if (NS_FAILED(rv)) return rv; + rv = url->SetSpec((char*)aSpec); + if (NS_FAILED(rv)) { + NS_RELEASE(url); + return rv; + } + + *result = url; + return rv; +} + +NS_IMETHODIMP +nsWyciwygProtocolHandler::NewChannel(nsIURI* url, nsIChannel* *result) +{ + nsresult rv; + + nsWyciwygChannel* channel = new nsWyciwygChannel(); + if (!channel) + return NS_ERROR_OUT_OF_MEMORY; + NS_ADDREF(channel); + rv = channel->Init(url); + if (NS_FAILED(rv)) { + NS_RELEASE(channel); + return rv; + } + + *result = channel; + return NS_OK; +} + +NS_IMETHODIMP +nsWyciwygProtocolHandler::GetProtocolFlags(PRUint32 *result) +{ + *result = URI_NORELATIVE | URI_NOAUTH; + return NS_OK; +} diff --git a/mozilla/content/html/document/src/nsWyciwygProtocolHandler.h b/mozilla/content/html/document/src/nsWyciwygProtocolHandler.h new file mode 100644 index 00000000000..73af575ea8f --- /dev/null +++ b/mozilla/content/html/document/src/nsWyciwygProtocolHandler.h @@ -0,0 +1,43 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape 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/NPL/ + * + * 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 Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): Radha Kulkarni(radha@netscape.com) + */ + +#ifndef nsWyciwygProtocolHandler_h___ +#define nsWyciwygProtocolHandler_h___ + +#include "nsIProtocolHandler.h" + + +class nsWyciwygProtocolHandler : public nsIProtocolHandler +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIPROTOCOLHANDLER + + // nsWyciwygProtocolHandler methods: + nsWyciwygProtocolHandler(); + virtual ~nsWyciwygProtocolHandler(); + + // Define a Create method to be used with a factory: +// static NS_METHOD Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult); +}; + +#endif /* nsWyciwygProtocolHandler_h___ */