~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/embedding/tests/wxEmbed/GeckoProtocolHandler.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ***** BEGIN LICENSE BLOCK *****
 
2
 * Version: Mozilla-sample-code 1.0
 
3
 *
 
4
 * Copyright (c) 2002 Netscape Communications Corporation and
 
5
 * other contributors
 
6
 *
 
7
 * Permission is hereby granted, free of charge, to any person obtaining a
 
8
 * copy of this Mozilla sample software and associated documentation files
 
9
 * (the "Software"), to deal in the Software without restriction, including
 
10
 * without limitation the rights to use, copy, modify, merge, publish,
 
11
 * distribute, sublicense, and/or sell copies of the Software, and to permit
 
12
 * persons to whom the Software is furnished to do so, subject to the
 
13
 * following conditions:
 
14
 *
 
15
 * The above copyright notice and this permission notice shall be included
 
16
 * in all copies or substantial portions of the Software.
 
17
 *
 
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 
19
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
20
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 
21
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
22
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 
23
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 
24
 * DEALINGS IN THE SOFTWARE.
 
25
 *
 
26
 * Contributor(s):
 
27
 *
 
28
 *   Adam Lock <adamlock@netscape.com>
 
29
 *
 
30
 * ***** END LICENSE BLOCK ***** */
 
31
 
 
32
#include "GeckoProtocolHandler.h"
 
33
 
 
34
#include "nsNetCID.h"
 
35
#include "nsNetUtil.h"
 
36
#include "nsIGenericFactory.h"
 
37
#include "nsIComponentManager.h"
 
38
#include "nsIProgressEventSink.h"
 
39
#include "nsILoadGroup.h"
 
40
#include "nsIInterfaceRequestor.h"
 
41
#include "nsIInterfaceRequestorUtils.h"
 
42
#include "nsIByteArrayInputStream.h"
 
43
#include "nsIStreamListener.h"
 
44
#include "nsIInputStreamPump.h"
 
45
#include "nsEmbedString.h"
 
46
 
 
47
// Everytime register handler is called, it picks the next available CID in the
 
48
// list.
 
49
// TODO - is there a cross-platform way to generate UUIDs and obviate this?
 
50
static const nsCID kProtocolCIDs[] = 
 
51
{
 
52
    { 0xfc8b2366, 0x0d07, 0x45ef, { 0x9f, 0xab, 0x22, 0x31, 0x9d, 0xbc, 0xfa, 0x77 } },
 
53
    { 0x6b5db250, 0xcf4b, 0x4ab1, { 0xb3, 0xaa, 0x1a, 0x9a, 0xd6, 0xdf, 0x7f, 0x95 } },
 
54
    { 0x677c6eaf, 0x3c3d, 0x4e0d, { 0xad, 0x30, 0x5a, 0xb8, 0x69, 0x1d, 0x1f, 0xfc } },
 
55
    { 0xbe383b01, 0x58d3, 0x4e65, { 0x9d, 0x50, 0x05, 0xb4, 0xc3, 0x92, 0x43, 0x2e } },
 
56
    { 0x81290231, 0xedf0, 0x4876, { 0x94, 0xa2, 0xdb, 0x96, 0xca, 0xa3, 0xc1, 0xfc } },
 
57
    { 0xf9c466b0, 0x0da8, 0x48a7, { 0xbb, 0xe4, 0x2f, 0x63, 0xb0, 0x71, 0x41, 0x6f } },
 
58
    { 0x9cbaef5e, 0xdf94, 0x4cb0, { 0xb4, 0xc3, 0x89, 0x66, 0x89, 0xd0, 0x2d, 0x56 } },
 
59
    { 0xce79440d, 0xdafc, 0x4908, { 0xb8, 0x94, 0xb2, 0x74, 0xa3, 0x51, 0x2f, 0x45 } }
 
60
};
 
61
static const int kProtocolCIDsSize = sizeof(kProtocolCIDs) / sizeof(kProtocolCIDs[0]);
 
62
static PRUint32 gUsedCIDs = 0;
 
63
struct GeckoChannelCallbacks
 
64
{
 
65
    nsCString mScheme;
 
66
    GeckoChannelCallback *mCallback;
 
67
    // SUCKS, component registry should properly copy this variable or take ownership of
 
68
    // it so it doesn't have to be made a static or global like this.
 
69
    // I also wonder if having component info memory dotted all over the place doesn't
 
70
    // impact component registry performance in some way.
 
71
    nsModuleComponentInfo mComponentInfo;
 
72
};
 
73
static GeckoChannelCallbacks gCallbacks[kProtocolCIDsSize];
 
74
 
 
75
class GeckoProtocolHandlerImpl :
 
76
    public nsIProtocolHandler
 
77
{
 
78
public:
 
79
    NS_DECL_ISUPPORTS
 
80
    NS_DECL_NSIPROTOCOLHANDLER
 
81
    static NS_METHOD Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
 
82
};
 
83
 
 
84
 
 
85
class GeckoProtocolChannel :
 
86
    public nsIChannel,
 
87
    public nsIStreamListener
 
88
{
 
89
public:
 
90
    NS_DECL_ISUPPORTS
 
91
    NS_DECL_NSIREQUEST
 
92
    NS_DECL_NSICHANNEL
 
93
    NS_DECL_NSIREQUESTOBSERVER
 
94
    NS_DECL_NSISTREAMLISTENER
 
95
 
 
96
    GeckoProtocolChannel();
 
97
    nsresult Init(nsIURI *aURI);
 
98
 
 
99
protected:
 
100
    nsCOMPtr<nsIURI>                    mURI;
 
101
    nsCOMPtr<nsIURI>                    mOriginalURI;
 
102
    nsCOMPtr<nsIInterfaceRequestor>     mCallbacks;
 
103
    nsCOMPtr<nsIProgressEventSink>      mProgressSink;
 
104
    nsCOMPtr<nsISupports>               mOwner;
 
105
    nsCOMPtr<nsILoadGroup>              mLoadGroup;
 
106
    nsCOMPtr<nsIStreamListener>         mListener;
 
107
    nsCOMPtr<nsISupports>               mListenerContext;
 
108
    nsCOMPtr<nsIInputStream>            mContentStream;
 
109
    nsCString                           mContentType;
 
110
    nsCString                           mContentCharset;
 
111
    PRUint32                            mLoadFlags;
 
112
    nsresult                            mStatus;
 
113
    PRUint32                            mContentLength;
 
114
    void                              * mData;
 
115
    nsCOMPtr<nsIInputStreamPump>        mPump;
 
116
 
 
117
    virtual ~GeckoProtocolChannel();
 
118
};
 
119
 
 
120
nsresult GeckoProtocolHandler::RegisterHandler(const char *aScheme, const char *aDescription, GeckoChannelCallback *aCallback)
 
121
{
 
122
    if (!aScheme || !aCallback)
 
123
    {
 
124
        return NS_ERROR_INVALID_ARG;
 
125
    }
 
126
 
 
127
    if (gUsedCIDs >= kProtocolCIDsSize)
 
128
    {
 
129
        // We've run out of CIDs. Perhaps this code should be generating them
 
130
        // on the fly somehow instead?
 
131
        return NS_ERROR_FAILURE;
 
132
    }
 
133
    for (PRUint32 i = 0; i < gUsedCIDs; i++)
 
134
    {
 
135
        if (gCallbacks[i].mScheme.EqualsIgnoreCase(aScheme))
 
136
            return NS_ERROR_FAILURE;
 
137
    }
 
138
 
 
139
    nsCAutoString contractID(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX);
 
140
    contractID.Append(aScheme);
 
141
    nsCID cid = kProtocolCIDs[gUsedCIDs];
 
142
    gCallbacks[gUsedCIDs].mScheme = aScheme;
 
143
    gCallbacks[gUsedCIDs].mCallback = aCallback;
 
144
    gUsedCIDs++;
 
145
 
 
146
    nsModuleComponentInfo &ci = gCallbacks[gUsedCIDs].mComponentInfo;
 
147
    memset(&ci, 0, sizeof(ci));
 
148
    ci.mDescription = strdup(aDescription);
 
149
    ci.mCID = cid;
 
150
    ci.mContractID = strdup(contractID.get());
 
151
    ci.mConstructor = GeckoProtocolHandlerImpl::Create;
 
152
 
 
153
    // Create a factory object which will create the protocol handler on demand
 
154
    nsCOMPtr<nsIGenericFactory> factory;
 
155
    NS_NewGenericFactory(getter_AddRefs(factory), &ci);
 
156
    nsComponentManager::RegisterFactory(
 
157
        cid, aDescription, contractID.get(), factory, PR_FALSE);
 
158
 
 
159
    return NS_OK;
 
160
}
 
161
 
 
162
 
 
163
///////////////////////////////////////////////////////////////////////////////
 
164
///////////////////////////////////////////////////////////////////////////////
 
165
 
 
166
 
 
167
GeckoProtocolChannel::GeckoProtocolChannel() :
 
168
    mContentLength(0),
 
169
    mData(nsnull),
 
170
    mStatus(NS_OK),
 
171
    mLoadFlags(LOAD_NORMAL)
 
172
{
 
173
}
 
174
 
 
175
GeckoProtocolChannel::~GeckoProtocolChannel()
 
176
{
 
177
//    if (mData)
 
178
//        nsMemory::Free(mData);
 
179
}
 
180
 
 
181
static NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID);
 
182
 
 
183
NS_METHOD GeckoProtocolHandlerImpl::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
 
184
{
 
185
    GeckoProtocolHandlerImpl *impl = new GeckoProtocolHandlerImpl();
 
186
    if (!impl)
 
187
    {
 
188
        return NS_ERROR_OUT_OF_MEMORY;
 
189
    }
 
190
    *aResult = nsnull;
 
191
    nsresult rv = impl->QueryInterface(aIID, aResult);
 
192
    if (NS_FAILED(rv))
 
193
    {
 
194
        impl->Release();
 
195
    }
 
196
    return rv;
 
197
}
 
198
 
 
199
NS_IMPL_ISUPPORTS1(GeckoProtocolHandlerImpl, nsIProtocolHandler)
 
200
 
 
201
/* readonly attribute ACString scheme; */
 
202
NS_IMETHODIMP GeckoProtocolHandlerImpl::GetScheme(nsACString & aScheme)
 
203
{
 
204
    // Since we have no clue what scheme we're an implementation of,
 
205
    // just return the first one that was registered.
 
206
    aScheme = gCallbacks[0].mScheme;
 
207
    return NS_OK;
 
208
}
 
209
 
 
210
/* readonly attribute long defaultPort; */
 
211
NS_IMETHODIMP GeckoProtocolHandlerImpl::GetDefaultPort(PRInt32 *aDefaultPort)
 
212
{
 
213
    *aDefaultPort = -1;
 
214
    return NS_OK;
 
215
}
 
216
 
 
217
/* readonly attribute unsigned long protocolFlags; */
 
218
NS_IMETHODIMP GeckoProtocolHandlerImpl::GetProtocolFlags(PRUint32 *aProtocolFlags)
 
219
{
 
220
    *aProtocolFlags = URI_NORELATIVE | URI_NOAUTH;
 
221
    return NS_OK;
 
222
}
 
223
 
 
224
/* nsIURI newURI (in AUTF8String aSpec, in string aOriginCharset, in nsIURI aBaseURI); */
 
225
NS_IMETHODIMP GeckoProtocolHandlerImpl::NewURI(const nsACString & aSpec, const char *aOriginCharset, nsIURI *aBaseURI, nsIURI **_retval)
 
226
{
 
227
    nsresult rv;
 
228
    nsIURI* url = nsnull;
 
229
    rv = nsComponentManager::CreateInstance(
 
230
        kSimpleURICID, nsnull, NS_GET_IID(nsIURI), (void**) &url);
 
231
    if (NS_FAILED(rv))
 
232
        return rv;
 
233
    rv = url->SetSpec(aSpec);
 
234
    if (NS_FAILED(rv))
 
235
    {
 
236
        NS_RELEASE(url);
 
237
        return rv;
 
238
    }
 
239
    *_retval = url;
 
240
    return rv;
 
241
}
 
242
 
 
243
/* nsIChannel newChannel (in nsIURI aURI); */
 
244
NS_IMETHODIMP GeckoProtocolHandlerImpl::NewChannel(nsIURI *aURI, nsIChannel **_retval)
 
245
{
 
246
    GeckoProtocolChannel *channel = new GeckoProtocolChannel;
 
247
    if (!channel)
 
248
    {
 
249
        return NS_ERROR_OUT_OF_MEMORY;
 
250
    }
 
251
    channel->Init(aURI);
 
252
    channel->QueryInterface(NS_GET_IID(nsIChannel), (void **) _retval);
 
253
    return NS_OK;
 
254
}
 
255
 
 
256
/* boolean allowPort (in long port, in string scheme); */
 
257
NS_IMETHODIMP GeckoProtocolHandlerImpl::AllowPort(PRInt32 port, const char *scheme, PRBool *_retval)
 
258
{
 
259
    return NS_ERROR_NOT_IMPLEMENTED;
 
260
}
 
261
 
 
262
 
 
263
///////////////////////////////////////////////////////////////////////////////
 
264
///////////////////////////////////////////////////////////////////////////////
 
265
 
 
266
NS_IMPL_ISUPPORTS4(GeckoProtocolChannel, nsIRequest, nsIChannel, nsIRequestObserver, nsIStreamListener)
 
267
 
 
268
nsresult GeckoProtocolChannel::Init(nsIURI *aURI)
 
269
{
 
270
    mURI = aURI;
 
271
    return NS_OK;
 
272
}
 
273
 
 
274
 
 
275
///////////////////////////////////////////////////////////////////////////////
 
276
// nsIRequest methods
 
277
 
 
278
 
 
279
NS_IMETHODIMP
 
280
GeckoProtocolChannel::GetName(nsACString &result)
 
281
{
 
282
    return mURI->GetSpec(result);
 
283
}
 
284
 
 
285
NS_IMETHODIMP
 
286
GeckoProtocolChannel::IsPending(PRBool *result)
 
287
{
 
288
    *result = PR_FALSE;
 
289
    return NS_OK;
 
290
}
 
291
 
 
292
NS_IMETHODIMP
 
293
GeckoProtocolChannel::GetStatus(nsresult *status)
 
294
{
 
295
    *status = mStatus;
 
296
    return NS_OK;
 
297
}
 
298
 
 
299
NS_IMETHODIMP
 
300
GeckoProtocolChannel::Cancel(nsresult status)
 
301
{
 
302
    NS_ASSERTION(NS_FAILED(status), "shouldn't cancel with a success code");
 
303
 
 
304
    mStatus = status;
 
305
    return NS_ERROR_UNEXPECTED;
 
306
}
 
307
 
 
308
NS_IMETHODIMP
 
309
GeckoProtocolChannel::Suspend()
 
310
{
 
311
    return NS_ERROR_UNEXPECTED;
 
312
}
 
313
 
 
314
NS_IMETHODIMP
 
315
GeckoProtocolChannel::Resume()
 
316
{
 
317
    return NS_ERROR_UNEXPECTED;
 
318
}
 
319
 
 
320
 
 
321
////////////////////////////////////////////////////////////////////////////////
 
322
// nsIChannel methods:
 
323
 
 
324
NS_IMETHODIMP
 
325
GeckoProtocolChannel::GetOriginalURI(nsIURI* *aURI)
 
326
{
 
327
    *aURI = mOriginalURI ? mOriginalURI : mURI;
 
328
    NS_ADDREF(*aURI);
 
329
    return NS_OK;
 
330
}
 
331
 
 
332
NS_IMETHODIMP
 
333
GeckoProtocolChannel::SetOriginalURI(nsIURI* aURI)
 
334
{
 
335
    mOriginalURI = aURI;
 
336
    return NS_OK;
 
337
}
 
338
 
 
339
NS_IMETHODIMP
 
340
GeckoProtocolChannel::GetURI(nsIURI* *aURI)
 
341
{
 
342
    *aURI = mURI;
 
343
    NS_IF_ADDREF(*aURI);
 
344
    return NS_OK;
 
345
}
 
346
 
 
347
NS_IMETHODIMP
 
348
GeckoProtocolChannel::Open(nsIInputStream **_retval)
 
349
{
 
350
    NS_NOTREACHED("GeckoProtocolChannel::Open");
 
351
    return NS_ERROR_NOT_IMPLEMENTED;
 
352
}
 
353
 
 
354
NS_IMETHODIMP
 
355
GeckoProtocolChannel::AsyncOpen(nsIStreamListener *aListener, nsISupports *aContext)
 
356
{
 
357
    nsresult rv = NS_OK;
 
358
 
 
359
    nsCAutoString scheme;
 
360
    mURI->GetScheme(scheme);
 
361
    for (PRUint32 i = 0; i < gUsedCIDs; i++)
 
362
    {
 
363
        if (stricmp(scheme.get(), gCallbacks[i].mScheme.get()) == 0)
 
364
        {
 
365
            rv = gCallbacks[i].mCallback->GetData(
 
366
                mURI, NS_STATIC_CAST(nsIChannel *,this), mContentType, &mData, &mContentLength);
 
367
            if (NS_FAILED(rv)) return rv;
 
368
            
 
369
            nsCOMPtr<nsIByteArrayInputStream> stream;
 
370
            rv = NS_NewByteArrayInputStream(getter_AddRefs(stream), (char *) mData, mContentLength);
 
371
            if (NS_FAILED(rv)) return rv;
 
372
            mContentStream = do_QueryInterface(stream);
 
373
 
 
374
            mListenerContext = aContext;
 
375
            mListener = aListener;
 
376
 
 
377
            nsresult rv = NS_NewInputStreamPump(
 
378
                getter_AddRefs(mPump), mContentStream, -1, mContentLength, 0, 0, PR_TRUE);
 
379
            if (NS_FAILED(rv)) return rv;
 
380
 
 
381
            if (mLoadGroup)
 
382
            {
 
383
                mLoadGroup->AddRequest(this, nsnull);
 
384
            }
 
385
 
 
386
            rv = mPump->AsyncRead(this, nsnull);
 
387
            if (NS_FAILED(rv)) return rv;
 
388
 
 
389
            return rv;
 
390
        }
 
391
    }
 
392
 
 
393
    return NS_ERROR_FAILURE;
 
394
}
 
395
 
 
396
NS_IMETHODIMP
 
397
GeckoProtocolChannel::GetLoadFlags(PRUint32 *aLoadFlags)
 
398
{
 
399
    *aLoadFlags = mLoadFlags;
 
400
    return NS_OK;
 
401
}
 
402
 
 
403
NS_IMETHODIMP
 
404
GeckoProtocolChannel::SetLoadFlags(PRUint32 aLoadFlags)
 
405
{
 
406
    mLoadFlags = aLoadFlags;
 
407
    return NS_OK;
 
408
}
 
409
 
 
410
NS_IMETHODIMP
 
411
GeckoProtocolChannel::GetContentType(nsACString &aContentType)
 
412
{
 
413
    aContentType = mContentType;
 
414
    return NS_OK;
 
415
}
 
416
 
 
417
NS_IMETHODIMP
 
418
GeckoProtocolChannel::SetContentType(const nsACString &aContentType)
 
419
{
 
420
    mContentType = aContentType;
 
421
    return NS_OK;
 
422
}
 
423
 
 
424
NS_IMETHODIMP
 
425
GeckoProtocolChannel::GetContentCharset(nsACString &aContentCharset)
 
426
{
 
427
    aContentCharset = mContentCharset;
 
428
    return NS_OK;
 
429
}
 
430
 
 
431
NS_IMETHODIMP
 
432
GeckoProtocolChannel::SetContentCharset(const nsACString &aContentCharset)
 
433
{
 
434
    mContentCharset = aContentCharset;
 
435
    return NS_OK;
 
436
}
 
437
 
 
438
NS_IMETHODIMP
 
439
GeckoProtocolChannel::GetContentLength(PRInt32 *aContentLength)
 
440
{
 
441
    *aContentLength = mContentLength;
 
442
    return NS_OK;
 
443
}
 
444
 
 
445
NS_IMETHODIMP
 
446
GeckoProtocolChannel::SetContentLength(PRInt32 aContentLength)
 
447
{
 
448
    // silently ignore this...
 
449
    return NS_OK;
 
450
}
 
451
 
 
452
NS_IMETHODIMP
 
453
GeckoProtocolChannel::GetLoadGroup(nsILoadGroup* *aLoadGroup)
 
454
{
 
455
    *aLoadGroup = mLoadGroup;
 
456
    NS_IF_ADDREF(*aLoadGroup);
 
457
    return NS_OK;
 
458
}
 
459
 
 
460
NS_IMETHODIMP
 
461
GeckoProtocolChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
 
462
{
 
463
    mLoadGroup = aLoadGroup;
 
464
    return NS_OK;
 
465
}
 
466
 
 
467
NS_IMETHODIMP
 
468
GeckoProtocolChannel::GetOwner(nsISupports* *aOwner)
 
469
{
 
470
    *aOwner = mOwner.get();
 
471
    NS_IF_ADDREF(*aOwner);
 
472
    return NS_OK;
 
473
}
 
474
 
 
475
NS_IMETHODIMP
 
476
GeckoProtocolChannel::SetOwner(nsISupports* aOwner)
 
477
{
 
478
    mOwner = aOwner;
 
479
    return NS_OK;
 
480
}
 
481
 
 
482
NS_IMETHODIMP
 
483
GeckoProtocolChannel::GetNotificationCallbacks(nsIInterfaceRequestor* *aNotificationCallbacks)
 
484
{
 
485
    *aNotificationCallbacks = mCallbacks.get();
 
486
    NS_IF_ADDREF(*aNotificationCallbacks);
 
487
    return NS_OK;
 
488
}
 
489
 
 
490
NS_IMETHODIMP
 
491
GeckoProtocolChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
 
492
{
 
493
    mCallbacks = aNotificationCallbacks;
 
494
    mProgressSink = do_GetInterface(mCallbacks);
 
495
    return NS_OK;
 
496
}
 
497
 
 
498
NS_IMETHODIMP 
 
499
GeckoProtocolChannel::GetSecurityInfo(nsISupports **aSecurityInfo)
 
500
{
 
501
    *aSecurityInfo = nsnull;
 
502
    return NS_OK;
 
503
}
 
504
 
 
505
 
 
506
///////////////////////////////////////////////////////////////////////////////
 
507
// nsIStreamListener methods
 
508
 
 
509
 
 
510
NS_IMETHODIMP
 
511
GeckoProtocolChannel::OnStartRequest(nsIRequest *req, nsISupports *ctx)
 
512
{
 
513
    return mListener->OnStartRequest(this, mListenerContext);
 
514
}
 
515
 
 
516
NS_IMETHODIMP
 
517
GeckoProtocolChannel::OnStopRequest(nsIRequest *req, nsISupports *ctx, nsresult status)
 
518
{
 
519
    if (NS_SUCCEEDED(mStatus))
 
520
        mStatus = status;
 
521
 
 
522
    mListener->OnStopRequest(this, mListenerContext, mStatus);
 
523
    mListener = 0;
 
524
    mListenerContext = 0;
 
525
 
 
526
    if (mLoadGroup)
 
527
        mLoadGroup->RemoveRequest(this, nsnull, mStatus);
 
528
 
 
529
    mPump = 0;
 
530
    mContentStream = 0;
 
531
    return NS_OK;
 
532
}
 
533
 
 
534
NS_IMETHODIMP
 
535
GeckoProtocolChannel::OnDataAvailable(nsIRequest *req, nsISupports *ctx,
 
536
                                      nsIInputStream *stream,
 
537
                                      PRUint32 offset, PRUint32 count)
 
538
{
 
539
    nsresult rv;
 
540
 
 
541
    rv = mListener->OnDataAvailable(this, mListenerContext, stream, offset, count);
 
542
 
 
543
    if (mProgressSink && NS_SUCCEEDED(rv) && !(mLoadFlags & LOAD_BACKGROUND))
 
544
        mProgressSink->OnProgress(this, nsnull, offset + count, mContentLength);
 
545
 
 
546
    return rv; // let the pump cancel on failure
 
547
}