modifications for bug 176919 "async streams" r=dougt,gordon sr=sspitzer a=valeski,asa

This commit is contained in:
darin%netscape.com 2003-01-18 02:15:14 +00:00
Родитель df826d5551
Коммит 8f284ed984
172 изменённых файлов: 7160 добавлений и 18410 удалений

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

@ -56,5 +56,5 @@ interface nsIWyciwygChannel : nsIChannel
/**
* Close the cache entry; subsequent writes have undefined behavior.
*/
void closeCacheEntry();
void closeCacheEntry(in nsresult reason);
};

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

@ -4029,7 +4029,7 @@ nsHTMLDocument::RemoveWyciwygChannel(void)
// note there can be a write request without a load group if
// this is a synchronously constructed about:blank document
if (loadGroup && mWyciwygChannel) {
mWyciwygChannel->CloseCacheEntry();
mWyciwygChannel->CloseCacheEntry(NS_OK);
rv = loadGroup->RemoveRequest(mWyciwygChannel, nsnull, NS_OK);
if (NS_FAILED(rv)) return rv;
}

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

@ -32,12 +32,14 @@
PRLogModuleInfo * gWyciwygLog = nsnull;
#define wyciwyg_TYPE "text/html"
#define LOG(args) PR_LOG(gWyciwygLog, 4, args)
// nsWyciwygChannel methods
nsWyciwygChannel::nsWyciwygChannel()
: mStatus(NS_OK),
mLoadFlags(LOAD_NORMAL),
mIsPending(PR_FALSE)
: mContentLength(-1)
, mLoadFlags(LOAD_NORMAL)
, mStatus(NS_OK)
, mIsPending(PR_FALSE)
{
}
@ -45,47 +47,22 @@ nsWyciwygChannel::~nsWyciwygChannel()
{
}
NS_IMPL_THREADSAFE_ISUPPORTS8(nsWyciwygChannel, nsIChannel, nsIRequest,
nsIStreamListener, nsICacheListener,
nsIInterfaceRequestor, nsIWyciwygChannel,
nsIRequestObserver, nsIProgressEventSink)
NS_IMPL_ISUPPORTS6(nsWyciwygChannel,
nsIChannel,
nsIRequest,
nsIStreamListener,
nsIRequestObserver,
nsICacheListener,
nsIWyciwygChannel)
nsresult
nsWyciwygChannel::Init(nsIURI* uri)
{
if (!uri)
return NS_ERROR_NULL_POINTER;
NS_ENSURE_ARG_POINTER(uri);
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:
///////////////////////////////////////////////////////////////////////////////
@ -106,39 +83,38 @@ nsWyciwygChannel::IsPending(PRBool *aIsPending)
NS_IMETHODIMP
nsWyciwygChannel::GetStatus(nsresult *aStatus)
{
*aStatus = mStatus;
if (NS_SUCCEEDED(mStatus) && mPump)
mPump->GetStatus(aStatus);
else
*aStatus = mStatus;
return NS_OK;
}
NS_IMETHODIMP
nsWyciwygChannel::Cancel(nsresult aStatus)
nsWyciwygChannel::Cancel(nsresult status)
{
LOG(("nsWyciwygChannel::Cancel [this=%x status=%x]\n", this, aStatus));
NS_ASSERTION(NS_FAILED(aStatus), "shouldn't cancel with a success code");
mStatus = aStatus;
if (mCacheReadRequest)
mCacheReadRequest->Cancel(aStatus);
// Clear out all cache handles.
CloseCacheEntry();
mStatus = status;
if (mPump)
mPump->Cancel(status);
// else we're waiting for OnCacheEntryAvailable
return NS_OK;
}
NS_IMETHODIMP
nsWyciwygChannel::Suspend(void)
nsWyciwygChannel::Suspend()
{
LOG(("nsWyciwygChannel::Suspend [this=%x]\n", this));
if (mCacheReadRequest)
return mCacheReadRequest->Suspend();
if (mPump)
mPump->Suspend();
// XXX else, we'll ignore this ... and that's probably bad!
return NS_OK;
}
NS_IMETHODIMP
nsWyciwygChannel::Resume(void)
nsWyciwygChannel::Resume()
{
LOG(("nsWyciwygChannel::Resume [this=%x]\n", this));
if (mCacheReadRequest)
return mCacheReadRequest->Resume();
if (mPump)
mPump->Resume();
// XXX else, we'll ignore this ... and that's probably bad!
return NS_OK;
}
@ -176,6 +152,7 @@ nsWyciwygChannel::GetLoadFlags(PRUint32 * aLoadFlags)
////////////////////////////////////////////////////////////////////////////////
// nsIChannel methods:
///////////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP
nsWyciwygChannel::GetOriginalURI(nsIURI* *aURI)
{
@ -205,36 +182,24 @@ nsWyciwygChannel::GetURI(nsIURI* *aURI)
}
NS_IMETHODIMP
nsWyciwygChannel::GetOwner(nsISupports* *aOwner)
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_ENSURE_TRUE(mOriginalURI, NS_ERROR_FAILURE); // without an owner or an original URI!
nsCOMPtr<nsIPrincipal> principal;
nsCOMPtr<nsIScriptSecurityManager> secMan(do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv));
if (secMan) {
rv = secMan->GetCodebasePrincipal(mOriginalURI, getter_AddRefs(principal));
if (NS_SUCCEEDED(rv))
mOwner = principal;
}
}
NS_ASSERTION(mOriginalURI,
"nsWyciwygChannel::GetOwner unable to get owner!");
if (mOwner) {
*aOwner = mOwner.get();
NS_IF_ADDREF(*aOwner);
} else {
*aOwner = nsnull;
}
NS_IF_ADDREF(*aOwner = mOwner);
return rv;
}
@ -312,30 +277,39 @@ nsWyciwygChannel::Open(nsIInputStream ** aReturn)
}
NS_IMETHODIMP
nsWyciwygChannel::AsyncOpen(nsIStreamListener * aListener, nsISupports * aContext)
nsWyciwygChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *ctx)
{
LOG(("nsWyciwygChannel::AsyncOpen [this=%x]\n", this));
NS_ENSURE_ARG_POINTER(aListener);
NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS);
NS_ENSURE_ARG_POINTER(listener);
//XXX Should I worry about Port safety?
nsCAutoString spec;
mURI->GetSpec(spec);
// open a cache entry for this channel...
PRBool delayed = PR_FALSE;
nsresult rv = OpenCacheEntry(spec.get(), nsICache::ACCESS_READ, &delayed);
if (NS_FAILED(rv)) {
LOG(("nsWyciwygChannel::OpenCacheEntry failed [rv=%x]\n", rv));
return rv;
}
if (!delayed) {
rv = ReadFromCache();
if (NS_FAILED(rv)) {
LOG(("nsWyciwygChannel::ReadFromCache failed [rv=%x]\n", rv));
return rv;
}
}
mIsPending = PR_TRUE;
mListener = aListener;
mListenerContext = aContext;
mListener = listener;
mListenerContext = ctx;
// 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;
}
@ -357,12 +331,8 @@ nsWyciwygChannel::WriteToCacheEntry(const nsACString &aScript)
}
if (!mCacheOutputStream) {
//Get the transport from cache
rv = mCacheEntry->GetTransport(getter_AddRefs(mCacheTransport));
if (NS_FAILED(rv)) return rv;
// Get the outputstream from the transport.
rv = mCacheTransport->OpenOutputStream(0, PRUint32(-1), 0, getter_AddRefs(mCacheOutputStream));
// Get the outputstream from the cache entry.
rv = mCacheEntry->OpenOutputStream(0, getter_AddRefs(mCacheOutputStream));
if (NS_FAILED(rv)) return rv;
}
@ -372,20 +342,19 @@ nsWyciwygChannel::WriteToCacheEntry(const nsACString &aScript)
NS_IMETHODIMP
nsWyciwygChannel::CloseCacheEntry()
nsWyciwygChannel::CloseCacheEntry(nsresult reason)
{
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;
mCacheInputStream = 0;
if (NS_FAILED(reason))
mCacheEntry->Doom();
mCacheEntry = 0;
}
return rv;
return NS_OK;
}
//////////////////////////////////////////////////////////////////////////////
@ -403,26 +372,39 @@ nsWyciwygChannel::OnCacheEntryAvailable(nsICacheEntryDescriptor * aCacheEntry, n
return NS_OK;
// otherwise, we have to handle this event.
if (NS_SUCCEEDED(aStatus)) {
if (NS_SUCCEEDED(aStatus))
mCacheEntry = aCacheEntry;
}
else if (NS_SUCCEEDED(mStatus))
mStatus = aStatus;
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);
else { // advance to the next state...
rv = ReadFromCache();
}
// a failure from Connect means that we have to abort the channel.
if (NS_FAILED(rv)) {
CloseCacheEntry();
AsyncAbort(rv);
CloseCacheEntry(rv);
if (mListener) {
mListener->OnStartRequest(this, mListenerContext);
mListener->OnStopRequest(this, mListenerContext, mStatus);
mListener = 0;
mListenerContext = 0;
}
mIsPending = PR_FALSE;
// Remove ourselves from the load group.
if (mLoadGroup)
mLoadGroup->RemoveRequest(this, nsnull, mStatus);
}
return rv;
return NS_OK;
}
//-----------------------------------------------------------------------------
@ -430,24 +412,21 @@ nsWyciwygChannel::OnCacheEntryAvailable(nsICacheEntryDescriptor * aCacheEntry, n
//-----------------------------------------------------------------------------
NS_IMETHODIMP
nsWyciwygChannel::OnDataAvailable(nsIRequest *aRequest, nsISupports *aCtxt,
nsIInputStream *aInput,
PRUint32 aOffset, PRUint32 aCount)
nsWyciwygChannel::OnDataAvailable(nsIRequest *request, nsISupports *ctx,
nsIInputStream *input,
PRUint32 offset, PRUint32 count)
{
LOG(("nsWyciwygChannel::OnDataAvailable [this=%x request=%x offset=%u count=%u]\n",
this, aRequest, aOffset, aCount));
this, request, offset, count));
// 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;
}
nsresult rv;
if (mListener)
return mListener->OnDataAvailable((nsIRequest *)this, mListenerContext, aInput, aOffset, aCount);
rv = mListener->OnDataAvailable(this, mListenerContext, input, offset, count);
return NS_BASE_STREAM_CLOSED;
if (mProgressSink && NS_SUCCEEDED(rv) && !(mLoadFlags & LOAD_BACKGROUND))
mProgressSink->OnProgress(this, nsnull, offset + count, mContentLength);
return rv; // let the pump cancel on failure
}
//////////////////////////////////////////////////////////////////////////////
@ -455,70 +434,41 @@ nsWyciwygChannel::OnDataAvailable(nsIRequest *aRequest, nsISupports *aCtxt,
//////////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP
nsWyciwygChannel::OnStartRequest(nsIRequest *aRequest, nsISupports *aCtxt)
nsWyciwygChannel::OnStartRequest(nsIRequest *request, nsISupports *ctx)
{
nsresult rv = NS_ERROR_FAILURE;
LOG(("nsWyciwygChannel::OnStartRequest [this=%x request=%x\n",
this, aRequest));
this, request));
// 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;
return mListener->OnStartRequest(this, mListenerContext);
}
NS_IMETHODIMP
nsWyciwygChannel::OnStopRequest(nsIRequest *aRequest, nsISupports *aCtxt, nsresult aStatus)
nsWyciwygChannel::OnStopRequest(nsIRequest *request, nsISupports *ctx, nsresult status)
{
LOG(("nsWyciwygChannel::OnStopRequest [this=%x request=%x status=%d\n",
this, aRequest, (PRUint32)aStatus));
this, request, status));
mIsPending = PR_FALSE;
mStatus = aStatus;
CloseCacheEntry();
if (mListener) {
mListener->OnStopRequest(this, mListenerContext, aStatus);
mListener = 0;
mListenerContext = 0;
}
if (NS_SUCCEEDED(mStatus))
mStatus = status;
mListener->OnStopRequest(this, mListenerContext, mStatus);
mListener = 0;
mListenerContext = 0;
if (mLoadGroup)
mLoadGroup->RemoveRequest(this, nsnull, aStatus);
mLoadGroup->RemoveRequest(this, nsnull, mStatus);
CloseCacheEntry(mStatus);
mPump = 0;
mIsPending = PR_FALSE;
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 )
{
@ -567,77 +517,25 @@ nsWyciwygChannel::OpenCacheEntry(const char * aCacheKey, nsCacheAccessMode aAcce
return rv;
}
nsresult
nsWyciwygChannel::Connect(PRBool aFirstTime)
{
nsresult rv = NS_ERROR_FAILURE;
LOG(("nsWyciwygChannel::Connect [this=%x]\n", this));
// true when called from AsyncOpen
if (aFirstTime) {
PRBool delayed = PR_FALSE;
nsCAutoString spec;
mURI->GetSpec(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;
NS_ENSURE_TRUE(mCacheEntry, NS_ERROR_FAILURE);
nsresult rv;
// Hookup the notification callbacks interface to the new transport...
mCacheTransport->SetNotificationCallbacks(this,
((mLoadFlags & nsIRequest::LOAD_BACKGROUND)
? nsITransport::DONT_REPORT_PROGRESS
: 0));
// Get a transport to the cached data...
rv = mCacheEntry->OpenInputStream(0, getter_AddRefs(mCacheInputStream));
if (NS_FAILED(rv))
return rv;
NS_ENSURE_TRUE(mCacheInputStream, NS_ERROR_UNEXPECTED);
rv = NS_NewInputStreamPump(getter_AddRefs(mPump), mCacheInputStream, -1);
if (NS_FAILED(rv)) return rv;
// Pump the cache data downstream
return mCacheTransport->AsyncRead(this, nsnull,
0, PRUint32(-1), 0,
getter_AddRefs(mCacheReadRequest));
return mPump->AsyncRead(this, nsnull);
}
// 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;
}
// vim: ts=2 sw=2

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

@ -23,76 +23,73 @@
#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 "nsXPIDLString.h"
#include "nsString.h"
#include "nsCOMPtr.h"
#include "prlog.h"
#include "nsIWyciwygChannel.h"
#include "nsILoadGroup.h"
#include "nsIOutputStream.h"
#include "nsIInputStream.h"
#include "nsIInputStreamPump.h"
#include "nsIInterfaceRequestor.h"
#include "nsIProgressEventSink.h"
#include "nsIStreamListener.h"
#include "nsICacheListener.h"
#include "nsITransport.h"
#include "nsICacheEntryDescriptor.h"
#include "nsIOutputStream.h"
#include "nsIProgressEventSink.h"
#include "prlog.h"
#include "nsIURI.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 nsICacheListener
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIREQUEST
NS_DECL_NSICHANNEL
NS_DECL_NSIWYCIWYGCHANNEL
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSICACHELISTENER
NS_DECL_NSIINTERFACEREQUESTOR
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSIPROGRESSEVENTSINK
// nsWyciwygChannel methods:
nsWyciwygChannel();
virtual ~nsWyciwygChannel();
nsresult Init(nsIURI* uri);
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> mURI;
nsCOMPtr<nsIURI> mOriginalURI;
nsCOMPtr<nsISupports> mOwner;
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
nsCOMPtr<nsIProgressEventSink> mProgressSink;
nsCOMPtr<nsILoadGroup> mLoadGroup;
nsCOMPtr<nsIStreamListener> mListener;
nsCOMPtr<nsISupports> mListenerContext;
nsCOMPtr<nsIURI> mURI;
nsCOMPtr<nsIProgressEventSink> mProgressSink;
nsCString mContentType;
nsCString mContentCharset;
PRInt32 mContentLength;
PRUint32 mLoadFlags;
nsresult mStatus;
PRBool mIsPending;
// reuse as much of this channel implementation as we can
nsCOMPtr<nsIInputStreamPump> mPump;
// Cache related stuff
nsCOMPtr<nsITransport> mCacheTransport;
nsCOMPtr<nsIRequest> mCacheReadRequest;
nsCOMPtr<nsICacheEntryDescriptor> mCacheEntry;
nsCOMPtr<nsIOutputStream> mCacheOutputStream;
// flags
PRUint32 mStatus;
PRUint32 mLoadFlags;
PRPackedBool mIsPending;
nsCOMPtr<nsIInputStream> mCacheInputStream;
};
#endif /* nsWyciwygChannel_h___ */

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

@ -729,13 +729,12 @@ nsDocShell::LoadURI(nsIURI * aURI,
}
NS_IMETHODIMP
nsDocShell::LoadStream(nsIInputStream * aStream, nsIURI * aURI,
const char *aContentType, PRInt32 aContentLen,
nsDocShell::LoadStream(nsIInputStream *aStream, nsIURI * aURI,
const nsACString &aContentType,
const nsACString &aContentCharset,
nsIDocShellLoadInfo * aLoadInfo)
{
NS_ENSURE_ARG(aStream);
NS_ENSURE_ARG(aContentType);
NS_ENSURE_ARG(aContentLen);
// if the caller doesn't pass in a URI we need to create a dummy URI. necko
// currently requires a URI in various places during the load. Some consumers
@ -770,9 +769,8 @@ nsDocShell::LoadStream(nsIInputStream * aStream, nsIURI * aURI,
nsCOMPtr<nsIChannel> channel;
NS_ENSURE_SUCCESS(NS_NewInputStreamChannel
(getter_AddRefs(channel), uri, aStream,
nsDependentCString(aContentType),
NS_LITERAL_CSTRING(""),
aContentLen), NS_ERROR_FAILURE);
aContentType, aContentCharset),
NS_ERROR_FAILURE);
nsCOMPtr<nsIURILoader>
uriLoader(do_GetService(NS_URI_LOADER_CONTRACTID));

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

@ -77,23 +77,23 @@ interface nsIDocShell : nsISupports
* here however, the URL dispatched will go through its normal process of
* content loading.
*
* @param aStream - The input stream that provides access to the data
* to be loaded.
* @param aURI - The URI representing the stream, or null.
* @param aContentType - The type (MIME) of data being loaded.
* @param aContentLen - The length (in bytes) of the stream. If you don't
* know the length of the stream this can be -1.
* @param aLoadInfo - This is the extended load info for this load. This
* most often will be null, but if you need to do
* additional setup for this load you can get a
* loadInfo object by calling createLoadInfo. Once
* you have this object you can set the needed
* properties on it and then pass it to loadStream.
* @param aStream - The input stream that provides access to the data
* to be loaded. This must be a blocking, threadsafe
* stream implementation.
* @param aURI - The URI representing the stream, or null.
* @param aContentType - The type (MIME) of data being loaded (empty if unknown).
* @param aContentCharset - The charset of the data being loaded (empty if unknown).
* @param aLoadInfo - This is the extended load info for this load. This
* most often will be null, but if you need to do
* additional setup for this load you can get a
* loadInfo object by calling createLoadInfo. Once
* you have this object you can set the needed
* properties on it and then pass it to loadStream.
*/
[noscript]void loadStream(in nsIInputStream aStream,
in nsIURI aURI,
in string aContentType,
in long aContentLen,
in ACString aContentType,
in ACString aContentCharset,
in nsIDocShellLoadInfo aLoadInfo);
/**

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

@ -57,7 +57,7 @@
#include "nsICodebasePrincipal.h"
#include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsIByteArrayInputStream.h"
#include "nsIStringStream.h"
#include "nsIWindowMediator.h"
#include "nsIDOMWindowInternal.h"
#include "nsIDOMDocument.h"
@ -72,13 +72,13 @@ static NS_DEFINE_CID(kWindowMediatorCID, NS_WINDOWMEDIATOR_CID);
class nsJSThunk : public nsIStreamIO
class nsJSThunk : public nsIInputStream
{
public:
nsJSThunk();
NS_DECL_ISUPPORTS
NS_DECL_NSISTREAMIO
NS_FORWARD_SAFE_NSIINPUTSTREAM(mInnerStream)
nsresult Init(nsIURI* uri);
nsresult EvaluateScript(nsIChannel *aChannel);
@ -88,24 +88,21 @@ protected:
virtual ~nsJSThunk();
nsCOMPtr<nsIURI> mURI;
char* mResult;
PRUint32 mLength;
nsCOMPtr<nsIInputStream> mInnerStream;
};
//
// nsISupports implementation...
//
NS_IMPL_THREADSAFE_ISUPPORTS1(nsJSThunk, nsIStreamIO);
NS_IMPL_THREADSAFE_ISUPPORTS1(nsJSThunk, nsIInputStream);
nsJSThunk::nsJSThunk()
: mResult(nsnull), mLength(0)
{
}
nsJSThunk::~nsJSThunk()
{
(void)Close(NS_BASE_STREAM_CLOSED);
}
nsresult nsJSThunk::Init(nsIURI* uri)
@ -289,9 +286,9 @@ nsresult nsJSThunk::EvaluateScript(nsIChannel *aChannel)
rv = NS_ERROR_DOM_RETVAL_UNDEFINED;
}
else {
// NS_NewStringInputStream calls ToNewCString
// XXXbe this should not decimate! pass back UCS-2 to necko
mResult = ToNewCString(result);
mLength = result.Length();
rv = NS_NewStringInputStream(getter_AddRefs(mInnerStream), result);
}
return rv;
}
@ -325,87 +322,6 @@ nsresult nsJSThunk::BringUpConsole(nsIDOMWindow *aDomWindow)
return rv;
}
//
// nsIStreamIO implementation...
//
NS_IMETHODIMP
nsJSThunk::Open()
{
return NS_OK;
}
NS_IMETHODIMP
nsJSThunk::GetContentType(nsACString &aContentType)
{
//
// At this point the script has already been evaluated...
// The resulting string (if any) is stored in mResult.
//
// If the resultant script evaluation actually does return a value, we
// treat it as html.
//
aContentType = NS_LITERAL_CSTRING("text/html");
return NS_OK;
}
NS_IMETHODIMP
nsJSThunk::GetContentCharset(nsACString &aContentCharset)
{
aContentCharset.Truncate();
return NS_OK;
}
NS_IMETHODIMP
nsJSThunk::GetContentLength(PRInt32 *result)
{
*result = mLength;
return NS_OK;
}
NS_IMETHODIMP
nsJSThunk::Close(nsresult status)
{
if (mResult) {
nsCRT::free(mResult);
mResult = nsnull;
}
mLength = 0;
return NS_OK;
}
NS_IMETHODIMP
nsJSThunk::GetInputStream(nsIInputStream* *aInputStream)
{
nsresult rv;
nsIByteArrayInputStream* str;
rv = NS_NewByteArrayInputStream(&str, mResult, mLength);
if (NS_SUCCEEDED(rv)) {
mResult = nsnull; // XXX Whackiness. The input stream takes ownership
*aInputStream = str;
}
else {
*aInputStream = nsnull;
}
return rv;
}
NS_IMETHODIMP
nsJSThunk::GetOutputStream(nsIOutputStream* *aOutputStream)
{
// should never be called
NS_NOTREACHED("nsJSThunk::GetOutputStream");
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsJSThunk::GetName(nsACString &aName)
{
return mURI->GetSpec(aName);
}
////////////////////////////////////////////////////////////////////////////////
class nsJSChannel : public nsIChannel
@ -454,17 +370,21 @@ nsresult nsJSChannel::Init(nsIURI *aURI)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(mIOThunk);
// Create a stock nsIStreamIOChannel...
// Create a stock input stream channel...
// Remember, until AsyncOpen is called, the script will not be evaluated
// and the underlying Input Stream will not be created...
nsCOMPtr<nsIStreamIOChannel> channel;
nsCOMPtr<nsIChannel> channel;
rv = NS_NewStreamIOChannel(getter_AddRefs(channel), aURI, mIOThunk);
// If the resultant script evaluation actually does return a value, we
// treat it as html.
rv = NS_NewInputStreamChannel(getter_AddRefs(channel), aURI, mIOThunk,
NS_LITERAL_CSTRING("text/html"),
NS_LITERAL_CSTRING(""));
if (NS_FAILED(rv)) return rv;
rv = mIOThunk->Init(aURI);
if (NS_SUCCEEDED(rv)) {
mStreamChannel = do_QueryInterface(channel);
mStreamChannel = channel;
}
return rv;

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

@ -117,8 +117,7 @@ EmbedStream::OpenStream(const char *aBaseURI, const char *aContentType)
rv = NS_NewInputStreamChannel(getter_AddRefs(mChannel), uri,
NS_STATIC_CAST(nsIInputStream *, this),
nsDependentCString(aContentType),
NS_LITERAL_CSTRING(""),
1024); /* len */
NS_LITERAL_CSTRING(""));
if (NS_FAILED(rv))
return rv;

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

@ -35,7 +35,6 @@
#include "nsNetUtil.h"
#include "nsComponentManagerUtils.h"
#include "nsIFileTransportService.h"
#include "nsIStorageStream.h"
#include "nsIHttpChannel.h"
#include "nsIEncodedChannel.h"
@ -85,7 +84,7 @@
#include "nsIDOMHTMLDocument.h"
#include "ftpCore.h"
#include "nsISocketTransportService.h"
#include "nsISocketTransport.h"
#include "nsIStringBundle.h"
#include "nsWebBrowserPersist.h"
@ -900,7 +899,6 @@ NS_IMETHODIMP nsWebBrowserPersist::OnStatus(
case NS_NET_STATUS_CONNECTED_TO:
case NS_NET_STATUS_SENDING_TO:
case NS_NET_STATUS_RECEIVING_FROM:
case NS_NET_STATUS_READ_FROM:
break;
default:

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

@ -51,6 +51,7 @@ MODULE_NAME = datetime
REQUIRES = xpcom \
string \
necko \
mimetype \
$(NULL)
CPPSRCS = \

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

@ -1,60 +1,56 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
/* -*- 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/
* 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.
* 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 the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
* The Initial Developer of the Original Code is Brian Ryner.
* Portions created by Brian Ryner are Copyright (C) 2000 Brian Ryner.
* All Rights Reserved.
*
* Contributor(s):
*
* 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 NPL, 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 NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
* Brian Ryner <bryner@uiuc.edu>
*/
// datetime implementation
// DateTime implementation
#include "nsDateTimeChannel.h"
#include "nsNetUtil.h"
#include "nsIServiceManager.h"
#include "nsILoadGroup.h"
#include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsXPIDLString.h"
#include "nsISocketTransportService.h"
#include "nsITransport.h"
#include "nsIStringStream.h"
#include "nsMimeTypes.h"
#include "nsIStreamConverterService.h"
#include "nsITXTToHTMLConv.h"
#include "nsIProgressEventSink.h"
#include "nsEventQueueUtils.h"
#include "nsNetUtil.h"
#include "nsCRT.h"
static NS_DEFINE_CID(kSocketTransportServiceCID, NS_SOCKETTRANSPORTSERVICE_CID);
static NS_DEFINE_CID(kStreamConverterServiceCID, NS_STREAMCONVERTERSERVICE_CID);
// nsDateTimeChannel methods
nsDateTimeChannel::nsDateTimeChannel() {
mContentLength = -1;
mPort = -1;
nsDateTimeChannel::nsDateTimeChannel()
: mLoadFlags(LOAD_NORMAL)
, mStatus(NS_OK)
, mPort(-1)
{
}
nsDateTimeChannel::~nsDateTimeChannel() {
nsDateTimeChannel::~nsDateTimeChannel()
{
}
NS_IMPL_ISUPPORTS4(nsDateTimeChannel,
@ -64,59 +60,52 @@ NS_IMPL_ISUPPORTS4(nsDateTimeChannel,
nsIRequestObserver)
nsresult
nsDateTimeChannel::Init(nsIURI* uri, nsIProxyInfo* proxyInfo)
nsDateTimeChannel::Init(nsIURI *uri, nsIProxyInfo *proxyInfo)
{
nsresult rv;
NS_ASSERTION(uri, "no uri");
mUrl = uri;
mURI = uri;
mProxyInfo = proxyInfo;
rv = mUrl->GetPort(&mPort);
rv = mURI->GetPort(&mPort);
if (NS_FAILED(rv) || mPort < 1)
mPort = DATETIME_PORT;
rv = mUrl->GetPath(mHost);
rv = mURI->GetPath(mHost);
if (NS_FAILED(rv)) return rv;
if (!*(const char *)mHost) return NS_ERROR_NOT_INITIALIZED;
if (mHost.IsEmpty())
return NS_ERROR_MALFORMED_URI;
mContentType = NS_LITERAL_CSTRING(TEXT_HTML); // expected content-type
return NS_OK;
}
NS_METHOD
nsDateTimeChannel::Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult)
{
nsDateTimeChannel* dc = new nsDateTimeChannel();
if (dc == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(dc);
nsresult rv = dc->QueryInterface(aIID, aResult);
NS_RELEASE(dc);
return rv;
}
////////////////////////////////////////////////////////////////////////////////
// nsIRequest methods:
NS_IMETHODIMP
nsDateTimeChannel::GetName(nsACString &result)
{
return NS_ERROR_NOT_IMPLEMENTED;
return mURI->GetSpec(result);
}
NS_IMETHODIMP
nsDateTimeChannel::IsPending(PRBool *result)
{
NS_NOTREACHED("nsDateTimeChannel::IsPending");
return NS_ERROR_NOT_IMPLEMENTED;
*result = (mPump != nsnull);
return NS_OK;
}
NS_IMETHODIMP
nsDateTimeChannel::GetStatus(nsresult *status)
{
*status = NS_OK;
if (NS_SUCCEEDED(mStatus) && mPump)
mPump->GetStatus(status);
else
*status = mStatus;
return NS_OK;
}
@ -124,22 +113,28 @@ NS_IMETHODIMP
nsDateTimeChannel::Cancel(nsresult status)
{
NS_ASSERTION(NS_FAILED(status), "shouldn't cancel with a success code");
NS_NOTREACHED("nsDateTimeChannel::Cancel");
return NS_ERROR_NOT_IMPLEMENTED;
mStatus = status;
if (mPump)
mPump->Cancel(status);
return NS_ERROR_UNEXPECTED;
}
NS_IMETHODIMP
nsDateTimeChannel::Suspend(void)
nsDateTimeChannel::Suspend()
{
NS_NOTREACHED("nsDateTimeChannel::Suspend");
return NS_ERROR_NOT_IMPLEMENTED;
if (mPump)
mPump->Suspend();
return NS_ERROR_UNEXPECTED;
}
NS_IMETHODIMP
nsDateTimeChannel::Resume(void)
nsDateTimeChannel::Resume()
{
NS_NOTREACHED("nsDateTimeChannel::Resume");
return NS_ERROR_NOT_IMPLEMENTED;
if (mPump)
mPump->Resume();
return NS_ERROR_UNEXPECTED;
}
////////////////////////////////////////////////////////////////////////////////
@ -148,7 +143,7 @@ nsDateTimeChannel::Resume(void)
NS_IMETHODIMP
nsDateTimeChannel::GetOriginalURI(nsIURI* *aURI)
{
*aURI = mOriginalURI ? mOriginalURI : mUrl;
*aURI = mOriginalURI ? mOriginalURI : mURI;
NS_ADDREF(*aURI);
return NS_OK;
}
@ -163,7 +158,7 @@ nsDateTimeChannel::SetOriginalURI(nsIURI* aURI)
NS_IMETHODIMP
nsDateTimeChannel::GetURI(nsIURI* *aURI)
{
*aURI = mUrl;
*aURI = mURI;
NS_IF_ADDREF(*aURI);
return NS_OK;
}
@ -171,58 +166,84 @@ nsDateTimeChannel::GetURI(nsIURI* *aURI)
NS_IMETHODIMP
nsDateTimeChannel::Open(nsIInputStream **_retval)
{
nsresult rv = NS_OK;
rv = NS_CheckPortSafety(mPort, "datetime");
if (NS_FAILED(rv))
return rv;
nsCOMPtr<nsISocketTransportService> sts =
do_GetService("@mozilla.org/network/socket-transport-service;1", &rv);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsITransport> transport;
rv = sts->CreateTransport(mHost,
mPort,
mProxyInfo,
32,
32,
getter_AddRefs(transport));
if (NS_FAILED(rv)) return rv;
transport->SetNotificationCallbacks(mCallbacks,
(mLoadFlags & LOAD_BACKGROUND));
return transport->OpenInputStream(0, PRUint32(-1), 0, _retval);
NS_NOTREACHED("nsDateTimeChannel::Open");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDateTimeChannel::AsyncOpen(nsIStreamListener *aListener, nsISupports *ctxt)
{
nsresult rv = NS_OK;
rv = NS_CheckPortSafety(mPort, "datetime");
if (NS_FAILED(rv))
return rv;
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIEventQueue> eventQ;
rv = NS_GetCurrentEventQ(getter_AddRefs(eventQ));
if (NS_FAILED(rv)) return rv;
//
// create transport
//
nsCOMPtr<nsISocketTransportService> sts =
do_GetService("@mozilla.org/network/socket-transport-service;1", &rv);
do_GetService(kSocketTransportServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsITransport> transport;
rv = sts->CreateTransport(mHost,
mPort,
mProxyInfo,
32,
32,
getter_AddRefs(transport));
rv = sts->CreateTransport(nsnull, 0, mHost, mPort, mProxyInfo,
getter_AddRefs(mTransport));
if (NS_FAILED(rv)) return rv;
transport->SetNotificationCallbacks(mCallbacks,
(mLoadFlags & LOAD_BACKGROUND));
// not fatal if these fail
mTransport->SetSecurityCallbacks(mCallbacks);
mTransport->SetEventSink(this, eventQ);
//
// create TXT to HTML stream converter
//
nsCOMPtr<nsIStreamConverterService> scs =
do_GetService(kStreamConverterServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
NS_NAMED_LITERAL_STRING(fromStr, "text/plain");
NS_NAMED_LITERAL_STRING(toStr, "text/html");
nsCOMPtr<nsIStreamListener> convListener;
rv = scs->AsyncConvertData(fromStr.get(), toStr.get(), this, nsnull,
getter_AddRefs(convListener));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsITXTToHTMLConv> conv = do_QueryInterface(convListener);
if (conv) {
nsCAutoString userHost;
rv = mURI->GetPath(userHost);
nsAutoString title;
title = NS_LITERAL_STRING("DateTime according to ")
+ NS_ConvertUTF8toUCS2(mHost);
conv->SetTitle(title.get());
conv->PreFormatHTML(PR_TRUE);
}
//
// open input stream, and create input stream pump...
//
nsCOMPtr<nsIInputStream> sockIn;
rv = mTransport->OpenInputStream(0, 0, 0, getter_AddRefs(sockIn));
if (NS_FAILED(rv)) return rv;
rv = NS_NewInputStreamPump(getter_AddRefs(mPump), sockIn);
if (NS_FAILED(rv)) return rv;
rv = mPump->AsyncRead(convListener, nsnull);
if (NS_FAILED(rv)) return rv;
if (mLoadGroup)
mLoadGroup->AddRequest(this, nsnull);
mListener = aListener;
nsCOMPtr<nsIRequest> request;
return transport->AsyncRead(this, ctxt, 0, PRUint32(-1), 0, getter_AddRefs(request));
mListenerContext = ctxt;
return NS_OK;
}
NS_IMETHODIMP
@ -239,49 +260,46 @@ nsDateTimeChannel::SetLoadFlags(PRUint32 aLoadFlags)
return NS_OK;
}
#define DATETIME_TYPE "text/plain"
NS_IMETHODIMP
nsDateTimeChannel::GetContentType(nsACString &aContentType)
{
aContentType = NS_LITERAL_CSTRING(DATETIME_TYPE);
aContentType = mContentType;
return NS_OK;
}
NS_IMETHODIMP
nsDateTimeChannel::SetContentType(const nsACString &aContentType)
{
// It doesn't make sense to set the content-type on this type
// of channel...
return NS_ERROR_FAILURE;
mContentType = aContentType;
return NS_OK;
}
NS_IMETHODIMP
nsDateTimeChannel::GetContentCharset(nsACString &aContentCharset)
{
aContentCharset.Truncate();
aContentCharset = mContentCharset;
return NS_OK;
}
NS_IMETHODIMP
nsDateTimeChannel::SetContentCharset(const nsACString &aContentCharset)
{
NS_NOTREACHED("nsDateTimeChannel::SetContentCharset");
return NS_ERROR_NOT_IMPLEMENTED;
mContentCharset = aContentCharset;
return NS_OK;
}
NS_IMETHODIMP
nsDateTimeChannel::GetContentLength(PRInt32 *aContentLength)
{
*aContentLength = mContentLength;
*aContentLength = -1;
return NS_OK;
}
NS_IMETHODIMP
nsDateTimeChannel::SetContentLength(PRInt32 aContentLength)
{
NS_NOTREACHED("nsDateTimeChannel::SetContentLength");
return NS_ERROR_NOT_IMPLEMENTED;
// silently ignore this...
return NS_OK;
}
NS_IMETHODIMP
@ -295,13 +313,7 @@ nsDateTimeChannel::GetLoadGroup(nsILoadGroup* *aLoadGroup)
NS_IMETHODIMP
nsDateTimeChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
{
if (mLoadGroup) // if we already had a load group remove ourselves...
(void)mLoadGroup->RemoveRequest(this, nsnull, NS_OK);
mLoadGroup = aLoadGroup;
if (mLoadGroup) {
return mLoadGroup->AddRequest(this, nsnull);
}
return NS_OK;
}
@ -332,40 +344,73 @@ NS_IMETHODIMP
nsDateTimeChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
{
mCallbacks = aNotificationCallbacks;
mProgressSink = do_GetInterface(mCallbacks);
return NS_OK;
}
NS_IMETHODIMP
nsDateTimeChannel::GetSecurityInfo(nsISupports **sec)
nsDateTimeChannel::GetSecurityInfo(nsISupports **aSecurityInfo)
{
NS_ENSURE_ARG_POINTER(sec);
*sec = nsnull;
if (mTransport)
return mTransport->GetSecurityInfo(aSecurityInfo);
*aSecurityInfo = nsnull;
return NS_OK;
}
//-----------------------------------------------------------------------------
// nsIRequestObserver methods
//-----------------------------------------------------------------------------
NS_IMETHODIMP
nsDateTimeChannel::OnStartRequest(nsIRequest *request, nsISupports *aContext) {
return mListener->OnStartRequest(this, aContext);
nsDateTimeChannel::OnStartRequest(nsIRequest *req, nsISupports *ctx)
{
return mListener->OnStartRequest(this, mListenerContext);
}
NS_IMETHODIMP
nsDateTimeChannel::OnStopRequest(nsIRequest *req, nsISupports *ctx, nsresult status)
{
if (NS_SUCCEEDED(mStatus))
mStatus = status;
mListener->OnStopRequest(this, mListenerContext, mStatus);
mListener = 0;
mListenerContext = 0;
if (mLoadGroup)
mLoadGroup->RemoveRequest(this, nsnull, mStatus);
mPump = 0;
mTransport = 0;
return NS_OK;
}
NS_IMETHODIMP
nsDateTimeChannel::OnStopRequest(nsIRequest *request, nsISupports* aContext,
nsresult aStatus) {
if (mLoadGroup) {
nsresult rv = mLoadGroup->RemoveRequest(this, nsnull, aStatus);
if (NS_FAILED(rv)) return rv;
nsDateTimeChannel::OnDataAvailable(nsIRequest *req, nsISupports *ctx,
nsIInputStream *stream, PRUint32 offset,
PRUint32 count)
{
return mListener->OnDataAvailable(this, mListenerContext, stream, offset, count);
}
//-----------------------------------------------------------------------------
// nsITransportEventSink methods
//-----------------------------------------------------------------------------
NS_IMETHODIMP
nsDateTimeChannel::OnTransportStatus(nsITransport *trans, nsresult status,
PRUint32 progress, PRUint32 progressMax)
{
// suppress status notification if channel is no longer pending!
if (mProgressSink && mPump && !(mLoadFlags & LOAD_BACKGROUND)) {
NS_ConvertUTF8toUCS2 host(mHost);
mProgressSink->OnStatus(this, nsnull, status, host.get());
if (status == nsISocketTransport::STATUS_RECEIVING_FROM ||
status == nsISocketTransport::STATUS_SENDING_TO) {
mProgressSink->OnProgress(this, nsnull, progress, progressMax);
}
}
return mListener->OnStopRequest(this, aContext, aStatus);
}
// nsIStreamListener method
NS_IMETHODIMP
nsDateTimeChannel::OnDataAvailable(nsIRequest *request, nsISupports* aContext,
nsIInputStream *aInputStream, PRUint32 aSourceOffset,
PRUint32 aLength) {
mContentLength = aLength;
return mListener->OnDataAvailable(this, aContext, aInputStream, aSourceOffset, aLength);
return NS_OK;
}

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

@ -1,95 +1,85 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
/* -*- 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/
* 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.
* 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 the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
* The Initial Developer of the Original Code is Brian Ryner.
* Portions created by Brian Ryner are Copyright (C) 2000 Brian Ryner.
* All Rights Reserved.
*
* Contributor(s):
*
* 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 NPL, 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 NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
* Darin Fisher <darin@netscape.com>
*/
// A datetime channel retrieves date time information from
// RFC 867 compliant datetime servers. The date/time returned
// to the caller is of MIME type "text/plain".
#ifndef nsDateTimeChannel_h___
#define nsDateTimeChannel_h___
#ifndef nsDateTimeChannel_h__
#define nsDateTimeChannel_h__
#include "nsDateTimeHandler.h"
#include "nsString.h"
#include "nsCOMPtr.h"
#include "nsILoadGroup.h"
#include "nsIInputStream.h"
#include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsCOMPtr.h"
#include "nsXPIDLString.h"
#include "nsIProgressEventSink.h"
#include "nsIInputStreamPump.h"
#include "nsIChannel.h"
#include "nsIURI.h"
#include "nsDateTimeHandler.h"
#include "nsIStreamListener.h"
#include "nsISocketTransport.h"
#include "nsIProxyInfo.h"
class nsDateTimeChannel
: public nsIChannel,
public nsIStreamListener {
//-----------------------------------------------------------------------------
class nsDateTimeChannel : public nsIChannel
, public nsIStreamListener
, public nsITransportEventSink
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIREQUEST
NS_DECL_NSICHANNEL
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSITRANSPORTEVENTSINK
// nsDateTimeChannel methods:
nsDateTimeChannel();
virtual ~nsDateTimeChannel();
// Define a Create method to be used with a factory:
static NS_METHOD
Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult);
nsresult Init(nsIURI* uri, nsIProxyInfo* proxyInfo);
nsresult Init(nsIURI *uri, nsIProxyInfo *proxyInfo);
protected:
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
nsCOMPtr<nsIURI> mURI;
nsCOMPtr<nsIURI> mOriginalURI;
nsCOMPtr<nsIURI> mUrl;
nsCOMPtr<nsIStreamListener> mListener;
PRUint32 mLoadFlags;
nsCOMPtr<nsILoadGroup> mLoadGroup;
nsCString mContentType;
PRInt32 mContentLength;
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
nsCOMPtr<nsIProgressEventSink> mProgressSink;
nsCOMPtr<nsISupports> mOwner;
nsCOMPtr<nsILoadGroup> mLoadGroup;
nsCOMPtr<nsIStreamListener> mListener;
nsCOMPtr<nsISupports> mListenerContext;
nsCString mContentType;
nsCString mContentCharset;
PRUint32 mLoadFlags;
nsresult mStatus;
nsCOMPtr<nsIInputStreamPump> mPump;
nsCOMPtr<nsISocketTransport> mTransport;
nsCOMPtr<nsIProxyInfo> mProxyInfo;
nsCString mHost;
PRInt32 mPort;
nsXPIDLCString mHost;
};
#endif /* nsDateTimeChannel_h___ */
#endif // !nsDateTimeChannel_h__

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

@ -128,17 +128,18 @@ nsDateTimeHandler::NewProxiedChannel(nsIURI* url, nsIProxyInfo* proxyInfo,
{
nsresult rv;
nsDateTimeChannel* channel;
rv = nsDateTimeChannel::Create(nsnull, NS_GET_IID(nsIChannel), (void**)&channel);
if (NS_FAILED(rv)) return rv;
nsDateTimeChannel *chan = new nsDateTimeChannel();
if (!chan)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(chan);
rv = channel->Init(url, proxyInfo);
rv = chan->Init(url, proxyInfo);
if (NS_FAILED(rv)) {
NS_RELEASE(channel);
NS_RELEASE(chan);
return rv;
}
*result = channel;
*result = chan;
return NS_OK;
}

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

@ -17,7 +17,8 @@
* All Rights Reserved.
*
* Contributor(s):
* Brian Ryner <bryner@uiuc.edu>
* Brian Ryner <bryner@uiuc.edu>
* Darin Fisher <darin@netscape.com>
*/
// finger implementation
@ -34,6 +35,7 @@
#include "nsIStreamConverterService.h"
#include "nsITXTToHTMLConv.h"
#include "nsIProgressEventSink.h"
#include "nsEventQueueUtils.h"
#include "nsNetUtil.h"
#include "nsCRT.h"
@ -45,31 +47,31 @@ static NS_DEFINE_CID(kStreamConverterServiceCID, NS_STREAMCONVERTERSERVICE_CID);
// nsFingerChannel methods
nsFingerChannel::nsFingerChannel()
: mContentLength(-1),
mActAsObserver(PR_TRUE),
mPort(-1),
mStatus(NS_OK)
: mLoadFlags(LOAD_NORMAL)
, mStatus(NS_OK)
, mPort(-1)
{
}
nsFingerChannel::~nsFingerChannel() {
nsFingerChannel::~nsFingerChannel()
{
}
NS_IMPL_THREADSAFE_ISUPPORTS4(nsFingerChannel,
nsIChannel,
nsIRequest,
nsIStreamListener,
nsIRequestObserver)
NS_IMPL_ISUPPORTS4(nsFingerChannel,
nsIChannel,
nsIRequest,
nsIStreamListener,
nsIRequestObserver)
nsresult
nsFingerChannel::Init(nsIURI* uri, nsIProxyInfo* proxyInfo)
nsFingerChannel::Init(nsIURI *uri, nsIProxyInfo *proxyInfo)
{
nsresult rv;
nsCAutoString autoBuffer;
NS_ASSERTION(uri, "no uri");
mUrl = uri;
mURI = uri;
mProxyInfo = proxyInfo;
// For security reasons, we do not allow the user to specify a
@ -77,7 +79,7 @@ nsFingerChannel::Init(nsIURI* uri, nsIProxyInfo* proxyInfo)
mPort = FINGER_PORT;
rv = mUrl->GetPath(autoBuffer); // autoBuffer = user@host
rv = mURI->GetPath(autoBuffer); // autoBuffer = user@host
if (NS_FAILED(rv)) return rv;
// Now parse out the user and host
@ -86,49 +88,43 @@ nsFingerChannel::Init(nsIURI* uri, nsIProxyInfo* proxyInfo)
// Catch the case of just the host being given
if (!pos) {
mUser.Truncate();
mHost.Assign(buf);
} else {
mUser.Assign(buf,pos-buf);
mUser.Assign(buf, pos-buf);
mHost.Assign(pos+1); // ignore '@'
}
if (mHost.IsEmpty()) return NS_ERROR_NOT_INITIALIZED;
if (mHost.IsEmpty())
return NS_ERROR_MALFORMED_URI;
mContentType = NS_LITERAL_CSTRING(TEXT_HTML); // expected content-type
return NS_OK;
}
NS_METHOD
nsFingerChannel::Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult)
{
nsFingerChannel* fc = new nsFingerChannel();
if (fc == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(fc);
nsresult rv = fc->QueryInterface(aIID, aResult);
NS_RELEASE(fc);
return rv;
}
////////////////////////////////////////////////////////////////////////////////
// nsIRequest methods:
NS_IMETHODIMP
nsFingerChannel::GetName(nsACString &result)
{
return NS_ERROR_NOT_IMPLEMENTED;
return mURI->GetSpec(result);
}
NS_IMETHODIMP
nsFingerChannel::IsPending(PRBool *result)
{
NS_NOTREACHED("nsFingerChannel::IsPending");
return NS_ERROR_NOT_IMPLEMENTED;
*result = (mPump != nsnull);
return NS_OK;
}
NS_IMETHODIMP
nsFingerChannel::GetStatus(nsresult *status)
{
*status = mStatus;
if (NS_SUCCEEDED(mStatus) && mPump)
mPump->GetStatus(status);
else
*status = mStatus;
return NS_OK;
}
@ -136,27 +132,28 @@ NS_IMETHODIMP
nsFingerChannel::Cancel(nsresult status)
{
NS_ASSERTION(NS_FAILED(status), "shouldn't cancel with a success code");
nsresult rv = NS_ERROR_FAILURE;
mStatus = status;
if (mTransportRequest) {
rv = mTransportRequest->Cancel(status);
}
return rv;
if (mPump)
mPump->Cancel(status);
return NS_ERROR_UNEXPECTED;
}
NS_IMETHODIMP
nsFingerChannel::Suspend(void)
nsFingerChannel::Suspend()
{
NS_NOTREACHED("nsFingerChannel::Suspend");
return NS_ERROR_NOT_IMPLEMENTED;
if (mPump)
mPump->Suspend();
return NS_ERROR_UNEXPECTED;
}
NS_IMETHODIMP
nsFingerChannel::Resume(void)
nsFingerChannel::Resume()
{
NS_NOTREACHED("nsFingerChannel::Resume");
return NS_ERROR_NOT_IMPLEMENTED;
if (mPump)
mPump->Resume();
return NS_ERROR_UNEXPECTED;
}
////////////////////////////////////////////////////////////////////////////////
@ -165,7 +162,7 @@ nsFingerChannel::Resume(void)
NS_IMETHODIMP
nsFingerChannel::GetOriginalURI(nsIURI* *aURI)
{
*aURI = mOriginalURI ? mOriginalURI : mUrl;
*aURI = mOriginalURI ? mOriginalURI : mURI;
NS_ADDREF(*aURI);
return NS_OK;
}
@ -180,7 +177,7 @@ nsFingerChannel::SetOriginalURI(nsIURI* aURI)
NS_IMETHODIMP
nsFingerChannel::GetURI(nsIURI* *aURI)
{
*aURI = mUrl;
*aURI = mURI;
NS_IF_ADDREF(*aURI);
return NS_OK;
}
@ -188,24 +185,8 @@ nsFingerChannel::GetURI(nsIURI* *aURI)
NS_IMETHODIMP
nsFingerChannel::Open(nsIInputStream **_retval)
{
nsresult rv = NS_OK;
rv = NS_CheckPortSafety(mPort, "finger");
if (NS_FAILED(rv))
return rv;
nsCOMPtr<nsISocketTransportService> socketService =
do_GetService(kSocketTransportServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
rv = socketService->CreateTransport(mHost.get(), mPort, mProxyInfo, BUFFER_SEG_SIZE,
BUFFER_MAX_SIZE, getter_AddRefs(mTransport));
if (NS_FAILED(rv)) return rv;
mTransport->SetNotificationCallbacks(mCallbacks,
(mLoadFlags & LOAD_BACKGROUND));
return mTransport->OpenInputStream(0, PRUint32(-1), 0, _retval);
NS_NOTREACHED("nsFingerChannel::Open");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
@ -214,24 +195,77 @@ nsFingerChannel::AsyncOpen(nsIStreamListener *aListener, nsISupports *ctxt)
nsresult rv = NS_OK;
rv = NS_CheckPortSafety(mPort, "finger");
if (NS_FAILED(rv))
return rv;
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsISocketTransportService> socketService =
nsCOMPtr<nsIEventQueue> eventQ;
rv = NS_GetCurrentEventQ(getter_AddRefs(eventQ));
if (NS_FAILED(rv)) return rv;
//
// create transport
//
nsCOMPtr<nsISocketTransportService> sts =
do_GetService(kSocketTransportServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
rv = socketService->CreateTransport(mHost.get(), mPort, mProxyInfo, BUFFER_SEG_SIZE,
BUFFER_MAX_SIZE, getter_AddRefs(mTransport));
rv = sts->CreateTransport(nsnull, 0, mHost, mPort, mProxyInfo,
getter_AddRefs(mTransport));
if (NS_FAILED(rv)) return rv;
mTransport->SetNotificationCallbacks(mCallbacks,
(mLoadFlags & LOAD_BACKGROUND));
// not fatal if these fail
mTransport->SetSecurityCallbacks(mCallbacks);
mTransport->SetEventSink(this, eventQ);
rv = WriteRequest(mTransport);
if (NS_FAILED(rv)) return rv;
//
// create TXT to HTML stream converter
//
nsCOMPtr<nsIStreamConverterService> scs =
do_GetService(kStreamConverterServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
NS_NAMED_LITERAL_STRING(fromStr, "text/plain");
NS_NAMED_LITERAL_STRING(toStr, "text/html");
nsCOMPtr<nsIStreamListener> convListener;
rv = scs->AsyncConvertData(fromStr.get(), toStr.get(), this, nsnull,
getter_AddRefs(convListener));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsITXTToHTMLConv> conv = do_QueryInterface(convListener);
if (conv) {
nsCAutoString userHost;
rv = mURI->GetPath(userHost);
nsAutoString title;
title = NS_LITERAL_STRING("Finger information for ")
+ NS_ConvertUTF8toUCS2(userHost);
conv->SetTitle(title.get());
conv->PreFormatHTML(PR_TRUE);
}
//
// open input stream, and create input stream pump...
//
nsCOMPtr<nsIInputStream> sockIn;
rv = mTransport->OpenInputStream(0, 0, 0, getter_AddRefs(sockIn));
if (NS_FAILED(rv)) return rv;
rv = NS_NewInputStreamPump(getter_AddRefs(mPump), sockIn);
if (NS_FAILED(rv)) return rv;
rv = mPump->AsyncRead(convListener, nsnull);
if (NS_FAILED(rv)) return rv;
if (mLoadGroup)
mLoadGroup->AddRequest(this, nsnull);
mListener = aListener;
mResponseContext = ctxt;
return SendRequest(mTransport);
mListenerContext = ctxt;
return NS_OK;
}
NS_IMETHODIMP
@ -248,49 +282,46 @@ nsFingerChannel::SetLoadFlags(PRUint32 aLoadFlags)
return NS_OK;
}
#define FINGER_TYPE TEXT_HTML
NS_IMETHODIMP
nsFingerChannel::GetContentType(nsACString &aContentType)
{
aContentType = NS_LITERAL_CSTRING(FINGER_TYPE);
aContentType = mContentType;
return NS_OK;
}
NS_IMETHODIMP
nsFingerChannel::SetContentType(const nsACString &aContentType)
{
//It doesn't make sense to set the content-type on this type
// of channel...
return NS_ERROR_FAILURE;
mContentType = aContentType;
return NS_OK;
}
NS_IMETHODIMP
nsFingerChannel::GetContentCharset(nsACString &aContentCharset)
{
aContentCharset.Truncate();
aContentCharset = mContentCharset;
return NS_OK;
}
NS_IMETHODIMP
nsFingerChannel::SetContentCharset(const nsACString &aContentCharset)
{
NS_NOTREACHED("nsFingerChannel::SetContentCharset");
return NS_ERROR_NOT_IMPLEMENTED;
mContentCharset = aContentCharset;
return NS_OK;
}
NS_IMETHODIMP
nsFingerChannel::GetContentLength(PRInt32 *aContentLength)
{
*aContentLength = mContentLength;
*aContentLength = -1;
return NS_OK;
}
NS_IMETHODIMP
nsFingerChannel::SetContentLength(PRInt32 aContentLength)
{
NS_NOTREACHED("nsFingerChannel::SetContentLength");
return NS_ERROR_NOT_IMPLEMENTED;
// silently ignore this...
return NS_OK;
}
NS_IMETHODIMP
@ -335,117 +366,96 @@ NS_IMETHODIMP
nsFingerChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
{
mCallbacks = aNotificationCallbacks;
mProgressSink = do_GetInterface(mCallbacks);
return NS_OK;
}
NS_IMETHODIMP
nsFingerChannel::GetSecurityInfo(nsISupports * *aSecurityInfo)
nsFingerChannel::GetSecurityInfo(nsISupports **aSecurityInfo)
{
if (mTransport)
return mTransport->GetSecurityInfo(aSecurityInfo);
*aSecurityInfo = nsnull;
return NS_OK;
}
//-----------------------------------------------------------------------------
// nsIRequestObserver methods
NS_IMETHODIMP
nsFingerChannel::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext) {
if (!mActAsObserver) {
// acting as a listener
return mListener->OnStartRequest(this, mResponseContext);
} else {
// we don't want to pass our AsyncWrite's OnStart through
// we just ignore this
return NS_OK;
}
}
//-----------------------------------------------------------------------------
NS_IMETHODIMP
nsFingerChannel::OnStopRequest(nsIRequest *aRequest, nsISupports* aContext,
nsresult aStatus)
nsFingerChannel::OnStartRequest(nsIRequest *req, nsISupports *ctx)
{
nsresult rv = NS_OK;
if (NS_FAILED(aStatus) || !mActAsObserver) {
if (mLoadGroup) {
rv = mLoadGroup->RemoveRequest(this, nsnull, aStatus);
if (NS_FAILED(rv)) return rv;
}
rv = mListener->OnStopRequest(this, mResponseContext, aStatus);
mTransport = 0;
return rv;
} else {
// at this point we know the request has been sent.
// we're no longer acting as an observer.
mActAsObserver = PR_FALSE;
nsCOMPtr<nsIStreamListener> converterListener;
nsCOMPtr<nsIStreamConverterService> StreamConvService =
do_GetService(kStreamConverterServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
nsAutoString fromStr(NS_LITERAL_STRING("text/plain"));
nsAutoString toStr(NS_LITERAL_STRING("text/html"));
rv = StreamConvService->AsyncConvertData(fromStr.get(),
toStr.get(), this, mResponseContext,
getter_AddRefs(converterListener));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsITXTToHTMLConv> converter(do_QueryInterface(converterListener));
if (converter) {
nsAutoString title(NS_LITERAL_STRING("Finger information for "));
nsCAutoString userHost;
rv = mUrl->GetPath(userHost);
title.Append(NS_ConvertUTF8toUCS2(userHost));
converter->SetTitle(title.get());
converter->PreFormatHTML(PR_TRUE);
}
return mTransport->AsyncRead(converterListener, mResponseContext, 0, PRUint32(-1), 0,
getter_AddRefs(mTransportRequest));
}
return mListener->OnStartRequest(this, mListenerContext);
}
// nsIStreamListener method
NS_IMETHODIMP
nsFingerChannel::OnDataAvailable(nsIRequest *aRequest, nsISupports* aContext,
nsIInputStream *aInputStream, PRUint32 aSourceOffset,
PRUint32 aLength) {
mContentLength = aLength;
return mListener->OnDataAvailable(this, mResponseContext, aInputStream, aSourceOffset, aLength);
nsFingerChannel::OnStopRequest(nsIRequest *req, nsISupports *ctx, nsresult status)
{
if (NS_SUCCEEDED(mStatus))
mStatus = status;
mListener->OnStopRequest(this, mListenerContext, mStatus);
mListener = 0;
mListenerContext = 0;
if (mLoadGroup)
mLoadGroup->RemoveRequest(this, nsnull, mStatus);
mPump = 0;
mTransport = 0;
return NS_OK;
}
NS_IMETHODIMP
nsFingerChannel::OnDataAvailable(nsIRequest *req, nsISupports *ctx,
nsIInputStream *stream, PRUint32 offset,
PRUint32 count)
{
return mListener->OnDataAvailable(this, mListenerContext, stream, offset, count);
}
//-----------------------------------------------------------------------------
// nsITransportEventSink methods
//-----------------------------------------------------------------------------
NS_IMETHODIMP
nsFingerChannel::OnTransportStatus(nsITransport *trans, nsresult status,
PRUint32 progress, PRUint32 progressMax)
{
// suppress status notification if channel is no longer pending!
if (mProgressSink && mPump && !(mLoadFlags & LOAD_BACKGROUND)) {
NS_ConvertUTF8toUCS2 host(mHost);
mProgressSink->OnStatus(this, nsnull, status, host.get());
if (status == nsISocketTransport::STATUS_RECEIVING_FROM ||
status == nsISocketTransport::STATUS_SENDING_TO) {
mProgressSink->OnProgress(this, nsnull, progress, progressMax);
}
}
return NS_OK;
}
//-----------------------------------------------------------------------------
nsresult
nsFingerChannel::SendRequest(nsITransport* aTransport) {
// The text to send should already be in mUser
nsFingerChannel::WriteRequest(nsITransport *trans)
{
// The text to send should already be in mUser
nsresult rv;
nsresult rv = NS_OK;
nsCOMPtr<nsISupports> result;
nsCOMPtr<nsIInputStream> charstream;
nsCString requestBuffer(mUser);
nsCAutoString requestBuf;
requestBuf = mUser + NS_LITERAL_CSTRING("\r\n");
if (mLoadGroup) {
mLoadGroup->AddRequest(this, nsnull);
}
nsCOMPtr<nsIOutputStream> stream;
rv = trans->OpenOutputStream(0, requestBuf.Length(), 1, getter_AddRefs(stream));
if (NS_FAILED(rv)) return rv;
requestBuffer.Append(CRLF);
PRUint32 n;
rv = stream->Write(requestBuf.get(), requestBuf.Length(), &n);
if (NS_FAILED(rv)) return rv;
mRequest.Assign(requestBuffer);
rv = NS_NewCharInputStream(getter_AddRefs(result), mRequest);
if (NS_FAILED(rv)) return rv;
charstream = do_QueryInterface(result, &rv);
if (NS_FAILED(rv)) return rv;
rv = NS_AsyncWriteFromStream(getter_AddRefs(mTransportRequest),
aTransport, charstream,
0, requestBuffer.Length(), 0,
this, nsnull);
return rv;
NS_ENSURE_TRUE(n == requestBuf.Length(), NS_ERROR_UNEXPECTED);
return NS_OK;
}

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

@ -17,75 +17,73 @@
* All Rights Reserved.
*
* Contributor(s):
* Brian Ryner <bryner@uiuc.edu>
* Brian Ryner <bryner@uiuc.edu>
* Darin Fisher <darin@netscape.com>
*/
#ifndef nsFingerChannel_h___
#define nsFingerChannel_h___
#ifndef nsFingerChannel_h__
#define nsFingerChannel_h__
#include "nsFingerHandler.h"
#include "nsString.h"
#include "nsCOMPtr.h"
#include "nsILoadGroup.h"
#include "nsIInputStream.h"
#include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsCOMPtr.h"
#include "nsXPIDLString.h"
#include "nsIProgressEventSink.h"
#include "nsIInputStreamPump.h"
#include "nsIChannel.h"
#include "nsIURI.h"
#include "nsFingerHandler.h"
#include "nsIStreamListener.h"
#include "nsITransport.h"
#include "nsISocketTransport.h"
#include "nsIProxyInfo.h"
class nsFingerChannel
: public nsIChannel,
public nsIStreamListener {
//-----------------------------------------------------------------------------
class nsFingerChannel : public nsIChannel
, public nsIStreamListener
, public nsITransportEventSink
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIREQUEST
NS_DECL_NSICHANNEL
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSITRANSPORTEVENTSINK
// nsFingerChannel methods:
nsFingerChannel();
virtual ~nsFingerChannel();
// Define a Create method to be used with a factory:
static NS_METHOD
Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult);
nsresult Init(nsIURI* uri, nsIProxyInfo* proxyInfo);
nsresult Init(nsIURI *uri, nsIProxyInfo *proxyInfo);
protected:
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
nsresult WriteRequest(nsITransport *transport);
nsCOMPtr<nsIURI> mURI;
nsCOMPtr<nsIURI> mOriginalURI;
nsCOMPtr<nsIURI> mUrl;
nsCOMPtr<nsIStreamListener> mListener;
PRUint32 mLoadFlags;
nsCOMPtr<nsILoadGroup> mLoadGroup;
nsCString mContentType;
PRInt32 mContentLength;
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
nsCOMPtr<nsIProgressEventSink> mProgressSink;
nsCOMPtr<nsISupports> mOwner;
PRUint32 mBufferSegmentSize;
PRUint32 mBufferMaxSize;
PRBool mActAsObserver;
nsCOMPtr<nsILoadGroup> mLoadGroup;
nsCOMPtr<nsIStreamListener> mListener;
nsCOMPtr<nsISupports> mListenerContext;
nsCString mContentType;
nsCString mContentCharset;
PRUint32 mLoadFlags;
nsresult mStatus;
nsCOMPtr<nsIInputStreamPump> mPump;
nsCOMPtr<nsISocketTransport> mTransport;
nsCOMPtr<nsIProxyInfo> mProxyInfo;
PRInt32 mPort;
nsCString mHost;
nsCString mUser;
nsXPIDLCString mRequest;
nsCOMPtr<nsISupports> mResponseContext;
nsCOMPtr<nsITransport> mTransport;
nsCOMPtr<nsIRequest> mTransportRequest;
nsCOMPtr<nsIProxyInfo> mProxyInfo;
nsresult mStatus;
protected:
nsresult SendRequest(nsITransport* aTransport);
};
#endif /* nsFingerChannel_h___ */
#endif // !nsFingerChannel_h__

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

@ -113,17 +113,18 @@ nsFingerHandler::NewProxiedChannel(nsIURI* url, nsIProxyInfo* proxyInfo,
{
nsresult rv;
nsFingerChannel* channel;
rv = nsFingerChannel::Create(nsnull, NS_GET_IID(nsIChannel), (void**)&channel);
if (NS_FAILED(rv)) return rv;
nsFingerChannel *chan = new nsFingerChannel();
if (!chan)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(chan);
rv = channel->Init(url, proxyInfo);
rv = chan->Init(url, proxyInfo);
if (NS_FAILED(rv)) {
NS_RELEASE(channel);
NS_RELEASE(chan);
return rv;
}
*result = channel;
*result = chan;
return NS_OK;
}

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

@ -93,26 +93,51 @@ function bc_connect(host, port, bind, tcp_flag, observer)
var uri = ios.newURI(spec,null,null);
var info = pps.examineForProxy(uri);
this._transport = this._sockService.createTransport (host, port, info,
0, 0);
if (!this._transport)
throw ("Error creating transport.");
if (jsenv.HAS_STREAM_PROVIDER)
{
this._transport = this._sockService.createTransport (host, port, info,
0, 0);
if (!this._transport)
throw ("Error creating transport.");
if (jsenv.HAS_NSPR_EVENTQ)
{ /* we've got an event queue, so start up an async write */
this._streamProvider = new StreamProvider (observer);
this._write_req =
this._transport.asyncWrite (this._streamProvider, this,
0, -1, 0);
if (jsenv.HAS_NSPR_EVENTQ)
{ /* we've got an event queue, so start up an async write */
this._streamProvider = new StreamProvider (observer);
this._write_req =
this._transport.asyncWrite (this._streamProvider, this,
0, -1, 0);
}
else
{ /* no nspr event queues in this environment, we can't use async calls,
* so set up the streams. */
this._outputStream = this._transport.openOutputStream(0, -1, 0);
if (!this._outputStream)
throw "Error getting output stream.";
this._inputStream =
toScriptableInputStream(this._transport.openInputStream (0, -1, 0));
if (!this._inputStream)
throw "Error getting input stream.";
}
}
else
{ /* no nspr event queues in this environment, we can't use async calls,
* so set up the streams. */
this._outputStream = this._transport.openOutputStream(0, -1, 0);
{
/* use new necko interfaces */
this._transport = this._sockService.createTransport(null, 0, host, port, info);
if (!this._transport)
throw ("Error creating transport.");
/* if we don't have an event queue, then all i/o must be blocking */
var openFlags;
if (jsenv.HAS_NSPR_EVENTQ)
openFlags = 0;
else
openFlags = Components.interfaces.nsITransport.OPEN_BLOCKING;
/* no limit on the output stream buffer */
this._outputStream = this._transport.openOutputStream(openFlags, 4096, -1);
if (!this._outputStream)
throw "Error getting output stream.";
this._inputStream =
toScriptableInputStream(this._transport.openInputStream (0, -1, 0));
this._inputStream = this._transport.openInputStream(openFlags, 0, 0);
if (!this._inputStream)
throw "Error getting input stream.";
}
@ -129,6 +154,8 @@ function bc_disconnect()
{
if ("_inputStream" in this && this._inputStream)
this._inputStream.close();
if ("_outputStream" in this && this._outputStream)
this._outputStream.close();
/*
this._streamProvider.close();
if (this._streamProvider.isBlocked)
@ -142,7 +169,7 @@ function bc_senddata(str)
if (!this.isConnected)
throw "Not Connected.";
if (jsenv.HAS_NSPR_EVENTQ)
if (jsenv.HAS_NSPR_EVENTQ && jsenv.HAS_STREAM_PROVIDER)
this.asyncWrite (str);
else
this.sendDataNow (str);
@ -158,7 +185,7 @@ function bc_readdata(timeout, count)
try
{
rv = this._inputStream.read (count);
rv = this._scriptableInputStream.read (count);
}
catch (ex)
{
@ -173,7 +200,15 @@ function bc_readdata(timeout, count)
CBSConnection.prototype.startAsyncRead =
function bc_saread (observer)
{
this._transport.asyncRead (new StreamListener (observer), this, 0, -1, 0);
if (jsenv.HAS_STREAM_PROVIDER)
this._transport.asyncRead (new StreamListener (observer), this, 0, -1, 0);
else
{
var pump = Components.classes["@mozilla.org/network/input-stream-pump;1"].
createInstance(Components.interfaces.nsIInputStreamPump);
pump.init(this._inputStream, -1, -1, 0, 0, false);
pump.asyncRead(new StreamListener(observer), this);
}
}
CBSConnection.prototype.asyncWrite =
@ -190,7 +225,10 @@ function bc_awrite (str)
CBSConnection.prototype.hasPendingWrite =
function bc_haspwrite ()
{
return (this._streamProvider.pendingData != "");
if (jsenv.HAS_STREAM_PROVIDER)
return (this._streamProvider.pendingData != "");
else
return false; /* data already pushed to necko */
}
CBSConnection.prototype.sendDataNow =
@ -223,10 +261,14 @@ if (!jsenv.HAS_NSPR_EVENTQ)
CBSConnection.prototype.startAsyncRead = _notimpl;
CBSConnection.prototype.asyncWrite = _notimpl;
}
else
else if (jsenv.HAS_STREAM_PROVIDER)
{
CBSConnection.prototype.sendDataNow = _notimpl;
}
else
{
CBSConnection.prototype.asyncWrite = _notimpl;
}
delete _notimpl;
@ -314,8 +356,8 @@ function sl_dataavail (request, ctxt, inStr, sourceOffset, count)
"StreamListener.onDataAvailable ***");
return;
}
if (!ctxt._inputStream)
ctxt._inputStream = toScriptableInputStream (inStr);
if (!ctxt._scriptableInputStream)
ctxt._scriptableInputStream = toScriptableInputStream (inStr);
if (this._observer)
this._observer.onStreamDataAvailable(request, inStr, sourceOffset,

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

@ -44,7 +44,6 @@
#include "nsIAutoConfig.h"
#include "nsIComponentManager.h"
#include "nsIFile.h"
#include "nsIFileStreams.h"
#include "nsIObserverService.h"
#include "nsIPrefBranch.h"
#include "nsIPrefService.h"
@ -52,6 +51,7 @@
#include "nsIServiceManager.h"
#include "nsIStringBundle.h"
#include "nsXPIDLString.h"
#include "nsNetUtil.h"
#include "prmem.h"
#include "nsString.h"
#include "nsCRT.h"

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

@ -34,7 +34,7 @@
#include "nsIDocumentViewer.h"
#include "nsILocalFile.h"
#include "nsIFileStreams.h"
#include "nsNetUtil.h"
#include "nsITextContent.h"

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

@ -204,13 +204,11 @@ NS_IMETHODIMP mozXMLTermStream::Open(nsIDOMWindowInternal* aDOMWindow,
return result;
// Create an input stream channel
PRInt32 contentLength = 1024;
result = NS_NewInputStreamChannel(getter_AddRefs(mChannel),
uri,
inputStream,
nsDependentCString(contentType),
NS_LITERAL_CSTRING(""),
contentLength);
NS_LITERAL_CSTRING(""));
if (NS_FAILED(result))
return result;

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

@ -136,9 +136,7 @@ nsAddbookProtocolHandler::GenerateXMLOutputChannel( nsString &aOutput,
NS_ENSURE_SUCCESS(rv, rv);
rv = NS_NewInputStreamChannel(&channel, aURI, inStr,
NS_LITERAL_CSTRING("text/xml"),
NS_LITERAL_CSTRING(""),
utf8String.Length());
NS_LITERAL_CSTRING("text/xml"));
NS_ENSURE_SUCCESS(rv, rv);
*_retval = channel;

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

@ -45,7 +45,7 @@
#include "nsIAddrBookSession.h"
#include "nsAddrDatabase.h"
#include "nsIOutputStream.h"
#include "nsIFileStreams.h"
#include "nsNetUtil.h"
#include "msgCore.h"
#include "nsIImportService.h"
#include "nsIStringBundle.h"

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

@ -376,7 +376,7 @@ const nsMsgBiffState nsMsgBiffState_Unknown = 2; // We dunno whether there is ne
boolean shouldStoreMsgOffline(in nsMsgKey msgKey);
boolean hasMsgOffline(in nsMsgKey msgKey);
nsITransport getOfflineFileTransport(in nsMsgKey msgKey, out PRUint32 offset, out PRUint32 size);
nsIInputStream getOfflineFileStream(in nsMsgKey msgKey, out PRUint32 offset, out PRUint32 size);
readonly attribute nsIOutputStream offlineStoreOutputStream;
readonly attribute nsIInputStream offlineStoreInputStream;
void DownloadMessagesForOffline(in nsISupportsArray messages, in nsIMsgWindow window);

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

@ -53,8 +53,8 @@
#include "nsIImportService.h"
#include "nsMsgBaseCID.h"
#include "nsIMsgFilterService.h"
#include "nsIFileStreams.h"
#include "nsISupportsObsolete.h"
#include "nsNetUtil.h"
// unicode "%s" format string
static const PRUnichar unicodeFormatter[] = {

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

@ -969,8 +969,7 @@ nsMessenger::SaveAs(const char* url, PRBool asFile, nsIMsgIdentity* identity, ns
aURL,
nsnull, // inputStream
NS_LITERAL_CSTRING(""), // contentType
NS_LITERAL_CSTRING(""), // contentCharset
-1); // contentLength
NS_LITERAL_CSTRING("")); // contentCharset
if (NS_FAILED(rv)) goto done;
saveListener->m_outputFormat.AssignWithConversion(saveAsFileType == 1 ? TEXT_HTML : TEXT_PLAIN);

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

@ -42,9 +42,9 @@
#include "nsILocalFile.h"
#include "plstr.h"
#include "prmem.h"
#include "nsIFileStreams.h"
#include "nsIMsgHdr.h"
#include "nsEscape.h"
#include "nsNetUtil.h"
#include "nsIMsgFolder.h"
#include "nsMsgUtils.h"
#include "nsMsgFolderFlags.h"

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

@ -42,7 +42,7 @@
#include "nsMsgFolderFlags.h"
#include "nsIPrefBranch.h"
#include "nsIPrefService.h"
#include "nsIFileChannel.h"
#include "nsNetUtil.h"
#include "nsIMsgFolderCache.h"
#include "nsIMsgFolderCacheElement.h"
#include "nsMsgBaseCID.h"
@ -53,7 +53,6 @@
#include "nsIFileStream.h"
#include "nsIChannel.h"
#include "nsITransport.h"
#include "nsIFileTransportService.h"
#include "nsIMsgFolderCompactor.h"
#include "nsIDocShell.h"
#include "nsIMsgWindow.h"
@ -520,50 +519,34 @@ NS_IMETHODIMP nsMsgDBFolder::GetOfflineStoreInputStream(nsIInputStream **stream)
return rv;
}
NS_IMETHODIMP nsMsgDBFolder::GetOfflineFileTransport(nsMsgKey msgKey, PRUint32 *offset, PRUint32 *size, nsITransport **aFileChannel)
NS_IMETHODIMP nsMsgDBFolder::GetOfflineFileStream(nsMsgKey msgKey, PRUint32 *offset, PRUint32 *size, nsIInputStream **aFileStream)
{
NS_ENSURE_ARG(aFileChannel);
NS_ENSURE_ARG(aFileStream);
*offset = *size = 0;
nsresult rv;
rv = nsComponentManager::CreateInstance(NS_LOCALFILECHANNEL_CONTRACTID, nsnull,
NS_GET_IID(nsIFileChannel), (void **) aFileChannel);
if (*aFileChannel)
nsXPIDLCString nativePath;
mPath->GetNativePath(getter_Copies(nativePath));
nsCOMPtr <nsILocalFile> localStore;
rv = NS_NewNativeLocalFile(nativePath, PR_TRUE, getter_AddRefs(localStore));
if (NS_SUCCEEDED(rv) && localStore)
{
nsXPIDLCString nativePath;
mPath->GetNativePath(getter_Copies(nativePath));
rv = NS_NewLocalFileInputStream(aFileStream, localStore);
nsCOMPtr <nsILocalFile> localStore;
rv = NS_NewNativeLocalFile(nativePath, PR_TRUE, getter_AddRefs(localStore));
if (NS_SUCCEEDED(rv) && localStore)
if (NS_SUCCEEDED(rv))
{
NS_DEFINE_CID(kFileTransportServiceCID, NS_FILETRANSPORTSERVICE_CID);
nsCOMPtr<nsIFileTransportService> fts =
do_GetService(kFileTransportServiceCID, &rv);
if (NS_FAILED(rv))
return rv;
rv = fts->CreateTransport(localStore,
PR_RDWR | PR_CREATE_FILE,
0664,
PR_TRUE,
aFileChannel);
if (NS_SUCCEEDED(rv))
nsresult rv = GetDatabase(nsnull);
NS_ENSURE_SUCCESS(rv, NS_OK);
nsCOMPtr<nsIMsgDBHdr> hdr;
rv = mDatabase->GetMsgHdrForKey(msgKey, getter_AddRefs(hdr));
if (hdr && NS_SUCCEEDED(rv))
{
nsresult rv = GetDatabase(nsnull);
NS_ENSURE_SUCCESS(rv, NS_OK);
nsCOMPtr<nsIMsgDBHdr> hdr;
rv = mDatabase->GetMsgHdrForKey(msgKey, getter_AddRefs(hdr));
if (hdr && NS_SUCCEEDED(rv))
{
hdr->GetMessageOffset(offset);
hdr->GetOfflineMessageSize(size);
}
hdr->GetMessageOffset(offset);
hdr->GetOfflineMessageSize(size);
}
}
}

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

@ -105,7 +105,7 @@ public:
NS_IMETHOD GetSupportsOffline(PRBool *aSupportsOffline);
NS_IMETHOD ShouldStoreMsgOffline(nsMsgKey msgKey, PRBool *result);
NS_IMETHOD GetOfflineFileTransport(nsMsgKey msgKey, PRUint32 *offset, PRUint32 *size, nsITransport **_retval);
NS_IMETHOD GetOfflineFileStream(nsMsgKey msgKey, PRUint32 *offset, PRUint32 *size, nsIInputStream **_retval);
NS_IMETHOD HasMsgOffline(nsMsgKey msgKey, PRBool *result);
NS_IMETHOD DownloadMessagesForOffline(nsISupportsArray *messages, nsIMsgWindow *msgWindow);
NS_IMETHOD DownloadAllForOffline(nsIUrlListener *listener, nsIMsgWindow *msgWindow);

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

@ -39,7 +39,9 @@
#include "nsReadableUtils.h"
#include "nsMsgProtocol.h"
#include "nsIMsgMailNewsUrl.h"
#include "nsIStreamTransportService.h"
#include "nsISocketTransportService.h"
#include "nsISocketTransport.h"
#include "nsXPIDLString.h"
#include "nsSpecialSystemDirectory.h"
#include "nsILoadGroup.h"
@ -47,7 +49,6 @@
#include "nsNetUtil.h"
#include "nsIFileURL.h"
#include "nsFileStream.h"
#include "nsIFileTransportService.h"
#include "nsIDNSService.h"
#include "nsIMsgWindow.h"
#include "nsIMsgStatusFeedback.h"
@ -58,10 +59,11 @@
#include "nsIStringBundle.h"
#include "nsIProtocolProxyService.h"
#include "nsIProxyInfo.h"
#include "nsEventQueueUtils.h"
static NS_DEFINE_CID(kSocketTransportServiceCID, NS_SOCKETTRANSPORTSERVICE_CID);
static NS_DEFINE_CID(kStreamTransportServiceCID, NS_STREAMTRANSPORTSERVICE_CID);
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
static NS_DEFINE_CID(kFileTransportServiceCID, NS_FILETRANSPORTSERVICE_CID);
NS_IMPL_THREADSAFE_ADDREF(nsMsgProtocol)
NS_IMPL_THREADSAFE_RELEASE(nsMsgProtocol)
@ -72,6 +74,7 @@ NS_INTERFACE_MAP_BEGIN(nsMsgProtocol)
NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
NS_INTERFACE_MAP_ENTRY(nsIChannel)
NS_INTERFACE_MAP_ENTRY(nsIRequest)
NS_INTERFACE_MAP_ENTRY(nsITransportEventSink)
NS_INTERFACE_MAP_END_THREADSAFE
static PRUnichar *GetStringByID(PRInt32 stringID);
@ -81,7 +84,6 @@ static PRUnichar *FormatStringWithHostNameByID(PRInt32 stringID, nsIMsgMailNewsU
nsMsgProtocol::nsMsgProtocol(nsIURI * aURL)
{
m_flags = 0;
m_startPosition = 0;
m_readCount = 0;
mLoadFlags = 0;
m_socketIsOpen = PR_FALSE;
@ -125,15 +127,24 @@ nsMsgProtocol::OpenNetworkSocketWithInfo(const char * aHostName,
// with socket connections we want to read as much data as arrives
m_readCount = -1;
m_startPosition = 0;
rv = socketService->CreateTransportOfType(connectionType, aHostName,
aGetPort, aProxyInfo, 0, 0,
getter_AddRefs(m_transport));
nsCOMPtr<nsISocketTransport> strans;
rv = socketService->CreateTransport(&connectionType, connectionType != nsnull,
nsDependentCString(aHostName),
aGetPort, aProxyInfo,
getter_AddRefs(strans));
if (NS_FAILED(rv)) return rv;
m_transport->SetNotificationCallbacks(callbacks, PR_FALSE);
strans->SetSecurityCallbacks(callbacks);
// creates cyclic reference!
nsCOMPtr<nsIEventQueue> eventQ;
NS_GetCurrentEventQ(getter_AddRefs(eventQ));
if (eventQ)
strans->SetEventSink(this, eventQ);
m_socketIsOpen = PR_FALSE;
m_transport = strans;
return SetupTransportState();
}
@ -220,37 +231,41 @@ nsresult nsMsgProtocol::OpenFileSocket(nsIURI * aURL, PRUint32 aStartPosition, P
// rid of this method completely.
nsresult rv = NS_OK;
m_startPosition = aStartPosition;
m_readCount = aReadCount;
nsCOMPtr <nsIFile> file;
rv = GetFileFromURL(aURL, getter_AddRefs(file));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIFileTransportService> fts =
do_GetService(kFileTransportServiceCID, &rv);
nsCOMPtr<nsIInputStream> stream;
rv = NS_NewLocalFileInputStream(getter_AddRefs(stream), file);
if (NS_FAILED(rv)) return rv;
//we are always using this file socket to read data from the mailbox.
rv = fts->CreateTransport(file, PR_RDONLY,
0664, PR_TRUE, getter_AddRefs(m_transport));
m_socketIsOpen = PR_FALSE;
// create input stream transport
nsCOMPtr<nsIStreamTransportService> sts =
do_GetService(kStreamTransportServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
rv = sts->CreateInputTransport(stream, aStartPosition, aReadCount, PR_TRUE, getter_AddRefs(m_transport));
m_socketIsOpen = PR_FALSE;
return rv;
}
nsresult nsMsgProtocol::SetupTransportState()
{
nsresult rv = NS_OK;
if (!m_socketIsOpen && m_transport)
{
rv = m_transport->OpenOutputStream(0, PRUint32(-1), 0, getter_AddRefs(m_outputStream));
nsresult rv;
// open buffered, blocking output stream
rv = m_transport->OpenOutputStream(nsITransport::OPEN_BLOCKING, 0, 0, getter_AddRefs(m_outputStream));
if (NS_FAILED(rv)) return rv;
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create an output stream");
// we want to open the stream
} // if m_transport
return rv;
return NS_OK;
}
nsresult nsMsgProtocol::CloseSocket()
@ -258,15 +273,24 @@ nsresult nsMsgProtocol::CloseSocket()
nsresult rv = NS_OK;
// release all of our socket state
m_socketIsOpen = PR_FALSE;
m_inputStream = nsnull;
m_outputStream = nsnull;
if (m_transport)
m_transport->SetNotificationCallbacks(nsnull, PR_FALSE);
if (m_transport) {
nsCOMPtr<nsISocketTransport> strans = do_QueryInterface(m_transport);
if (strans) {
strans->SetSecurityCallbacks(nsnull);
strans->SetEventSink(nsnull, nsnull); // break cyclic reference!
}
}
// we need to call Cancel so that we remove the socket transport from the mActiveTransportList. see bug #30648
if (m_request) {
rv = m_request->Cancel(NS_BINDING_ABORTED);
}
m_request = 0;
m_transport = 0;
m_request = 0;
if (m_transport) {
m_transport->Close(NS_BINDING_ABORTED);
m_transport = 0;
}
return rv;
}
@ -434,8 +458,23 @@ nsresult nsMsgProtocol::LoadUrl(nsIURI * aURL, nsISupports * aConsumer)
nsCOMPtr<nsISupports> urlSupports = do_QueryInterface(aURL);
if (m_transport)
{
// don't open the input stream more than once
if (!m_inputStream)
{
// open buffered, asynchronous input stream
rv = m_transport->OpenInputStream(0, 0, 0, getter_AddRefs(m_inputStream));
if (NS_FAILED(rv)) return rv;
}
nsCOMPtr<nsIInputStreamPump> pump;
rv = NS_NewInputStreamPump(getter_AddRefs(pump),
m_inputStream, -1, m_readCount);
if (NS_FAILED(rv)) return rv;
m_request = pump; // keep a reference to the pump so we can cancel it
// put us in a state where we are always notified of incoming data
rv = m_transport->AsyncRead(this, urlSupports, m_startPosition, m_readCount, 0, getter_AddRefs(m_request));
rv = pump->AsyncRead(this, urlSupports);
NS_ASSERTION(NS_SUCCEEDED(rv), "AsyncRead failed");
m_socketIsOpen = PR_TRUE; // mark the channel as open
}
@ -626,6 +665,24 @@ nsMsgProtocol::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCall
return NS_OK;
}
NS_IMETHODIMP
nsMsgProtocol::OnTransportStatus(nsITransport *transport, nsresult status,
PRUint32 progress, PRUint32 progressMax)
{
if (mProgressEventSink && !(mLoadFlags & LOAD_BACKGROUND)) {
nsCAutoString host;
if (m_url)
m_url->GetHost(host);
mProgressEventSink->OnStatus(this, nsnull, status, NS_ConvertUTF8toUCS2(host).get());
if (status == nsISocketTransport::STATUS_RECEIVING_FROM ||
status == nsISocketTransport::STATUS_SENDING_TO ||
status == nsITransport::STATUS_READING ||
status == nsITransport::STATUS_WRITING)
mProgressEventSink->OnProgress(this, nsnull, progress, progressMax);
}
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// From nsIRequest
////////////////////////////////////////////////////////////////////////////////
@ -656,14 +713,20 @@ NS_IMETHODIMP nsMsgProtocol::Cancel(nsresult status)
NS_IMETHODIMP nsMsgProtocol::Suspend()
{
NS_NOTREACHED("Suspend");
return NS_ERROR_NOT_IMPLEMENTED;
if (m_request)
return m_request->Suspend();
NS_WARNING("no request to suspend");
return NS_ERROR_NOT_AVAILABLE;
}
NS_IMETHODIMP nsMsgProtocol::Resume()
{
NS_NOTREACHED("Resume");
return NS_ERROR_NOT_IMPLEMENTED;
if (m_request)
return m_request->Resume();
NS_WARNING("no request to resume");
return NS_ERROR_NOT_AVAILABLE;
}
nsresult nsMsgProtocol::PostMessage(nsIURI* url, nsIFileSpec *fileSpec)
@ -780,7 +843,7 @@ nsresult nsMsgProtocol::PostMessage(nsIURI* url, nsIFileSpec *fileSpec)
// nsMsgAsyncWriteProtocol subclass and related helper classes
/////////////////////////////////////////////////////////////////////
class nsMsgProtocolStreamProvider : public nsIStreamProvider
class nsMsgProtocolStreamProvider : public nsIOutputStreamNotify
{
public:
NS_DECL_ISUPPORTS
@ -788,20 +851,16 @@ public:
nsMsgProtocolStreamProvider() { }
virtual ~nsMsgProtocolStreamProvider() {}
void Init(nsMsgAsyncWriteProtocol *aProtInstance, nsIInputStream *aInputStream) { mMsgProtocol = aProtInstance; mInStream = aInputStream;}
void Init(nsMsgAsyncWriteProtocol *aProtInstance, nsIInputStream *aInputStream)
{
mMsgProtocol = aProtInstance;
mInStream = aInputStream;
}
//
// nsIRequestObserver implementation ...
// nsIOutputStreamNotify implementation ...
//
NS_IMETHODIMP OnStartRequest(nsIRequest *chan, nsISupports *ctxt) { return NS_OK; }
NS_IMETHODIMP OnStopRequest(nsIRequest *chan, nsISupports *ctxt, nsresult status) { return NS_OK; }
//
// nsIStreamProvider implementation ...
//
NS_IMETHODIMP OnDataWritable(nsIRequest *aChannel, nsISupports *aContext,
nsIOutputStream *aOutStream,
PRUint32 aOffset, PRUint32 aCount)
NS_IMETHODIMP OnOutputStreamReady(nsIAsyncOutputStream *aOutStream)
{
NS_ASSERTION(mInStream, "not initialized");
@ -817,30 +876,37 @@ public:
if (avail == 0)
{
// ok, stop writing...
mMsgProtocol->mSuspendedWrite = PR_TRUE;
return NS_BASE_STREAM_WOULD_BLOCK;
return NS_OK;
}
PRUint32 bytesWritten;
rv = aOutStream->WriteFrom(mInStream, PR_MIN(avail, aCount), &bytesWritten);
rv = aOutStream->WriteFrom(mInStream, PR_MIN(avail, 4096), &bytesWritten);
// if were full at the time, the input stream may be backed up and we need to read any remains from the last ODA call
// before we'll get more ODA calls
if (mMsgProtocol->mSuspendedRead)
mMsgProtocol->UnblockPostReader();
mMsgProtocol->UpdateProgress(bytesWritten);
return rv;
// try to write again...
if (NS_SUCCEEDED(rv))
rv = aOutStream->AsyncWait(this, 0, mMsgProtocol->mProviderEventQ);
NS_ASSERTION(NS_SUCCEEDED(rv) || rv == NS_BINDING_ABORTED, "unexpected error writing stream");
return NS_OK;
}
protected:
nsMsgAsyncWriteProtocol * mMsgProtocol;
nsCOMPtr<nsIInputStream> mInStream;
nsCOMPtr<nsIInputStream> mInStream;
};
NS_IMPL_THREADSAFE_ISUPPORTS2(nsMsgProtocolStreamProvider,
nsIStreamProvider,
nsIRequestObserver)
// XXX this probably doesn't need to be threadsafe
NS_IMPL_THREADSAFE_ISUPPORTS1(nsMsgProtocolStreamProvider,
nsIOutputStreamNotify)
class nsMsgFilePostHelper : public nsIStreamListener
{
@ -874,18 +940,19 @@ nsresult nsMsgFilePostHelper::Init(nsIOutputStream * aOutStream, nsMsgAsyncWrite
mOutStream = aOutStream;
mProtInstance = aProtInstance; // mscott work out ref counting issue
nsCOMPtr<nsIFileTransportService> fts =
do_GetService(kFileTransportServiceCID, &rv);
nsCOMPtr<nsIInputStream> stream;
rv = NS_NewLocalFileInputStream(getter_AddRefs(stream), aFileToPost);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsITransport> transport;
rv = fts->CreateTransport(aFileToPost, PR_RDONLY, 0664, PR_TRUE, getter_AddRefs(transport));
if (transport)
{
rv = transport->AsyncRead(this, nsnull, 0, PRUint32(-1), 0, getter_AddRefs(mPostFileRequest));
}
return rv;
nsCOMPtr<nsIInputStreamPump> pump;
rv = NS_NewInputStreamPump(getter_AddRefs(pump), stream);
if (NS_FAILED(rv)) return rv;
rv = pump->AsyncRead(this, nsnull);
if (NS_FAILED(rv)) return rv;
mPostFileRequest = pump;
return NS_OK;
}
NS_IMETHODIMP nsMsgFilePostHelper::OnStartRequest(nsIRequest * aChannel, nsISupports *ctxt)
@ -923,7 +990,8 @@ NS_IMETHODIMP nsMsgFilePostHelper::OnDataAvailable(nsIRequest * /* aChannel */,
// data to write (i.e. the pipe went empty). So resume the channel to kick
// things off again.
mProtInstance->mSuspendedWrite = PR_FALSE;
mProtInstance->m_WriteRequest->Resume();
mProtInstance->mAsyncOutStream->AsyncWait(mProtInstance->mProvider, 0,
mProtInstance->mProviderEventQ);
}
return NS_OK;
@ -954,8 +1022,8 @@ NS_IMETHODIMP nsMsgAsyncWriteProtocol::Cancel(nsresult status)
if (m_request)
m_request->Cancel(status);
if (m_WriteRequest)
m_WriteRequest->Cancel(status);
if (mAsyncOutStream)
mAsyncOutStream->CloseEx(status);
return NS_OK;
}
@ -1188,15 +1256,25 @@ nsresult nsMsgAsyncWriteProtocol::SetupTransportState()
PR_TRUE,
PR_TRUE);
nsCOMPtr<nsIStreamProvider> provider;
rv = NS_GetCurrentEventQ(getter_AddRefs(mProviderEventQ));
if (NS_FAILED(rv)) return rv;
nsMsgProtocolStreamProvider *provider;
NS_NEWXPCOM(provider, nsMsgProtocolStreamProvider);
if (!provider) return NS_ERROR_OUT_OF_MEMORY;
NS_STATIC_CAST(nsMsgProtocolStreamProvider*,
NS_STATIC_CAST(nsIStreamProvider*, provider))->Init(this, mInStream);
provider->Init(this, mInStream);
mProvider = provider; // ADDREF
rv = m_transport->AsyncWrite(provider, nsnull, 0, 0, 0, getter_AddRefs(m_WriteRequest));
nsCOMPtr<nsIOutputStream> stream;
rv = m_transport->OpenOutputStream(0, 0, 0, getter_AddRefs(stream));
if (NS_FAILED(rv)) return rv;
mAsyncOutStream = do_QueryInterface(stream, &rv);
if (NS_FAILED(rv)) return rv;
// wait for the output stream to become writable
rv = mAsyncOutStream->AsyncWait(mProvider, 0, mProviderEventQ);
} // if m_transport
return rv;
@ -1207,9 +1285,8 @@ nsresult nsMsgAsyncWriteProtocol::CloseSocket()
nsresult rv = NS_OK;
nsMsgProtocol::CloseSocket();
// we need to call Cancel so that we remove the socket transport from the mActiveTransportList. see bug #30648
if (m_WriteRequest)
rv = m_WriteRequest->Cancel(NS_BINDING_ABORTED);
if (mAsyncOutStream)
mAsyncOutStream->CloseEx(NS_BINDING_ABORTED);
if (mFilePostHelper)
{
@ -1217,7 +1294,9 @@ nsresult nsMsgAsyncWriteProtocol::CloseSocket()
mFilePostHelper = nsnull;
}
m_WriteRequest = 0;
mAsyncOutStream = 0;
mProvider = 0;
mProviderEventQ = 0;
return rv;
}
@ -1238,7 +1317,8 @@ void nsMsgAsyncWriteProtocol::UpdateProgress(PRUint32 aNewBytes)
nsCOMPtr<nsIWebProgressListener> webProgressListener (do_QueryInterface(statusFeedback));
if (!webProgressListener) return;
webProgressListener->OnProgressChange(nsnull, m_WriteRequest, mNumBytesPosted, mFilePostSize, mNumBytesPosted, mFilePostSize);
// XXX not sure if m_request is correct here
webProgressListener->OnProgressChange(nsnull, m_request, mNumBytesPosted, mFilePostSize, mNumBytesPosted, mFilePostSize);
}
return;
@ -1258,7 +1338,7 @@ PRInt32 nsMsgAsyncWriteProtocol::SendData(nsIURI * aURL, const char * dataBuffer
// data to write (i.e. the pipe went empty). So resume the channel to kick
// things off again.
mSuspendedWrite = PR_FALSE;
m_WriteRequest->Resume();
mAsyncOutStream->AsyncWait(mProvider, 0, mProviderEventQ);
}
return NS_OK;
}
@ -1325,3 +1405,5 @@ PRUnichar *FormatStringWithHostNameByID(PRInt32 stringID, nsIMsgMailNewsUrl *msg
return (ptrv);
}
// vim: ts=2 sw=2

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

@ -48,9 +48,10 @@
#include "nsIFileSpec.h"
#include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsIStreamProvider.h"
#include "nsIProgressEventSink.h"
#include "nsITransport.h"
#include "nsIAsyncOutputStream.h"
#include "nsIEventQueue.h"
#define UNKNOWN_ERROR 101
#define UNKNOWN_HOST_ERROR 102
@ -67,7 +68,9 @@ class nsIProxyInfo;
// it unifies the core networking code for the protocols. My hope is that
// this will make unification with Necko easier as we'll only have to change
// this class and not all of the mailnews protocols.
class NS_MSG_BASE nsMsgProtocol : public nsIStreamListener, public nsIChannel
class NS_MSG_BASE nsMsgProtocol : public nsIStreamListener
, public nsIChannel
, public nsITransportEventSink
{
public:
nsMsgProtocol(nsIURI * aURL);
@ -80,6 +83,7 @@ public:
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSITRANSPORTEVENTSINK
// LoadUrl -- A protocol typically overrides this function, sets up any local state for the url and
// then calls the base class which opens the socket if it needs opened. If the socket is
@ -139,6 +143,7 @@ protected:
// Ouput stream for writing commands to the socket
nsCOMPtr<nsIOutputStream> m_outputStream; // this will be obtained from the transport interface
nsCOMPtr<nsIInputStream> m_inputStream;
// Ouput stream for writing commands to the socket
nsCOMPtr<nsITransport> m_transport;
@ -147,7 +152,7 @@ protected:
PRBool m_socketIsOpen; // mscott: we should look into keeping this state in the nsSocketTransport...
// I'm using it to make sure I open the socket the first time a URL is loaded into the connection
PRUint32 m_flags; // used to store flag information
PRUint32 m_startPosition;
//PRUint32 m_startPosition;
PRInt32 m_readCount;
nsFileSpec m_tempMsgFileSpec; // we currently have a hack where displaying a msg involves writing it to a temp file first
@ -197,6 +202,9 @@ public:
// if we suspended the asynch write while waiting for more data to write then this will be TRUE
PRBool mSuspendedWrite;
nsCOMPtr<nsIRequest> m_WriteRequest;
nsCOMPtr<nsIAsyncOutputStream> mAsyncOutStream;
nsCOMPtr<nsIOutputStreamNotify> mProvider;
nsCOMPtr<nsIEventQueue> mProviderEventQ;
// because we are reading the post data in asychronously, it's possible that we aren't sending it
// out fast enough and the reading gets blocked. The following set of state variables are used to

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

@ -571,8 +571,7 @@ nsMsgAttachmentHandler::SnarfMsgAttachment(nsMsgCompFields *compFields)
if (aURL)
aURL->SetSpec(nsDependentCString(uri.get()));
rv = NS_NewInputStreamChannel(getter_AddRefs(m_converter_channel), aURL, nsnull,
NS_LITERAL_CSTRING(""), NS_LITERAL_CSTRING(""), -1);
rv = NS_NewInputStreamChannel(getter_AddRefs(m_converter_channel), aURL, nsnull);
if (NS_FAILED(rv))
goto done;

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

@ -42,7 +42,7 @@
#include "nsIMimeConverter.h"
#include "nsMsgCompFields.h"
#include "nsIMsgStatusFeedback.h"
#include "nsIRequest.h"
#include "nsIChannel.h"
#include "nsIMsgSend.h"
#include "nsIFileStreams.h"
#include "nsIStreamConverter.h"

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

@ -173,8 +173,7 @@ nsMsgDraft::ProcessDraftOrTemplateOperation(const char *msgURI, nsMimeOutputType
}
nsCOMPtr<nsIChannel> dummyChannel;
rv = NS_NewInputStreamChannel(getter_AddRefs(dummyChannel), aURL, nsnull,
NS_LITERAL_CSTRING(""), NS_LITERAL_CSTRING(""), -1);
rv = NS_NewInputStreamChannel(getter_AddRefs(dummyChannel), aURL, nsnull);
if (NS_FAILED(mimeParser->AsyncConvertData(nsnull, nsnull, nsnull, dummyChannel)))
{
Release();

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

@ -46,6 +46,7 @@
#include "nsIStreamListener.h"
#include "nsIInputStream.h"
#include "nsIOutputStream.h"
#include "nsISocketTransport.h"
#include "nsIMsgHeaderParser.h"
#include "nsFileStream.h"
#include "nsIMsgMailNewsUrl.h"
@ -712,14 +713,10 @@ PRInt32 nsSmtpProtocol::SendTLSResponse()
if (m_responseCode == 220)
{
nsCOMPtr<nsISupports> secInfo;
nsCOMPtr<nsITransport> trans;
nsCOMPtr<nsITransportRequest> transReq = do_QueryInterface(m_request, &rv);
nsCOMPtr<nsISocketTransport> strans = do_QueryInterface(m_transport, &rv);
if (NS_FAILED(rv)) return rv;
rv = transReq->GetTransport(getter_AddRefs(trans));
if (NS_FAILED(rv)) return rv;
rv = trans->GetSecurityInfo(getter_AddRefs(secInfo));
rv = strans->GetSecurityInfo(getter_AddRefs(secInfo));
if (NS_SUCCEEDED(rv) && secInfo) {
nsCOMPtr<nsISSLSocketControl> sslControl = do_QueryInterface(secInfo, &rv);

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

@ -104,6 +104,7 @@ PRLogModuleInfo *IMAP;
#include "nsIProxyObjectManager.h"
#include "nsIStreamConverterService.h"
#include "nsIProxyInfo.h"
#include "nsEventQueueUtils.h"
#if 0
#include "nsIHashAlgorithm.h"
#endif
@ -413,6 +414,8 @@ nsImapProtocol::nsImapProtocol() :
m_dataOutputBuf = (char *) PR_CALLOC(sizeof(char) * OUTPUT_BUFFER_SIZE);
m_allocatedSize = OUTPUT_BUFFER_SIZE;
m_pumpSuspended = PR_FALSE;
// used to buffer incoming data by ReadNextLineFromInput
m_inputStreamBuffer = new nsMsgLineStreamBuffer(OUTPUT_BUFFER_SIZE, PR_TRUE /* allocate new lines */, PR_FALSE /* leave CRLFs on the returned string */);
m_currentBiffState = nsIMsgFolder::nsMsgBiffState_Unknown;
@ -735,7 +738,7 @@ nsresult nsImapProtocol::SetupWithUrl(nsIURI * aURL, nsISupports* aConsumer)
imapServer->GetFetchByChunks(&m_fetchByChunks);
}
if ( m_runningUrl && !m_channel /* and we don't have a transport yet */)
if ( m_runningUrl && !m_transport /* and we don't have a transport yet */)
{
// extract the file name and create a file transport...
PRInt32 port=-1;
@ -771,35 +774,67 @@ nsresult nsImapProtocol::SetupWithUrl(nsIURI * aURL, nsISupports* aConsumer)
rv = NS_ExamineForProxy("imap", hostName.get(), port, getter_AddRefs(proxyInfo));
if (NS_FAILED(rv)) proxyInfo = nsnull;
const nsACString *socketHost;
PRUint16 socketPort;
if (m_overRideUrlConnectionInfo)
rv = socketService->CreateTransportOfType(connectionType, m_logonHost.get(), m_logonPort, proxyInfo, 0, 0, getter_AddRefs(m_channel));
else
rv = socketService->CreateTransportOfType(connectionType, hostName, port, proxyInfo, 0, 0, getter_AddRefs(m_channel));
// Ensure that the socket can get the notification callbacks
nsCOMPtr<nsIInterfaceRequestor> callbacks;
m_mockChannel->GetNotificationCallbacks(getter_AddRefs(callbacks));
if (m_channel)
{
m_channel->SetNotificationCallbacks(callbacks, PR_FALSE);
socketHost = &m_logonHost;
socketPort = m_logonPort;
}
else
{
socketHost = &hostName;
socketPort = port;
}
rv = socketService->CreateTransport(&connectionType, connectionType != nsnull,
*socketHost, socketPort, proxyInfo,
getter_AddRefs(m_transport));
if (NS_SUCCEEDED(rv))
rv = m_channel->OpenOutputStream(0, PRUint32(-1), 0, getter_AddRefs(m_outputStream));
if (m_transport)
{
// Ensure that the socket can get the notification callbacks
nsCOMPtr<nsIInterfaceRequestor> callbacks;
m_mockChannel->GetNotificationCallbacks(getter_AddRefs(callbacks));
if (callbacks)
m_transport->SetSecurityCallbacks(callbacks);
nsCOMPtr<nsITransportEventSink> sink = do_QueryInterface(m_mockChannel);
if (sink) {
nsCOMPtr<nsIEventQueue> eventQ;
NS_GetMainEventQ(getter_AddRefs(eventQ));
m_transport->SetEventSink(sink, eventQ);
}
// open buffered, asynchronous input stream
rv = m_transport->OpenInputStream(0, 0, 0, getter_AddRefs(m_inputStream));
if (NS_FAILED(rv)) return rv;
// open buffered, blocking output stream
rv = m_transport->OpenOutputStream(nsITransport::OPEN_BLOCKING, 0, 0, getter_AddRefs(m_outputStream));
if (NS_FAILED(rv)) return rv;
}
}
} // if m_runningUrl
if (m_channel && m_mockChannel)
if (m_transport && m_mockChannel)
{
// set the security info for the mock channel to be the security status for our underlying transport.
nsCOMPtr<nsISupports> securityInfo;
m_channel->GetSecurityInfo(getter_AddRefs(securityInfo));
m_transport->GetSecurityInfo(getter_AddRefs(securityInfo));
m_mockChannel->SetSecurityInfo(securityInfo);
nsCOMPtr<nsIInterfaceRequestor> callbacks;
m_mockChannel->GetNotificationCallbacks(getter_AddRefs(callbacks));
if (callbacks && m_channel)
m_channel->SetNotificationCallbacks(callbacks, PR_FALSE);
if (callbacks && m_transport)
m_transport->SetSecurityCallbacks(callbacks);
nsCOMPtr<nsITransportEventSink> sink = do_QueryInterface(m_mockChannel);
if (sink) {
nsCOMPtr<nsIEventQueue> eventQ;
NS_GetMainEventQ(getter_AddRefs(eventQ));
m_transport->SetEventSink(sink, eventQ);
}
// and if we have a cache entry that we are saving the message to, set the security info on it too.
// since imap only uses the memory cache, passing this on is the right thing to do.
@ -822,8 +857,11 @@ nsresult nsImapProtocol::SetupWithUrl(nsIURI * aURL, nsISupports* aConsumer)
void nsImapProtocol::ReleaseUrlState()
{
// clear out the socket's reference to the notification callbacks for this transaction
if (m_channel)
m_channel->SetNotificationCallbacks(nsnull, PR_FALSE);
if (m_transport)
{
m_transport->SetSecurityCallbacks(nsnull);
m_transport->SetEventSink(nsnull, nsnull);
}
if (m_mockChannel)
{
@ -923,7 +961,8 @@ NS_IMETHODIMP nsImapProtocol::Run()
}
me->m_runningUrl = nsnull;
me->m_channel = nsnull;
me->m_transport = nsnull;
me->m_inputStream = nsnull;
me->m_outputStream = nsnull;
me->m_channelListener = nsnull;
me->m_channelContext = nsnull;
@ -1030,8 +1069,8 @@ nsImapProtocol::TellThreadToDie(PRBool isSaveToClose)
}
}
if (mAsyncReadRequest)
mAsyncReadRequest->Cancel(NS_OK);
if (m_pump)
m_pump->Cancel(NS_ERROR_ABORT);
PR_EnterMonitor(m_threadDeathMonitor);
m_threadShouldDie = PR_TRUE;
PR_ExitMonitor(m_threadDeathMonitor);
@ -1114,7 +1153,7 @@ nsImapProtocol::ImapThreadMainLoop()
// process the current url. Don't try to wait for the monitor
// the first time because it may have already been signaled.
// But make sure we have a channel first, or ProcessCurrentUrl will fail.
if (TestFlag(IMAP_FIRST_PASS_IN_THREAD) && m_runningUrl && m_channel)
if (TestFlag(IMAP_FIRST_PASS_IN_THREAD) && m_runningUrl && m_transport)
{
// if we launched another url, just loop around and process it.
if (ProcessCurrentURL())
@ -1202,13 +1241,19 @@ PRBool nsImapProtocol::ProcessCurrentURL()
PRBool isExternalUrl;
nsresult rv = NS_OK;
PseudoInterrupt(PR_FALSE); // clear this if left over from previous url.
if (!TestFlag(IMAP_CONNECTION_IS_OPEN) && m_channel)
if (!TestFlag(IMAP_CONNECTION_IS_OPEN) && m_inputStream)
{
m_channel->AsyncRead(this /* stream listener */, nsnull, 0, PRUint32(-1), 0,
getter_AddRefs(mAsyncReadRequest));
SetFlag(IMAP_CONNECTION_IS_OPEN);
rv = NS_NewInputStreamPump(getter_AddRefs(m_pump), m_inputStream);
if (NS_SUCCEEDED(rv))
{
rv = m_pump->AsyncRead(this /* stream listener */, nsnull);
if (NS_SUCCEEDED(rv))
SetFlag(IMAP_CONNECTION_IS_OPEN);
}
}
if (m_runningUrl)
{
@ -1244,7 +1289,6 @@ PRBool nsImapProtocol::ProcessCurrentURL()
GetServerStateParser().SetConnected(PR_TRUE);
// acknowledge that we are running the url now..
nsresult rv = NS_OK;
nsCOMPtr<nsIMsgMailNewsUrl> mailnewsurl = do_QueryInterface(m_runningUrl, &rv);
#ifdef DEBUG_bienvenu1
nsXPIDLCString urlSpec;
@ -1425,26 +1469,30 @@ void nsImapProtocol::ParseIMAPandCheckForNewMail(const char* commandString, PRBo
////////////////////////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP nsImapProtocol::OnDataAvailable(nsIRequest *request, nsISupports *ctxt, nsIInputStream *aIStream, PRUint32 aSourceOffset, PRUint32 aLength)
{
nsresult res = NS_OK;
if(NS_SUCCEEDED(res) && aLength > 0)
{
if (aLength > 0)
{
// make sure m_inputStream is set to the right input stream...
if (!m_inputStream)
m_inputStream = dont_QueryInterface(aIStream);
NS_ASSERTION(m_inputStream == aIStream, "unexpected stream");
if (TestFlag(IMAP_WAITING_FOR_DATA))
{
// if we received data, we need to signal the data available monitor...
if (TestFlag(IMAP_WAITING_FOR_DATA))
{
// if we received data, we need to signal the data available monitor...
// Read next line from input will actually read the data out of the stream
ClearFlag(IMAP_WAITING_FOR_DATA); // we are no longer waiting for data
PR_EnterMonitor(m_dataAvailableMonitor);
ClearFlag(IMAP_WAITING_FOR_DATA); // we are no longer waiting for data
// XXX no one ever waits on this monitor!
PR_EnterMonitor(m_dataAvailableMonitor);
PR_Notify(m_dataAvailableMonitor);
PR_ExitMonitor(m_dataAvailableMonitor);
}
PR_ExitMonitor(m_dataAvailableMonitor);
}
// suspend this request until we've read from the input stream
NS_ASSERTION(m_pump == request, "unexpected request");
request->Suspend();
m_pumpSuspended = PR_TRUE;
}
return res;
return NS_OK;
}
NS_IMETHODIMP nsImapProtocol::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
@ -1466,7 +1514,6 @@ NS_IMETHODIMP nsImapProtocol::OnStartRequest(nsIRequest *request, nsISupports *c
// stop binding is a "notification" informing us that the stream associated with aURL is going away.
NS_IMETHODIMP nsImapProtocol::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult aStatus)
{
PRBool killThread = PR_TRUE; // we always want to kill the thread, I believe.
if (NS_FAILED(aStatus))
@ -1509,14 +1556,14 @@ NS_IMETHODIMP nsImapProtocol::OnStopRequest(nsIRequest *request, nsISupports *ct
}
PR_CEnterMonitor(this);
mAsyncReadRequest = nsnull; // don't need to cache this anymore, it's going away
m_pump = nsnull; // don't need to cache this anymore, it's going away
if (killThread == PR_TRUE)
{
ClearFlag(IMAP_CONNECTION_IS_OPEN);
TellThreadToDie(PR_FALSE);
}
m_channel = nsnull;
m_transport = nsnull;
m_outputStream = nsnull;
m_inputStream = nsnull;
PR_CExitMonitor(this);
@ -1558,10 +1605,9 @@ NS_IMETHODIMP nsImapProtocol::GetRunningImapURL(nsIImapUrl **aImapUrl)
nsresult nsImapProtocol::SendData(const char * dataBuffer, PRBool aSuppressLogging)
{
PRUint32 writeCount = 0;
nsresult rv = NS_ERROR_NULL_POINTER;
if (!m_channel)
if (!m_transport)
{
// the connection died unexpectedly! so clear the open connection flag
ClearFlag(IMAP_CONNECTION_IS_OPEN);
@ -1577,7 +1623,10 @@ nsresult nsImapProtocol::SendData(const char * dataBuffer, PRBool aSuppressLoggi
Log("SendData", nsnull, dataBuffer);
else
Log("SendData", nsnull, "Logging suppressed for this command (it probably contained authentication information)");
rv = m_outputStream->Write(dataBuffer, PL_strlen(dataBuffer), &writeCount);
PRUint32 n;
rv = m_outputStream->Write(dataBuffer, PL_strlen(dataBuffer), &n);
if (NS_FAILED(rv))
{
// the connection died unexpectedly! so clear the open connection flag
@ -1615,7 +1664,7 @@ nsresult nsImapProtocol::LoadUrl(nsIURI * aURL, nsISupports * aConsumer)
if (NS_FAILED(rv)) return rv;
SetupSinkProxy(); // generate proxies for all of the event sinks in the url
m_lastActiveTime = PR_Now();
if (m_channel && m_runningUrl)
if (m_transport && m_runningUrl)
{
nsImapAction imapAction;
m_runningUrl->GetImapAction(&imapAction);
@ -1650,7 +1699,7 @@ NS_IMETHODIMP nsImapProtocol::IsBusy(PRBool *aIsConnectionBusy,
nsresult rv = NS_OK;
*aIsConnectionBusy = PR_FALSE;
*isInboxConnection = PR_FALSE;
if (!m_channel)
if (!m_transport)
{
// ** jt -- something is really wrong kill the thread
TellThreadToDie(PR_FALSE);
@ -1694,7 +1743,7 @@ NS_IMETHODIMP nsImapProtocol::CanHandleUrl(nsIImapUrl * aImapUrl,
PRBool isBusy = PR_FALSE;
PRBool isInboxConnection = PR_FALSE;
if (!m_channel)
if (!m_transport)
{
// *** jt -- something is really wrong; it could be the dialer gave up
// the connection or ip binding has been release by the operating
@ -4045,9 +4094,20 @@ char* nsImapProtocol::CreateNewLineFromSocket()
{
m_eventQueue->ProcessPendingEvents();
newLine = m_inputStreamBuffer->ReadNextLine(m_inputStream, numBytesInLine, needMoreData);
PR_LOG(IMAP, PR_LOG_DEBUG, ("ReadNextLine [stream=%x nb=%u needmore=%u]\n",
m_inputStream.get(), numBytesInLine, needMoreData));
if (needMoreData)
{
SetFlag(IMAP_WAITING_FOR_DATA);
if (m_pump && m_pumpSuspended)
{
m_pump->Resume();
m_pumpSuspended = PR_FALSE;
}
// we want to put this thread to rest until the on data available monitor goes off..
// so sleep until the timeout hits, then pump some events. This may cause the IMAP_WAITING_FOR_DATA
// flag to get cleared which means data has arrived so we can kick out of the loop or the
@ -7374,6 +7434,7 @@ NS_INTERFACE_MAP_BEGIN(nsImapMockChannel)
NS_INTERFACE_MAP_ENTRY(nsIChannel)
NS_INTERFACE_MAP_ENTRY(nsIRequest)
NS_INTERFACE_MAP_ENTRY(nsICacheListener)
NS_INTERFACE_MAP_ENTRY(nsITransportEventSink)
NS_INTERFACE_MAP_END_THREADSAFE
@ -7589,19 +7650,14 @@ nsImapMockChannel::OnCacheEntryAvailable(nsICacheEntryDescriptor *entry, nsCache
nsCOMPtr<nsIStreamListenerTee> tee = do_CreateInstance(kStreamListenerTeeCID, &rv);
if (NS_SUCCEEDED(rv))
{
nsCOMPtr<nsITransport> transport;
rv = entry->GetTransport(getter_AddRefs(transport));
nsCOMPtr<nsIOutputStream> out;
// this will fail with the mem cache turned off, so we need to fall through
// to ReadFromImapConnection instead of aborting with NS_ENSURE_SUCCESS(rv,rv)
rv = entry->OpenOutputStream(0, getter_AddRefs(out));
if (NS_SUCCEEDED(rv))
{
nsCOMPtr<nsIOutputStream> out;
// this will fail with the mem cache turned off, so we need to fall through
// to ReadFromImapConnection instead of aborting with NS_ENSURE_SUCCESS(rv,rv)
rv = transport->OpenOutputStream(0, PRUint32(-1), 0, getter_AddRefs(out));
if (NS_SUCCEEDED(rv))
{
rv = tee->Init(m_channelListener, out);
m_channelListener = do_QueryInterface(tee);
}
rv = tee->Init(m_channelListener, out);
m_channelListener = do_QueryInterface(tee);
}
}
}
@ -7701,36 +7757,41 @@ nsresult nsImapMockChannel::ReadFromMemCache(nsICacheEntryDescriptor *entry)
}
if (shouldUseCacheEntry)
{
nsCOMPtr<nsITransport> cacheTransport;
rv = entry->GetTransport(getter_AddRefs(cacheTransport));
if (NS_SUCCEEDED(rv))
nsCOMPtr<nsIInputStream> in;
rv = entry->OpenInputStream(0, getter_AddRefs(in));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIInputStreamPump> pump;
rv = NS_NewInputStreamPump(getter_AddRefs(pump), in);
if (NS_FAILED(rv)) return rv;
// if we are going to read from the cache, then create a mock stream listener class and use it
nsImapCacheStreamListener * cacheListener = new nsImapCacheStreamListener();
NS_ADDREF(cacheListener);
cacheListener->Init(m_channelListener, NS_STATIC_CAST(nsIChannel *, this));
rv = pump->AsyncRead(cacheListener, m_channelContext);
NS_RELEASE(cacheListener);
if (NS_SUCCEEDED(rv)) // ONLY if we succeeded in actually starting the read should we return
{
// if we are going to read from the cache, then create a mock stream listener class and use it
nsImapCacheStreamListener * cacheListener = new nsImapCacheStreamListener();
NS_ADDREF(cacheListener);
cacheListener->Init(m_channelListener, NS_STATIC_CAST(nsIChannel *, this));
rv = cacheTransport->AsyncRead(cacheListener, m_channelContext, 0, PRUint32(-1), 0, getter_AddRefs(mCacheRequest));
NS_RELEASE(cacheListener);
mCacheRequest = pump;
if (NS_SUCCEEDED(rv)) // ONLY if we succeeded in actually starting the read should we return
{
nsCOMPtr<nsIImapUrl> imapUrl = do_QueryInterface(m_url);
nsCOMPtr<nsIImapUrl> imapUrl = do_QueryInterface(m_url);
// if the msg is unread, we should mark it read on the server. This lets
// the code running this url we're loading from the cache, if it cares.
imapUrl->SetMsgLoadingFromCache(PR_TRUE);
// if the msg is unread, we should mark it read on the server. This lets
// the code running this url we're loading from the cache, if it cares.
imapUrl->SetMsgLoadingFromCache(PR_TRUE);
// and force the url to remove its reference on the mock channel...this is to solve
// a nasty reference counting problem...
imapUrl->SetMockChannel(nsnull);
// and force the url to remove its reference on the mock channel...this is to solve
// a nasty reference counting problem...
imapUrl->SetMockChannel(nsnull);
// be sure to set the cache entry's security info status as our security info status...
nsCOMPtr<nsISupports> securityInfo;
entry->GetSecurityInfo(getter_AddRefs(securityInfo));
SetSecurityInfo(securityInfo);
return NS_OK;
} // if AsyncRead succeeded.
} // if get transport succeeded
// be sure to set the cache entry's security info status as our security info status...
nsCOMPtr<nsISupports> securityInfo;
entry->GetSecurityInfo(getter_AddRefs(securityInfo));
SetSecurityInfo(securityInfo);
return NS_OK;
} // if AsyncRead succeeded.
} // if contnet is not modified
else
rv = NS_ERROR_FAILURE; // content is modified so return an error so we try to open it the old fashioned way
@ -7791,13 +7852,13 @@ PRBool nsImapMockChannel::ReadFromLocalCache()
if (folder && NS_SUCCEEDED(rv))
{
// we want to create a file channel and read the msg from there.
nsCOMPtr<nsITransport> fileChannel;
nsCOMPtr<nsIInputStream> fileStream;
nsMsgKey msgKey = atoi(messageIdString);
PRUint32 size, offset;
rv = folder->GetOfflineFileTransport(msgKey, &offset, &size, getter_AddRefs(fileChannel));
rv = folder->GetOfflineFileStream(msgKey, &offset, &size, getter_AddRefs(fileStream));
// get the file channel from the folder, somehow (through the message or
// folder sink?) We also need to set the transfer offset to the message offset
if (fileChannel && NS_SUCCEEDED(rv))
if (fileStream && NS_SUCCEEDED(rv))
{
// dougt - This may break the ablity to "cancel" a read from offline mail reading.
// fileChannel->SetLoadGroup(m_loadGroup);
@ -7809,8 +7870,13 @@ PRBool nsImapMockChannel::ReadFromLocalCache()
nsImapCacheStreamListener * cacheListener = new nsImapCacheStreamListener();
NS_ADDREF(cacheListener);
cacheListener->Init(m_channelListener, NS_STATIC_CAST(nsIChannel *, this));
nsCOMPtr<nsIRequest> request;
rv = fileChannel->AsyncRead(cacheListener, m_channelContext, offset, size, 0, getter_AddRefs(request));
// create a stream pump that will async read the specified amount of data.
nsCOMPtr<nsIInputStreamPump> pump;
rv = NS_NewInputStreamPump(getter_AddRefs(pump), fileStream, offset, size);
if (NS_SUCCEEDED(rv))
rv = pump->AsyncRead(cacheListener, m_channelContext);
NS_RELEASE(cacheListener);
if (NS_SUCCEEDED(rv)) // ONLY if we succeeded in actually starting the read should we return
@ -8082,3 +8148,26 @@ nsImapMockChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotification
return NS_OK;
}
NS_IMETHODIMP
nsImapMockChannel::OnTransportStatus(nsITransport *transport, nsresult status,
PRUint32 progress, PRUint32 progressMax)
{
if (mProgressEventSink && !(mLoadFlags & LOAD_BACKGROUND))
{
// these transport events should not generate any status messages
if (status == nsISocketTransport::STATUS_RECEIVING_FROM ||
status == nsISocketTransport::STATUS_SENDING_TO)
{
mProgressEventSink->OnProgress(this, nsnull, progress, progressMax);
}
else
{
nsCAutoString host;
if (m_url)
m_url->GetHost(host);
mProgressEventSink->OnStatus(this, nsnull, status, NS_ConvertUTF8toUCS2(host).get());
}
}
return NS_OK;
}

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

@ -51,7 +51,8 @@
#include "nsIProgressEventSink.h"
#include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsITransport.h"
#include "nsISocketTransport.h"
#include "nsIInputStreamPump.h"
// imap event sinks
#include "nsIImapMailFolderSink.h"
@ -390,16 +391,18 @@ private:
nsCAutoString m_trashFolderName;
// Ouput stream for writing commands to the socket
nsCOMPtr<nsITransport> m_channel;
nsCOMPtr<nsIOutputStream> m_outputStream; // this will be obtained from the transport interface
nsCOMPtr<nsIInputStream> m_inputStream;
nsCOMPtr<nsISocketTransport> m_transport;
nsCOMPtr<nsIOutputStream> m_outputStream; // this will be obtained from the transport interface
nsCOMPtr<nsIInputStream> m_inputStream;
nsCOMPtr<nsIInputStreamPump> m_pump;
PRBool m_pumpSuspended;
nsCOMPtr<nsIInputStream> m_channelInputStream;
nsCOMPtr<nsIOutputStream> m_channelOutputStream;
nsCOMPtr<nsIStreamListener> m_channelListener; // if we are displaying an article this is the rfc-822 display sink...
nsCOMPtr<nsISupports> m_channelContext;
nsCOMPtr<nsIImapMockChannel> m_mockChannel; // this is the channel we should forward to people
nsCOMPtr<nsIRequest> mAsyncReadRequest; // we're going to cancel this when we're done with the conn.
//nsCOMPtr<nsIRequest> mAsyncReadRequest; // we're going to cancel this when we're done with the conn.
// this is a method designed to buffer data coming from the input stream and efficiently extract out
@ -669,7 +672,9 @@ private:
class nsICacheEntryDescriptor;
class nsImapMockChannel : public nsIImapMockChannel, public nsICacheListener
class nsImapMockChannel : public nsIImapMockChannel
, public nsICacheListener
, public nsITransportEventSink
{
public:
@ -678,6 +683,7 @@ public:
NS_DECL_NSICHANNEL
NS_DECL_NSIREQUEST
NS_DECL_NSICACHELISTENER
NS_DECL_NSITRANSPORTEVENTSINK
nsImapMockChannel();
virtual ~nsImapMockChannel();

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

@ -42,6 +42,7 @@
#include "nsILineInputStream.h"
#include "nsReadableUtils.h"
#include "nsIPrefMigration.h"
#include "nsNetCID.h"
nsComm4xProfile::nsComm4xProfile()

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

@ -61,11 +61,10 @@
#include "nsFileStream.h"
PRLogModuleInfo *MAILBOX;
#include "nsIFileChannel.h"
#include "nsIFileStreams.h"
#include "nsIStreamTransportService.h"
#include "nsIStreamConverterService.h"
#include "nsIIOService.h"
#include "nsIFileTransportService.h"
#include "nsXPIDLString.h"
#include "nsNetUtil.h"
#include "nsIMsgWindow.h"
@ -128,12 +127,25 @@ NS_IMETHODIMP nsMailboxProtocol::GetContentLength(PRInt32 * aContentLength)
return NS_OK;
}
nsresult nsMailboxProtocol::OpenMultipleMsgTransport(PRUint32 offset, PRInt32 size)
{
nsresult rv;
NS_DEFINE_CID(kStreamTransportServiceCID, NS_STREAMTRANSPORTSERVICE_CID);
nsCOMPtr<nsIStreamTransportService> serv =
do_GetService(kStreamTransportServiceCID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = serv->CreateInputTransport(m_multipleMsgMoveCopyStream, offset, size, PR_FALSE, getter_AddRefs(m_transport));
return rv;
}
nsresult nsMailboxProtocol::OpenFileSocketForReuse(nsIURI * aURL, PRUint32 aStartPosition, PRInt32 aReadCount)
{
NS_ENSURE_ARG_POINTER(aURL);
nsresult rv = NS_OK;
m_startPosition = aStartPosition;
m_readCount = aReadCount;
nsCOMPtr <nsIFile> file;
@ -141,31 +153,16 @@ nsresult nsMailboxProtocol::OpenFileSocketForReuse(nsIURI * aURL, PRUint32 aStar
rv = GetFileFromURL(aURL, getter_AddRefs(file));
NS_ENSURE_SUCCESS(rv, rv);
NS_DEFINE_CID(kFileTransportServiceCID, NS_FILETRANSPORTSERVICE_CID);
nsCOMPtr<nsIFileTransportService> fts =
do_GetService(kFileTransportServiceCID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIFileInputStream> fileStream = do_CreateInstance(NS_LOCALFILEINPUTSTREAM_CONTRACTID, &rv);
nsCOMPtr<nsIFileInputStream> fileStream = do_CreateInstance(NS_LOCALFILEINPUTSTREAM_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
m_multipleMsgMoveCopyStream = do_QueryInterface(fileStream, &rv);
NS_ENSURE_SUCCESS(rv, rv);
fileStream->Init(file, PR_RDONLY, 0664, PR_FALSE); //just have to read the messages
PRUint32 length;
PRInt64 fileSize;
rv = file->GetFileSize( &fileSize);
LL_L2UI( length, fileSize );
// probably should pass in the file size instead of aReadCount
rv = fts->CreateTransportFromStream(NS_LITERAL_CSTRING("mailbox"),
m_multipleMsgMoveCopyStream,
NS_LITERAL_CSTRING(""),
NS_LITERAL_CSTRING(""),
length, PR_FALSE, getter_AddRefs(m_transport));
rv = OpenMultipleMsgTransport(aStartPosition, aReadCount);
m_socketIsOpen = PR_FALSE;
return rv;
}
@ -329,8 +326,32 @@ NS_IMETHODIMP nsMailboxProtocol::OnStopRequest(nsIRequest *request, nsISupports
// basically re-initialize the transport with the correct message size.
// then, we have to make sure the url keeps running somehow.
nsCOMPtr<nsISupports> urlSupports = do_QueryInterface(m_runningUrl);
//
// put us in a state where we are always notified of incoming data
rv = m_transport->AsyncRead(this, urlSupports, msgKey, msgSize, 0, getter_AddRefs(m_request));
//
m_transport = 0; // open new stream transport
m_inputStream = 0;
m_outputStream = 0;
rv = OpenMultipleMsgTransport(msgKey, msgSize);
if (NS_SUCCEEDED(rv))
{
if (!m_inputStream)
rv = m_transport->OpenInputStream(0, 0, 0, getter_AddRefs(m_inputStream));
if (NS_SUCCEEDED(rv))
{
nsCOMPtr<nsIInputStreamPump> pump;
rv = NS_NewInputStreamPump(getter_AddRefs(pump), m_inputStream);
if (NS_SUCCEEDED(rv)) {
rv = pump->AsyncRead(this, urlSupports);
if (NS_SUCCEEDED(rv))
m_request = pump;
}
}
}
NS_ASSERTION(NS_SUCCEEDED(rv), "AsyncRead failed");
if (m_loadGroup)
m_loadGroup->RemoveRequest(NS_STATIC_CAST(nsIRequest *, this), nsnull, aStatus);
@ -795,3 +816,4 @@ nsresult nsMailboxProtocol::CloseSocket()
return 0;
}
// vim: ts=2 sw=2

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

@ -127,6 +127,7 @@ private:
virtual nsresult CloseSocket();
PRInt32 SetupMessageExtraction();
nsresult OpenMultipleMsgTransport(PRUint32 offset, PRInt32 size);
nsresult OpenFileSocketForReuse(nsIURI * aURL, PRUint32 aStartPosition, PRInt32 aReadCount);
PRBool RunningMultipleMsgUrl();

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

@ -78,8 +78,6 @@ NS_IMPL_THREADSAFE_RELEASE(nsMimeBaseEmitter)
NS_INTERFACE_MAP_BEGIN(nsMimeBaseEmitter)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIMimeEmitter)
NS_INTERFACE_MAP_ENTRY(nsIMimeEmitter)
NS_INTERFACE_MAP_ENTRY(nsIInputStreamObserver)
NS_INTERFACE_MAP_ENTRY(nsIOutputStreamObserver)
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
NS_INTERFACE_MAP_END
@ -345,51 +343,6 @@ nsMimeBaseEmitter::LocalizeHeaderName(const char *aHeaderName, const char *aDefa
return nsCRT::strdup(aDefaultName);
}
///////////////////////////////////////////////////////////////////////////
// nsIPipeObserver Interface
///////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP nsMimeBaseEmitter::OnWrite(nsIOutputStream* out, PRUint32 aCount)
{
return NS_OK;
}
NS_IMETHODIMP nsMimeBaseEmitter::OnEmpty(nsIInputStream* in)
{
return NS_OK;
}
NS_IMETHODIMP nsMimeBaseEmitter::OnFull(nsIOutputStream* out)
{
// the pipe is full so we should flush our data to the converter's listener
// in order to make more room.
// since we only have one pipe per mime emitter, i can ignore the pipe param and use
// my outStream object directly (it will be the same thing as what we'd get from aPipe.
nsresult rv = NS_OK;
if (mOutListener && mInputStream)
{
PRUint32 bytesAvailable = 0;
rv = mInputStream->Available(&bytesAvailable);
NS_ASSERTION(NS_SUCCEEDED(rv), "Available failed");
nsCOMPtr<nsIRequest> request = do_QueryInterface(mChannel);
rv = mOutListener->OnDataAvailable(request, mURL, mInputStream, 0, bytesAvailable);
}
else
rv = NS_ERROR_NULL_POINTER;
return rv;
}
NS_IMETHODIMP nsMimeBaseEmitter::OnClose(nsIInputStream* in)
{
return NS_OK;
}
///////////////////////////////////////////////////////////////////////////
// nsMimeBaseEmitter Interface
///////////////////////////////////////////////////////////////////////////
@ -537,8 +490,7 @@ nsMimeBaseEmitter::Write(const char *buf, PRUint32 size, PRUint32 *amountWritten
// First, handle any old buffer data...
if (needToWrite > 0)
{
rv = mOutStream->Write(mBufferMgr->GetBuffer(),
needToWrite, &written);
rv = WriteHelper(mBufferMgr->GetBuffer(), needToWrite, &written);
mTotalWritten += written;
mBufferMgr->ReduceBuffer(written);
@ -556,7 +508,7 @@ nsMimeBaseEmitter::Write(const char *buf, PRUint32 size, PRUint32 *amountWritten
// if we get here, we are dealing with new data...try to write
// and then do the right thing...
rv = mOutStream->Write(buf, size, &written);
rv = WriteHelper(buf, size, &written);
*amountWritten = written;
mTotalWritten += written;
@ -566,6 +518,26 @@ nsMimeBaseEmitter::Write(const char *buf, PRUint32 size, PRUint32 *amountWritten
return rv;
}
nsresult
nsMimeBaseEmitter::WriteHelper(const char *buf, PRUint32 count, PRUint32 *countWritten)
{
nsresult rv;
rv = mOutStream->Write(buf, count, countWritten);
if (rv == NS_BASE_STREAM_WOULD_BLOCK) {
// pipe is full, push contents of pipe to listener...
PRUint32 avail;
rv = mInputStream->Available(&avail);
if (NS_SUCCEEDED(rv) && avail) {
mOutListener->OnDataAvailable(mChannel, mURL, mInputStream, 0, avail);
// try writing again...
rv = mOutStream->Write(buf, count, countWritten);
}
}
return rv;
}
//
// Find a cached header! Note: Do NOT free this value!
//

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

@ -44,8 +44,7 @@
#include "nsIStreamListener.h"
#include "nsIInputStream.h"
#include "nsIOutputStream.h"
#include "nsIObservableInputStream.h"
#include "nsIObservableOutputStream.h"
#include "nsIAsyncInputStream.h"
#include "nsIURI.h"
#include "nsIPref.h"
#include "nsIChannel.h"
@ -87,9 +86,7 @@ typedef struct {
} headerInfoType;
class nsMimeBaseEmitter : public nsIMimeEmitter,
public nsIInterfaceRequestor,
public nsIInputStreamObserver,
public nsIOutputStreamObserver
public nsIInterfaceRequestor
{
public:
nsMimeBaseEmitter ();
@ -99,8 +96,6 @@ public:
NS_DECL_ISUPPORTS
NS_DECL_NSIMIMEEMITTER
NS_DECL_NSIINPUTSTREAMOBSERVER
NS_DECL_NSIOUTPUTSTREAMOBSERVER
NS_DECL_NSIINTERFACEREQUESTOR
// Utility output functions...
@ -129,6 +124,8 @@ protected:
nsresult DumpRestOfHeaders();
nsresult OutputGenericHeader(const char *aHeaderVal);
nsresult WriteHelper(const char *buf, PRUint32 count, PRUint32 *countWritten);
// For string bundle usage...
nsCOMPtr<nsIStringBundle> m_stringBundle; // for translated strings
nsCOMPtr<nsIStringBundle> m_headerStringBundle; // for non-translated header strings

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

@ -1121,15 +1121,12 @@ mime_image_begin(const char *image_url, const char *content_type,
{
mailUrl->CacheCacheEntry(entry);
entry->MarkValid();
nsCOMPtr<nsITransport> transport;
rv = entry->GetTransport(getter_AddRefs(transport));
if (NS_FAILED(rv)) return nsnull;
// remember the content type as meta data so we can pull it out in the imap code
// to feed the cache entry directly to imglib w/o going through mime.
entry->SetMetaDataElement("contentType", content_type);
nsCOMPtr<nsIOutputStream> out;
rv = transport->OpenOutputStream(0, PRUint32(-1), 0, getter_AddRefs(mid->memCacheOutputStream));
rv = entry->OpenOutputStream(0, getter_AddRefs(mid->memCacheOutputStream));
if (NS_FAILED(rv)) return nsnull;
}
}

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

@ -70,8 +70,8 @@
#include "nsICategoryManager.h"
#include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsIObservableInputStream.h"
#include "nsIObservableOutputStream.h"
#include "nsIAsyncInputStream.h"
#include "nsIAsyncOutputStream.h"
#define PREF_MAIL_DISPLAY_GLYPH "mail.display_glyph"
#define PREF_MAIL_DISPLAY_STRUCT "mail.display_struct"
@ -699,22 +699,6 @@ NS_IMETHODIMP nsStreamConverter::Init(nsIURI *aURI, nsIStreamListener * aOutList
NS_STREAM_CONVERTER_BUFFER_SIZE,
PR_TRUE, PR_TRUE);
if (NS_SUCCEEDED(rv))
{
nsCOMPtr<nsIInputStreamObserver> inObs = do_GetInterface(mEmitter, &rv);
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIObservableInputStream> observableIn(do_QueryInterface(mInputStream, &rv));
if (NS_SUCCEEDED(rv))
observableIn->SetObserver(inObs);
}
nsCOMPtr<nsIOutputStreamObserver> outObs = do_GetInterface(mEmitter, &rv);
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIObservableOutputStream> observableOut(do_QueryInterface(mOutputStream, &rv));
if (NS_SUCCEEDED(rv))
observableOut->SetObserver(outObs);
}
}
// initialize our emitter
if (NS_SUCCEEDED(rv) && mEmitter)
{

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

@ -795,11 +795,15 @@ nsresult nsNNTPProtocol::ReadFromMemCache(nsICacheEntryDescriptor *entry)
{
NS_ENSURE_ARG(entry);
nsCOMPtr<nsITransport> cacheTransport;
nsresult rv = entry->GetTransport(getter_AddRefs(cacheTransport));
nsCOMPtr<nsIInputStream> cacheStream;
nsresult rv = entry->OpenInputStream(0, getter_AddRefs(cacheStream));
if (NS_SUCCEEDED(rv))
{
nsCOMPtr<nsIInputStreamPump> pump;
rv = NS_NewInputStreamPump(getter_AddRefs(pump), cacheStream);
if (NS_FAILED(rv)) return rv;
nsXPIDLCString group;
nsXPIDLCString commandSpecificData;
// do this to get m_key set, so that marking the message read will work.
@ -815,9 +819,9 @@ nsresult nsNNTPProtocol::ReadFromMemCache(nsICacheEntryDescriptor *entry)
nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(m_runningURL);
cacheListener->Init(m_channelListener, NS_STATIC_CAST(nsIChannel *, this), mailnewsUrl);
nsCOMPtr<nsIRequest> request;
m_ContentType = ""; // reset the content type for the upcoming read....
rv = cacheTransport->AsyncRead(cacheListener, m_channelContext, 0, PRUint32(-1), 0, getter_AddRefs(request));
rv = pump->AsyncRead(cacheListener, m_channelContext);
NS_RELEASE(cacheListener);
MarkCurrentMsgRead();
@ -857,23 +861,30 @@ PRBool nsNNTPProtocol::ReadFromLocalCache()
if (folder && NS_SUCCEEDED(rv))
{
// we want to create a file channel and read the msg from there.
nsCOMPtr<nsITransport> fileChannel;
nsCOMPtr<nsIInputStream> fileStream;
PRUint32 offset=0, size=0;
rv = folder->GetOfflineFileTransport(m_key, &offset, &size, getter_AddRefs(fileChannel));
rv = folder->GetOfflineFileStream(m_key, &offset, &size, getter_AddRefs(fileStream));
// get the file channel from the folder, somehow (through the message or
// get the file stream from the folder, somehow (through the message or
// folder sink?) We also need to set the transfer offset to the message offset
if (fileChannel && NS_SUCCEEDED(rv))
if (fileStream && NS_SUCCEEDED(rv))
{
// dougt - This may break the ablity to "cancel" a read from offline mail reading.
// fileChannel->SetLoadGroup(m_loadGroup);
m_typeWanted = ARTICLE_WANTED;
nsNntpCacheStreamListener * cacheListener = new nsNntpCacheStreamListener();
NS_ADDREF(cacheListener);
cacheListener->Init(m_channelListener, NS_STATIC_CAST(nsIChannel *, this), mailnewsUrl);
nsCOMPtr<nsIRequest> request;
rv = fileChannel->AsyncRead(cacheListener, m_channelContext, offset, size, 0, getter_AddRefs(request));
// create a stream pump that will async read the specified amount of data.
nsCOMPtr<nsIInputStreamPump> pump;
rv = NS_NewInputStreamPump(getter_AddRefs(pump),
fileStream, offset, size);
if (NS_SUCCEEDED(rv))
rv = pump->AsyncRead(cacheListener, m_channelContext);
NS_RELEASE(cacheListener);
MarkCurrentMsgRead();
@ -909,12 +920,8 @@ nsNNTPProtocol::OnCacheEntryAvailable(nsICacheEntryDescriptor *entry, nsCacheAcc
nsCOMPtr<nsIStreamListenerTee> tee = do_CreateInstance(kStreamListenerTeeCID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsITransport> transport;
rv = entry->GetTransport(getter_AddRefs(transport));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIOutputStream> out;
rv = transport->OpenOutputStream(0, PRUint32(-1), 0, getter_AddRefs(out));
rv = entry->OpenOutputStream(0, getter_AddRefs(out));
NS_ENSURE_SUCCESS(rv, rv);
rv = tee->Init(m_channelListener, out);

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

@ -37,16 +37,7 @@
#include "nsIChannel.idl"
interface nsISimpleEnumerator;
[scriptable, uuid(c7e410d1-85f2-11d3-9f63-006008a6efe9)]
interface nsIJARChannel : nsIChannel
{
/**
* Enumerates all the entries in the JAR (the root URI).
* ARGUMENTS:
* aRoot - a string representing the root dir to enumerate from
* or null to enumerate the whole thing.
*/
nsISimpleEnumerator EnumerateEntries(in string aRoot);
};

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -39,104 +39,70 @@
#define nsJARChannel_h__
#include "nsIJARChannel.h"
#include "nsIStreamListener.h"
#include "nsIJARProtocolHandler.h"
#include "nsIJARURI.h"
#include "nsIStreamIO.h"
#include "nsIChannel.h"
#include "nsIZipReader.h"
#include "nsIChannel.h"
#include "nsILoadGroup.h"
#include "nsIInputStreamPump.h"
#include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsCOMPtr.h"
#include "nsIFile.h"
#include "prmon.h"
#include "nsIProgressEventSink.h"
#include "nsIStreamListener.h"
#include "nsIDownloader.h"
#include "nsIInputStream.h"
#include "nsJARProtocolHandler.h"
#include "nsILoadGroup.h"
#include "nsIFile.h"
#include "nsIURI.h"
#include "nsCOMPtr.h"
#include "nsString.h"
#include "prlog.h"
#ifdef DEBUG
#include "prthread.h"
#endif
class nsJARInputThunk;
class nsIFileChannel;
class nsJARChannel;
//-----------------------------------------------------------------------------
#define NS_JARCHANNEL_CID \
{ /* 0xc7e410d5-0x85f2-11d3-9f63-006008a6efe9 */ \
0xc7e410d5, \
0x85f2, \
0x11d3, \
{0x9f, 0x63, 0x00, 0x60, 0x08, 0xa6, 0xef, 0xe9} \
}
class nsJARChannel : public nsIJARChannel,
public nsIStreamListener,
public nsIStreamIO,
public nsIDownloadObserver
class nsJARChannel : public nsIJARChannel
, public nsIDownloadObserver
, public nsIStreamListener
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIREQUEST
NS_DECL_NSICHANNEL
NS_DECL_NSIJARCHANNEL
NS_DECL_NSIDOWNLOADOBSERVER
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSIDOWNLOADOBSERVER
// NS_DECL_NSISTREAMIO and nsIChannel both define (attribute string contentType)
NS_IMETHOD Open();
NS_IMETHOD Close(nsresult status);
NS_IMETHOD GetInputStream(nsIInputStream * *aInputStream);
NS_IMETHOD GetOutputStream(nsIOutputStream * *aOutputStream);
NS_IMETHOD GetName(char * *aName);
nsJARChannel();
virtual ~nsJARChannel();
// Define a Create method to be used with a factory:
static NS_METHOD
Create(nsISupports* aOuter, REFNSIID aIID, void **aResult);
nsresult Init(nsIURI *uri);
nsresult Init(nsJARProtocolHandler* aHandler, nsIURI* uri);
nsresult EnsureJARFileAvailable();
nsresult OpenJARElement();
nsresult AsyncReadJARElement();
nsresult EnsureZipReader();
private:
nsresult CreateJarInput();
nsresult EnsureJarInput(PRBool blocking);
friend class nsJARDownloadObserver;
protected:
nsJARProtocolHandler* mJARProtocolHandler;
nsCOMPtr<nsIJARURI> mURI;
nsCOMPtr<nsILoadGroup> mLoadGroup;
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
nsCOMPtr<nsIURI> mOriginalURI;
nsLoadFlags mLoadFlags;
nsCOMPtr<nsISupports> mOwner;
nsCOMPtr<nsISupports> mUserContext;
nsCOMPtr<nsIStreamListener> mUserListener;
nsCString mContentType;
nsCString mContentCharset;
PRInt32 mContentLength;
nsCOMPtr<nsIURI> mJARBaseURI;
nsCString mJAREntry;
nsCOMPtr<nsIZipReader> mJAR;
nsCOMPtr<nsIFile> mDownloadedJARFile;
nsresult mStatus;
PRBool mSynchronousRead;
nsCOMPtr<nsIInputStream> mSynchronousInputStream;
nsCOMPtr<nsIDownloader> mDownloader;
nsCOMPtr<nsIRequest> mJarExtractionTransport;
#ifdef DEBUG
PRThread* mInitiator;
#if defined(PR_LOGGING)
nsCString mSpec;
#endif
nsCOMPtr<nsIJARURI> mJarURI;
nsCOMPtr<nsIURI> mOriginalURI;
nsCOMPtr<nsISupports> mOwner;
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
nsCOMPtr<nsIProgressEventSink> mProgressSink;
nsCOMPtr<nsILoadGroup> mLoadGroup;
nsCOMPtr<nsIStreamListener> mListener;
nsCOMPtr<nsISupports> mListenerContext;
nsCString mContentType;
nsCString mContentCharset;
PRInt32 mContentLength;
PRUint32 mLoadFlags;
nsresult mStatus;
PRBool mIsPending;
nsJARInputThunk *mJarInput;
nsCOMPtr<nsIInputStreamPump> mPump;
nsCOMPtr<nsIDownloader> mDownloader;
nsCOMPtr<nsIFile> mJarFile;
nsCOMPtr<nsIURI> mJarBaseURI;
nsCString mJarEntry;
};
#endif // nsJARChannel_h__

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

@ -52,12 +52,20 @@
static NS_DEFINE_CID(kZipReaderCacheCID, NS_ZIPREADERCACHE_CID);
#define NS_JAR_CACHE_SIZE 32
#define NS_JAR_CACHE_SIZE 32
////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
nsJARProtocolHandler *gJarHandler = nsnull;
nsJARProtocolHandler::nsJARProtocolHandler()
{
gJarHandler = this;
}
nsJARProtocolHandler::~nsJARProtocolHandler()
{
gJarHandler = nsnull;
}
nsresult
@ -74,17 +82,13 @@ nsJARProtocolHandler::Init()
return rv;
}
nsIMIMEService*
nsJARProtocolHandler::GetCachedMimeService()
nsIMIMEService *
nsJARProtocolHandler::MimeService()
{
if (!mMimeService) {
if (!mMimeService)
mMimeService = do_GetService(NS_MIMESERVICE_CONTRACTID);
}
return mMimeService.get();
}
nsJARProtocolHandler::~nsJARProtocolHandler()
{
return mMimeService.get();
}
NS_IMPL_THREADSAFE_ISUPPORTS3(nsJARProtocolHandler,
@ -124,7 +128,7 @@ nsJARProtocolHandler::GetJARCache(nsIZipReaderCache* *result)
NS_IMETHODIMP
nsJARProtocolHandler::GetScheme(nsACString &result)
{
result = "jar";
result = NS_LITERAL_CSTRING("jar");
return NS_OK;
}
@ -185,21 +189,20 @@ nsJARProtocolHandler::NewURI(const nsACString &aSpec,
}
NS_IMETHODIMP
nsJARProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result)
nsJARProtocolHandler::NewChannel(nsIURI *uri, nsIChannel **result)
{
nsresult rv;
nsJARChannel *chan = new nsJARChannel();
if (!chan)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(chan);
nsJARChannel* channel;
rv = nsJARChannel::Create(nsnull, NS_GET_IID(nsIJARChannel), (void**)&channel);
if (NS_FAILED(rv)) return rv;
rv = channel->Init(this, uri);
nsresult rv = chan->Init(uri);
if (NS_FAILED(rv)) {
NS_RELEASE(channel);
NS_RELEASE(chan);
return rv;
}
*result = channel;
*result = chan;
return NS_OK;
}

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

@ -35,8 +35,8 @@
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsJARProtocolHandler_h___
#define nsJARProtocolHandler_h___
#ifndef nsJARProtocolHandler_h__
#define nsJARProtocolHandler_h__
#include "nsIJARProtocolHandler.h"
#include "nsIProtocolHandler.h"
@ -46,15 +46,6 @@
#include "nsWeakReference.h"
#include "nsCOMPtr.h"
#define NS_JARPROTOCOLHANDLER_CID \
{ /* 0xc7e410d4-0x85f2-11d3-9f63-006008a6efe9 */ \
0xc7e410d4, \
0x85f2, \
0x11d3, \
{0x9f, 0x63, 0x00, 0x60, 0x08, 0xa6, 0xef, 0xe9} \
}
class nsJARProtocolHandler : public nsIJARProtocolHandler
, public nsSupportsWeakReference
{
@ -73,11 +64,14 @@ public:
nsresult Init();
// returns non addref'ed pointer.
nsIMIMEService* GetCachedMimeService();
nsIMIMEService *MimeService();
nsIZipReaderCache *JarCache() { return mJARCache; }
protected:
nsCOMPtr<nsIZipReaderCache> mJARCache;
nsCOMPtr<nsIMIMEService> mMimeService;
};
#endif /* nsJARProtocolHandler_h___ */
extern nsJARProtocolHandler *gJarHandler;
#endif // !nsJARProtocolHandler_h__

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

@ -24,14 +24,6 @@
#include "nsCOMPtr.h"
#include "nsString.h"
#define NS_JARURI_CID \
{ /* 0xc7e410d7-0x85f2-11d3-9f63-006008a6efe9 */ \
0xc7e410d7, \
0x85f2, \
0x11d3, \
{0x9f, 0x63, 0x00, 0x60, 0x08, 0xa6, 0xef, 0xe9} \
}
class nsJARURI : public nsIJARURI, nsISerializable
{
public:

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

@ -43,8 +43,8 @@
#include "nsDirectoryServiceDefs.h"
#include "nsICategoryManager.h"
#include "nsCategoryManagerUtils.h"
#include "nsNetUtil.h"
#include "nsIFile.h"
#include "nsIFileStreams.h"
#include "nsILocalFile.h"
#include "nsIObserverService.h"
#include "nsPrefBranch.h"

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

@ -29,11 +29,11 @@ include $(DEPTH)/config/autoconf.mk
DIRS = \
base \
cookie \
cache \
dns \
socket \
mime \
streamconv \
cache \
protocol \
build \
build2 \

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

@ -1,54 +0,0 @@
#
# This is a list of local files which get copied to the mozilla:dist directory
#
nsIAuthenticator.idl
nsIAuthPrompt.idl
nsIChannel.idl
nsIDirectoryListing.idl
nsIDownloader.idl
nsIEncodedChannel.idl
nsIFileURL.idl
nsIFileChannel.idl
nsIFileTransportService.idl
nsIMIMEInputStream.idl
nsIPasswordManager.idl
nsIPasswordManagerInternal.idl
nsIPrompt.idl
nsIProtocolProxyService.idl
nsIProxiedProtocolHandler.idl
nsIProxyAutoConfig.idl
nsIProxyInfo.idl
nsIProxy.idl
nsIRequest.idl
nsISocketTransportService.idl
nsIStreamIO.idl
nsIStreamIOChannel.idl
nsIStreamListener.idl
nsIStreamListenerProxy.idl
nsIStreamListenerTee.idl
nsIFileStreams.idl
nsITransport.idl
nsIStreamLoader.idl
nsIUnicharStreamLoader.idl
nsIDownloader.idl
nsIResumableChannel.idl
nsIResumableEntityID.idl
nsIRequestObserver.idl
nsIRequestObserverProxy.idl
nsISimpleStreamListener.idl
nsISimpleStreamProvider.idl
nsIStreamProvider.idl
nsIStreamProviderProxy.idl
nsIUploadChannel.idl
nsIURI.idl
nsIURIChecker.idl
nsIURL.idl
nsIURLParser.idl
nsIStandardURL.idl
nsIWebFilters.idl
nsISecurityEventSink.idl
nsISecretDecoderRing.idl
nsISecureBrowserUI.idl
nsIByteRangeRequest.idl
nsIMultiPartChannel.idl

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

@ -44,14 +44,15 @@ SDK_XPIDLSRCS = \
$(NULL)
XPIDLSRCS = \
nsIAuthenticator.idl \
nsIAuthPrompt.idl \
nsIAsyncStreamCopier.idl \
nsIBufferedStreams.idl \
nsIDirectoryListing.idl \
nsIDownloader.idl \
nsIEncodedChannel.idl \
nsIFileChannel.idl \
nsIFileStreams.idl \
nsIFileTransportService.idl \
nsIInputStreamPump.idl \
nsIInputStreamChannel.idl \
nsIMIMEInputStream.idl \
nsINetModRegEntry.idl \
nsINetModuleMgr.idl \
@ -68,23 +69,18 @@ XPIDLSRCS = \
nsITransport.idl \
nsISocketTransport.idl \
nsISocketTransportService.idl \
nsIStreamIO.idl \
nsIStreamIOChannel.idl \
nsIResumableChannel.idl \
nsIResumableEntityID.idl \
nsIRequestObserverProxy.idl \
nsIStreamListenerProxy.idl \
nsIStreamListenerTee.idl \
nsIStreamProvider.idl \
nsIStreamProviderProxy.idl \
nsISimpleStreamListener.idl \
nsISimpleStreamProvider.idl \
nsIStreamTransportService.idl \
nsIStreamLoader.idl \
nsIUnicharStreamLoader.idl \
nsIStandardURL.idl \
nsIURLParser.idl \
nsIURIChecker.idl \
nsIWebFilters.idl \
nsISecurityEventSink.idl \
nsISecretDecoderRing.idl \
nsISecureBrowserUI.idl \

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

@ -1,88 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* 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 the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Darin Fisher <darin@netscape.com>
*
* 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 NPL, 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 NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsIChannel.idl"
interface nsIFile;
/**
* nsIFileChannel is an interface that allows for the initialization
* of a simple nsIChannel that is constructed from a single nsIFile and
* associated content type.
*/
[scriptable, uuid(68a26506-f947-11d3-8cda-0060b0fc14a3)]
interface nsIFileChannel : nsIChannel
{
/**
* Values for ioFlags parameters to be or'd together.
* (From prio.h)
*/
const long NS_RDONLY = 0x01;
const long NS_WRONLY = 0x02;
const long NS_RDWR = 0x04;
const long NS_CREATE_FILE = 0x08;
const long NS_APPEND = 0x10;
const long NS_TRUNCATE = 0x20;
const long NS_SYNC = 0x40;
const long NS_EXCL = 0x80;
void init(in nsIFile file,
in long ioFlags,
in long perm);
readonly attribute nsIFile file;
attribute long ioFlags;
attribute long permissions;
};
%{C++
#define NS_LOCALFILECHANNEL_CLASSNAME "Local File Channel"
#define NS_LOCALFILECHANNEL_CONTRACTID "@mozilla.org/network/local-file-channel;1"
#define NS_LOCALFILECHANNEL_CID \
{ /* 6d5b2d44-f947-11d3-8cda-0060b0fc14a3 */ \
0x6d5b2d44, \
0xf947, \
0x11d3, \
{0x8c, 0xda, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
%}
////////////////////////////////////////////////////////////////////////////////

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

@ -37,7 +37,6 @@
#include "nsIInputStream.idl"
#include "nsIOutputStream.idl"
#include "nsISeekableStream.idl"
interface nsIFile;
@ -97,211 +96,3 @@ interface nsIFileOutputStream : nsIOutputStream
void init(in nsIFile file, in long ioFlags, in long perm,
in long behaviorFlags);
};
/**
* An input stream that reads ahead and keeps a buffer coming from another input
* stream so that fewer accesses to the underlying stream are necessary.
*/
[scriptable, uuid(616f5b48-da09-11d3-8cda-0060b0fc14a3)]
interface nsIBufferedInputStream : nsIInputStream
{
/**
* @param fillFromStream - add buffering to this stream
* @param bufferSize - specifies the maximum buffer size
*/
void init(in nsIInputStream fillFromStream,
in unsigned long bufferSize);
};
/**
* An output stream that stores up data to write out to another output stream
* and does the entire write only when the buffer is full, so that fewer writes
* to the underlying output stream are necessary.
*/
[scriptable, uuid(6476378a-da09-11d3-8cda-0060b0fc14a3)]
interface nsIBufferedOutputStream : nsIOutputStream
{
/**
* @param sinkToStream - add buffering to this stream
* @param bufferSize - specifies the maximum buffer size
*/
void init(in nsIOutputStream sinkToStream,
in unsigned long bufferSize);
};
%{C++
////////////////////////////////////////////////////////////////////////////////
#define NS_LOCALFILEINPUTSTREAM_CLASSNAME "Local File Input Stream"
#define NS_LOCALFILEINPUTSTREAM_CONTRACTID "@mozilla.org/network/file-input-stream;1"
#define NS_LOCALFILEINPUTSTREAM_CID \
{ /* be9a53ae-c7e9-11d3-8cda-0060b0fc14a3 */ \
0xbe9a53ae, \
0xc7e9, \
0x11d3, \
{0x8c, 0xda, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
#define NS_LOCALFILEOUTPUTSTREAM_CLASSNAME "Local File Output Stream"
#define NS_LOCALFILEOUTPUTSTREAM_CONTRACTID "@mozilla.org/network/file-output-stream;1"
#define NS_LOCALFILEOUTPUTSTREAM_CID \
{ /* c272fee0-c7e9-11d3-8cda-0060b0fc14a3 */ \
0xc272fee0, \
0xc7e9, \
0x11d3, \
{0x8c, 0xda, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
////////////////////////////////////////////////////////////////////////////////
#define NS_BUFFEREDINPUTSTREAM_CLASSNAME "Buffered Input Stream"
#define NS_BUFFEREDINPUTSTREAM_CONTRACTID "@mozilla.org/network/buffered-input-stream;1"
#define NS_BUFFEREDINPUTSTREAM_CID \
{ /* 9226888e-da08-11d3-8cda-0060b0fc14a3 */ \
0x9226888e, \
0xda08, \
0x11d3, \
{0x8c, 0xda, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
#define NS_BUFFEREDOUTPUTSTREAM_CLASSNAME "Buffered Output Stream"
#define NS_BUFFEREDOUTPUTSTREAM_CONTRACTID "@mozilla.org/network/buffered-output-stream;1"
#define NS_BUFFEREDOUTPUTSTREAM_CID \
{ /* 9868b4ce-da08-11d3-8cda-0060b0fc14a3 */ \
0x9868b4ce, \
0xda08, \
0x11d3, \
{0x8c, 0xda, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
////////////////////////////////////////////////////////////////////////////////
// move to nsNetUtil.h later...
#include "nsCOMPtr.h"
#include "nsIComponentManager.h"
#include "nsIFileChannel.h"
#include "nsIInputStream.h"
#include "nsIOutputStream.h"
#include "prio.h" // for read/write flags, permissions, etc.
// This will QI the file argument to an nsILocalFile in the Init method.
inline nsresult
NS_NewLocalFileChannel(nsIFileChannel** aResult,
nsIFile* aFile,
PRInt32 aIOFlags = -1,
PRInt32 aPerm = -1)
{
nsresult rv;
nsCOMPtr<nsIFileChannel> channel;
static NS_DEFINE_CID(kLocalFileChannelCID, NS_LOCALFILECHANNEL_CID);
rv = nsComponentManager::CreateInstance(kLocalFileChannelCID,
nsnull,
NS_GET_IID(nsIFileChannel),
getter_AddRefs(channel));
if (NS_FAILED(rv)) return rv;
rv = channel->Init(aFile, aIOFlags, aPerm);
if (NS_FAILED(rv)) return rv;
*aResult = channel;
NS_ADDREF(*aResult);
return NS_OK;
}
// This will QI the file argument to an nsILocalFile in the Init method.
inline nsresult
NS_NewLocalFileInputStream(nsIInputStream** aResult,
nsIFile* aFile,
PRInt32 aIOFlags = -1,
PRInt32 aPerm = -1,
PRInt32 aBehaviorFlags = 0)
{
nsresult rv;
nsCOMPtr<nsIFileInputStream> in;
static NS_DEFINE_CID(kLocalFileInputStreamCID, NS_LOCALFILEINPUTSTREAM_CID);
rv = nsComponentManager::CreateInstance(kLocalFileInputStreamCID,
nsnull,
NS_GET_IID(nsIFileInputStream),
getter_AddRefs(in));
if (NS_FAILED(rv)) return rv;
rv = in->Init(aFile, aIOFlags, aPerm, aBehaviorFlags);
if (NS_FAILED(rv)) return rv;
*aResult = in;
NS_ADDREF(*aResult);
return NS_OK;
}
// This will QI the file argument to an nsILocalFile in the Init method.
inline nsresult
NS_NewLocalFileOutputStream(nsIOutputStream** aResult,
nsIFile* aFile,
PRInt32 aIOFlags = -1,
PRInt32 aPerm = -1,
PRInt32 aBehaviorFlags = 0)
{
nsresult rv;
nsCOMPtr<nsIFileOutputStream> out;
static NS_DEFINE_CID(kLocalFileOutputStreamCID, NS_LOCALFILEOUTPUTSTREAM_CID);
rv = nsComponentManager::CreateInstance(kLocalFileOutputStreamCID,
nsnull,
NS_GET_IID(nsIFileOutputStream),
getter_AddRefs(out));
if (NS_FAILED(rv)) return rv;
rv = out->Init(aFile, aIOFlags, aPerm, aBehaviorFlags);
if (NS_FAILED(rv)) return rv;
*aResult = out;
NS_ADDREF(*aResult);
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
inline nsresult
NS_NewBufferedInputStream(nsIInputStream** aResult,
nsIInputStream* aStr,
PRUint32 aBufferSize)
{
nsresult rv;
nsCOMPtr<nsIBufferedInputStream> in;
static NS_DEFINE_CID(kBufferedInputStreamCID, NS_BUFFEREDINPUTSTREAM_CID);
rv = nsComponentManager::CreateInstance(kBufferedInputStreamCID,
nsnull,
NS_GET_IID(nsIBufferedInputStream),
getter_AddRefs(in));
if (NS_FAILED(rv)) return rv;
rv = in->Init(aStr, aBufferSize);
if (NS_FAILED(rv)) return rv;
*aResult = in;
NS_ADDREF(*aResult);
return NS_OK;
}
inline nsresult
NS_NewBufferedOutputStream(nsIOutputStream** aResult,
nsIOutputStream* aStr,
PRUint32 aBufferSize)
{
nsresult rv;
nsCOMPtr<nsIBufferedOutputStream> out;
static NS_DEFINE_CID(kBufferedOutputStreamCID, NS_BUFFEREDOUTPUTSTREAM_CID);
rv = nsComponentManager::CreateInstance(kBufferedOutputStreamCID,
nsnull,
NS_GET_IID(nsIBufferedOutputStream),
getter_AddRefs(out));
if (NS_FAILED(rv)) return rv;
rv = out->Init(aStr, aBufferSize);
if (NS_FAILED(rv)) return rv;
*aResult = out;
NS_ADDREF(*aResult);
return NS_OK;
}
%}

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

@ -37,59 +37,76 @@
#include "nsITransport.idl"
[scriptable, uuid(785CA0F0-C39E-11d3-9ED6-0010A4053FD0)]
interface nsIInterfaceRequestor;
interface nsISocketEventSink;
%{C++
#include "prio.h"
%}
[ptr] native PRNetAddrStar(PRNetAddr);
/**
* nsISocketTransport
*
* NOTE: This is a free-threaded interface.
*/
[scriptable, uuid(1e372001-ca12-4507-8405-3267d4e0c1fd)]
interface nsISocketTransport : nsITransport
{
/**
* Destination host and port. These are used for reporting status messages
* Since the end server may change at any time (eg persistent connections
* through proxies), a client can update this to get correct results.
* There is no other effect of setting these attributes, and if a proxy
* server is not being used, NS_ERROR_FAILURE is returned.
* Get the host for the underlying socket connection.
*/
attribute string host;
attribute long port;
readonly attribute AUTF8String host;
/**
* Get the port for the underlying socket connection.
*/
readonly attribute long port;
/**
* Get the PRNetAddr for the underlying socket connection.
*/
[noscript] void getAddress(in PRNetAddrStar addr);
/**
* Security info object returned from the PSM socket provider. This object
* supports nsISSLSocketControl, nsITransportSecurityInfo, and possibly
* other interfaces.
*/
readonly attribute nsISupports securityInfo;
/**
* Security notification callbacks passed to PSM via nsISSLSocketControl at
* socket creation time.
*
* NOTE: this attribute cannot be changed once a stream has been opened.
*/
attribute boolean reuseConnection;
attribute nsIInterfaceRequestor securityCallbacks;
/**
* socket read/write timeout in seconds; 0 = no timeout
* Test if this socket transport is (still) connected.
*/
attribute unsigned long socketTimeout;
boolean isAlive();
/**
* socket connect timeout in seconds; 0 = no timeout
* nsITransportEventSink status codes:
*/
attribute unsigned long socketConnectTimeout;
/**
* Is used to tell the channel to stop reading data after a certain point;
* needed by HTTP/1.1
*/
attribute long bytesExpected;
attribute unsigned long reuseCount;
/**
* Checks if the socket is still alive
*
* @param seconds amount of time after which the socket is always deemed to be
* dead (no further checking is done in this case); seconds = 0
* will cause it not to do the timeout checking at all
*/
boolean isAlive (in unsigned long seconds);
/**
* maximum amount of time in seconds the transport is allowed to stay alive
* while connected (0 - default; no maximum idle timeout)
*/
attribute unsigned long idleTimeout;
/**
* the string representation of the underlying ip address. Caller
* is responsible for de-allocating the returned string.
*/
[noscript] string GetIPStr(in unsigned long aStrLen);
const unsigned long STATUS_RESOLVING = 0x804b0003;
const unsigned long STATUS_CONNECTED_TO = 0x804b0004;
const unsigned long STATUS_SENDING_TO = 0x804b0005;
const unsigned long STATUS_RECEIVING_FROM = 0x804b0006;
const unsigned long STATUS_CONNECTING_TO = 0x804b0007;
const unsigned long STATUS_WAITING_FOR = 0x804b000a;
};
%{C++
/**
* #define's for compatibility
*/
#define NS_NET_STATUS_RESOLVING_HOST nsISocketTransport::STATUS_RESOLVING
#define NS_NET_STATUS_CONNECTED_TO nsISocketTransport::STATUS_CONNECTED_TO
#define NS_NET_STATUS_SENDING_TO nsISocketTransport::STATUS_SENDING_TO
#define NS_NET_STATUS_RECEIVING_FROM nsISocketTransport::STATUS_RECEIVING_FROM
#define NS_NET_STATUS_CONNECTING_TO nsISocketTransport::STATUS_CONNECTING_TO
%}

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

@ -37,9 +37,8 @@
#include "nsISupports.idl"
interface nsITransport;
interface nsIEventSinkGetter;
interface nsIChannel;
interface nsISocketTransport;
interface nsISocketEventHandler;
interface nsIProxyInfo;
[scriptable, uuid(05331390-6884-11d3-9382-00104ba0fd40)]
@ -48,86 +47,70 @@ interface nsISocketTransportService : nsISupports
/**
* Creates a transport for a specified host and port.
*
* @param proxyInfo Information about any transport-layer proxying. Used
* for communicating information about proxies like socks.
* This can either be the proxyInfo attribute on an
* nsISupportsTransparentProxy (or from the protocolProxyService),
* or null for no proxying.
* @param aSocketTypes
* array of socket type strings. null if using default socket type.
* @param aTypeCount
* specifies length of aSocketTypes.
* @param aHost
* specifies the target hostname or IP address literal of the peer
* for this socket.
* @param aPort
* specifies the target port of the peer for this socket.
* @param aProxyInfo
* specifies the transport-layer proxy type to use. null if no
* proxy. used for communicating information about proxies like
* SOCKS (which are transparent to upper protocols).
*
* @see nsISupportsTransparentProxy
* @see nsIProxiedProtocolHandler
* @see nsIProtocolProxyService::GetProxyInfo
*/
nsITransport createTransport(in string host,
in long port,
in nsIProxyInfo proxyInfo,
in unsigned long bufferSegmentSize,
in unsigned long bufferMaxSize);
nsITransport createTransportOfType(in string socketType,
in string host,
in long port,
in nsIProxyInfo proxyInfo,
in unsigned long bufferSegmentSize,
in unsigned long bufferMaxSize);
nsITransport createTransportOfTypes(in unsigned long typeCount,
[array, size_is(typeCount)] in string socketTypes,
in string host,
in long port,
in nsIProxyInfo proxyInfo,
in unsigned long bufferSegmentSize,
in unsigned long bufferMaxSize);
nsISocketTransport createTransport([array, size_is(aTypeCount)]
in string aSocketTypes,
in unsigned long aTypeCount,
in AUTF8String aHost,
in long aPort,
in nsIProxyInfo aProxyInfo);
/**
* Returns true if the specified transport is good enough for
* being used again. The situations in which this may return false
* include- an error including server resets, an explicit
* Connection: close header (for HTTP) and timeouts!
* init/shutdown routines.
*/
boolean reuseTransport(in nsITransport i_Transport);
void init ();
void init();
void shutdown();
void wakeup (in nsITransport i_Transport);
/**
* Total number of nsSocketTransport objects currently alive
*/
readonly attribute unsigned long totalTransportCount;
/**
* A number of nsSocketTransport objects with I/O operation currently in-progress
*/
readonly attribute unsigned long inUseTransportCount;
/**
* A number of nsSocketTransport objects connected (this may include keep-alive idle connections)
*/
readonly attribute unsigned long connectedTransportCount;
/**
* Autodial helper is enabled via pref.
* Post an event to be executed on the socket thread.
*
* @param aHandler
* handler that will be executed on the socket thread.
* @param aType
* caller defined message parameter
* @param aUParam
* caller defined message parameter
* @param aVParam
* caller defined message parameter
*
* The socket transport service treats each parameter as opaque data (i.e.,
* it is not responsible for cleaning up aVParam if it happens to be
* dynamically allocated). If this function succeeds, then the message
* will be delivered. All messages successfully posted will be delivered
* before the socket transport service shuts down.
*/
[noscript] void postEvent(in nsISocketEventHandler aHandler,
in unsigned long aType,
in unsigned long aUParam,
in voidPtr aVParam);
/**
* controls whether or not the socket transport service should poke
* the autodialer on connection failure.
*/
attribute boolean autodialEnabled;
};
%{C++
#define NS_SOCKETTRANSPORTSERVICE_CID \
{ /* c07e81e0-ef12-11d2-92b6-00105a1b0d64 */ \
0xc07e81e0, \
0xef12, \
0x11d2, \
{0x92, 0xb6, 0x00, 0x10, 0x5a, 0x1b, 0x0d, 0x64} \
}
#include "nsNetError.h"
/**
* Status nsresult codes: used with nsIProgressEventSink::OnStatus
*/
#define NS_NET_STATUS_RESOLVING_HOST NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 3)
#define NS_NET_STATUS_CONNECTED_TO NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 4)
#define NS_NET_STATUS_SENDING_TO NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 5)
#define NS_NET_STATUS_RECEIVING_FROM NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 6)
#define NS_NET_STATUS_CONNECTING_TO NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 7)
%}
[uuid(c20f98be-b3e4-4f9b-a492-97a688577355)]
interface nsISocketEventHandler : nsISupports
{
[noscript] void onSocketEvent(in unsigned long aType,
in unsigned long aUParam,
in voidPtr aVParam);
};

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

@ -1,88 +0,0 @@
/* ***** 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.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Darin Fisher <darin@netscape.com> (original author)
*
* 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 "nsIStreamListener.idl"
interface nsIEventQueue;
/**
* A stream listener proxy is used to ship data over to another thread specified
* by the thread's event queue. The "true" stream listener's methods are
* invoked on the other thread.
*
* This interface only provides the initialization needed after construction.
* Otherwise, these objects are used as nsIStreamListener.
*/
[scriptable, uuid(e400e688-6b54-4a84-8c4e-56b40281981a)]
interface nsIStreamListenerProxy : nsIStreamListener
{
/**
* Initializes an nsIStreamListenerProxy.
*
* @param aListener receives listener notifications on the other thread
* @param aEventQ may be NULL indicating the calling thread's event queue
* @param aBufferSegmentSize passing zero indicates the default
* @param aBufferMaxSize passing zero indicates the default
*/
void init(in nsIStreamListener aListener,
in nsIEventQueue aEventQ,
in unsigned long aBufferSegmentSize,
in unsigned long aBufferMaxSize);
};
/**
* THIS INTERFACE IS DEPRACATED
*
* An asynchronous stream listener is used to ship data over to another thread specified
* by the thread's event queue. The receiver stream listener is then used to receive
* the notifications on the other thread.
*
* This interface only provides the initialization needed after construction. Otherwise,
* these objects are used simply as nsIStreamListener.
*/
[scriptable, uuid(1b012ade-91bf-11d3-8cd9-0060b0fc14a3)]
interface nsIAsyncStreamListener : nsIStreamListener
{
/**
* Initializes an nsIAsyncStreamListener.
*
* @param aReceiver receives listener notifications on the other thread
* @param aEventQ may be null indicating the calling thread's event queue
*/
void init(in nsIStreamListener aReceiver,
in nsIEventQueue aEventQ);
};

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

@ -1,25 +1,25 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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/
* 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 Original Code is Mozilla.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Darin Fisher <darin@netscape.com>
*
* 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
@ -27,121 +27,112 @@
* 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 NPL, indicate your
* 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 NPL, the GPL or the LGPL.
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
#include "nsIRequest.idl"
interface nsIStreamListener;
interface nsIStreamProvider;
interface nsIInputStream;
interface nsIOutputStream;
interface nsIInterfaceRequestor;
interface nsITransportEventSink;
interface nsIEventQueue;
[scriptable, uuid(fd01f9a4-d492-4cf8-b76e-160ffc8c01e8)]
[scriptable, uuid(cbb0baeb-5fcb-408b-a2be-9f8fc98d0af1)]
interface nsITransport : nsISupports
{
/**
* Get security info for this transport.
* Open flags.
*/
readonly attribute nsISupports securityInfo;
/**
* Get/set notificationCallbacks for this transport.
*/
nsIInterfaceRequestor getNotificationCallbacks();
void setNotificationCallbacks(in nsIInterfaceRequestor callbacks,
in unsigned long flags);
/**
* If the notificationCallbacks provide a nsIProgressEventSink
* implementation, then progress is by default reported to the thread
* that called setNotificationCallbacks. The following flags provide
* finer control over progress notifications:
*
* DONT_REPORT_PROGRESS - progress notifications are not sent.
* DONT_PROXY_PROGRESS - progress notifications can occur on any thread.
*/
const unsigned long DONT_REPORT_PROGRESS = 1;
const unsigned long DONT_PROXY_PROGRESS = 2;
const unsigned long OPEN_BLOCKING = 1<<0;
const unsigned long OPEN_UNBUFFERED = 1<<1;
/**
* Open an input stream on this transport.
*
* @param offset - read starting at this offset
* @param count - read this many bytes (pass PRUint32(-1) if unlimited)
* @param flags - optional transport specific flags
* @param aFlags
* optional transport specific flags.
* @param aSegmentSize
* if OPEN_UNBUFFERED is not set, then this parameter specifies the
* size of each buffer segment (pass 0 to use default value).
* @param aSegmentCount
* if OPEN_UNBUFFERED is not set, then this parameter specifies the
* maximum number of buffer segments (pass 0 to use default value).
*/
nsIInputStream openInputStream(in unsigned long offset,
in unsigned long count,
in unsigned long flags);
nsIInputStream openInputStream(in unsigned long aFlags,
in unsigned long aSegmentSize,
in unsigned long aSegmentCount);
/**
* Open an output stream on this transport.
*
* @param offset - write starting at this offset
* @param count - write no more than this many bytes (pass PRUint32(-1) if unlimited)
* @param flags - optional transport specific flags
* @param aFlags
* optional transport specific flags.
* @param aSegmentSize
* if OPEN_UNBUFFERED is not set, then this parameter specifies the
* size of each buffer segment (pass 0 to use default value).
* @param aSegmentCount
* if OPEN_UNBUFFERED is not set, then this parameter specifies the
* maximum number of buffer segments (pass 0 to use default value).
*/
nsIOutputStream openOutputStream(in unsigned long offset,
in unsigned long count,
in unsigned long flags);
nsIOutputStream openOutputStream(in unsigned long aFlags,
in unsigned long aSegmentSize,
in unsigned long aSegmentCount);
/**
* Asynchronously read data from the transport.
* Close the transport and any open streams.
*
* @param listener - notify this listener when data is available
* @param ctxt - opaque parameter passed to listener methods
* @param offset - read starting at this offset
* @param count - read this many bytes (pass PRUint32(-1) if unlimited)
* @param flags - optional transport specific flags
* @param aReason
* the reason for closing the stream.
*/
nsIRequest asyncRead(in nsIStreamListener listener,
in nsISupports ctxt,
in unsigned long offset,
in unsigned long count,
in unsigned long flags);
void close(in nsresult aReason);
/**
* Asynchronously write data to the transport.
* Set the transport event sink.
*
* @param provider - notify this provider when data can be written
* @param ctxt - opaque parameter passed to provider methods
* @param offset - write starting at this offset
* @param count - write no more than this many bytes (pass PRUint32(-1) if unlimited)
* @param flags - optional transport specific flags
* @param aSink
* receives transport layer notifications
* @param aEventQ
* indicates the event queue to which the notifications should
* be delivered. if NULL, then the notifications may occur on
* any thread. (NOTE: the event queue must be resolved.)
*/
nsIRequest asyncWrite(in nsIStreamProvider provider,
in nsISupports ctxt,
in unsigned long offset,
in unsigned long count,
in unsigned long flags);
void setEventSink(in nsITransportEventSink aSink,
in nsIEventQueue aEventQ);
/**
* Callbacks from asyncRead and asyncWrite may be proxied from a
* background thread (if one exists) to the thread which initiated
* the request. This is the expected behavior of such a nsITransport
* implementation. A caller of asyncRead or asyncWrite can explicitly
* ask the transport to not proxy the callback. The caller must then
* be prepared to handle callbacks on any thread.
* Generic nsITransportEventSink status codes. nsITransport
* implementations may override these status codes with their own more
* specific status codes (e.g., see nsISocketTransport).
*/
const unsigned long DONT_PROXY_OBSERVER = 1 << 0;
const unsigned long DONT_PROXY_LISTENER = 1 << 1;
const unsigned long DONT_PROXY_PROVIDER = 1 << 1;
const unsigned long STATUS_READING = 0x804b0008;
const unsigned long STATUS_WRITING = 0x804b0009;
};
[scriptable, uuid(d7abf5a4-ce72-482a-9217-a219a905c019)]
interface nsITransportRequest : nsIRequest
[scriptable, uuid(561de8af-1b74-4cd4-8479-89447d48185c)]
interface nsITransportEventSink : nsISupports
{
/**
* Get the transport associated with this request.
* Transport status notification.
*
* @param aTransport
* the transport sending this status notification.
* @param aStatus
* the transport status (resolvable to a string using
* nsIErrorService).
* @param aProgress
* the amount of data either read or written depending on the value
* of the status code. this value is relative to aProgressMax.
* @param aProgressMax
* the maximum amount of data that will be read or written. if
* unknown, 0xFFFFFFFF will be passed.
*/
readonly attribute nsITransport transport;
void onTransportStatus(in nsITransport aTransport,
in nsresult aStatus,
in unsigned long aProgress,
in unsigned long aProgressMax);
};

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

@ -38,47 +38,46 @@
#ifndef nsNetUtil_h__
#define nsNetUtil_h__
#include "nsString.h"
#include "nsNetError.h"
#include "nsNetCID.h"
#include "nsReadableUtils.h"
#include "netCore.h"
#include "nsString.h"
#include "nsMemory.h"
#include "nsCOMPtr.h"
#include "prio.h" // for read/write flags, permissions, etc.
#include "nsIURI.h"
#include "nsIInputStream.h"
#include "nsIOutputStream.h"
#include "nsIStreamListener.h"
#include "nsIStreamProvider.h"
#include "nsIRequestObserverProxy.h"
#include "nsIStreamListenerProxy.h"
#include "nsIStreamProviderProxy.h"
#include "nsIStreamListenerProxy.h" // XXX for nsIAsyncStreamListener
#include "nsISimpleStreamListener.h"
#include "nsISimpleStreamProvider.h"
#include "nsILoadGroup.h"
#include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsIIOService.h"
#include "nsIServiceManager.h"
#include "nsIChannel.h"
#include "nsIStreamIOChannel.h"
#include "nsIInputStreamChannel.h"
#include "nsITransport.h"
#include "nsIHttpChannel.h"
#include "nsMemory.h"
#include "nsCOMPtr.h"
#include "nsIDownloader.h"
#include "nsIResumableEntityID.h"
#include "nsIStreamLoader.h"
#include "nsIUnicharStreamLoader.h"
#include "nsIStreamIO.h"
#include "nsIPipe.h"
#include "nsIProtocolHandler.h"
#include "nsIFileProtocolHandler.h"
#include "nsIStringStream.h"
#include "nsILocalFile.h"
#include "nsIFileStreams.h"
#include "nsXPIDLString.h"
#include "nsIProtocolProxyService.h"
#include "nsIProxyInfo.h"
#include "prio.h" // for read/write flags, permissions, etc.
#include "nsNetCID.h"
#include "nsIFileStreams.h"
#include "nsIBufferedStreams.h"
#include "nsIInputStreamPump.h"
#include "nsIAsyncStreamCopier.h"
// Helper, to simplify getting the I/O service.
inline const nsGetServiceByCID
@ -289,77 +288,79 @@ NS_MakeAbsoluteURI(nsAString &result,
}
inline nsresult
NS_NewPostDataStream(nsIInputStream **result,
PRBool isFile,
const nsACString &data,
PRUint32 encodeFlags,
nsIIOService* ioService = nsnull) // pass in nsIIOService to optimize callers
NS_NewInputStreamChannel(nsIChannel **result,
nsIURI *uri,
nsIInputStream *stream,
const nsACString &contentType = NS_LITERAL_CSTRING(""),
const nsACString &contentCharset = NS_LITERAL_CSTRING(""))
{
nsresult rv;
if (isFile) {
nsCOMPtr<nsILocalFile> file;
nsCOMPtr<nsIInputStream> fileStream;
rv = NS_NewNativeLocalFile(data, PR_FALSE, getter_AddRefs(file));
if (NS_FAILED(rv)) return rv;
rv = NS_NewLocalFileInputStream(getter_AddRefs(fileStream), file);
if (NS_FAILED(rv)) return rv;
// wrap the file stream with a buffered input stream
return NS_NewBufferedInputStream(result, fileStream, 8192);
}
// otherwise, create a string stream for the data
return NS_NewCStringInputStream(result, data);
}
inline nsresult
NS_NewStreamIOChannel(nsIStreamIOChannel **result,
nsIURI* uri,
nsIStreamIO* io)
{
nsresult rv;
nsCOMPtr<nsIStreamIOChannel> channel;
static NS_DEFINE_CID(kStreamIOChannelCID, NS_STREAMIOCHANNEL_CID);
rv = nsComponentManager::CreateInstance(kStreamIOChannelCID,
nsnull,
NS_GET_IID(nsIStreamIOChannel),
getter_AddRefs(channel));
if (NS_FAILED(rv)) return rv;
rv = channel->Init(uri, io);
static NS_DEFINE_CID(kInputStreamChannelCID, NS_INPUTSTREAMCHANNEL_CID);
nsCOMPtr<nsIInputStreamChannel> channel =
do_CreateInstance(kInputStreamChannelCID, &rv);
if (NS_FAILED(rv)) return rv;
*result = channel;
NS_ADDREF(*result);
rv = channel->SetURI(uri);
if (NS_FAILED(rv)) return rv;
rv = channel->SetContentStream(stream);
if (NS_FAILED(rv)) return rv;
rv = channel->SetContentType(contentType);
if (NS_FAILED(rv)) return rv;
rv = channel->SetContentCharset(contentCharset);
if (NS_FAILED(rv)) return rv;
NS_ADDREF(*result = channel);
return NS_OK;
}
inline nsresult
NS_NewInputStreamChannel(nsIChannel **result,
nsIURI* uri,
nsIInputStream* inStr,
const nsACString &contentType,
const nsACString &contentCharset,
PRInt32 contentLength)
NS_NewInputStreamPump(nsIInputStreamPump **result,
nsIInputStream *stream,
PRInt32 streamPos = -1,
PRInt32 streamLen = -1,
PRUint32 segsize = 0,
PRUint32 segcount = 0,
PRBool closeWhenDone = PR_FALSE)
{
nsresult rv;
nsCAutoString spec;
rv = uri->GetSpec(spec);
static NS_DEFINE_CID(kInputStreamPumpCID, NS_INPUTSTREAMPUMP_CID);
nsCOMPtr<nsIInputStreamPump> pump =
do_CreateInstance(kInputStreamPumpCID, &rv);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIInputStreamIO> io;
rv = NS_NewInputStreamIO(getter_AddRefs(io), spec, inStr,
contentType, contentCharset, contentLength);
rv = pump->Init(stream, streamPos, streamLen,
segsize, segcount, closeWhenDone);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIStreamIOChannel> channel;
rv = NS_NewStreamIOChannel(getter_AddRefs(channel), uri, io);
NS_ADDREF(*result = pump);
return NS_OK;
}
// NOTE: you can optimize the copy by specifying whether or not your streams
// are buffered (i.e., do they implement ReadSegments/WriteSegments). the
// default assumption of FALSE for both streams is OK, but the copy is much
// more efficient if one of the streams is buffered.
inline nsresult
NS_NewAsyncStreamCopier(nsIAsyncStreamCopier **result,
nsIInputStream *source,
nsIOutputStream *sink,
PRBool sourceBuffered = PR_FALSE,
PRBool sinkBuffered = PR_FALSE,
PRUint32 chunkSize = 0)
{
nsresult rv;
static NS_DEFINE_CID(kAsyncStreamCopierCID, NS_ASYNCSTREAMCOPIER_CID);
nsCOMPtr<nsIAsyncStreamCopier> copier =
do_CreateInstance(kAsyncStreamCopierCID, &rv);
if (NS_FAILED(rv)) return rv;
*result = channel;
NS_ADDREF(*result);
rv = copier->Init(source, sink, sourceBuffered, sinkBuffered, chunkSize);
if (NS_FAILED(rv)) return rv;
NS_ADDREF(*result = copier);
return NS_OK;
}
@ -505,58 +506,6 @@ NS_NewRequestObserverProxy(nsIRequestObserver **aResult,
return CallQueryInterface(proxy, aResult);
}
inline nsresult
NS_NewStreamListenerProxy(nsIStreamListener **aResult,
nsIStreamListener *aListener,
nsIEventQueue *aEventQ=nsnull,
PRUint32 aBufferSegmentSize=0,
PRUint32 aBufferMaxSize=0)
{
NS_ENSURE_ARG_POINTER(aResult);
nsresult rv;
nsCOMPtr<nsIStreamListenerProxy> proxy;
static NS_DEFINE_CID(kStreamListenerProxyCID, NS_STREAMLISTENERPROXY_CID);
rv = nsComponentManager::CreateInstance(kStreamListenerProxyCID,
nsnull,
NS_GET_IID(nsIStreamListenerProxy),
getter_AddRefs(proxy));
if (NS_FAILED(rv)) return rv;
rv = proxy->Init(aListener, aEventQ, aBufferSegmentSize, aBufferMaxSize);
if (NS_FAILED(rv)) return rv;
NS_ADDREF(*aResult = proxy);
return NS_OK;
}
inline nsresult
NS_NewStreamProviderProxy(nsIStreamProvider **aResult,
nsIStreamProvider *aProvider,
nsIEventQueue *aEventQ=nsnull,
PRUint32 aBufferSegmentSize=0,
PRUint32 aBufferMaxSize=0)
{
NS_ENSURE_ARG_POINTER(aResult);
nsresult rv;
nsCOMPtr<nsIStreamProviderProxy> proxy;
static NS_DEFINE_CID(kStreamProviderProxyCID, NS_STREAMPROVIDERPROXY_CID);
rv = nsComponentManager::CreateInstance(kStreamProviderProxyCID,
nsnull,
NS_GET_IID(nsIStreamProviderProxy),
getter_AddRefs(proxy));
if (NS_FAILED(rv)) return rv;
rv = proxy->Init(aProvider, aEventQ, aBufferSegmentSize, aBufferMaxSize);
if (NS_FAILED(rv)) return rv;
NS_ADDREF(*aResult = proxy);
return NS_OK;
}
inline nsresult
NS_NewSimpleStreamListener(nsIStreamListener **aResult,
nsIOutputStream *aSink,
@ -580,53 +529,7 @@ NS_NewSimpleStreamListener(nsIStreamListener **aResult,
return NS_OK;
}
inline nsresult
NS_NewSimpleStreamProvider(nsIStreamProvider **aResult,
nsIInputStream *aSource,
nsIRequestObserver *aObserver=nsnull)
{
NS_ENSURE_ARG_POINTER(aResult);
nsresult rv;
nsCOMPtr<nsISimpleStreamProvider> provider;
static NS_DEFINE_CID(kSimpleStreamProviderCID, NS_SIMPLESTREAMPROVIDER_CID);
rv = nsComponentManager::CreateInstance(kSimpleStreamProviderCID,
nsnull,
NS_GET_IID(nsISimpleStreamProvider),
getter_AddRefs(provider));
if (NS_FAILED(rv)) return rv;
rv = provider->Init(aSource, aObserver);
if (NS_FAILED(rv)) return rv;
NS_ADDREF(*aResult = provider);
return NS_OK;
}
/*
// Depracated, prefer NS_NewStreamObserverProxy
inline nsresult
NS_NewAsyncStreamObserver(nsIRequestObserver **result,
nsIRequestObserver *receiver,
nsIEventQueue *eventQueue)
{
nsresult rv;
nsCOMPtr<nsIAsyncStreamObserver> obs;
static NS_DEFINE_CID(kAsyncStreamObserverCID, NS_ASYNCSTREAMOBSERVER_CID);
rv = nsComponentManager::CreateInstance(kAsyncStreamObserverCID,
nsnull,
NS_GET_IID(nsIAsyncStreamObserver),
getter_AddRefs(obs));
if (NS_FAILED(rv)) return rv;
rv = obs->Init(receiver, eventQueue);
if (NS_FAILED(rv)) return rv;
NS_ADDREF(*result = obs);
return NS_OK;
}
*/
// Depracated, prefer NS_NewStreamListenerProxy
// Deprecated, prefer NS_NewStreamListenerProxy
inline nsresult
NS_NewAsyncStreamListener(nsIStreamListener **result,
nsIStreamListener *receiver,
@ -647,106 +550,6 @@ NS_NewAsyncStreamListener(nsIStreamListener **result,
return NS_OK;
}
// Depracated, prefer a true synchonous implementation
inline nsresult
NS_NewSyncStreamListener(nsIInputStream **aInStream,
nsIOutputStream **aOutStream,
nsIStreamListener **aResult)
{
nsresult rv;
NS_ENSURE_ARG_POINTER(aInStream);
NS_ENSURE_ARG_POINTER(aOutStream);
nsCOMPtr<nsIInputStream> pipeIn;
nsCOMPtr<nsIOutputStream> pipeOut;
rv = NS_NewPipe(getter_AddRefs(pipeIn),
getter_AddRefs(pipeOut),
4*1024, // NS_SYNC_STREAM_LISTENER_SEGMENT_SIZE
32*1024); // NS_SYNC_STREAM_LISTENER_BUFFER_SIZE
if (NS_FAILED(rv)) return rv;
rv = NS_NewSimpleStreamListener(aResult, pipeOut);
if (NS_FAILED(rv)) return rv;
NS_ADDREF(*aInStream = pipeIn);
NS_ADDREF(*aOutStream = pipeOut);
return NS_OK;
}
//
// Calls AsyncWrite on the specified transport, with a stream provider that
// reads data from the specified input stream.
//
inline nsresult
NS_AsyncWriteFromStream(nsIRequest **aRequest,
nsITransport *aTransport,
nsIInputStream *aSource,
PRUint32 aOffset=0,
PRUint32 aCount=0,
PRUint32 aFlags=0,
nsIRequestObserver *aObserver=NULL,
nsISupports *aContext=NULL)
{
NS_ENSURE_ARG_POINTER(aTransport);
nsresult rv;
nsCOMPtr<nsIStreamProvider> provider;
rv = NS_NewSimpleStreamProvider(getter_AddRefs(provider),
aSource,
aObserver);
if (NS_FAILED(rv)) return rv;
//
// We can safely allow the transport impl to bypass proxying the provider
// since we are using a simple stream provider.
//
// A simple stream provider masks the OnDataWritable from consumers.
// Moreover, it makes an assumption about the underlying nsIInputStream
// implementation: namely, that it is thread-safe and blocking.
//
// So, let's always make this optimization.
//
aFlags |= nsITransport::DONT_PROXY_PROVIDER;
return aTransport->AsyncWrite(provider, aContext,
aOffset,
aCount,
aFlags,
aRequest);
}
//
// Calls AsyncRead on the specified transport, with a stream listener that
// writes data to the specified output stream.
//
inline nsresult
NS_AsyncReadToStream(nsIRequest **aRequest,
nsITransport *aTransport,
nsIOutputStream *aSink,
PRUint32 aOffset=0,
PRUint32 aCount=0,
PRUint32 aFlags=0,
nsIRequestObserver *aObserver=NULL,
nsISupports *aContext=NULL)
{
NS_ENSURE_ARG_POINTER(aTransport);
nsresult rv;
nsCOMPtr<nsIStreamListener> listener;
rv = NS_NewSimpleStreamListener(getter_AddRefs(listener),
aSink,
aObserver);
if (NS_FAILED(rv)) return rv;
return aTransport->AsyncRead(listener, aContext,
aOffset,
aCount,
aFlags,
aRequest);
}
inline nsresult
NS_CheckPortSafety(PRInt32 port, const char* scheme, nsIIOService* ioService = nsnull)
{
@ -903,5 +706,119 @@ NS_ParseContentType(const nsACString &rawContentType,
return NS_OK;
}
#endif // nsNetUtil_h__
inline nsresult
NS_NewLocalFileInputStream(nsIInputStream** aResult,
nsIFile* aFile,
PRInt32 aIOFlags = -1,
PRInt32 aPerm = -1,
PRInt32 aBehaviorFlags = 0)
{
nsresult rv;
nsCOMPtr<nsIFileInputStream> in;
static NS_DEFINE_CID(kLocalFileInputStreamCID, NS_LOCALFILEINPUTSTREAM_CID);
rv = nsComponentManager::CreateInstance(kLocalFileInputStreamCID,
nsnull,
NS_GET_IID(nsIFileInputStream),
getter_AddRefs(in));
if (NS_FAILED(rv)) return rv;
rv = in->Init(aFile, aIOFlags, aPerm, aBehaviorFlags);
if (NS_FAILED(rv)) return rv;
*aResult = in;
NS_ADDREF(*aResult);
return NS_OK;
}
inline nsresult
NS_NewLocalFileOutputStream(nsIOutputStream** aResult,
nsIFile* aFile,
PRInt32 aIOFlags = -1,
PRInt32 aPerm = -1,
PRInt32 aBehaviorFlags = 0)
{
nsresult rv;
nsCOMPtr<nsIFileOutputStream> out;
static NS_DEFINE_CID(kLocalFileOutputStreamCID, NS_LOCALFILEOUTPUTSTREAM_CID);
rv = nsComponentManager::CreateInstance(kLocalFileOutputStreamCID,
nsnull,
NS_GET_IID(nsIFileOutputStream),
getter_AddRefs(out));
if (NS_FAILED(rv)) return rv;
rv = out->Init(aFile, aIOFlags, aPerm, aBehaviorFlags);
if (NS_FAILED(rv)) return rv;
*aResult = out;
NS_ADDREF(*aResult);
return NS_OK;
}
inline nsresult
NS_NewBufferedInputStream(nsIInputStream** aResult,
nsIInputStream* aStr,
PRUint32 aBufferSize)
{
nsresult rv;
nsCOMPtr<nsIBufferedInputStream> in;
static NS_DEFINE_CID(kBufferedInputStreamCID, NS_BUFFEREDINPUTSTREAM_CID);
rv = nsComponentManager::CreateInstance(kBufferedInputStreamCID,
nsnull,
NS_GET_IID(nsIBufferedInputStream),
getter_AddRefs(in));
if (NS_FAILED(rv)) return rv;
rv = in->Init(aStr, aBufferSize);
if (NS_FAILED(rv)) return rv;
*aResult = in;
NS_ADDREF(*aResult);
return NS_OK;
}
inline nsresult
NS_NewBufferedOutputStream(nsIOutputStream** aResult,
nsIOutputStream* aStr,
PRUint32 aBufferSize)
{
nsresult rv;
nsCOMPtr<nsIBufferedOutputStream> out;
static NS_DEFINE_CID(kBufferedOutputStreamCID, NS_BUFFEREDOUTPUTSTREAM_CID);
rv = nsComponentManager::CreateInstance(kBufferedOutputStreamCID,
nsnull,
NS_GET_IID(nsIBufferedOutputStream),
getter_AddRefs(out));
if (NS_FAILED(rv)) return rv;
rv = out->Init(aStr, aBufferSize);
if (NS_FAILED(rv)) return rv;
*aResult = out;
NS_ADDREF(*aResult);
return NS_OK;
}
inline nsresult
NS_NewPostDataStream(nsIInputStream **result,
PRBool isFile,
const nsACString &data,
PRUint32 encodeFlags,
nsIIOService* ioService = nsnull) // pass in nsIIOService to optimize callers
{
nsresult rv;
if (isFile) {
nsCOMPtr<nsILocalFile> file;
nsCOMPtr<nsIInputStream> fileStream;
rv = NS_NewNativeLocalFile(data, PR_FALSE, getter_AddRefs(file));
if (NS_FAILED(rv)) return rv;
rv = NS_NewLocalFileInputStream(getter_AddRefs(fileStream), file);
if (NS_FAILED(rv)) return rv;
// wrap the file stream with a buffered input stream
return NS_NewBufferedInputStream(result, fileStream, 8192);
}
// otherwise, create a string stream for the data
return NS_NewCStringInputStream(result, data);
}
#endif // nsNetUtil_h__

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

@ -39,14 +39,15 @@ REQUIRES = xpcom \
$(NULL)
CPPSRCS = \
nsAsyncStreamCopier.cpp \
nsAsyncStreamListener.cpp \
nsBufferedStreams.cpp \
nsDirectoryIndexStream.cpp \
nsDownloader.cpp \
nsFileStreams.cpp \
nsFileTransport.cpp \
nsFileTransportService.cpp \
nsInputStreamChannel.cpp \
nsInputStreamPump.cpp \
nsStreamTransportService.cpp \
nsIOService.cpp \
nsLoadGroup.cpp \
nsMIMEInputStream.cpp \
@ -56,17 +57,13 @@ CPPSRCS = \
nsRequestObserverProxy.cpp \
nsResumableEntityID.cpp \
nsSimpleStreamListener.cpp \
nsSimpleStreamProvider.cpp \
nsSimpleURI.cpp \
nsStandardURL.cpp \
nsSocketTransport.cpp \
nsSocketTransportService.cpp \
nsStorageTransport.cpp \
nsStreamListenerProxy.cpp \
nsSocketTransport2.cpp \
nsSocketTransportService2.cpp \
nsStreamListenerTee.cpp \
nsStreamLoader.cpp \
nsUnicharStreamLoader.cpp \
nsStreamProviderProxy.cpp \
nsURIChecker.cpp \
nsURLHelper.cpp \
nsURLParsers.cpp \

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

@ -38,9 +38,10 @@
#ifndef nsBufferedStreams_h__
#define nsBufferedStreams_h__
#include "nsIFileStreams.h"
#include "nsIBufferedStreams.h"
#include "nsIInputStream.h"
#include "nsIOutputStream.h"
#include "nsISeekableStream.h"
#include "nsIStreamBufferAccess.h"
#include "nsCOMPtr.h"

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

@ -44,55 +44,60 @@
#include "nsICachingChannel.h"
#include "nsProxiedService.h"
#include "nsIFile.h"
#include "nsIFileURL.h"
#include "nsXPIDLString.h"
static NS_DEFINE_CID(kProxyObjectManagerCID, NS_PROXYEVENT_MANAGER_CID);
// XXX this API seems all wrong for "sync" downloading
NS_IMETHODIMP
nsDownloader::Init(nsIURI* aURL,
nsIDownloadObserver* aObserver,
nsISupports* aContext,
PRBool aIsSynchronous,
nsILoadGroup* aGroup,
nsIInterfaceRequestor* aNotificationCallbacks,
nsLoadFlags aLoadAttributes)
nsIInterfaceRequestor* aCallbacks,
nsLoadFlags aLoadFlags)
{
NS_ENSURE_ARG_POINTER(aObserver);
nsresult rv;
mObserver = aObserver;
mContext = aContext;
nsCOMPtr<nsIFile> localFile;
nsCOMPtr<nsIChannel> channel;
rv = NS_NewChannel(getter_AddRefs(channel), aURL, nsnull, aGroup, aNotificationCallbacks,
aLoadAttributes);
if (NS_SUCCEEDED(rv) && channel)
{
nsCOMPtr<nsIFileChannel> fc = do_QueryInterface(channel);
if (fc)
rv = fc->GetFile(getter_AddRefs(localFile));
}
if (mObserver && (NS_FAILED(rv) || localFile))
{
if (aIsSynchronous)
return mObserver->OnDownloadComplete(this, mContext, rv, localFile);
else
{
// If the open failed or the file is local, call the observer.
// don't callback synchronously as it puts the caller
// in a recursive situation and breaks the asynchronous
// semantics of nsIDownloader
nsresult rv2 = NS_OK;
nsCOMPtr<nsIProxyObjectManager> pIProxyObjectManager =
do_GetService(kProxyObjectManagerCID, &rv);
if (NS_FAILED(rv2)) return rv2;
nsCOMPtr<nsIDownloadObserver> pObserver;
rv2 = pIProxyObjectManager->GetProxyForObject(NS_CURRENT_EVENTQ,
NS_GET_IID(nsIDownloadObserver), mObserver,
PROXY_ASYNC | PROXY_ALWAYS, getter_AddRefs(pObserver));
if (NS_FAILED(rv2)) return rv2;
return pObserver->OnDownloadComplete(this, mContext, rv, localFile);
}
nsCOMPtr<nsIFile> file;
nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(aURL);
if (fileURL)
fileURL->GetFile(getter_AddRefs(file));
if (file) {
if (aIsSynchronous)
return mObserver->OnDownloadComplete(this, mContext, rv, file);
// If the open failed or the file is local, call the observer.
// don't callback synchronously as it puts the caller
// in a recursive situation and breaks the asynchronous
// semantics of nsIDownloader
nsCOMPtr<nsIProxyObjectManager> pIProxyObjectManager =
do_GetService(kProxyObjectManagerCID, &rv);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIDownloadObserver> pObserver;
rv = pIProxyObjectManager->GetProxyForObject(NS_CURRENT_EVENTQ,
NS_GET_IID(nsIDownloadObserver), mObserver,
PROXY_ASYNC | PROXY_ALWAYS, getter_AddRefs(pObserver));
if (NS_FAILED(rv)) return rv;
return pObserver->OnDownloadComplete(this, mContext, NS_OK, file);
}
nsCOMPtr<nsIChannel> channel;
rv = NS_NewChannel(getter_AddRefs(channel), aURL, nsnull,
aGroup, aCallbacks, aLoadFlags);
if (NS_FAILED(rv)) return rv;
return channel->AsyncOpen(this, aContext);
}

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

@ -71,7 +71,8 @@
#include "nsDirectoryIndexStream.h"
#include "nsMimeTypes.h"
#include "nsReadLine.h"
#include "nsFileTransportService.h"
#include "nsNetUtil.h"
//#include "nsFileTransportService.h"
#define NS_NO_INPUT_BUFFERING 1 // see http://bugzilla.mozilla.org/show_bug.cgi?id=41067
@ -91,308 +92,6 @@ PRLogModuleInfo* gFileIOLog = nsnull;
#endif /* PR_LOGGING */
////////////////////////////////////////////////////////////////////////////////
// nsFileIO
#define NS_INPUT_STREAM_BUFFER_SIZE (16 * 1024)
#define NS_OUTPUT_STREAM_BUFFER_SIZE (64 * 1024)
NS_IMPL_THREADSAFE_ISUPPORTS2(nsFileIO,
nsIFileIO,
nsIStreamIO)
nsFileIO::nsFileIO()
: mFD(0),
mIOFlags(0),
mPerm(0),
mStatus(NS_OK)
{
#if defined(PR_LOGGING)
//
// Initialize the global PRLogModule for socket transport logging
// if necessary...
//
if (nsnull == gFileIOLog) {
gFileIOLog = PR_NewLogModule("nsFileIO");
}
#endif /* PR_LOGGING */
}
nsFileIO::~nsFileIO()
{
(void)Close(NS_OK);
if (mFD) {
PR_Close(mFD);
mFD = nsnull;
}
}
NS_METHOD
nsFileIO::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
nsFileIO* io = new nsFileIO();
if (io == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(io);
nsresult rv = io->QueryInterface(aIID, aResult);
NS_RELEASE(io);
return rv;
}
NS_IMETHODIMP
nsFileIO::Init(nsIFile* file, PRInt32 ioFlags, PRInt32 perm)
{
NS_ASSERTION(file, "File must not be null");
if (file == nsnull)
return NS_ERROR_NOT_INITIALIZED;
mFile = file;
mIOFlags = ioFlags;
mPerm = perm;
#ifdef PR_LOGGING
nsresult rv = mFile->GetNativePath(mSpec);
NS_ASSERTION(NS_SUCCEEDED(rv), "GetSpec failed");
#endif
return NS_OK;
}
NS_IMETHODIMP
nsFileIO::GetFile(nsIFile* *aFile)
{
*aFile = mFile;
NS_ADDREF(*aFile);
return NS_OK;
}
NS_IMETHODIMP
nsFileIO::Open()
{
NS_ASSERTION(mFile, "File must not be null");
if (mFile == nsnull)
return NS_ERROR_NOT_INITIALIZED;
nsresult rv = NS_OK;
nsCOMPtr<nsILocalFile> localFile = do_QueryInterface(mFile, &rv);
if (NS_FAILED(rv)) return rv;
if (mIOFlags == -1)
mIOFlags = PR_RDONLY;
if (mPerm == -1)
mPerm = 0;
rv = localFile->OpenNSPRFileDesc(mIOFlags, mPerm, &mFD);
if (NS_FAILED(rv)) {
mFD = nsnull; // just in case
#ifdef PR_LOGGING
nsresult openError = rv;
#endif
// maybe we can't open this because it is a directory...
PRBool isDir;
rv = localFile->IsDirectory(&isDir);
if (NS_SUCCEEDED(rv) && isDir) {
return NS_OK;
}
PR_LOG(gFileIOLog, PR_LOG_DEBUG,
("nsFileIO: OpenNSPRFileDesc failed [rv=%x]\n", openError));
return NS_ERROR_FILE_NOT_FOUND;
}
PR_LOG(gFileIOLog, PR_LOG_DEBUG,
("nsFileIO: logically opening %s", mSpec.get()));
return rv;
}
NS_IMETHODIMP
nsFileIO::GetContentType(nsACString &result)
{
if (!mContentType.IsEmpty()) {
result = mContentType;
return NS_OK;
}
if (mFile == nsnull)
return NS_ERROR_NOT_INITIALIZED;
nsresult rv = NS_OK;
nsIMIMEService* mimeServ = nsnull;
nsFileTransportService* fileTransportService = nsFileTransportService::GetInstance();
if (fileTransportService) {
mimeServ = fileTransportService->GetCachedMimeService();
if (mimeServ) {
nsXPIDLCString mimeType; // XXX fix mime service to use |ACString|
rv = mimeServ->GetTypeFromFile(mFile, getter_Copies(mimeType));
if (NS_SUCCEEDED(rv))
result = mimeType;
}
}
if (!mimeServ || (NS_FAILED(rv))) {
// if all else fails treat it as text/html?
result = NS_LITERAL_CSTRING(UNKNOWN_CONTENT_TYPE);
}
mContentType = result;
return NS_OK;
}
NS_IMETHODIMP
nsFileIO::GetContentCharset(nsACString &result)
{
result.Truncate();
return NS_OK;
}
NS_IMETHODIMP
nsFileIO::GetContentLength(PRInt32 *result)
{
NS_ENSURE_ARG_POINTER(result);
*result = -1;
if (!mFile)
return NS_ERROR_NOT_INITIALIZED;
// We'll try to use the file's length, if it has one. If not,
// assume the file to be special, and set the content length
// to -1, which means "read the stream until exhausted".
PRInt64 size;
nsresult rv = mFile->GetFileSize(&size);
if (NS_SUCCEEDED(rv)) {
*result = nsInt64(size);
if (*result == 0)
*result = -1;
}
return rv;
}
NS_IMETHODIMP
nsFileIO::Close(nsresult status)
{
if (mFile) {
PR_LOG(gFileIOLog, PR_LOG_DEBUG,
("nsFileIO: logically closing %s: status=%x",
mSpec.get(), status));
mFile = nsnull;
}
mStatus = status;
return NS_OK;
}
NS_IMETHODIMP
nsFileIO::GetInputStream(nsIInputStream * *aInputStream)
{
NS_ASSERTION(mFile, "File must not be null");
if (!mFile)
return NS_ERROR_NOT_INITIALIZED;
nsresult rv;
if (!mFD) {
rv = Open();
if (NS_FAILED(rv)) // file or directory does not exist
return rv;
}
PRBool isDir;
rv = mFile->IsDirectory(&isDir);
if (NS_FAILED(rv)) // file or directory does not exist
return rv;
if (isDir) {
if (mFD) {
PR_Close(mFD);
mFD = nsnull;
}
rv = nsDirectoryIndexStream::Create(mFile, aInputStream);
PR_LOG(gFileIOLog, PR_LOG_DEBUG,
("nsFileIO: opening local dir %s for input (%x)",
mSpec.get(), rv));
return rv;
}
nsFileInputStream* fileIn = new nsFileInputStream();
if (fileIn == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(fileIn);
rv = fileIn->InitWithFileDescriptor(mFD, this);
if (NS_SUCCEEDED(rv)) {
#ifdef NS_NO_INPUT_BUFFERING
*aInputStream = fileIn;
NS_ADDREF(*aInputStream);
#else
rv = NS_NewBufferedInputStream(aInputStream,
fileIn,
NS_INPUT_STREAM_BUFFER_SIZE);
#endif
}
NS_RELEASE(fileIn);
PR_LOG(gFileIOLog, PR_LOG_DEBUG,
("nsFileIO: opening local file %s for input (%x)",
mSpec.get(), rv));
return rv;
}
NS_IMETHODIMP
nsFileIO::GetOutputStream(nsIOutputStream * *aOutputStream)
{
NS_ASSERTION(mFile, "File must not be null");
if (mFile == nsnull)
return NS_ERROR_NOT_INITIALIZED;
nsresult rv;
if (!mFD) {
rv = Open();
if (NS_FAILED(rv)) // file or directory does not exist
return rv;
}
PRBool isDir;
rv = mFile->IsDirectory(&isDir);
if (NS_SUCCEEDED(rv) && isDir) {
return NS_ERROR_FAILURE;
}
nsFileOutputStream* fileOut = new nsFileOutputStream();
if (fileOut == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(fileOut);
rv = fileOut->InitWithFileDescriptor(mFD, this);
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIOutputStream> bufStr;
#ifdef NS_NO_OUTPUT_BUFFERING
*aOutputStream = fileOut;
NS_ADDREF(*aOutputStream);
#else
rv = NS_NewBufferedOutputStream(aOutputStream,
fileOut,
NS_OUTPUT_STREAM_BUFFER_SIZE);
#endif
}
NS_RELEASE(fileOut);
PR_LOG(gFileIOLog, PR_LOG_DEBUG,
("nsFileIO: opening local file %s for output (%x)",
mSpec.get(), rv));
return rv;
}
NS_IMETHODIMP
nsFileIO::GetName(nsACString &aName)
{
NS_ASSERTION(mFile, "File must not be null");
if (mFile == nsnull)
return NS_ERROR_NOT_INITIALIZED;
nsAutoString path;
nsresult rv = mFile->GetPath(path);
if (NS_FAILED(rv)) return rv;
aName = NS_ConvertUCS2toUTF8(path);
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsFileStream

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

@ -40,44 +40,16 @@
#include "nsIFileStreams.h"
#include "nsIFile.h"
#include "nsIChannel.h"
#include "nsIInputStream.h"
#include "nsIOutputStream.h"
#include "nsISeekableStream.h"
#include "nsILineInputStream.h"
#include "nsIStreamIO.h"
#include "nsCOMPtr.h"
#include "nsReadLine.h"
#include "prlog.h"
////////////////////////////////////////////////////////////////////////////////
class nsFileIO : public nsIFileIO
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSISTREAMIO
NS_DECL_NSIFILEIO
nsFileIO();
virtual ~nsFileIO();
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
protected:
nsCOMPtr<nsIFile> mFile;
PRFileDesc* mFD;
PRInt32 mIOFlags;
PRInt32 mPerm;
nsresult mStatus;
nsCString mContentType;
#ifdef PR_LOGGING
nsCString mSpec;
#endif
};
////////////////////////////////////////////////////////////////////////////////
class nsFileStream : public nsISeekableStream
{
public:

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

@ -41,7 +41,6 @@
#include "nscore.h"
#include "nsIServiceManager.h"
#include "nsIEventQueueService.h"
#include "nsIFileTransportService.h"
#include "nsIURI.h"
#include "nsIStreamListener.h"
#include "prprf.h"
@ -53,7 +52,6 @@
#include "nsIErrorService.h"
#include "netCore.h"
#include "nsIObserverService.h"
#include "nsIHttpProtocolHandler.h"
#include "nsIPrefService.h"
#include "nsIPrefBranchInternal.h"
#include "nsIPrefLocalizedString.h"
@ -66,12 +64,14 @@
#include "nsEscape.h"
#include "nsNetCID.h"
#include "nsIRecyclingAllocator.h"
#include "nsISocketTransport.h"
#include "nsCRT.h"
#define PORT_PREF_PREFIX "network.security.ports."
#define PORT_PREF(x) PORT_PREF_PREFIX x
#define AUTODIAL_PREF "network.autodial-helper.enabled"
static NS_DEFINE_CID(kFileTransportService, NS_FILETRANSPORTSERVICE_CID);
static NS_DEFINE_CID(kStreamTransportServiceCID, NS_STREAMTRANSPORTSERVICE_CID);
static NS_DEFINE_CID(kSocketTransportServiceCID, NS_SOCKETTRANSPORTSERVICE_CID);
static NS_DEFINE_CID(kDNSServiceCID, NS_DNSSERVICE_CID);
static NS_DEFINE_CID(kErrorServiceCID, NS_ERRORSERVICE_CID);
@ -176,65 +176,52 @@ nsIOService::nsIOService()
nsresult
nsIOService::Init()
{
nsresult rv = NS_OK;
nsresult rv;
// Hold onto the eventQueue service. We do not want any eventqueues to go away
// when we shutdown until we process all remaining transports
if (NS_SUCCEEDED(rv))
mEventQueueService = do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv);
mEventQueueService = do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID);
if (NS_FAILED(rv))
NS_WARNING("failed to get event queue service");
// We need to get references to these services so that we can shut them
// down later. If we wait until the nsIOService is being shut down,
// GetService will fail at that point.
rv = nsServiceManager::GetService(kSocketTransportServiceCID,
NS_GET_IID(nsISocketTransportService),
getter_AddRefs(mSocketTransportService));
if (NS_FAILED(rv)) return rv;
rv = nsServiceManager::GetService(kFileTransportService,
NS_GET_IID(nsIFileTransportService),
getter_AddRefs(mFileTransportService));
if (NS_FAILED(rv)) return rv;
rv = nsServiceManager::GetService(kDNSServiceCID,
NS_GET_IID(nsIDNSService),
getter_AddRefs(mDNSService));
if (NS_FAILED(rv)) return rv;
rv = nsServiceManager::GetService(kProtocolProxyServiceCID,
NS_GET_IID(nsIProtocolProxyService),
getter_AddRefs(mProxyService));
if (NS_FAILED(rv)) return rv;
// XXX hack until xpidl supports error info directly (http://bugzilla.mozilla.org/show_bug.cgi?id=13423)
nsCOMPtr<nsIErrorService> errorService = do_GetService(kErrorServiceCID, &rv);
mSocketTransportService = do_GetService(kSocketTransportServiceCID, &rv);
if (NS_FAILED(rv))
return rv;
NS_WARNING("failed to get socket transport service");
rv = errorService->RegisterErrorStringBundle(NS_ERROR_MODULE_NETWORK, NECKO_MSGS_URL);
if (NS_FAILED(rv)) return rv;
rv = errorService->RegisterErrorStringBundleKey(NS_NET_STATUS_READ_FROM, "ReadFrom");
if (NS_FAILED(rv)) return rv;
rv = errorService->RegisterErrorStringBundleKey(NS_NET_STATUS_WROTE_TO, "WroteTo");
if (NS_FAILED(rv)) return rv;
rv = errorService->RegisterErrorStringBundleKey(NS_NET_STATUS_RESOLVING_HOST, "ResolvingHost");
if (NS_FAILED(rv)) return rv;
rv = errorService->RegisterErrorStringBundleKey(NS_NET_STATUS_CONNECTED_TO, "ConnectedTo");
if (NS_FAILED(rv)) return rv;
rv = errorService->RegisterErrorStringBundleKey(NS_NET_STATUS_SENDING_TO, "SendingTo");
if (NS_FAILED(rv)) return rv;
rv = errorService->RegisterErrorStringBundleKey(NS_NET_STATUS_RECEIVING_FROM, "ReceivingFrom");
if (NS_FAILED(rv)) return rv;
rv = errorService->RegisterErrorStringBundleKey(NS_NET_STATUS_CONNECTING_TO, "ConnectingTo");
if (NS_FAILED(rv)) return rv;
mStreamTransportService = do_GetService(kStreamTransportServiceCID, &rv);
if (NS_FAILED(rv))
NS_WARNING("failed to get stream transport service");
mDNSService = do_GetService(kDNSServiceCID, &rv);
if (NS_FAILED(rv))
NS_WARNING("failed to get DNS service");
mProxyService = do_GetService(kProtocolProxyServiceCID, &rv);
if (NS_FAILED(rv))
NS_WARNING("failed to get protocol proxy service");
// XXX hack until xpidl supports error info directly (bug 13423)
nsCOMPtr<nsIErrorService> errorService = do_GetService(kErrorServiceCID);
if (errorService) {
errorService->RegisterErrorStringBundle(NS_ERROR_MODULE_NETWORK, NECKO_MSGS_URL);
errorService->RegisterErrorStringBundleKey(nsISocketTransport::STATUS_RESOLVING, "ResolvingHost");
errorService->RegisterErrorStringBundleKey(nsISocketTransport::STATUS_CONNECTED_TO, "ConnectedTo");
errorService->RegisterErrorStringBundleKey(nsISocketTransport::STATUS_SENDING_TO, "SendingTo");
errorService->RegisterErrorStringBundleKey(nsISocketTransport::STATUS_RECEIVING_FROM, "ReceivingFrom");
errorService->RegisterErrorStringBundleKey(nsISocketTransport::STATUS_CONNECTING_TO, "ConnectingTo");
errorService->RegisterErrorStringBundleKey(nsISocketTransport::STATUS_WAITING_FOR, "WaitingFor");
}
else
NS_WARNING("failed to get error service");
// setup our bad port list stuff
for(int i=0; gBadPortList[i]; i++) {
for(int i=0; gBadPortList[i]; i++)
mRestrictedPortList.AppendElement(NS_REINTERPRET_CAST(void *, gBadPortList[i]));
}
// Further modifications to the port list come from prefs
nsCOMPtr<nsIPrefBranch> prefBranch;
@ -251,12 +238,13 @@ nsIOService::Init()
// Register for profile change notifications
nsCOMPtr<nsIObserverService> observerService =
do_GetService("@mozilla.org/observer-service;1");
NS_ASSERTION(observerService, "Failed to get observer service");
if (observerService) {
observerService->AddObserver(this, kProfileChangeNetTeardownTopic, PR_TRUE);
observerService->AddObserver(this, kProfileChangeNetRestoreTopic, PR_TRUE);
observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_TRUE);
}
else
NS_WARNING("failed to get observer service");
return NS_OK;
}
@ -266,47 +254,6 @@ nsIOService::~nsIOService()
{
}
NS_METHOD
nsIOService::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
static nsISupports *_rValue = nsnull;
nsresult rv;
NS_ENSURE_NO_AGGREGATION(aOuter);
if (_rValue)
{
NS_ADDREF (_rValue);
*aResult = _rValue;
return NS_OK;
}
nsIOService* _ios = new nsIOService();
if (_ios == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(_ios);
rv = _ios->Init();
if (NS_FAILED(rv))
{
delete _ios;
return rv;
}
rv = _ios->QueryInterface(aIID, aResult);
if (NS_FAILED(rv))
{
delete _ios;
return rv;
}
_rValue = NS_STATIC_CAST (nsISupports*, *aResult);
NS_RELEASE (_rValue);
_rValue = nsnull;
return rv;
}
NS_IMPL_THREADSAFE_ISUPPORTS3(nsIOService,
nsIIOService,
nsIObserver,
@ -481,8 +428,6 @@ nsIOService::NewChannelFromURI(nsIURI *aURI, nsIChannel **result)
{
nsresult rv;
NS_ENSURE_ARG_POINTER(aURI);
// If XPCOM shutdown has started, mProxyService could be null.
NS_ENSURE_TRUE(mProxyService, NS_ERROR_NOT_AVAILABLE);
NS_TIMELINE_MARK_URI("nsIOService::NewChannelFromURI(%s)", aURI);
nsCAutoString scheme;
@ -490,8 +435,11 @@ nsIOService::NewChannelFromURI(nsIURI *aURI, nsIChannel **result)
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIProxyInfo> pi;
rv = mProxyService->ExamineForProxy(aURI, getter_AddRefs(pi));
if (NS_FAILED(rv)) return rv;
if (mProxyService) {
rv = mProxyService->ExamineForProxy(aURI, getter_AddRefs(pi));
if (NS_FAILED(rv))
pi = 0;
}
nsCOMPtr<nsIProtocolHandler> handler;
@ -535,50 +483,56 @@ nsIOService::GetOffline(PRBool *offline)
NS_IMETHODIMP
nsIOService::SetOffline(PRBool offline)
{
nsCOMPtr<nsIObserverService>
observerService(do_GetService("@mozilla.org/observer-service;1"));
nsCOMPtr<nsIObserverService> observerService =
do_GetService("@mozilla.org/observer-service;1");
nsresult rv1 = NS_OK;
nsresult rv2 = NS_OK;
nsresult rv;
if (offline) {
NS_NAMED_LITERAL_STRING(offlineString, "offline");
mOffline = PR_TRUE; // indicate we're trying to shutdown
mOffline = PR_TRUE; // indicate we're trying to shutdown
// don't care if notification fails
if (observerService)
// this allows users to attempt a little cleanup before dns and socket transport are shut down.
(void)observerService->NotifyObservers(NS_STATIC_CAST(nsIIOService *, this),
"network:offline-about-to-go-offline",
offlineString.get());
// be sure to try and shutdown both (even if the first fails)
if (mDNSService)
rv1 = mDNSService->Shutdown(); // shutdown dns service first, because it has callbacks for socket transport
if (mSocketTransportService)
rv2 = mSocketTransportService->Shutdown();
if (NS_FAILED(rv1)) return rv1;
if (NS_FAILED(rv2)) return rv2;
if (observerService)
observerService->NotifyObservers(NS_STATIC_CAST(nsIIOService *, this),
"network:offline-about-to-go-offline",
offlineString.get());
// be sure to try and shutdown both (even if the first fails)...
// shutdown dns service first, because it has callbacks for socket transport
if (mDNSService) {
rv = mDNSService->Shutdown();
NS_ASSERTION(NS_SUCCEEDED(rv), "DNS service shutdown failed");
}
if (mSocketTransportService) {
rv = mSocketTransportService->Shutdown();
NS_ASSERTION(NS_SUCCEEDED(rv), "socket transport service shutdown failed");
}
// don't care if notification fails
if (observerService)
(void)observerService->NotifyObservers(NS_STATIC_CAST(nsIIOService *, this),
"network:offline-status-changed",
offlineString.get());
observerService->NotifyObservers(NS_STATIC_CAST(nsIIOService *, this),
"network:offline-status-changed",
offlineString.get());
}
else if (!offline && mOffline) {
// go online
if (mDNSService)
rv1 = mDNSService->Init();
if (NS_FAILED(rv2)) return rv1;
if (mSocketTransportService)
rv2 = mSocketTransportService->Init(); //XXX should we shutdown the dns service?
if (NS_FAILED(rv2)) return rv1;
if (mDNSService) {
rv = mDNSService->Init();
NS_ASSERTION(NS_SUCCEEDED(rv), "DNS service init failed");
}
if (mSocketTransportService) {
rv = mSocketTransportService->Init();
NS_ASSERTION(NS_SUCCEEDED(rv), "socket transport service init failed");
}
mOffline = PR_FALSE; // indicate success only AFTER we've
// brought up the services
// don't care if notification fails
if (observerService)
(void)observerService->NotifyObservers(NS_STATIC_CAST(nsIIOService *, this),
"network:offline-status-changed",
NS_LITERAL_STRING("online").get());
observerService->NotifyObservers(NS_STATIC_CAST(nsIIOService *, this),
"network:offline-status-changed",
NS_LITERAL_STRING("online").get());
}
return NS_OK;
}
@ -718,12 +672,13 @@ nsIOService::Observe(nsISupports *subject,
}
}
else if (!strcmp(topic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
(void)SetOffline(PR_TRUE);
if (mFileTransportService)
(void)mFileTransportService->Shutdown();
SetOffline(PR_TRUE);
if (mStreamTransportService)
mStreamTransportService->Shutdown();
// Break circular reference.
mProxyService = nsnull;
mProxyService = 0;
}
return NS_OK;
}

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

@ -42,7 +42,7 @@
#include "nsIIOService.h"
#include "nsVoidArray.h"
#include "nsISocketTransportService.h"
#include "nsIFileTransportService.h"
#include "nsIStreamTransportService.h"
#include "nsIDNSService.h"
#include "nsIProtocolProxyService.h"
#include "nsCOMPtr.h"
@ -103,7 +103,7 @@ protected:
PRPackedBool mOffline;
PRPackedBool mOfflineForProfileChange;
nsCOMPtr<nsISocketTransportService> mSocketTransportService;
nsCOMPtr<nsIFileTransportService> mFileTransportService;
nsCOMPtr<nsIStreamTransportService> mStreamTransportService;
nsCOMPtr<nsIDNSService> mDNSService;
nsCOMPtr<nsIProtocolProxyService> mProxyService;
nsCOMPtr<nsIEventQueueService> mEventQueueService;

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

@ -36,233 +36,140 @@
* ***** END LICENSE BLOCK ***** */
#include "nsInputStreamChannel.h"
#include "nsCOMPtr.h"
#include "nsIIOService.h"
#include "nsIServiceManager.h"
#include "nsIFileTransportService.h"
#include "nsXPIDLString.h"
#include "nsIStreamTransportService.h"
#include "nsIEventQueueService.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsITransport.h"
#include "nsNetUtil.h"
#include "nsCOMPtr.h"
#include "prlog.h"
static NS_DEFINE_CID(kFileTransportServiceCID, NS_FILETRANSPORTSERVICE_CID);
static NS_DEFINE_CID(kStreamTransportServiceCID, NS_STREAMTRANSPORTSERVICE_CID);
static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
////////////////////////////////////////////////////////////////////////////////
// nsInputStreamIO methods:
#if defined(PR_LOGGING)
//
// NSPR_LOG_MODULES=nsStreamChannel:5
//
static PRLogModuleInfo *gStreamChannelLog = nsnull;
#endif
NS_IMPL_THREADSAFE_ISUPPORTS2(nsInputStreamIO,
nsIInputStreamIO,
nsIStreamIO)
#define LOG(args) PR_LOG(gStreamChannelLog, PR_LOG_DEBUG, args)
#define LOG_ENABLED() PR_LOG_TEST(gStreamChannelLog, 4)
nsInputStreamIO::nsInputStreamIO()
: mContentLength(-1), mStatus(NS_OK)
//-----------------------------------------------------------------------------
// nsInputStreamChannel methods
//-----------------------------------------------------------------------------
nsInputStreamChannel::nsInputStreamChannel()
: mContentLength(-1)
, mLoadFlags(LOAD_NORMAL)
, mStatus(NS_OK)
{
#if defined(PR_LOGGING)
if (!gStreamChannelLog)
gStreamChannelLog = PR_NewLogModule("nsStreamChannel");
#endif
}
nsInputStreamChannel::~nsInputStreamChannel()
{
}
nsInputStreamIO::~nsInputStreamIO()
{
Close(NS_OK);
}
//-----------------------------------------------------------------------------
// nsInputStreamChannel::nsISupports
//-----------------------------------------------------------------------------
NS_METHOD
nsInputStreamIO::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
nsInputStreamIO* io = new nsInputStreamIO();
if (io == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(io);
nsresult rv = io->QueryInterface(aIID, aResult);
NS_RELEASE(io);
return rv;
}
NS_IMPL_ISUPPORTS5(nsInputStreamChannel,
nsIChannel,
nsIRequest,
nsIStreamListener,
nsIRequestObserver,
nsIInputStreamChannel)
//-----------------------------------------------------------------------------
// nsInputStreamChannel::nsIRequest
//-----------------------------------------------------------------------------
NS_IMETHODIMP
nsInputStreamIO::Init(const nsACString &name,
nsIInputStream* input,
const nsACString &contentType,
const nsACString &contentCharset,
PRInt32 contentLength)
{
mName = name;
mInputStream = input;
mContentLength = contentLength;
mContentCharset = contentCharset;
// mContentCharset is unchanged if not parsed
NS_ParseContentType(contentType, mContentType, mContentCharset);
return NS_OK;
}
NS_IMETHODIMP
nsInputStreamIO::Open()
{
return NS_OK;
}
NS_IMETHODIMP
nsInputStreamIO::GetContentType(nsACString &aContentType)
{
aContentType = mContentType;
return NS_OK;
}
NS_IMETHODIMP
nsInputStreamIO::GetContentCharset(nsACString &aContentCharset)
{
aContentCharset = mContentCharset;
return NS_OK;
}
NS_IMETHODIMP
nsInputStreamIO::GetContentLength(PRInt32 *aContentLength)
{
*aContentLength = mContentLength;
return NS_OK;
}
NS_IMETHODIMP
nsInputStreamIO::Close(nsresult status)
{
mStatus = status;
if (mInputStream)
return mInputStream->Close();
return NS_OK;
}
NS_IMETHODIMP
nsInputStreamIO::GetInputStream(nsIInputStream * *aInputStream)
{
*aInputStream = mInputStream;
NS_IF_ADDREF(*aInputStream);
return NS_OK;
}
NS_IMETHODIMP
nsInputStreamIO::GetOutputStream(nsIOutputStream * *aOutputStream)
{
// this method should never be called
NS_NOTREACHED("nsInputStreamIO::GetOutputStream");
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsInputStreamIO::GetName(nsACString &aName)
{
aName = mName;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsStreamIOChannel methods:
nsStreamIOChannel::nsStreamIOChannel()
: mContentLength(-1),
mBufferSegmentSize(0), mBufferMaxSize(0),
mLoadFlags(LOAD_NORMAL), mStatus(NS_OK)
{
}
nsStreamIOChannel::~nsStreamIOChannel()
{
}
NS_METHOD
nsStreamIOChannel::Create(nsISupports *aOuter, REFNSIID aIID,
void **aResult)
{
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
nsStreamIOChannel* channel = new nsStreamIOChannel();
if (channel == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(channel);
nsresult rv = channel->QueryInterface(aIID, aResult);
NS_RELEASE(channel);
return rv;
}
NS_IMETHODIMP
nsStreamIOChannel::Init(nsIURI* uri, nsIStreamIO* io)
{
mURI = uri;
mStreamIO = io;
return NS_OK;
}
NS_INTERFACE_MAP_BEGIN(nsStreamIOChannel)
NS_INTERFACE_MAP_ENTRY(nsIStreamIOChannel)
NS_INTERFACE_MAP_ENTRY(nsIChannel)
NS_INTERFACE_MAP_ENTRY(nsIRequest)
NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
NS_INTERFACE_MAP_ENTRY(nsIStreamProvider)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIRequestObserver, nsIStreamListener)
NS_INTERFACE_MAP_ENTRY(nsIProgressEventSink)
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStreamListener)
NS_INTERFACE_MAP_END_THREADSAFE
NS_IMPL_THREADSAFE_ADDREF(nsStreamIOChannel)
NS_IMPL_THREADSAFE_RELEASE(nsStreamIOChannel)
NS_IMETHODIMP
nsStreamIOChannel::GetName(nsACString &result)
nsInputStreamChannel::GetName(nsACString &result)
{
return mURI->GetSpec(result);
}
NS_IMETHODIMP
nsStreamIOChannel::IsPending(PRBool *result)
nsInputStreamChannel::IsPending(PRBool *result)
{
if (mRequest)
return mRequest->IsPending(result);
*result = PR_FALSE;
NS_ENSURE_TRUE(mPump, NS_ERROR_NOT_INITIALIZED);
return mPump->IsPending(result);
}
NS_IMETHODIMP
nsInputStreamChannel::GetStatus(nsresult *status)
{
if (mPump && NS_SUCCEEDED(mStatus))
mPump->GetStatus(status);
else
*status = mStatus;
return NS_OK;
}
NS_IMETHODIMP
nsStreamIOChannel::GetStatus(nsresult *status)
nsInputStreamChannel::Cancel(nsresult status)
{
*status = mStatus;
// if we don't have a status error of our own to report
// then we should propagate the status error of the underlying
// file transport (if we have one)
if (NS_SUCCEEDED(mStatus) && mRequest)
mRequest->GetStatus(status);
NS_ENSURE_TRUE(mPump, NS_ERROR_NOT_INITIALIZED);
return mPump->Cancel(status);
}
NS_IMETHODIMP
nsInputStreamChannel::Suspend()
{
NS_ENSURE_TRUE(mPump, NS_ERROR_NOT_INITIALIZED);
return mPump->Suspend();
}
NS_IMETHODIMP
nsInputStreamChannel::Resume()
{
NS_ENSURE_TRUE(mPump, NS_ERROR_NOT_INITIALIZED);
return mPump->Resume();
}
NS_IMETHODIMP
nsInputStreamChannel::GetLoadFlags(nsLoadFlags *aLoadFlags)
{
*aLoadFlags = mLoadFlags;
return NS_OK;
}
NS_IMETHODIMP
nsStreamIOChannel::Cancel(nsresult status)
nsInputStreamChannel::SetLoadFlags(nsLoadFlags aLoadFlags)
{
NS_ASSERTION(NS_FAILED(status), "shouldn't cancel with a success code");
mStatus = status;
if (mRequest)
return mRequest->Cancel(status);
mLoadFlags = aLoadFlags;
return NS_OK;
}
NS_IMETHODIMP
nsStreamIOChannel::Suspend(void)
nsInputStreamChannel::GetLoadGroup(nsILoadGroup **aLoadGroup)
{
if (mRequest)
return mRequest->Suspend();
NS_IF_ADDREF(*aLoadGroup = mLoadGroup);
return NS_OK;
}
NS_IMETHODIMP
nsStreamIOChannel::Resume(void)
nsInputStreamChannel::SetLoadGroup(nsILoadGroup *aLoadGroup)
{
if (mRequest)
return mRequest->Resume();
mLoadGroup = aLoadGroup;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsIChannel implementation:
////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
// nsInputStreamChannel::nsIChannel implementation
//-----------------------------------------------------------------------------
NS_IMETHODIMP
nsStreamIOChannel::GetOriginalURI(nsIURI* *aURI)
nsInputStreamChannel::GetOriginalURI(nsIURI **aURI)
{
*aURI = mOriginalURI ? mOriginalURI : mURI;
NS_IF_ADDREF(*aURI);
@ -270,153 +177,64 @@ nsStreamIOChannel::GetOriginalURI(nsIURI* *aURI)
}
NS_IMETHODIMP
nsStreamIOChannel::SetOriginalURI(nsIURI* aURI)
nsInputStreamChannel::SetOriginalURI(nsIURI *aURI)
{
mOriginalURI = aURI;
return NS_OK;
}
NS_IMETHODIMP
nsStreamIOChannel::GetURI(nsIURI* *aURI)
nsInputStreamChannel::GetURI(nsIURI **aURI)
{
*aURI = mURI;
NS_IF_ADDREF(*aURI);
NS_IF_ADDREF(*aURI = mURI);
return NS_OK;
}
NS_IMETHODIMP
nsStreamIOChannel::Open(nsIInputStream **result)
nsInputStreamChannel::GetOwner(nsISupports **aOwner)
{
// XXX not calling mStreamIO->Open(), does that matter?
return mStreamIO->GetInputStream(result);
}
NS_IMETHODIMP
nsStreamIOChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *ctxt)
{
nsresult rv;
NS_ASSERTION(listener, "no listener");
SetListener(listener);
if (mLoadGroup) {
rv = mLoadGroup->AddRequest(this, nsnull);
if (NS_FAILED(rv)) return rv;
}
if (mFileTransport == nsnull) {
nsCOMPtr<nsIFileTransportService> fts =
do_GetService(kFileTransportServiceCID, &rv);
if (NS_FAILED(rv)) goto done;
rv = fts->CreateTransportFromStreamIO(mStreamIO, PR_TRUE,
getter_AddRefs(mFileTransport));
if (NS_FAILED(rv)) goto done;
}
// Hook up the notification callbacks InterfaceRequestor...
{
nsCOMPtr<nsIInterfaceRequestor> requestor =
do_QueryInterface(NS_STATIC_CAST(nsIRequest*, this));
rv = mFileTransport->SetNotificationCallbacks
(requestor, (mLoadFlags & nsIRequest::LOAD_BACKGROUND));
if (NS_FAILED(rv)) goto done;
}
rv = mFileTransport->AsyncRead(this, ctxt, 0, PRUint32(-1), 0, getter_AddRefs(mRequest));
done:
if (NS_FAILED(rv)) {
nsresult rv2;
rv2 = mLoadGroup->RemoveRequest(this, ctxt, rv);
NS_ASSERTION(NS_SUCCEEDED(rv2), "RemoveRequest failed");
// release the transport so that we don't think we're in progress
mFileTransport = nsnull;
}
return rv;
}
NS_IMETHODIMP
nsStreamIOChannel::GetLoadFlags(nsLoadFlags *aLoadFlags)
{
*aLoadFlags = mLoadFlags;
NS_IF_ADDREF(*aOwner = mOwner);
return NS_OK;
}
NS_IMETHODIMP
nsStreamIOChannel::SetLoadFlags(nsLoadFlags aLoadFlags)
{
mLoadFlags = aLoadFlags;
return NS_OK;
}
NS_IMETHODIMP
nsStreamIOChannel::GetLoadGroup(nsILoadGroup* *aLoadGroup)
{
*aLoadGroup = mLoadGroup.get();
NS_IF_ADDREF(*aLoadGroup);
return NS_OK;
}
NS_IMETHODIMP
nsStreamIOChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
{
mLoadGroup = aLoadGroup;
return NS_OK;
}
NS_IMETHODIMP
nsStreamIOChannel::GetOwner(nsISupports* *aOwner)
{
*aOwner = mOwner.get();
NS_IF_ADDREF(*aOwner);
return NS_OK;
}
NS_IMETHODIMP
nsStreamIOChannel::SetOwner(nsISupports* aOwner)
nsInputStreamChannel::SetOwner(nsISupports *aOwner)
{
mOwner = aOwner;
return NS_OK;
}
NS_IMETHODIMP
nsStreamIOChannel::GetNotificationCallbacks(nsIInterfaceRequestor* *aNotificationCallbacks)
nsInputStreamChannel::GetNotificationCallbacks(nsIInterfaceRequestor **aCallbacks)
{
*aNotificationCallbacks = mCallbacks.get();
NS_IF_ADDREF(*aNotificationCallbacks);
return NS_OK;
NS_IF_ADDREF(*aCallbacks = mCallbacks);
return NS_OK;
}
NS_IMETHODIMP
nsStreamIOChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
nsInputStreamChannel::SetNotificationCallbacks(nsIInterfaceRequestor *aCallbacks)
{
nsresult rv = NS_OK;
mCallbacks = aNotificationCallbacks;
mProgressSink = do_GetInterface(mCallbacks);
return rv;
mCallbacks = aCallbacks;
mProgressSink = do_GetInterface(mCallbacks);
return NS_OK;
}
NS_IMETHODIMP
nsStreamIOChannel::GetSecurityInfo(nsISupports * *aSecurityInfo)
nsInputStreamChannel::GetSecurityInfo(nsISupports **aSecurityInfo)
{
*aSecurityInfo = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsStreamIOChannel::GetContentType(nsACString &aContentType)
nsInputStreamChannel::GetContentType(nsACString &aContentType)
{
if (mContentType.IsEmpty()) {
nsresult rv = mStreamIO->GetContentType(mContentType);
if (NS_FAILED(rv)) return rv;
}
aContentType = mContentType;
return NS_OK;
}
NS_IMETHODIMP
nsStreamIOChannel::SetContentType(const nsACString &aContentType)
nsInputStreamChannel::SetContentType(const nsACString &aContentType)
{
// mContentCharset is unchanged if not parsed
NS_ParseContentType(aContentType, mContentType, mContentCharset);
@ -424,133 +242,134 @@ nsStreamIOChannel::SetContentType(const nsACString &aContentType)
}
NS_IMETHODIMP
nsStreamIOChannel::GetContentCharset(nsACString &aContentCharset)
nsInputStreamChannel::GetContentCharset(nsACString &aContentCharset)
{
if (mContentCharset.IsEmpty()) {
nsresult rv = mStreamIO->GetContentCharset(mContentCharset);
if (NS_FAILED(rv)) return rv;
}
aContentCharset = mContentCharset;
return NS_OK;
}
NS_IMETHODIMP
nsStreamIOChannel::SetContentCharset(const nsACString &aContentCharset)
nsInputStreamChannel::SetContentCharset(const nsACString &aContentCharset)
{
mContentCharset = aContentCharset;
return NS_OK;
}
NS_IMETHODIMP
nsStreamIOChannel::GetContentLength(PRInt32 *aContentLength)
nsInputStreamChannel::GetContentLength(PRInt32 *aContentLength)
{
nsresult rv;
if (mContentLength == -1) {
rv = mStreamIO->GetContentLength(&mContentLength);
if (NS_FAILED(rv)) return rv;
}
*aContentLength = mContentLength;
return NS_OK;
return NS_OK;
}
NS_IMETHODIMP
nsStreamIOChannel::SetContentLength(PRInt32 aContentLength)
nsInputStreamChannel::SetContentLength(PRInt32 aContentLength)
{
// XXX does this really make any sense at all?
mContentLength = aContentLength;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsIRequestObserver implementation:
////////////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP
nsStreamIOChannel::OnStartRequest(nsIRequest *request, nsISupports* context)
nsInputStreamChannel::Open(nsIInputStream **result)
{
NS_ASSERTION(mUserObserver, "No listener...");
return mUserObserver->OnStartRequest(this, context);
NS_ENSURE_TRUE(mContentStream, NS_ERROR_NOT_INITIALIZED);
NS_ENSURE_TRUE(!mPump, NS_ERROR_IN_PROGRESS);
NS_ADDREF(*result = mContentStream);
return NS_OK;
}
NS_IMETHODIMP
nsStreamIOChannel::OnStopRequest(nsIRequest *request, nsISupports* context, nsresult aStatus)
nsInputStreamChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *ctxt)
{
if (mUserObserver)
mUserObserver->OnStopRequest(this, context, aStatus);
NS_ENSURE_TRUE(mContentStream, NS_ERROR_NOT_INITIALIZED);
NS_ENSURE_TRUE(!mPump, NS_ERROR_IN_PROGRESS);
if (mContentLength == -1)
mContentStream->Available((PRUint32 *) &mContentLength);
nsresult rv = NS_NewInputStreamPump(getter_AddRefs(mPump), mContentStream,
-1, mContentLength, 0, 0, PR_TRUE);
if (NS_FAILED(rv)) return rv;
rv = mPump->AsyncRead(this, nsnull);
if (NS_FAILED(rv)) return rv;
if (mLoadGroup)
mLoadGroup->RemoveRequest(this, context, aStatus);
mLoadGroup->AddRequest(this, nsnull);
// Release the reference to the consumer stream listener...
mRequest = 0;
mFileTransport = 0;
mUserObserver = 0;
// Make sure the stream io is closed
mStreamIO->Close(aStatus);
// There is no point in returning anything other than NS_OK
mListener = listener;
mListenerContext = ctxt;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsIStreamListener implementation:
////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
// nsInputStreamChannel::nsIInputStreamChannel implementation
//-----------------------------------------------------------------------------
NS_IMETHODIMP
nsStreamIOChannel::OnDataAvailable(nsIRequest *request, nsISupports* context,
nsIInputStream *aIStream, PRUint32 aSourceOffset,
PRUint32 aLength)
nsInputStreamChannel::SetURI(nsIURI *uri)
{
return GetListener()->OnDataAvailable(this, context, aIStream,
aSourceOffset, aLength);
}
////////////////////////////////////////////////////////////////////////////////
// nsIStreamProvider implementation:
////////////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP
nsStreamIOChannel::OnDataWritable(nsIRequest *request, nsISupports *context,
nsIOutputStream *aOStream,
PRUint32 aOffset, PRUint32 aLength)
{
return GetProvider()->OnDataWritable(this, context, aOStream,
aOffset, aLength);
}
////////////////////////////////////////////////////////////////////////////////
// nsIProgressEventSink implementation:
////////////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP
nsStreamIOChannel::OnProgress(nsIRequest *request, nsISupports *context,
PRUint32 progress, PRUint32 progressMax)
{
if (mProgressSink)
mProgressSink->OnProgress(this, context, progress, progressMax);
NS_ENSURE_TRUE(!mPump, NS_ERROR_IN_PROGRESS);
mURI = uri;
return NS_OK;
}
NS_IMETHODIMP
nsStreamIOChannel::OnStatus(nsIRequest *request, nsISupports *context,
nsresult status, const PRUnichar *statusText)
nsInputStreamChannel::GetContentStream(nsIInputStream **stream)
{
if (mProgressSink)
mProgressSink->OnStatus(this, context, status, statusText);
NS_IF_ADDREF(*stream = mContentStream);
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsIInterfaceRequestor implementation:
////////////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP
nsStreamIOChannel::GetInterface(const nsIID &iid, void **result)
nsInputStreamChannel::SetContentStream(nsIInputStream *stream)
{
if (iid.Equals(NS_GET_IID(nsIProgressEventSink)))
return QueryInterface(iid, result);
return NS_ERROR_NO_INTERFACE;
NS_ENSURE_TRUE(!mPump, NS_ERROR_IN_PROGRESS);
mContentStream = stream;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
// nsInputStreamChannel::nsIStreamListener implementation
//-----------------------------------------------------------------------------
NS_IMETHODIMP
nsInputStreamChannel::OnStartRequest(nsIRequest *req, nsISupports *ctx)
{
return mListener->OnStartRequest(this, mListenerContext);
}
NS_IMETHODIMP
nsInputStreamChannel::OnStopRequest(nsIRequest *req, nsISupports *ctx, nsresult status)
{
if (NS_SUCCEEDED(mStatus))
mStatus = status;
mListener->OnStopRequest(this, mListenerContext, mStatus);
mListener = 0;
mListenerContext = 0;
if (mLoadGroup)
mLoadGroup->RemoveRequest(this, nsnull, mStatus);
mPump = 0;
mContentStream = 0;
return NS_OK;
}
NS_IMETHODIMP
nsInputStreamChannel::OnDataAvailable(nsIRequest *req, nsISupports *ctx,
nsIInputStream *stream,
PRUint32 offset, PRUint32 count)
{
nsresult rv;
rv = mListener->OnDataAvailable(this, mListenerContext, stream, offset, count);
if (mProgressSink && NS_SUCCEEDED(rv) && !(mLoadFlags & LOAD_BACKGROUND))
mProgressSink->OnProgress(this, nsnull, offset + count, mContentLength);
return rv; // let the pump cancel on failure
}

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

@ -38,91 +38,51 @@
#ifndef nsInputStreamChannel_h__
#define nsInputStreamChannel_h__
#include "nsIStreamIOChannel.h"
#include "nsString.h"
#include "nsCOMPtr.h"
#include "nsIInputStreamChannel.h"
#include "nsIInputStreamPump.h"
#include "nsIInputStream.h"
#include "nsIURI.h"
#include "nsCRT.h"
#include "nsILoadGroup.h"
#include "nsIStreamListener.h"
#include "nsIStreamProvider.h"
#include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsIProgressEventSink.h"
#include "nsIStreamIO.h"
#include "nsITransport.h"
#include "nsString.h"
class nsInputStreamIO : public nsIInputStreamIO
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSISTREAMIO
NS_DECL_NSIINPUTSTREAMIO
//-----------------------------------------------------------------------------
nsInputStreamIO();
virtual ~nsInputStreamIO();
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
protected:
nsCString mName;
nsCOMPtr<nsIInputStream> mInputStream;
nsCString mContentType;
nsCString mContentCharset;
PRInt32 mContentLength;
nsresult mStatus;
};
////////////////////////////////////////////////////////////////////////////////
class nsStreamIOChannel : public nsIStreamIOChannel,
public nsIStreamListener,
public nsIStreamProvider,
public nsIProgressEventSink,
public nsIInterfaceRequestor
class nsInputStreamChannel : public nsIInputStreamChannel
, public nsIStreamListener
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIREQUEST
NS_DECL_NSICHANNEL
NS_DECL_NSISTREAMIOCHANNEL
NS_DECL_NSIINPUTSTREAMCHANNEL
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSISTREAMPROVIDER
NS_DECL_NSIPROGRESSEVENTSINK
NS_DECL_NSIINTERFACEREQUESTOR
nsStreamIOChannel();
virtual ~nsStreamIOChannel();
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
nsInputStreamChannel();
virtual ~nsInputStreamChannel();
protected:
nsIStreamListener* GetListener() { return (nsIStreamListener*)mUserObserver.get(); }
void SetListener(nsIStreamListener* listener) { mUserObserver = listener; }
nsIStreamProvider* GetProvider() { return (nsIStreamProvider*)mUserObserver.get(); }
void SetProvider(nsIStreamProvider* provider) { mUserObserver = provider; }
protected:
nsCOMPtr<nsIInputStreamPump> mPump;
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
nsCOMPtr<nsIProgressEventSink> mProgressSink;
nsCOMPtr<nsIURI> mOriginalURI;
nsCOMPtr<nsIURI> mURI;
nsCOMPtr<nsILoadGroup> mLoadGroup;
nsCOMPtr<nsISupports> mOwner;
nsCOMPtr<nsIStreamListener> mListener;
nsCOMPtr<nsISupports> mListenerContext;
nsCOMPtr<nsIInputStream> mContentStream;
nsCString mContentType;
nsCString mContentCharset;
PRInt32 mContentLength;
nsCOMPtr<nsIStreamIO> mStreamIO;
nsCOMPtr<nsILoadGroup> mLoadGroup;
nsCOMPtr<nsISupports> mOwner;
nsCOMPtr<nsITransport> mFileTransport;
nsCOMPtr<nsIRequest> mRequest;
nsCOMPtr<nsIRequestObserver> mUserObserver;
PRUint32 mBufferSegmentSize;
PRUint32 mBufferMaxSize;
PRUint32 mLoadFlags;
nsresult mStatus;
};
#endif // nsInputStreamChannel_h__
#endif // !nsInputStreamChannel_h__

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

@ -441,11 +441,11 @@ nsProtocolProxyService::NewProxyInfo(const char *aType,
const char *type = nsnull;
// canonicalize type
if (PL_strcasecmp(aType, "http"))
if (PL_strcasecmp(aType, "http") == 0)
type = "http";
else if (PL_strcasecmp(aType, "socks"))
else if (PL_strcasecmp(aType, "socks") == 0)
type = "socks";
else if (PL_strcasecmp(aType, "socks4"))
else if (PL_strcasecmp(aType, "socks4") == 0)
type = "socks4";
else
return NS_ERROR_INVALID_ARG;

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

@ -40,7 +40,7 @@
#include "nsIURL.h"
#include "nsNetUtil.h"
#include "nsIChannel.h"
#include "nsIHttpChannel.h"
//#include "nsIHttpChannel.h"
#include "nsProxiedService.h"
static NS_DEFINE_CID(kProxyObjectManagerCID, NS_PROXYEVENT_MANAGER_CID);

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

@ -152,32 +152,6 @@
{0x9c, 0x46, 0xd0, 0x3f, 0xaa, 0x7b, 0x69, 0x6b} \
}
// component implementing nsIStreamListenerProxy.
#define NS_STREAMLISTENERPROXY_CLASSNAME \
"nsStreamListenerProxy"
#define NS_STREAMLISTENERPROXY_CONTRACTID \
"@mozilla.org/network/stream-listener-proxy;1"
#define NS_STREAMLISTENERPROXY_CID \
{ /* 96c48f15-aa8a-4da7-a9d5-e842bd76f015 */ \
0x96c48f15, \
0xaa8a, \
0x4da7, \
{0xa9, 0xd5, 0xe8, 0x42, 0xbd, 0x76, 0xf0, 0x15} \
}
// component implementing nsIStreamProviderProxy.
#define NS_STREAMPROVIDERPROXY_CLASSNAME \
"nsStreamProviderProxy"
#define NS_STREAMPROVIDERPROXY_CONTRACTID \
"@mozilla.org/network/stream-provider-proxy;1"
#define NS_STREAMPROVIDERPROXY_CID \
{ /* ae964fcf-9c27-40f7-9bbd-78894bfc1f31 */ \
0xae964fcf, \
0x9c27, \
0x40f7, \
{0x9b, 0xbd, 0x78, 0x89, 0x4b, 0xfc, 0x1f, 0x31} \
}
// component implementing nsISimpleStreamListener.
#define NS_SIMPLESTREAMLISTENER_CLASSNAME \
"nsSimpleStreamListener"
@ -191,19 +165,6 @@
{0xb1, 0xd6, 0x53, 0x88, 0xe0, 0x41, 0xfb, 0x67} \
}
// component implementing nsISimpleStreamProvider.
#define NS_SIMPLESTREAMPROVIDER_CLASSNAME \
"nsSimpleStreamProvider"
#define NS_SIMPLESTREAMPROVIDER_CONTRACTID \
"@mozilla.org/network/simple-stream-provider;1"
#define NS_SIMPLESTREAMPROVIDER_CID \
{ /* f9f6a519-4efb-4f36-af40-2a5ec3992710 */ \
0xf9f6a519, \
0x4efb, \
0x4f36, \
{0xaf, 0x40, 0x2a, 0x5e, 0xc3, 0x99, 0x27, 0x10} \
}
// DEPRECATED component implementing nsIAsyncStreamListener.
#define NS_ASYNCSTREAMLISTENER_CLASSNAME \
"nsAsyncStreamListener"
@ -230,31 +191,38 @@
{0xb0, 0x2e, 0x77, 0xc8, 0x81, 0xcc, 0x57, 0x73} \
}
// A simple implementation of nsITransport that stores a segmented memory
// buffer (4k chunks). As long as the nsITransport is referenced, the data
// remains in memory. It can be read multiple times (only AsyncRead is
// implemented). There can be only one writer at a time (only OpenOutputStream
// is implemented). AsyncRead can be called while an output stream is still
// being written to. The readers will get notified automatically as more
// data is written via the output stream.
#define NS_STORAGETRANSPORT_CLASSNAME \
"nsStorageTransport"
#define NS_STORAGETRANSPORT_CONTRACTID \
"@mozilla.org/network/storage-transport;1"
#define NS_STORAGETRANSPORT_CID \
{ /* 5e955cdb-1334-4b8f-86b5-3b0f4d54b9d2 */ \
0x5e955cdb, \
0x1334, \
0x4b8f, \
{0x86, 0xb5, 0x3b, 0x0f, 0x4d, 0x54, 0xb9, 0xd2} \
// component implementing nsIAsyncStreamCopier.
#define NS_ASYNCSTREAMCOPIER_CLASSNAME \
"nsAsyncStreamCopier"
#define NS_ASYNCSTREAMCOPIER_CONTRACTID \
"@mozilla.org/network/async-stream-copier;1"
#define NS_ASYNCSTREAMCOPIER_CID \
{ /* e746a8b1-c97a-4fc5-baa4-66607521bd08 */ \
0xe746a8b1, \
0xc97a, \
0x4fc5, \
{0xba, 0xa4, 0x66, 0x60, 0x75, 0x21, 0xbd, 0x08} \
}
// component implementing nsIStreamIOChannel.
#define NS_STREAMIOCHANNEL_CLASSNAME \
// component implementing nsIInputStreamPump.
#define NS_INPUTSTREAMPUMP_CLASSNAME \
"nsInputStreamPump"
#define NS_INPUTSTREAMPUMP_CONTRACTID \
"@mozilla.org/network/input-stream-pump;1"
#define NS_INPUTSTREAMPUMP_CID \
{ /* ccd0e960-7947-4635-b70e-4c661b63d675 */ \
0xccd0e960, \
0x7947, \
0x4635, \
{0xb7, 0x0e, 0x4c, 0x66, 0x1b, 0x63, 0xd6, 0x75} \
}
// component implementing nsIInputStreamChannel.
#define NS_INPUTSTREAMCHANNEL_CLASSNAME \
"nsInputStreamChannel"
#define NS_STREAMIOCHANNEL_CONTRACTID \
"@mozilla.org/network/stream-io-channel;1"
#define NS_STREAMIOCHANNEL_CID \
#define NS_INPUTSTREAMCHANNEL_CONTRACTID \
"@mozilla.org/network/input-stream-channel;1"
#define NS_INPUTSTREAMCHANNEL_CID \
{ /* 6ddb050c-0d04-11d4-986e-00c04fa0cf4a */ \
0x6ddb050c, \
0x0d04, \
@ -327,6 +295,92 @@
{0xb9, 0x5c, 0xe5, 0xd6, 0x7a, 0x34, 0xe6, 0xb3} \
}
// service implementing nsIStreamTransportService
#define NS_STREAMTRANSPORTSERVICE_CLASSNAME \
"nsStreamTransportService"
#define NS_STREAMTRANSPORTSERVICE_CONTRACTID \
"@mozilla.org/network/stream-transport-service;1"
#define NS_STREAMTRANSPORTSERVICE_CID \
{ /* 0885d4f8-f7b8-4cda-902e-94ba38bc256e */ \
0x0885d4f8, \
0xf7b8, \
0x4cda, \
{0x90, 0x2e, 0x94, 0xba, 0x38, 0xbc, 0x25, 0x6e} \
}
// service implementing nsISocketTransportService
#define NS_SOCKETTRANSPORTSERVICE_CLASSNAME \
"nsSocketTransportService"
#define NS_SOCKETTRANSPORTSERVICE_CONTRACTID \
"@mozilla.org/network/socket-transport-service;1"
#define NS_SOCKETTRANSPORTSERVICE_CID \
{ /* c07e81e0-ef12-11d2-92b6-00105a1b0d64 */ \
0xc07e81e0, \
0xef12, \
0x11d2, \
{0x92, 0xb6, 0x00, 0x10, 0x5a, 0x1b, 0x0d, 0x64} \
}
#define NS_FILETRANSPORTSERVICE_CLASSNAME \
"nsFileTransportService"
#define NS_FILETRANSPORTSERVICE_CONTRACTID \
"@mozilla.org/network/file-transport-service;1"
#define NS_FILETRANSPORTSERVICE_CID \
{ /* 2bb2b250-ea35-11d2-931b-00104ba0fd40 */ \
0x2bb2b250, \
0xea35, \
0x11d2, \
{0x93, 0x1b, 0x00, 0x10, 0x4b, 0xa0, 0xfd, 0x40} \
}
#define NS_LOCALFILEINPUTSTREAM_CLASSNAME \
"nsFileInputStream"
#define NS_LOCALFILEINPUTSTREAM_CONTRACTID \
"@mozilla.org/network/file-input-stream;1"
#define NS_LOCALFILEINPUTSTREAM_CID \
{ /* be9a53ae-c7e9-11d3-8cda-0060b0fc14a3 */ \
0xbe9a53ae, \
0xc7e9, \
0x11d3, \
{0x8c, 0xda, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
#define NS_LOCALFILEOUTPUTSTREAM_CLASSNAME \
"nsFileOutputStream"
#define NS_LOCALFILEOUTPUTSTREAM_CONTRACTID \
"@mozilla.org/network/file-output-stream;1"
#define NS_LOCALFILEOUTPUTSTREAM_CID \
{ /* c272fee0-c7e9-11d3-8cda-0060b0fc14a3 */ \
0xc272fee0, \
0xc7e9, \
0x11d3, \
{0x8c, 0xda, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
#define NS_BUFFEREDINPUTSTREAM_CLASSNAME \
"nsBufferedInputStream"
#define NS_BUFFEREDINPUTSTREAM_CONTRACTID \
"@mozilla.org/network/buffered-input-stream;1"
#define NS_BUFFEREDINPUTSTREAM_CID \
{ /* 9226888e-da08-11d3-8cda-0060b0fc14a3 */ \
0x9226888e, \
0xda08, \
0x11d3, \
{0x8c, 0xda, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
#define NS_BUFFEREDOUTPUTSTREAM_CLASSNAME \
"nsBufferedOutputStream"
#define NS_BUFFEREDOUTPUTSTREAM_CONTRACTID \
"@mozilla.org/network/buffered-output-stream;1"
#define NS_BUFFEREDOUTPUTSTREAM_CID \
{ /* 9868b4ce-da08-11d3-8cda-0060b0fc14a3 */ \
0x9868b4ce, \
0xda08, \
0x11d3, \
{0x8c, 0xda, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
/******************************************************************************
* netwerk/cache/ classes
@ -386,6 +440,8 @@
* netwerk/protocol/res/ classes
*/
#define NS_RESPROTOCOLHANDLER_CLASSNAME \
"nsResProtocolHandler"
#define NS_RESPROTOCOLHANDLER_CID \
{ /* e64f152a-9f07-11d3-8cda-0060b0fc14a3 */ \
0xe64f152a, \
@ -394,6 +450,48 @@
{0x8c, 0xda, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
/******************************************************************************
* netwerk/protocol/file/ classes
*/
#define NS_FILEPROTOCOLHANDLER_CLASSNAME \
"nsFileProtocolHandler"
#define NS_FILEPROTOCOLHANDLER_CID \
{ /* fbc81170-1f69-11d3-9344-00104ba0fd40 */ \
0xfbc81170, \
0x1f69, \
0x11d3, \
{0x93, 0x44, 0x00, 0x10, 0x4b, 0xa0, 0xfd, 0x40} \
}
/******************************************************************************
* netwerk/protocol/data/ classes
*/
#define NS_DATAPROTOCOLHANDLER_CLASSNAME \
"nsDataProtocolHandler"
#define NS_DATAPROTOCOLHANDLER_CID \
{ /* {B6ED3030-6183-11d3-A178-0050041CAF44} */ \
0xb6ed3030, \
0x6183, \
0x11d3, \
{0xa1, 0x78, 0x00, 0x50, 0x04, 0x1c, 0xaf, 0x44} \
}
/******************************************************************************
* netwerk/protocol/data/ classes
*/
#define NS_JARPROTOCOLHANDLER_CLASSNAME \
"nsJarProtocolHandler"
#define NS_JARPROTOCOLHANDLER_CID \
{ /* 0xc7e410d4-0x85f2-11d3-9f63-006008a6efe9 */ \
0xc7e410d4, \
0x85f2, \
0x11d3, \
{0x9f, 0x63, 0x00, 0x60, 0x08, 0xa6, 0xef, 0xe9} \
}
/******************************************************************************
* netwerk/dns/ classes

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

@ -41,16 +41,12 @@
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
#include "nsICategoryManager.h"
#include "nsIOService.h"
#include "nsNetModuleMgr.h"
#include "nsFileTransportService.h"
#include "nsSocketTransportService.h"
#include "nsSocketProviderService.h"
#include "nscore.h"
#include "nsSimpleURI.h"
#include "nsDnsService.h"
#include "nsLoadGroup.h"
#include "nsInputStreamChannel.h"
#include "nsStreamLoader.h"
#include "nsUnicharStreamLoader.h"
#include "nsDownloader.h"
@ -75,6 +71,27 @@
///////////////////////////////////////////////////////////////////////////////
#include "nsIOService.h"
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsIOService, Init)
#include "nsStreamTransportService.h"
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsStreamTransportService, Init)
#include "nsSocketTransportService2.h"
#undef LOG
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsSocketTransportService, Init)
#include "nsAsyncStreamCopier.h"
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAsyncStreamCopier)
#include "nsInputStreamPump.h"
NS_GENERIC_FACTORY_CONSTRUCTOR(nsInputStreamPump)
#include "nsInputStreamChannel.h"
NS_GENERIC_FACTORY_CONSTRUCTOR(nsInputStreamChannel)
///////////////////////////////////////////////////////////////////////////////
#include "nsStreamConverterService.h"
#ifdef BUILD_APPLEFILE_DECODER
@ -91,18 +108,12 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsMIMEInfoImpl)
///////////////////////////////////////////////////////////////////////////////
#include "nsRequestObserverProxy.h"
#include "nsStreamListenerProxy.h"
#include "nsStreamProviderProxy.h"
#include "nsSimpleStreamListener.h"
#include "nsSimpleStreamProvider.h"
#include "nsDirIndexParser.h"
#include "nsDirIndex.h"
NS_GENERIC_FACTORY_CONSTRUCTOR(nsRequestObserverProxy)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsStreamListenerProxy)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsStreamProviderProxy)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSimpleStreamListener)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSimpleStreamProvider)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsDirIndexParser, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsDirIndex)
@ -113,15 +124,10 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsStreamListenerTee)
///////////////////////////////////////////////////////////////////////////////
#include "nsStorageTransport.h"
NS_GENERIC_FACTORY_CONSTRUCTOR(nsStorageTransport)
///////////////////////////////////////////////////////////////////////////////
#include "nsHttpHandler.h"
#include "nsHttpBasicAuth.h"
#include "nsHttpDigestAuth.h"
#undef LOG
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsHttpHandler, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsHttpsHandler, Init)
@ -160,10 +166,13 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsIDNService)
///////////////////////////////////////////////////////////////////////////////
#include "nsFileChannel.h"
#include "nsFileProtocolHandler.h"
#include "nsDataHandler.h"
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsFileProtocolHandler, Init)
#include "nsJARProtocolHandler.h"
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsJARProtocolHandler, Init)
#include "nsDataHandler.h"
#include "nsAboutProtocolHandler.h"
#include "nsAboutBlank.h"
@ -515,15 +524,15 @@ static const nsModuleComponentInfo gNetModuleInfo[] = {
{ NS_IOSERVICE_CLASSNAME,
NS_IOSERVICE_CID,
NS_IOSERVICE_CONTRACTID,
nsIOService::Create },
{ "File Transport Service",
NS_FILETRANSPORTSERVICE_CID,
"@mozilla.org/network/file-transport-service;1",
nsFileTransportService::Create },
{ "Socket Transport Service",
nsIOServiceConstructor },
{ NS_STREAMTRANSPORTSERVICE_CLASSNAME,
NS_STREAMTRANSPORTSERVICE_CID,
NS_STREAMTRANSPORTSERVICE_CONTRACTID,
nsStreamTransportServiceConstructor },
{ NS_SOCKETTRANSPORTSERVICE_CLASSNAME,
NS_SOCKETTRANSPORTSERVICE_CID,
"@mozilla.org/network/socket-transport-service;1",
nsSocketTransportService::Create },
NS_SOCKETTRANSPORTSERVICE_CONTRACTID,
nsSocketTransportServiceConstructor },
{ "Socket Provider Service",
NS_SOCKETPROVIDERSERVICE_CID,
"@mozilla.org/network/socket-provider-service;1",
@ -544,18 +553,18 @@ static const nsModuleComponentInfo gNetModuleInfo[] = {
NS_NETMODULEMGR_CID,
"@mozilla.org/network/net-extern-mod;1",
nsNetModuleMgr::Create },
{ NS_FILEIO_CLASSNAME,
NS_FILEIO_CID,
NS_FILEIO_CONTRACTID,
nsFileIO::Create },
{ NS_INPUTSTREAMIO_CLASSNAME,
NS_INPUTSTREAMIO_CID,
NS_INPUTSTREAMIO_CONTRACTID,
nsInputStreamIO::Create },
{ NS_STREAMIOCHANNEL_CLASSNAME,
NS_STREAMIOCHANNEL_CID,
NS_STREAMIOCHANNEL_CONTRACTID,
nsStreamIOChannel::Create },
{ NS_ASYNCSTREAMCOPIER_CLASSNAME,
NS_ASYNCSTREAMCOPIER_CID,
NS_ASYNCSTREAMCOPIER_CONTRACTID,
nsAsyncStreamCopierConstructor },
{ NS_INPUTSTREAMPUMP_CLASSNAME,
NS_INPUTSTREAMPUMP_CID,
NS_INPUTSTREAMPUMP_CONTRACTID,
nsInputStreamPumpConstructor },
{ NS_INPUTSTREAMCHANNEL_CLASSNAME,
NS_INPUTSTREAMCHANNEL_CID,
NS_INPUTSTREAMCHANNEL_CONTRACTID,
nsInputStreamChannelConstructor },
{ NS_STREAMLOADER_CLASSNAME,
NS_STREAMLOADER_CID,
NS_STREAMLOADER_CONTRACTID,
@ -572,22 +581,10 @@ static const nsModuleComponentInfo gNetModuleInfo[] = {
NS_REQUESTOBSERVERPROXY_CID,
NS_REQUESTOBSERVERPROXY_CONTRACTID,
nsRequestObserverProxyConstructor },
{ NS_STREAMLISTENERPROXY_CLASSNAME,
NS_STREAMLISTENERPROXY_CID,
NS_STREAMLISTENERPROXY_CONTRACTID,
nsStreamListenerProxyConstructor },
{ NS_STREAMPROVIDERPROXY_CLASSNAME,
NS_STREAMPROVIDERPROXY_CID,
NS_STREAMPROVIDERPROXY_CONTRACTID,
nsStreamProviderProxyConstructor },
{ NS_SIMPLESTREAMLISTENER_CLASSNAME,
NS_SIMPLESTREAMLISTENER_CID,
NS_SIMPLESTREAMLISTENER_CONTRACTID,
nsSimpleStreamListenerConstructor },
{ NS_SIMPLESTREAMPROVIDER_CLASSNAME,
NS_SIMPLESTREAMPROVIDER_CID,
NS_SIMPLESTREAMPROVIDER_CONTRACTID,
nsSimpleStreamProviderConstructor },
{ NS_ASYNCSTREAMLISTENER_CLASSNAME,
NS_ASYNCSTREAMLISTENER_CID,
NS_ASYNCSTREAMLISTENER_CONTRACTID,
@ -596,10 +593,6 @@ static const nsModuleComponentInfo gNetModuleInfo[] = {
NS_STREAMLISTENERTEE_CID,
NS_STREAMLISTENERTEE_CONTRACTID,
nsStreamListenerTeeConstructor },
{ NS_STORAGETRANSPORT_CLASSNAME,
NS_STORAGETRANSPORT_CID,
NS_STORAGETRANSPORT_CONTRACTID,
nsStorageTransportConstructor },
{ NS_LOADGROUP_CLASSNAME,
NS_LOADGROUP_CID,
NS_LOADGROUP_CONTRACTID,
@ -786,12 +779,6 @@ static const nsModuleComponentInfo gNetModuleInfo[] = {
nsDirIndexConstructor
},
#if defined(OLD_CACHE)
// from netwerk/cache:
{ "Memory Cache", NS_MEM_CACHE_FACTORY_CID, NS_NETWORK_MEMORY_CACHE_CONTRACTID, nsMemCacheConstructor },
{ "File Cache", NS_NETDISKCACHE_CID, NS_NETWORK_FILE_CACHE_CONTRACTID, nsNetDiskCacheConstructor },
{ "Cache Manager",NS_CACHE_MANAGER_CID, NS_NETWORK_CACHE_MANAGER_CONTRACTID,nsCacheManagerConstructor },
#endif
// from netwerk/mime:
{ "xml mime INFO",
NS_MIMEINFO_CID,
@ -800,15 +787,10 @@ static const nsModuleComponentInfo gNetModuleInfo[] = {
},
// from netwerk/protocol/file:
{ "File Protocol Handler",
{ NS_FILEPROTOCOLHANDLER_CLASSNAME,
NS_FILEPROTOCOLHANDLER_CID,
NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "file",
nsFileProtocolHandler::Create
},
{ NS_LOCALFILECHANNEL_CLASSNAME,
NS_LOCALFILECHANNEL_CID,
NS_LOCALFILECHANNEL_CONTRACTID,
nsFileChannel::Create
nsFileProtocolHandlerConstructor
},
{ "HTTP Handler",
@ -839,20 +821,20 @@ static const nsModuleComponentInfo gNetModuleInfo[] = {
},
// from netwerk/protocol/data:
{ "Data Protocol Handler",
NS_DATAHANDLER_CID,
{ NS_DATAPROTOCOLHANDLER_CLASSNAME,
NS_DATAPROTOCOLHANDLER_CID,
NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "data",
nsDataHandler::Create},
// from netwerk/protocol/jar:
{ "JAR Protocol Handler",
NS_JARPROTOCOLHANDLER_CID,
NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "jar",
nsJARProtocolHandler::Create
{ NS_JARPROTOCOLHANDLER_CLASSNAME,
NS_JARPROTOCOLHANDLER_CID,
NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "jar",
nsJARProtocolHandlerConstructor
},
// from netwerk/protocol/res:
{ "Resource Protocol Handler",
{ NS_RESPROTOCOLHANDLER_CLASSNAME,
NS_RESPROTOCOLHANDLER_CID,
NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "resource",
nsResProtocolHandlerConstructor
@ -899,6 +881,7 @@ static const nsModuleComponentInfo gNetModuleInfo[] = {
NS_ABOUT_MODULE_CONTRACTID_PREFIX "logo",
nsAboutRedirector::Create
},
{ "about:cache",
NS_ABOUT_CACHE_MODULE_CID,
NS_ABOUT_MODULE_CONTRACTID_PREFIX "cache",
@ -909,6 +892,7 @@ static const nsModuleComponentInfo gNetModuleInfo[] = {
NS_ABOUT_MODULE_CONTRACTID_PREFIX "cache-entry",
nsAboutCacheEntryConstructor
},
// from netwerk/protocol/keyword:
{ "The Keyword Protocol Handler",
NS_KEYWORDPROTOCOLHANDLER_CID,

5
netwerk/cache/Makefile.in поставляемый
Просмотреть файл

@ -26,10 +26,7 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS = \
public \
src \
$(NULL)
DIRS = public src
include $(topsrcdir)/config/rules.mk

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

@ -29,7 +29,8 @@
interface nsISimpleEnumerator;
interface nsICacheListener;
interface nsITransport;
interface nsIInputStream;
interface nsIOutputStream;
interface nsIFile;
interface nsICacheMetaDataVisitor;
@ -50,10 +51,33 @@ interface nsICacheEntryDescriptor : nsICacheEntryInfo
void setDataSize(in unsigned long size);
/**
* Get a transport to the cache data. This will fail if the cache entry
* IS NOT stream based.
* Open blocking input stream to cache data. This will fail if the cache
* entry IS NOT stream based. Use the stream transport service to
* asynchronously read this stream on a background thread. The returned
* stream MAY implement nsISeekableStream.
*
* @param offset
* read starting from this offset into the cached data.
*
* @return blocking, unbuffered input stream.
*/
readonly attribute nsITransport transport;
nsIInputStream openInputStream(in unsigned long offset);
/**
* Open blocking output stream to cache data. This will fail if the cache
* entry IS NOT stream based. Use the stream transport service to
* asynchronously write to this stream on a background thread. The returned
* stream MAY implement nsISeekableStream.
*
* If opening an output stream to existing cached data, the data will be
* truncated to the specified offset.
*
* @param offset
* write starting from this offset into the cached data.
*
* @return blocking, unbuffered output stream.
*/
nsIOutputStream openOutputStream(in unsigned long offset);
/**
* Get/set the cache data element. This will fail if the cache entry

2
netwerk/cache/src/Makefile.in поставляемый
Просмотреть файл

@ -48,13 +48,13 @@ CPPSRCS = \
nsCacheMetaData.cpp \
nsCacheService.cpp \
nsCacheSession.cpp \
nsMemoryCacheDevice.cpp \
nsDiskCacheBinding.cpp \
nsDiskCacheBlockFile.cpp \
nsDiskCacheDevice.cpp \
nsDiskCacheEntry.cpp \
nsDiskCacheMap.cpp \
nsDiskCacheStreams.cpp \
nsMemoryCacheDevice.cpp \
$(NULL)
include $(topsrcdir)/config/config.mk

15
netwerk/cache/src/nsCacheDevice.h поставляемый
Просмотреть файл

@ -32,7 +32,8 @@ class nsIFile;
class nsCString;
class nsCacheEntry;
class nsICacheVisitor;
class nsITransport;
class nsIInputStream;
class nsIOutputStream;
/******************************************************************************
* nsCacheDevice
@ -52,9 +53,15 @@ public:
virtual nsresult BindEntry( nsCacheEntry * entry ) = 0;
virtual void DoomEntry( nsCacheEntry * entry ) = 0;
virtual nsresult GetTransportForEntry( nsCacheEntry * entry,
nsCacheAccessMode mode,
nsITransport **result ) = 0;
virtual nsresult OpenInputStreamForEntry(nsCacheEntry * entry,
nsCacheAccessMode mode,
PRUint32 offset,
nsIInputStream ** result) = 0;
virtual nsresult OpenOutputStreamForEntry(nsCacheEntry * entry,
nsCacheAccessMode mode,
PRUint32 offset,
nsIOutputStream ** result) = 0;
virtual nsresult GetFileForEntry( nsCacheEntry * entry,
nsIFile ** result ) = 0;

390
netwerk/cache/src/nsCacheEntryDescriptor.cpp поставляемый
Просмотреть файл

@ -233,14 +233,48 @@ nsCacheEntryDescriptor::SetDataSize(PRUint32 dataSize)
NS_IMETHODIMP
nsCacheEntryDescriptor::GetTransport(nsITransport ** result)
nsCacheEntryDescriptor::OpenInputStream(PRUint32 offset, nsIInputStream ** result)
{
NS_ENSURE_ARG_POINTER(result);
nsAutoLock lock(nsCacheService::ServiceLock());
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
if (!mCacheEntry->IsStreamData()) return NS_ERROR_CACHE_DATA_IS_NOT_STREAM;
NS_ADDREF(*result = &mTransportWrapper);
{
nsAutoLock lock(nsCacheService::ServiceLock());
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
if (!mCacheEntry->IsStreamData()) return NS_ERROR_CACHE_DATA_IS_NOT_STREAM;
// ensure valid permissions
if (!(mAccessGranted & nsICache::ACCESS_READ))
return NS_ERROR_CACHE_READ_ACCESS_DENIED;
}
nsInputStreamWrapper* cacheInput =
new nsInputStreamWrapper(this, offset);
if (!cacheInput) return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*result = cacheInput);
return NS_OK;
}
NS_IMETHODIMP
nsCacheEntryDescriptor::OpenOutputStream(PRUint32 offset, nsIOutputStream ** result)
{
NS_ENSURE_ARG_POINTER(result);
{
nsAutoLock lock(nsCacheService::ServiceLock());
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
if (!mCacheEntry->IsStreamData()) return NS_ERROR_CACHE_DATA_IS_NOT_STREAM;
// ensure valid permissions
if (!(mAccessGranted & nsICache::ACCESS_WRITE))
return NS_ERROR_CACHE_WRITE_ACCESS_DENIED;
}
nsOutputStreamWrapper* cacheOutput =
new nsOutputStreamWrapper(this, offset);
if (!cacheOutput) return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*result = cacheOutput);
return NS_OK;
}
@ -438,259 +472,122 @@ nsCacheEntryDescriptor::VisitMetaData(nsICacheMetaDataVisitor * visitor)
/******************************************************************************
* nsCacheTransportWrapper
* nsCacheInputStream - a wrapper for nsIInputstream keeps the cache entry
* open while referenced.
******************************************************************************/
NS_IMPL_QUERY_INTERFACE1(nsCacheEntryDescriptor::nsTransportWrapper, nsITransport)
// special AddRef and Release, because we are part of the descriptor
#define GET_DESCRIPTOR_FROM_TRANSPORT_WRAPPER(_this) \
((nsCacheEntryDescriptor*)((char*)(_this) - \
offsetof(nsCacheEntryDescriptor, mTransportWrapper)))
NS_IMETHODIMP_(nsrefcnt) nsCacheEntryDescriptor::
nsTransportWrapper::AddRef(void)
{
return GET_DESCRIPTOR_FROM_TRANSPORT_WRAPPER(this)->AddRef();
}
NS_IMETHODIMP_(nsrefcnt) nsCacheEntryDescriptor::
nsTransportWrapper::Release(void)
{
return GET_DESCRIPTOR_FROM_TRANSPORT_WRAPPER(this)->Release();
}
NS_IMPL_THREADSAFE_ISUPPORTS1(nsCacheEntryDescriptor::nsInputStreamWrapper,
nsIInputStream)
nsresult nsCacheEntryDescriptor::
nsTransportWrapper::EnsureTransportWithAccess(nsCacheAccessMode mode)
nsInputStreamWrapper::LazyInit()
{
nsresult rv = NS_OK;
nsAutoLock lock(nsCacheService::ServiceLock());
nsCacheEntryDescriptor * descriptor = GET_DESCRIPTOR_FROM_TRANSPORT_WRAPPER(this);
nsAutoLock lock(nsCacheService::ServiceLock());
if (!descriptor->mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
if (!descriptor->mAccessGranted & mode) {
rv = (mode == nsICache::ACCESS_READ) ?
NS_ERROR_CACHE_READ_ACCESS_DENIED : NS_ERROR_CACHE_WRITE_ACCESS_DENIED;
return rv;
}
if (!mTransport) {
rv = nsCacheService::GetTransportForEntry(descriptor->mCacheEntry,
descriptor->mAccessGranted,
getter_AddRefs(mTransport));
if (NS_FAILED(rv)) return rv;
if (mCallbacks) {
mTransport->SetNotificationCallbacks(mCallbacks, mCallbackFlags);
}
}
return NS_OK;
}
nsresult
nsCacheEntryDescriptor::NewOutputStreamWrapper(nsIOutputStream ** result,
nsCacheEntryDescriptor * descriptor,
nsIOutputStream * output)
{
nsOutputStreamWrapper* cacheOutput =
new nsOutputStreamWrapper(descriptor, output);
if (!cacheOutput) return NS_ERROR_OUT_OF_MEMORY;
nsCOMPtr<nsISupports> ref(cacheOutput);
nsresult rv = cacheOutput->Init();
nsCacheAccessMode mode;
nsresult rv = mDescriptor->GetAccessGranted(&mode);
if (NS_FAILED(rv)) return rv;
NS_ADDREF(*result = cacheOutput);
NS_ENSURE_TRUE(mode & nsICache::ACCESS_READ, NS_ERROR_UNEXPECTED);
nsCacheEntry* cacheEntry = mDescriptor->CacheEntry();
if (!cacheEntry) return NS_ERROR_NOT_AVAILABLE;
nsCOMPtr<nsIInputStream> input;
rv = nsCacheService::OpenInputStreamForEntry(cacheEntry, mode,
mStartOffset,
getter_AddRefs(mInput));
if (NS_FAILED(rv)) return rv;
mInitialized = PR_TRUE;
return NS_OK;
}
NS_IMETHODIMP nsCacheEntryDescriptor::
nsTransportWrapper::GetSecurityInfo(nsISupports ** securityInfo)
nsresult nsCacheEntryDescriptor::
nsInputStreamWrapper::Close()
{
nsresult rv = EnsureInit();
if (NS_FAILED(rv)) return rv;
return mInput->Close();
}
nsresult nsCacheEntryDescriptor::
nsInputStreamWrapper::Available(PRUint32 *avail)
{
nsresult rv = EnsureInit();
if (NS_FAILED(rv)) return rv;
return mInput->Available(avail);
}
nsresult nsCacheEntryDescriptor::
nsInputStreamWrapper::Read(char *buf, PRUint32 count, PRUint32 *countRead)
{
nsresult rv = EnsureInit();
if (NS_FAILED(rv)) return rv;
return mInput->Read(buf, count, countRead);
}
nsresult nsCacheEntryDescriptor::
nsInputStreamWrapper::ReadSegments(nsWriteSegmentFun writer, void *closure,
PRUint32 count, PRUint32 *countRead)
{
NS_NOTREACHED("cache stream not buffered");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsCacheEntryDescriptor::
nsTransportWrapper::GetNotificationCallbacks(nsIInterfaceRequestor **result)
nsresult nsCacheEntryDescriptor::
nsInputStreamWrapper::IsNonBlocking(PRBool *result)
{
NS_ENSURE_ARG_POINTER(result);
*result = mCallbacks;
NS_IF_ADDREF(*result);
// cache streams will never return NS_BASE_STREAM_WOULD_BLOCK
*result = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP nsCacheEntryDescriptor::
nsTransportWrapper::SetNotificationCallbacks(nsIInterfaceRequestor *requestor,
PRUint32 flags)
{
if (mTransport) {
mTransport->SetNotificationCallbacks(requestor, flags);
}
mCallbacks = requestor;
mCallbackFlags = flags;
return NS_OK;;
}
NS_IMETHODIMP nsCacheEntryDescriptor::
nsTransportWrapper::OpenInputStream(PRUint32 offset,
PRUint32 count,
PRUint32 flags,
nsIInputStream ** result)
{
NS_ENSURE_ARG_POINTER(result);
nsresult rv = EnsureTransportWithAccess(nsICache::ACCESS_READ);
if (NS_FAILED(rv)) return rv;
return mTransport->OpenInputStream(offset, count, flags, result);
}
NS_IMETHODIMP nsCacheEntryDescriptor::
nsTransportWrapper::OpenOutputStream(PRUint32 offset,
PRUint32 count,
PRUint32 flags,
nsIOutputStream ** result)
{
NS_ENSURE_ARG_POINTER(result);
nsresult rv = EnsureTransportWithAccess(nsICache::ACCESS_WRITE);
if (NS_FAILED(rv)) return rv;
// Create the underlying output stream using the wrapped transport.
nsCOMPtr<nsIOutputStream> output;
rv = mTransport->OpenOutputStream(offset, count, flags, getter_AddRefs(output));
if (NS_FAILED(rv)) return rv;
// Wrap this output stream with a stream that monitors how much data gets written,
// maintains the cache entry's size, and informs the cache device.
// This mechanism provides a way for the cache device to enforce space limits,
// and to drive cache entry eviction.
nsCacheEntryDescriptor * descriptor = GET_DESCRIPTOR_FROM_TRANSPORT_WRAPPER(this);
// reset datasize of entry based on offset so OnWrite calculates delta changes correctly.
rv = descriptor->SetDataSize(offset);
if (NS_FAILED(rv)) return rv;
return NewOutputStreamWrapper(result, descriptor, output);
}
NS_IMETHODIMP nsCacheEntryDescriptor::
nsTransportWrapper::AsyncRead(nsIStreamListener * listener,
nsISupports * ctxt,
PRUint32 offset,
PRUint32 count,
PRUint32 flags,
nsIRequest ** result)
{
NS_ENSURE_ARG_POINTER(result);
nsresult rv = EnsureTransportWithAccess(nsICache::ACCESS_READ);
if (NS_FAILED(rv)) return rv;
return mTransport->AsyncRead(listener, ctxt, offset, count, flags, result);
}
NS_IMETHODIMP nsCacheEntryDescriptor::
nsTransportWrapper::AsyncWrite(nsIStreamProvider * provider,
nsISupports * ctxt,
PRUint32 offset,
PRUint32 count,
PRUint32 flags,
nsIRequest ** result)
{
// we're not planning on implementing this
return NS_ERROR_NOT_IMPLEMENTED;
#if 0
NS_ENSURE_ARG_POINTER(result);
nsresult rv = EnsureTransportWithAccess(nsICache::ACCESS_WRITE);
if (NS_FAILED(rv)) return rv;
return mTransport->AsyncWrite(provider, ctxt, offset, count, flags, result);
#endif
}
/******************************************************************************
* nsCacheOutputStream - a wrapper for nsIOutputstream to track the amount of
* data written to a cache entry.
* - also keeps the cache entry open while referenced.
******************************************************************************/
NS_IMPL_ISUPPORTS1(nsCacheEntryDescriptor::nsOutputStreamWrapper, nsIOutputStream);
NS_IMPL_THREADSAFE_ISUPPORTS1(nsCacheEntryDescriptor::nsOutputStreamWrapper,
nsIOutputStream)
nsresult nsCacheEntryDescriptor::
nsOutputStreamWrapper::Init()
nsOutputStreamWrapper::LazyInit()
{
nsAutoLock lock(nsCacheService::ServiceLock());
nsCacheAccessMode mode;
nsresult rv = mDescriptor->GetAccessGranted(&mode);
if (NS_FAILED(rv)) return rv;
if (mode == nsICache::ACCESS_WRITE) {
nsAutoLock lock(nsCacheService::ServiceLock());
nsCacheEntry* cacheEntry = mDescriptor->CacheEntry();
if (!cacheEntry) return NS_ERROR_NOT_AVAILABLE;
NS_ENSURE_TRUE(mode & nsICache::ACCESS_WRITE, NS_ERROR_UNEXPECTED);
nsCacheDevice* device = cacheEntry->CacheDevice();
if (!device) return NS_ERROR_NOT_AVAILABLE;
nsCacheEntry* cacheEntry = mDescriptor->CacheEntry();
if (!cacheEntry) return NS_ERROR_NOT_AVAILABLE;
// the entry has been truncated to zero bytes, inform the device.
PRInt32 delta = cacheEntry->DataSize();
rv = device->OnDataSizeChange(cacheEntry, -delta);
cacheEntry->SetDataSize(0);
}
return rv;
}
NS_IMETHODIMP nsCacheEntryDescriptor::
nsOutputStreamWrapper::Write(const char * buf,
PRUint32 count,
PRUint32 * result)
{
nsresult rv = OnWrite(count);
rv = nsCacheService::OpenOutputStreamForEntry(cacheEntry, mode, mStartOffset,
getter_AddRefs(mOutput));
if (NS_FAILED(rv)) return rv;
return mOutput->Write(buf, count, result);
}
nsCacheDevice* device = cacheEntry->CacheDevice();
if (!device) return NS_ERROR_NOT_AVAILABLE;
NS_IMETHODIMP nsCacheEntryDescriptor::
nsOutputStreamWrapper::WriteFrom(nsIInputStream * inStr,
PRUint32 count,
PRUint32 * result)
{
nsresult rv = OnWrite(count);
// the entry has been truncated to mStartOffset bytes, inform the device.
PRInt32 size = cacheEntry->DataSize();
rv = device->OnDataSizeChange(cacheEntry, mStartOffset - size);
if (NS_FAILED(rv)) return rv;
return mOutput->WriteFrom(inStr, count, result);
cacheEntry->SetDataSize(mStartOffset);
mInitialized = PR_TRUE;
return NS_OK;
}
NS_IMETHODIMP nsCacheEntryDescriptor::
nsOutputStreamWrapper::WriteSegments(nsReadSegmentFun reader,
void * closure,
PRUint32 count,
PRUint32 * result)
{
nsresult rv = OnWrite(count);
if (NS_FAILED(rv)) return rv;
return mOutput->WriteSegments(reader, closure, count, result);
}
nsresult nsCacheEntryDescriptor::
nsOutputStreamWrapper::OnWrite(PRUint32 count)
{
@ -698,4 +595,61 @@ nsOutputStreamWrapper::OnWrite(PRUint32 count)
return mDescriptor->RequestDataSizeChange((PRInt32)count);
}
NS_IMETHODIMP nsCacheEntryDescriptor::
nsOutputStreamWrapper::Close()
{
nsresult rv = EnsureInit();
if (NS_FAILED(rv)) return rv;
return mOutput->Close();
}
NS_IMETHODIMP nsCacheEntryDescriptor::
nsOutputStreamWrapper::Flush()
{
nsresult rv = EnsureInit();
if (NS_FAILED(rv)) return rv;
return mOutput->Flush();
}
NS_IMETHODIMP nsCacheEntryDescriptor::
nsOutputStreamWrapper::Write(const char * buf,
PRUint32 count,
PRUint32 * result)
{
nsresult rv = EnsureInit();
if (NS_FAILED(rv)) return rv;
rv = OnWrite(count);
if (NS_FAILED(rv)) return rv;
return mOutput->Write(buf, count, result);
}
NS_IMETHODIMP nsCacheEntryDescriptor::
nsOutputStreamWrapper::WriteFrom(nsIInputStream * inStr,
PRUint32 count,
PRUint32 * result)
{
NS_NOTREACHED("cache stream not buffered");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsCacheEntryDescriptor::
nsOutputStreamWrapper::WriteSegments(nsReadSegmentFun reader,
void * closure,
PRUint32 count,
PRUint32 * result)
{
NS_NOTREACHED("cache stream not buffered");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsCacheEntryDescriptor::
nsOutputStreamWrapper::IsNonBlocking(PRBool *result)
{
// cache streams will never return NS_BASE_STREAM_WOULD_BLOCK
*result = PR_FALSE;
return NS_OK;
}

105
netwerk/cache/src/nsCacheEntryDescriptor.h поставляемый
Просмотреть файл

@ -27,10 +27,8 @@
#include "nsICacheEntryDescriptor.h"
#include "nsCacheEntry.h"
#include "nsIInputStream.h"
#include "nsIOutputStream.h"
#include "nsITransport.h"
#include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h"
/******************************************************************************
* nsCacheEntryDescriptor
@ -64,98 +62,85 @@ public:
private:
/*************************************************************************
* transport wrapper class -
* input stream wrapper class -
*
* we want the transport wrapper to have the same lifetime as the
* descriptor, but since they each need to reference the other, we have the
* descriptor include the transport wrapper as a member, rather than just
* pointing to it, which avoids circular AddRefs.
* The input stream wrapper references the descriptor, but the descriptor
* doesn't need any references to the stream wrapper.
*************************************************************************/
class nsTransportWrapper : public nsITransport
{
class nsInputStreamWrapper : public nsIInputStream {
private:
nsCacheEntryDescriptor * mDescriptor;
nsCOMPtr<nsIInputStream> mInput;
PRUint32 mStartOffset;
PRBool mInitialized;
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSITRANSPORT
NS_DECL_ISUPPORTS
NS_DECL_NSIINPUTSTREAM
nsTransportWrapper() : mCallbackFlags(0) {}
virtual ~nsTransportWrapper() {}
nsInputStreamWrapper(nsCacheEntryDescriptor * desc, PRUint32 off)
: mDescriptor(desc)
, mStartOffset(off)
, mInitialized(PR_FALSE)
{
NS_ADDREF(mDescriptor);
}
virtual ~nsInputStreamWrapper()
{
NS_RELEASE(mDescriptor);
}
nsresult EnsureTransportWithAccess(nsCacheAccessMode mode);
PRUint32 mCallbackFlags;
nsCOMPtr<nsITransport> mTransport;
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
}; // end of class nsTransportWrapper
friend class nsTransportWrapper;
private:
nsresult LazyInit();
nsresult EnsureInit() { return mInitialized ? NS_OK : LazyInit(); }
};
friend class nsInputStreamWrapper;
/*************************************************************************
* output stream wrapper class -
*
* The output stream wrapper references the descriptor, but the descriptor
* doesn't need any references to the stream wrapper, so we don't need the
* same kind of tricks that we're using for the transport wrapper.
* doesn't need any references to the stream wrapper.
*************************************************************************/
class nsOutputStreamWrapper : public nsIOutputStream {
private:
nsCacheEntryDescriptor * mDescriptor;
nsCOMPtr<nsIOutputStream> mOutput;
nsCacheEntryDescriptor * mDescriptor;
nsCOMPtr<nsIOutputStream> mOutput;
PRUint32 mStartOffset;
PRBool mInitialized;
public:
NS_DECL_ISUPPORTS
// NS_DECL_NSIOUTPUTSTREAM
NS_IMETHOD Close(void) { return mOutput->Close(); }
NS_IMETHOD Flush(void) { return mOutput->Flush(); }
NS_DECL_NSIOUTPUTSTREAM
NS_IMETHOD Write(const char * buf,
PRUint32 count,
PRUint32 * result);
NS_IMETHOD WriteFrom(nsIInputStream * inStr,
PRUint32 count,
PRUint32 * result);
NS_IMETHOD WriteSegments(nsReadSegmentFun reader,
void * closure,
PRUint32 count,
PRUint32 * result);
NS_IMETHOD IsNonBlocking(PRBool * nonBlocking)
{ return mOutput->IsNonBlocking(nonBlocking); }
nsOutputStreamWrapper(nsCacheEntryDescriptor * descriptor,
nsIOutputStream * output)
: mDescriptor(nsnull), mOutput(output)
nsOutputStreamWrapper(nsCacheEntryDescriptor * desc, PRUint32 off)
: mDescriptor(desc)
, mStartOffset(off)
, mInitialized(PR_FALSE)
{
NS_ADDREF(mDescriptor = descriptor);
NS_ADDREF(mDescriptor); // owning ref
}
virtual ~nsOutputStreamWrapper()
{
// XXX _HACK_ the storage stream needs this!
Close();
NS_RELEASE(mDescriptor);
}
nsresult Init();
private:
nsresult LazyInit();
nsresult EnsureInit() { return mInitialized ? NS_OK : LazyInit(); }
nsresult OnWrite(PRUint32 count);
}; // end of class nsOutputStreamWrapper
};
friend class nsOutputStreamWrapper;
static nsresult NewOutputStreamWrapper(nsIOutputStream ** result,
nsCacheEntryDescriptor * descriptor,
nsIOutputStream * output);
private:
/**
* nsCacheEntryDescriptor data members
*/
nsCacheEntry * mCacheEntry; // we are a child of the entry
nsCacheAccessMode mAccessGranted;
nsTransportWrapper mTransportWrapper;
};

22
netwerk/cache/src/nsCacheService.cpp поставляемый
Просмотреть файл

@ -40,6 +40,7 @@
#include "nsIPrefBranch.h"
#include "nsIPrefBranchInternal.h"
#include "nsIPref.h"
#include "nsILocalFile.h"
#include "nsDirectoryServiceDefs.h"
#include "nsAppDirectoryServiceDefs.h"
#include "nsVoidArray.h"
@ -1240,14 +1241,27 @@ nsCacheService::GetFileForEntry(nsCacheEntry * entry,
nsresult
nsCacheService::GetTransportForEntry(nsCacheEntry * entry,
nsCacheAccessMode mode,
nsITransport ** result)
nsCacheService::OpenInputStreamForEntry(nsCacheEntry * entry,
nsCacheAccessMode mode,
PRUint32 offset,
nsIInputStream ** result)
{
nsCacheDevice * device = gService->EnsureEntryHasDevice(entry);
if (!device) return NS_ERROR_UNEXPECTED;
return device->GetTransportForEntry(entry, mode, result);
return device->OpenInputStreamForEntry(entry, mode, offset, result);
}
nsresult
nsCacheService::OpenOutputStreamForEntry(nsCacheEntry * entry,
nsCacheAccessMode mode,
PRUint32 offset,
nsIOutputStream ** result)
{
nsCacheDevice * device = gService->EnsureEntryHasDevice(entry);
if (!device) return NS_ERROR_UNEXPECTED;
return device->OpenOutputStreamForEntry(entry, mode, offset, result);
}

12
netwerk/cache/src/nsCacheService.h поставляемый
Просмотреть файл

@ -86,9 +86,15 @@ public:
static nsresult GetFileForEntry(nsCacheEntry * entry,
nsIFile ** result);
static nsresult GetTransportForEntry(nsCacheEntry * entry,
nsCacheAccessMode mode,
nsITransport ** result);
static nsresult OpenInputStreamForEntry(nsCacheEntry * entry,
nsCacheAccessMode mode,
PRUint32 offset,
nsIInputStream ** result);
static nsresult OpenOutputStreamForEntry(nsCacheEntry * entry,
nsCacheAccessMode mode,
PRUint32 offset,
nsIOutputStream ** result);
static nsresult OnDataSizeChange(nsCacheEntry * entry, PRInt32 deltaSize);

19
netwerk/cache/src/nsDiskCacheBinding.cpp поставляемый
Просмотреть файл

@ -110,6 +110,7 @@ NS_IMPL_THREADSAFE_ISUPPORTS0(nsDiskCacheBinding);
nsDiskCacheBinding::nsDiskCacheBinding(nsCacheEntry* entry, nsDiskCacheRecord * record)
: mCacheEntry(entry)
, mStreamIO(nsnull)
{
NS_ASSERTION(record->ValidRecord(), "bad record");
PR_INIT_CLIST(this);
@ -125,9 +126,21 @@ nsDiskCacheBinding::~nsDiskCacheBinding()
PR_REMOVE_LINK(this); // XXX why are we still on a list?
// sever streamIO/binding link
// XXX what's the right way to call a method on the concrete class?
nsDiskCacheStreamIO * streamIO = (nsDiskCacheStreamIO *)mStreamIO.get();
if (streamIO) streamIO->ClearBinding();
if (mStreamIO) {
mStreamIO->ClearBinding();
NS_RELEASE(mStreamIO);
}
}
nsresult
nsDiskCacheBinding::EnsureStreamIO()
{
if (!mStreamIO) {
mStreamIO = new nsDiskCacheStreamIO(this);
if (!mStreamIO) return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(mStreamIO);
}
return NS_OK;
}

3
netwerk/cache/src/nsDiskCacheBinding.h поставляемый
Просмотреть файл

@ -52,12 +52,13 @@ public:
nsDiskCacheBinding(nsCacheEntry* entry, nsDiskCacheRecord * record);
virtual ~nsDiskCacheBinding();
nsresult EnsureStreamIO();
// XXX make friends
public:
nsCacheEntry* mCacheEntry; // back pointer to parent nsCacheEntry
nsDiskCacheRecord mRecord;
nsCOMPtr<nsIStreamIO> mStreamIO;
nsDiskCacheStreamIO* mStreamIO;
PRBool mDoomed; // record is not stored in cache map
PRUint8 mGeneration; // possibly just reservation
};

58
netwerk/cache/src/nsDiskCacheDevice.cpp поставляемый
Просмотреть файл

@ -55,8 +55,6 @@
#include "nsCacheService.h"
#include "nsCache.h"
#include "nsIFileTransportService.h"
#include "nsITransport.h"
#include "nsICacheVisitor.h"
#include "nsXPIDLString.h"
#include "nsReadableUtils.h"
@ -310,7 +308,6 @@ nsDiskCache::Truncate(PRFileDesc * fd, PRUint32 newEOF)
/******************************************************************************
* nsDiskCacheDevice
*****************************************************************************/
static nsCOMPtr<nsIFileTransportService> gFileTransportService;
#ifdef XP_MAC
#pragma mark -
@ -345,10 +342,6 @@ nsDiskCacheDevice::Init()
rv = mBindery.Init();
if (NS_FAILED(rv)) return rv;
// hold the file transport service to avoid excessive calls to the service manager.
gFileTransportService = do_GetService("@mozilla.org/network/file-transport-service;1", &rv);
if (NS_FAILED(rv)) return rv;
// XXX we should spawn another thread to do this after startup
// delete "Cache.Trash" folder
nsCOMPtr<nsIFile> cacheTrashDir;
@ -379,7 +372,6 @@ error_exit:
delete mCacheMap;
mCacheMap = nsnull;
}
gFileTransportService = nsnull;
return rv;
}
@ -405,9 +397,6 @@ nsDiskCacheDevice::Shutdown()
mInitialized = PR_FALSE;
}
// release the reference to the cached file transport service.
gFileTransportService = nsnull;
return NS_OK;
}
@ -596,33 +585,52 @@ nsDiskCacheDevice::DoomEntry(nsCacheEntry * entry)
}
}
/**
* NOTE: called while holding the cache service lock
*/
nsresult
nsDiskCacheDevice::GetTransportForEntry(nsCacheEntry * entry,
nsCacheAccessMode mode,
nsITransport ** result)
nsDiskCacheDevice::OpenInputStreamForEntry(nsCacheEntry * entry,
nsCacheAccessMode mode,
PRUint32 offset,
nsIInputStream ** result)
{
NS_ENSURE_ARG_POINTER(entry);
NS_ENSURE_ARG_POINTER(result);
nsresult rv;
nsDiskCacheBinding * binding = GetCacheEntryBinding(entry);
NS_ASSERTION(binding, "GetTransportForEntry: binding == nsnull");
if (!binding) return NS_ERROR_UNEXPECTED;
NS_ENSURE_TRUE(binding, NS_ERROR_UNEXPECTED);
NS_ASSERTION(binding->mCacheEntry == entry, "binding & entry don't point to each other");
if (!binding->mStreamIO) {
binding->mStreamIO = new nsDiskCacheStreamIO(binding);
if (!binding->mStreamIO) return NS_ERROR_OUT_OF_MEMORY;
}
// XXX assumption: CreateTransportFromStreamIO() is light-weight
// PR_FALSE = keep streamIO open for lifetime of transport
rv = gFileTransportService->CreateTransportFromStreamIO(binding->mStreamIO, PR_FALSE, result);
return rv;
rv = binding->EnsureStreamIO();
if (NS_FAILED(rv)) return rv;
return binding->mStreamIO->GetInputStream(offset, result);
}
/**
* NOTE: called while holding the cache service lock
*/
nsresult
nsDiskCacheDevice::OpenOutputStreamForEntry(nsCacheEntry * entry,
nsCacheAccessMode mode,
PRUint32 offset,
nsIOutputStream ** result)
{
NS_ENSURE_ARG_POINTER(entry);
NS_ENSURE_ARG_POINTER(result);
nsresult rv;
nsDiskCacheBinding * binding = GetCacheEntryBinding(entry);
NS_ENSURE_TRUE(binding, NS_ERROR_UNEXPECTED);
NS_ASSERTION(binding->mCacheEntry == entry, "binding & entry don't point to each other");
rv = binding->EnsureStreamIO();
if (NS_FAILED(rv)) return rv;
return binding->mStreamIO->GetOutputStream(offset, result);
}

12
netwerk/cache/src/nsDiskCacheDevice.h поставляемый
Просмотреть файл

@ -52,9 +52,15 @@ public:
virtual nsresult BindEntry(nsCacheEntry * entry);
virtual void DoomEntry( nsCacheEntry * entry );
virtual nsresult GetTransportForEntry(nsCacheEntry * entry,
nsCacheAccessMode mode,
nsITransport ** result);
virtual nsresult OpenInputStreamForEntry(nsCacheEntry * entry,
nsCacheAccessMode mode,
PRUint32 offset,
nsIInputStream ** result);
virtual nsresult OpenOutputStreamForEntry(nsCacheEntry * entry,
nsCacheAccessMode mode,
PRUint32 offset,
nsIOutputStream ** result);
virtual nsresult GetFileForEntry(nsCacheEntry * entry,
nsIFile ** result);

136
netwerk/cache/src/nsDiskCacheStreams.cpp поставляемый
Просмотреть файл

@ -29,7 +29,6 @@
#include "nsIInputStream.h"
#include "nsIOutputStream.h"
#include "nsISeekableStream.h"
#include "nsAutoLock.h"
@ -64,7 +63,7 @@ public:
private:
friend class nsDiskCacheStreamIO;
nsCOMPtr<nsDiskCacheStreamIO> mStreamIO; // backpointer to parent
nsDiskCacheStreamIO * mStreamIO; // backpointer to parent
PRFileDesc * mFD;
const char * mBuffer;
PRUint32 mStreamEnd;
@ -73,7 +72,7 @@ private:
};
NS_IMPL_THREADSAFE_ISUPPORTS1(nsDiskCacheInputStream, nsIInputStream);
NS_IMPL_THREADSAFE_ISUPPORTS1(nsDiskCacheInputStream, nsIInputStream)
nsDiskCacheInputStream::nsDiskCacheInputStream( nsDiskCacheStreamIO * parent,
@ -87,6 +86,7 @@ nsDiskCacheInputStream::nsDiskCacheInputStream( nsDiskCacheStreamIO * parent,
, mPos(0)
, mClosed(PR_FALSE)
{
NS_ADDREF(mStreamIO);
mStreamIO->IncrementInputStreamCount();
}
@ -95,6 +95,7 @@ nsDiskCacheInputStream::~nsDiskCacheInputStream()
{
Close();
mStreamIO->DecrementInputStreamCount();
NS_RELEASE(mStreamIO);
}
@ -182,37 +183,37 @@ nsDiskCacheInputStream::IsNonBlocking(PRBool * nonBlocking)
#pragma mark -
#pragma mark nsDiskCacheOutputStream
#endif
class nsDiskCacheOutputStream : public nsIOutputStream, nsISeekableStream {
class nsDiskCacheOutputStream : public nsIOutputStream {
public:
nsDiskCacheOutputStream( nsDiskCacheStreamIO * parent);
virtual ~nsDiskCacheOutputStream();
nsDiskCacheOutputStream( nsDiskCacheStreamIO * parent);
virtual ~nsDiskCacheOutputStream();
NS_DECL_ISUPPORTS
NS_DECL_NSIOUTPUTSTREAM
NS_DECL_NSISEEKABLESTREAM
NS_DECL_ISUPPORTS
NS_DECL_NSIOUTPUTSTREAM
private:
friend class nsDiskCacheStreamIO;
nsCOMPtr<nsDiskCacheStreamIO> mStreamIO; // backpointer to parent
nsDiskCacheStreamIO * mStreamIO; // backpointer to parent
PRBool mClosed;
};
NS_IMPL_THREADSAFE_ISUPPORTS2(nsDiskCacheOutputStream, nsIOutputStream, nsISeekableStream);
NS_IMPL_THREADSAFE_ISUPPORTS1(nsDiskCacheOutputStream,
nsIOutputStream)
nsDiskCacheOutputStream::nsDiskCacheOutputStream( nsDiskCacheStreamIO * parent)
: mStreamIO(parent)
, mClosed(PR_FALSE)
{
NS_ADDREF(mStreamIO);
}
nsDiskCacheOutputStream::~nsDiskCacheOutputStream()
{
Close();
NS_RELEASE(mStreamIO);
}
@ -264,30 +265,6 @@ nsDiskCacheOutputStream::WriteSegments( nsReadSegmentFun reader,
}
NS_IMETHODIMP
nsDiskCacheOutputStream::Seek(PRInt32 whence, PRInt32 offset)
{
if (mClosed) return NS_ERROR_NOT_AVAILABLE;
return mStreamIO->Seek(whence, offset);
}
NS_IMETHODIMP
nsDiskCacheOutputStream::Tell(PRUint32 * result)
{
if (mClosed) return NS_ERROR_NOT_AVAILABLE;
return mStreamIO->Tell(result);
}
NS_IMETHODIMP
nsDiskCacheOutputStream::SetEOF()
{
if (mClosed) return NS_ERROR_NOT_AVAILABLE;
return mStreamIO->SetEOF();
}
NS_IMETHODIMP
nsDiskCacheOutputStream::IsNonBlocking(PRBool * nonBlocking)
{
@ -305,7 +282,7 @@ nsDiskCacheOutputStream::IsNonBlocking(PRBool * nonBlocking)
#pragma mark nsDiskCacheStreamIO
#endif
NS_IMPL_THREADSAFE_ISUPPORTS1(nsDiskCacheStreamIO, nsIStreamIO);
NS_IMPL_THREADSAFE_ISUPPORTS0(nsDiskCacheStreamIO)
// we pick 16k as the max buffer size because that is the threshold above which
// we are unable to store the data in the cache block files
@ -335,7 +312,7 @@ nsDiskCacheStreamIO::nsDiskCacheStreamIO(nsDiskCacheBinding * binding)
nsDiskCacheStreamIO::~nsDiskCacheStreamIO()
{
(void) Close(NS_OK);
Close();
// release "death grip" on cache service
nsCacheService *service = nsCacheService::GlobalInstance();
@ -343,15 +320,8 @@ nsDiskCacheStreamIO::~nsDiskCacheStreamIO()
}
NS_IMETHODIMP
nsDiskCacheStreamIO::Open()
{
return NS_OK;
}
NS_IMETHODIMP
nsDiskCacheStreamIO::Close(nsresult status)
void
nsDiskCacheStreamIO::Close()
{
// this should only be called from our destructor
// no one is interested in us anymore, so we don't need to grab any locks
@ -362,18 +332,18 @@ nsDiskCacheStreamIO::Close(nsresult status)
NS_ASSERTION(!mFD, "file descriptor not closed");
DeleteBuffer();
return NS_OK;
}
NS_IMETHODIMP
nsDiskCacheStreamIO::GetInputStream(nsIInputStream ** inputStream)
// NOTE: called with service lock held
nsresult
nsDiskCacheStreamIO::GetInputStream(PRUint32 offset, nsIInputStream ** inputStream)
{
NS_ENSURE_ARG_POINTER(inputStream);
NS_ENSURE_TRUE(offset == 0, NS_ERROR_NOT_IMPLEMENTED);
*inputStream = nsnull;
nsAutoLock lock(nsCacheService::ServiceLock()); // grab service lock
if (!mBinding) return NS_ERROR_NOT_AVAILABLE;
if (mOutStream) {
@ -413,13 +383,13 @@ nsDiskCacheStreamIO::GetInputStream(nsIInputStream ** inputStream)
}
NS_IMETHODIMP
nsDiskCacheStreamIO::GetOutputStream(nsIOutputStream ** outputStream)
// NOTE: called with service lock held
nsresult
nsDiskCacheStreamIO::GetOutputStream(PRUint32 offset, nsIOutputStream ** outputStream)
{
NS_ENSURE_ARG_POINTER(outputStream);
*outputStream = nsnull;
nsAutoLock lock(nsCacheService::ServiceLock()); // grab service lock
if (!mBinding) return NS_ERROR_NOT_AVAILABLE;
NS_ASSERTION(!mOutStream, "already have an output stream open");
@ -432,6 +402,14 @@ nsDiskCacheStreamIO::GetOutputStream(nsIOutputStream ** outputStream)
mStreamPos = 0;
mStreamEnd = mBinding->mCacheEntry->DataSize();
nsresult rv;
if (offset) {
rv = Seek(PR_SEEK_SET, offset);
if (NS_FAILED(rv)) return rv;
}
rv = SetEOF();
if (NS_FAILED(rv)) return rv;
// create a new output stream
mOutStream = new nsDiskCacheOutputStream(this);
if (!mOutStream) return NS_ERROR_OUT_OF_MEMORY;
@ -440,40 +418,6 @@ nsDiskCacheStreamIO::GetOutputStream(nsIOutputStream ** outputStream)
return NS_OK;
}
NS_IMETHODIMP
nsDiskCacheStreamIO::GetName(nsACString & name)
{
name = NS_LITERAL_CSTRING("nsDiskCacheStreamIO");
return NS_OK;
}
NS_IMETHODIMP
nsDiskCacheStreamIO::GetContentType(nsACString & contentType)
{
contentType.Truncate();
return NS_OK;
}
NS_IMETHODIMP
nsDiskCacheStreamIO::GetContentCharset(nsACString & contentCharset)
{
contentCharset.Truncate();
return NS_OK;
}
NS_IMETHODIMP
nsDiskCacheStreamIO::GetContentLength(PRInt32 *contentLength)
{
NS_ENSURE_ARG_POINTER(contentLength);
*contentLength = -1;
return NS_OK;
}
void
nsDiskCacheStreamIO::ClearBinding()
{
@ -799,12 +743,12 @@ nsDiskCacheStreamIO::DeleteBuffer()
}
// called only from nsDiskCacheOutputStream::Seek
// NOTE: called with service lock held
nsresult
nsDiskCacheStreamIO::Seek(PRInt32 whence, PRInt32 offset)
{
PRInt32 newPos;
nsAutoLock lock(nsCacheService::ServiceLock()); // grab service lock
//nsAutoLock lock(nsCacheService::ServiceLock()); // grab service lock
if (!mBinding) return NS_ERROR_NOT_AVAILABLE;
if (PRUint32(offset) > mStreamEnd) return NS_ERROR_FAILURE;
@ -891,17 +835,11 @@ nsDiskCacheStreamIO::Tell(PRUint32 * result)
}
// SetEOF() will only be called by FileTransport.
// nsCacheEntryDescriptor::TransportWrapper::OpenOutputStream() will eventually update
// the cache entry, so we need only update the underlying data structure here.
//
// called only from nsDiskCacheOutputStream::SetEOF
// NOTE: called with service lock held
nsresult
nsDiskCacheStreamIO::SetEOF()
{
nsresult rv;
nsAutoLock lock(nsCacheService::ServiceLock()); // grab service lock
NS_ASSERTION(mStreamPos <= mStreamEnd, "bad stream");
if (!mBinding) return NS_ERROR_NOT_AVAILABLE;

15
netwerk/cache/src/nsDiskCacheStreams.h поставляемый
Просмотреть файл

@ -29,7 +29,6 @@
#include "nsCache.h"
#include "nsIStreamIO.h"
#include "nsIInputStream.h"
#include "nsIOutputStream.h"
@ -39,20 +38,17 @@ class nsDiskCacheInputStream;
class nsDiskCacheOutputStream;
class nsDiskCacheDevice;
class nsDiskCacheStreamIO : public nsIStreamIO {
// we're implementing nsIStreamIO to leverage the AsyncRead on the FileTransport thread
class nsDiskCacheStreamIO : public nsISupports {
public:
nsDiskCacheStreamIO(nsDiskCacheBinding * binding);
virtual ~nsDiskCacheStreamIO();
NS_DECL_ISUPPORTS
NS_DECL_NSISTREAMIO
// NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISUPPORTS_IID)
void CloseInputStream(nsDiskCacheInputStream * inputStream);
nsresult CloseOutputStream(nsDiskCacheOutputStream * outputStream);
nsresult GetInputStream(PRUint32 offset, nsIInputStream ** inputStream);
nsresult GetOutputStream(PRUint32 offset, nsIOutputStream ** outputStream);
nsresult CloseOutputStream(nsDiskCacheOutputStream * outputStream);
nsresult Write( const char * buffer,
PRUint32 count,
@ -77,6 +73,7 @@ public:
private:
void Close();
nsresult OpenCacheFile(PRIntn flags, PRFileDesc ** fd);
nsresult ReadCacheBlocks();
nsresult FlushBufferToFile(PRBool clearBuffer); // XXX clearBuffer is always PR_TRUE

81
netwerk/cache/src/nsMemoryCacheDevice.cpp поставляемый
Просмотреть файл

@ -25,19 +25,11 @@
#include "nsMemoryCacheDevice.h"
#include "nsCacheService.h"
#include "nsICacheService.h"
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
#include "nsNetCID.h"
#include "nsIObserverService.h"
#include "nsIPref.h"
#include "nsIStorageStream.h"
#include "nsICacheVisitor.h"
#include "nsITransport.h"
#include "nsCRT.h"
#include <signal.h>
static NS_DEFINE_CID(kStorageTransportCID, NS_STORAGETRANSPORT_CID);
const char *gMemoryDeviceID = "memory";
@ -69,7 +61,7 @@ nsMemoryCacheDevice::Init()
nsresult rv = mMemCacheEntries.Init();
// set some default memory limits, in case prefs aren't available
mSoftLimit = mHardLimit * 0.9;
mSoftLimit = (mHardLimit * 9) / 10;
mInitialized = NS_SUCCEEDED(rv);
return rv;
@ -208,32 +200,65 @@ nsMemoryCacheDevice::DoomEntry(nsCacheEntry * entry)
nsresult
nsMemoryCacheDevice::GetTransportForEntry( nsCacheEntry * entry,
nsCacheAccessMode mode,
nsITransport ** transport )
nsMemoryCacheDevice::OpenInputStreamForEntry( nsCacheEntry * entry,
nsCacheAccessMode mode,
PRUint32 offset,
nsIInputStream ** result)
{
NS_ENSURE_ARG_POINTER(entry);
NS_ENSURE_ARG_POINTER(transport);
NS_ENSURE_ARG_POINTER(result);
nsCOMPtr<nsISupports> data;
nsCOMPtr<nsIStorageStream> storage;
nsresult rv = entry->GetData(getter_AddRefs(data));
if (NS_FAILED(rv))
return rv;
if (data)
return CallQueryInterface(data, transport);
else {
// create a new transport for this entry
rv = nsComponentManager::CreateInstance(kStorageTransportCID,
nsnull,
NS_GET_IID(nsITransport),
(void **) transport);
if (NS_FAILED(rv)) return rv;
entry->SetData(*transport);
return NS_OK;
if (data) {
storage = do_QueryInterface(data, &rv);
if (NS_FAILED(rv))
return rv;
}
else {
rv = NS_NewStorageStream(4096, PRUint32(-1), getter_AddRefs(storage));
if (NS_FAILED(rv))
return rv;
entry->SetData(storage);
}
return storage->NewInputStream(offset, result);
}
nsresult
nsMemoryCacheDevice::OpenOutputStreamForEntry( nsCacheEntry * entry,
nsCacheAccessMode mode,
PRUint32 offset,
nsIOutputStream ** result)
{
NS_ENSURE_ARG_POINTER(entry);
NS_ENSURE_ARG_POINTER(result);
nsCOMPtr<nsISupports> data;
nsCOMPtr<nsIStorageStream> storage;
nsresult rv = entry->GetData(getter_AddRefs(data));
if (NS_FAILED(rv))
return rv;
if (data) {
storage = do_QueryInterface(data, &rv);
if (NS_FAILED(rv))
return rv;
}
else {
rv = NS_NewStorageStream(4096, PRUint32(-1), getter_AddRefs(storage));
if (NS_FAILED(rv))
return rv;
entry->SetData(storage);
}
return storage->GetOutputStream(offset, result);
}
@ -251,7 +276,7 @@ nsMemoryCacheDevice::OnDataSizeChange( nsCacheEntry * entry, PRInt32 deltaSize)
if (entry->IsStreamData()) {
// we have the right to refuse or pre-evict
PRUint32 newSize = entry->DataSize() + deltaSize;
if (newSize > mSoftLimit) {
if ((PRInt32) newSize > mSoftLimit) {
nsresult rv = nsCacheService::DoomEntry(entry);
NS_ASSERTION(NS_SUCCEEDED(rv),"DoomEntry() failed.");
return NS_ERROR_ABORT;
@ -407,7 +432,7 @@ void
nsMemoryCacheDevice::SetCapacity(PRInt32 capacity)
{
PRInt32 hardLimit = capacity * 1024; // convert k into bytes
PRInt32 softLimit = hardLimit * 0.9;
PRInt32 softLimit = (hardLimit * 9) / 10;
AdjustMemoryLimits(softLimit, hardLimit);
}

12
netwerk/cache/src/nsMemoryCacheDevice.h поставляемый
Просмотреть файл

@ -50,9 +50,15 @@ public:
virtual void DoomEntry( nsCacheEntry * entry );
virtual nsresult DeactivateEntry( nsCacheEntry * entry );
virtual nsresult GetTransportForEntry( nsCacheEntry * entry,
nsCacheAccessMode mode,
nsITransport **transport );
virtual nsresult OpenInputStreamForEntry(nsCacheEntry * entry,
nsCacheAccessMode mode,
PRUint32 offset,
nsIInputStream ** result);
virtual nsresult OpenOutputStreamForEntry(nsCacheEntry * entry,
nsCacheAccessMode mode,
PRUint32 offset,
nsIOutputStream ** result);
virtual nsresult GetFileForEntry( nsCacheEntry * entry,
nsIFile ** result );

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

@ -1008,14 +1008,14 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsSocketTransport.cpp</PATH>
<PATH>nsSocketTransport2.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsSocketTransportService.cpp</PATH>
<PATH>nsSocketTransportService2.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
@ -1085,14 +1085,14 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsFileTransportService.cpp</PATH>
<PATH>nsStreamTransportService.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsFileTransport.cpp</PATH>
<PATH>nsInputStreamPump.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
@ -1386,28 +1386,7 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsSimpleStreamProvider.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsStreamListenerProxy.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsStreamProviderProxy.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsStorageTransport.cpp</PATH>
<PATH>nsAsyncStreamCopier.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
@ -1765,12 +1744,12 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsFileTransportService.cpp</PATH>
<PATH>nsStreamTransportService.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsFileTransport.cpp</PATH>
<PATH>nsInputStreamPump.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
@ -1780,12 +1759,12 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsSocketTransport.cpp</PATH>
<PATH>nsSocketTransport2.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsSocketTransportService.cpp</PATH>
<PATH>nsSocketTransportService2.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
@ -2050,22 +2029,7 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsSimpleStreamProvider.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsStreamListenerProxy.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsStreamProviderProxy.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsStorageTransport.cpp</PATH>
<PATH>nsAsyncStreamCopier.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
@ -3260,14 +3224,14 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsSocketTransport.cpp</PATH>
<PATH>nsSocketTransport2.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsSocketTransportService.cpp</PATH>
<PATH>nsSocketTransportService2.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
@ -3337,14 +3301,14 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsFileTransportService.cpp</PATH>
<PATH>nsStreamTransportService.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsFileTransport.cpp</PATH>
<PATH>nsInputStreamPump.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
@ -3638,28 +3602,7 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsSimpleStreamProvider.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsStreamListenerProxy.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsStreamProviderProxy.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsStorageTransport.cpp</PATH>
<PATH>nsAsyncStreamCopier.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
@ -4017,12 +3960,12 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsFileTransportService.cpp</PATH>
<PATH>nsStreamTransportService.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsFileTransport.cpp</PATH>
<PATH>nsInputStreamPump.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
@ -4032,12 +3975,12 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsSocketTransport.cpp</PATH>
<PATH>nsSocketTransport2.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsSocketTransportService.cpp</PATH>
<PATH>nsSocketTransportService2.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
@ -4302,22 +4245,7 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsSimpleStreamProvider.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsStreamListenerProxy.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsStreamProviderProxy.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsStorageTransport.cpp</PATH>
<PATH>nsAsyncStreamCopier.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
@ -5512,14 +5440,14 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsSocketTransport.cpp</PATH>
<PATH>nsSocketTransport2.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsSocketTransportService.cpp</PATH>
<PATH>nsSocketTransportService2.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
@ -5589,14 +5517,14 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsFileTransportService.cpp</PATH>
<PATH>nsStreamTransportService.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsFileTransport.cpp</PATH>
<PATH>nsInputStreamPump.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
@ -5876,28 +5804,7 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsSimpleStreamProvider.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsStreamListenerProxy.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsStreamProviderProxy.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsStorageTransport.cpp</PATH>
<PATH>nsAsyncStreamCopier.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
@ -6255,12 +6162,12 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsFileTransportService.cpp</PATH>
<PATH>nsStreamTransportService.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsFileTransport.cpp</PATH>
<PATH>nsInputStreamPump.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
@ -6270,12 +6177,12 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsSocketTransport.cpp</PATH>
<PATH>nsSocketTransport2.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsSocketTransportService.cpp</PATH>
<PATH>nsSocketTransportService2.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
@ -6530,22 +6437,7 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsSimpleStreamProvider.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsStreamListenerProxy.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsStreamProviderProxy.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsStorageTransport.cpp</PATH>
<PATH>nsAsyncStreamCopier.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
@ -7740,14 +7632,14 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsSocketTransport.cpp</PATH>
<PATH>nsSocketTransport2.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsSocketTransportService.cpp</PATH>
<PATH>nsSocketTransportService2.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
@ -7817,14 +7709,14 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsFileTransportService.cpp</PATH>
<PATH>nsStreamTransportService.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsFileTransport.cpp</PATH>
<PATH>nsInputStreamPump.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
@ -8104,28 +7996,7 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsSimpleStreamProvider.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsStreamListenerProxy.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsStreamProviderProxy.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsStorageTransport.cpp</PATH>
<PATH>nsAsyncStreamCopier.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
@ -8483,12 +8354,12 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsFileTransportService.cpp</PATH>
<PATH>nsStreamTransportService.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsFileTransport.cpp</PATH>
<PATH>nsInputStreamPump.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
@ -8498,12 +8369,12 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsSocketTransport.cpp</PATH>
<PATH>nsSocketTransport2.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsSocketTransportService.cpp</PATH>
<PATH>nsSocketTransportService2.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
@ -8758,22 +8629,7 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsSimpleStreamProvider.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsStreamListenerProxy.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsStreamProviderProxy.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsStorageTransport.cpp</PATH>
<PATH>nsAsyncStreamCopier.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
@ -9063,13 +8919,13 @@
<FILEREF>
<TARGETNAME>Necko.shlb</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsFileTransport.cpp</PATH>
<PATH>nsInputStreamPump.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<TARGETNAME>Necko.shlb</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsFileTransportService.cpp</PATH>
<PATH>nsStreamTransportService.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
@ -9135,7 +8991,7 @@
<FILEREF>
<TARGETNAME>Necko.shlb</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsSimpleStreamProvider.cpp</PATH>
<PATH>nsAsyncStreamCopier.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
@ -9147,13 +9003,13 @@
<FILEREF>
<TARGETNAME>Necko.shlb</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsSocketTransport.cpp</PATH>
<PATH>nsSocketTransport2.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<TARGETNAME>Necko.shlb</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsSocketTransportService.cpp</PATH>
<PATH>nsSocketTransportService2.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
@ -9162,18 +9018,6 @@
<PATH>nsStandardURL.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<TARGETNAME>Necko.shlb</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsStorageTransport.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<TARGETNAME>Necko.shlb</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsStreamListenerProxy.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<TARGETNAME>Necko.shlb</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
@ -9192,12 +9036,6 @@
<PATH>nsUnicharStreamLoader.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<TARGETNAME>Necko.shlb</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsStreamProviderProxy.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<TARGETNAME>Necko.shlb</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -26,8 +26,16 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS = about data file ftp http keyword jar res \
gopher viewsource
DIRS = about \
data \
keyword \
res \
file \
jar \
http \
viewsource \
ftp \
gopher \
$(NULL)
include $(topsrcdir)/config/rules.mk

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

@ -58,8 +58,7 @@ nsAboutBlank::NewChannel(nsIURI *aURI, nsIChannel **result)
rv = NS_NewInputStreamChannel(&channel, aURI, in,
NS_LITERAL_CSTRING("text/html"),
NS_LITERAL_CSTRING(""),
strlen(kBlankPage));
NS_LITERAL_CSTRING(""));
if (NS_FAILED(rv)) return rv;
*result = channel;

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

@ -81,15 +81,12 @@ nsAboutBloat::NewChannel(nsIURI *aURI, nsIChannel **result)
}
nsCOMPtr<nsIInputStream> inStr;
PRUint32 size;
if (clear) {
nsTraceRefcnt::ResetStatistics();
const char* msg = "Bloat statistics cleared.";
rv = NS_NewCStringInputStream(getter_AddRefs(inStr), nsDependentCString(msg));
if (NS_FAILED(rv)) return rv;
size = strlen(msg);
}
else if (leaks) {
// dump the current set of leaks.
@ -98,8 +95,6 @@ nsAboutBloat::NewChannel(nsIURI *aURI, nsIChannel **result)
const char* msg = "Memory leaks dumped.";
rv = NS_NewCStringInputStream(getter_AddRefs(inStr), nsDependentCString(msg));
if (NS_FAILED(rv)) return rv;
size = strlen(msg);
}
else {
nsCOMPtr<nsIFile> file;
@ -146,11 +141,6 @@ nsAboutBloat::NewChannel(nsIURI *aURI, nsIChannel **result)
::fclose(out);
if (NS_FAILED(rv)) return rv;
PRInt64 bigSize;
rv = file->GetFileSize(&bigSize);
if (NS_FAILED(rv)) return rv;
LL_L2UI(size, bigSize);
rv = NS_NewLocalFileInputStream(getter_AddRefs(inStr), file);
if (NS_FAILED(rv)) return rv;
}
@ -158,8 +148,7 @@ nsAboutBloat::NewChannel(nsIURI *aURI, nsIChannel **result)
nsIChannel* channel;
rv = NS_NewInputStreamChannel(&channel, aURI, inStr,
NS_LITERAL_CSTRING("text/plain"),
NS_LITERAL_CSTRING(""),
size);
NS_LITERAL_CSTRING(""));
if (NS_FAILED(rv)) return rv;
*result = channel;

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

@ -139,10 +139,6 @@ nsAboutCache::NewChannel(nsIURI *aURI, nsIChannel **result)
outputStream->Write(mBuffer.get(), mBuffer.Length(), &bytesWritten);
nsCOMPtr<nsIInputStream> inStr;
PRUint32 size;
rv = storageStream->GetLength(&size);
if (NS_FAILED(rv)) return rv;
rv = storageStream->NewInputStream(0, getter_AddRefs(inStr));
if (NS_FAILED(rv)) return rv;
@ -150,8 +146,7 @@ nsAboutCache::NewChannel(nsIURI *aURI, nsIChannel **result)
nsIChannel* channel;
rv = NS_NewInputStreamChannel(&channel, aURI, inStr,
NS_LITERAL_CSTRING("text/html"),
NS_LITERAL_CSTRING(""),
size);
NS_LITERAL_CSTRING(""));
if (NS_FAILED(rv)) return rv;
*result = channel;

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

@ -66,11 +66,13 @@ nsAboutCacheEntry::NewChannel(nsIURI *aURI, nsIChannel **result)
{
nsresult rv;
nsCOMPtr<nsIStreamIOChannel> chan;
rv = NS_NewStreamIOChannel(getter_AddRefs(chan), aURI, nsnull);
nsCOMPtr<nsIChannel> chan;
rv = NS_NewInputStreamChannel(getter_AddRefs(chan), aURI, nsnull,
NS_LITERAL_CSTRING("application/xhtml+xml"));
if (NS_FAILED(rv)) return rv;
mStreamChannel = do_QueryInterface(chan);
mStreamChannel = do_QueryInterface(chan, &rv);
if (NS_FAILED(rv)) return rv;
return CallQueryInterface((nsIAboutModule *) this, result);
}
@ -125,24 +127,7 @@ nsAboutCacheEntry::OnCacheEntryAvailable(nsICacheEntryDescriptor *descriptor,
rv = storageStream->NewInputStream(0, getter_AddRefs(inStr));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIURI> uri;
rv = mStreamChannel->GetURI(getter_AddRefs(uri));
if (NS_FAILED(rv)) return rv;
nsCAutoString spec;
rv = uri->GetSpec(spec);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIInputStreamIO> io;
rv = NS_NewInputStreamIO(getter_AddRefs(io), spec, inStr,
NS_LITERAL_CSTRING("application/xhtml+xml"),
NS_LITERAL_CSTRING(""),
size);
nsCOMPtr<nsIStreamIOChannel> chan = do_QueryInterface(mStreamChannel, &rv);
if (NS_FAILED(rv)) return rv;
rv = chan->Init(uri, io);
rv = mStreamChannel->SetContentStream(inStr);
if (NS_FAILED(rv)) return rv;
return mStreamChannel->AsyncOpen(mListener, mListenerContext);

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

@ -46,6 +46,8 @@
#include "nsICacheEntryDescriptor.h"
#include "nsIStreamListener.h"
#include "nsIOutputStream.h"
#include "nsIInputStreamChannel.h"
#include "nsIURI.h"
#include "nsCOMPtr.h"
#include "nsString.h"
@ -76,7 +78,8 @@ private:
nsresult ParseURI(nsCString &, PRBool &, nsCString &);
private:
nsCOMPtr<nsIChannel> mStreamChannel;
nsCOMPtr<nsIURI> mURI;
nsCOMPtr<nsIInputStreamChannel> mStreamChannel;
nsCOMPtr<nsIStreamListener> mListener;
nsCOMPtr<nsISupports> mListenerContext;
nsCOMPtr<nsICacheSession> mCacheSession;

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

@ -39,9 +39,6 @@
#define nsDataHandler_h___
#include "nsIProtocolHandler.h"
// {B6ED3030-6183-11d3-A178-0050041CAF44}
#define NS_DATAHANDLER_CID \
{ 0xb6ed3030, 0x6183, 0x11d3, { 0xa1, 0x78, 0x00, 0x50, 0x04, 0x1c, 0xaf, 0x44 } }
class nsDataHandler : public nsIProtocolHandler
{

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

@ -1 +0,0 @@
nsIFileProtocolHandler.idl

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше