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
This commit is contained in:
parent
cad9148b23
commit
0a2fcf9a45
633
mozilla/content/html/document/src/nsWyciwygChannel.cpp
Normal file
633
mozilla/content/html/document/src/nsWyciwygChannel.cpp
Normal file
@ -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<nsIScriptSecurityManager> 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<nsICacheService> cacheService(do_GetService(NS_CACHESERVICE_CONTRACTID, &rv));
|
||||
|
||||
if (NS_SUCCEEDED(rv) && cacheService) {
|
||||
nsXPIDLCString spec;
|
||||
nsAutoString newURIString;
|
||||
nsCOMPtr<nsICacheSession> 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;
|
||||
}
|
||||
99
mozilla/content/html/document/src/nsWyciwygChannel.h
Normal file
99
mozilla/content/html/document/src/nsWyciwygChannel.h
Normal file
@ -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<nsIInterfaceRequestor> mCallbacks;
|
||||
nsCOMPtr<nsILoadGroup> mLoadGroup;
|
||||
nsCOMPtr<nsIURI> mOriginalURI;
|
||||
nsCOMPtr<nsISupports> mOwner;
|
||||
nsCOMPtr<nsIStreamListener> mListener;
|
||||
nsCOMPtr<nsISupports> mListenerContext;
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
nsCOMPtr<nsIProgressEventSink> mProgressSink;
|
||||
|
||||
// Cache related stuff
|
||||
nsCOMPtr<nsITransport> mCacheTransport;
|
||||
nsCOMPtr<nsIRequest> mCacheReadRequest;
|
||||
nsCOMPtr<nsICacheEntryDescriptor> mCacheEntry;
|
||||
nsCOMPtr<nsIOutputStream> mCacheOutputStream;
|
||||
|
||||
// flags
|
||||
PRUint32 mStatus;
|
||||
PRUint32 mLoadFlags;
|
||||
PRPackedBool mIsPending;
|
||||
|
||||
};
|
||||
|
||||
#endif /* nsWyciwygChannel_h___ */
|
||||
121
mozilla/content/html/document/src/nsWyciwygProtocolHandler.cpp
Normal file
121
mozilla/content/html/document/src/nsWyciwygProtocolHandler.cpp
Normal file
@ -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;
|
||||
}
|
||||
43
mozilla/content/html/document/src/nsWyciwygProtocolHandler.h
Normal file
43
mozilla/content/html/document/src/nsWyciwygProtocolHandler.h
Normal file
@ -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___ */
|
||||
Loading…
x
Reference in New Issue
Block a user