Back to index

lightning-sunbird  0.9+nobinonly
nsViewSourceChannel.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /* vim:set ts=4 sw=4 sts=4 et: */
00003 /* ***** BEGIN LICENSE BLOCK *****
00004  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00005  *
00006  * The contents of this file are subject to the Mozilla Public License Version
00007  * 1.1 (the "License"); you may not use this file except in compliance with
00008  * the License. You may obtain a copy of the License at
00009  * http://www.mozilla.org/MPL/
00010  *
00011  * Software distributed under the License is distributed on an "AS IS" basis,
00012  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00013  * for the specific language governing rights and limitations under the
00014  * License.
00015  *
00016  * The Original Code is mozilla.org code.
00017  *
00018  * The Initial Developer of the Original Code is
00019  * Netscape Communications Corporation.
00020  * Portions created by the Initial Developer are Copyright (C) 1998
00021  * the Initial Developer. All Rights Reserved.
00022  *
00023  * Contributor(s):
00024  *   Chak Nanga <chak@netscape.com>
00025  *   Darin Fisher <darin@meer.net>
00026  *
00027  * Alternatively, the contents of this file may be used under the terms of
00028  * either the GNU General Public License Version 2 or later (the "GPL"), or
00029  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00030  * in which case the provisions of the GPL or the LGPL are applicable instead
00031  * of those above. If you wish to allow use of your version of this file only
00032  * under the terms of either the GPL or the LGPL, and not to allow others to
00033  * use your version of this file under the terms of the MPL, indicate your
00034  * decision by deleting the provisions above and replace them with the notice
00035  * and other provisions required by the GPL or the LGPL. If you do not delete
00036  * the provisions above, a recipient may use your version of this file under
00037  * the terms of any one of the MPL, the GPL or the LGPL.
00038  *
00039  * ***** END LICENSE BLOCK ***** */
00040 
00041 #include "nsViewSourceChannel.h"
00042 #include "nsIIOService.h"
00043 #include "nsIServiceManager.h"
00044 #include "nsIInterfaceRequestor.h"
00045 #include "nsIInterfaceRequestorUtils.h"
00046 #include "nsXPIDLString.h"
00047 #include "nsReadableUtils.h"
00048 #include "nsMimeTypes.h"
00049 #include "nsNetUtil.h"
00050 #include "nsIHttpHeaderVisitor.h"
00051 
00052 NS_IMPL_ADDREF(nsViewSourceChannel)
00053 NS_IMPL_RELEASE(nsViewSourceChannel)
00054 /*
00055   This QI uses NS_INTERFACE_MAP_ENTRY_CONDITIONAL to check for
00056   non-nullness of mHttpChannel, mCachingChannel, and mUploadChannel.
00057 */
00058 NS_INTERFACE_MAP_BEGIN(nsViewSourceChannel)
00059     NS_INTERFACE_MAP_ENTRY(nsIViewSourceChannel)
00060     NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
00061     NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
00062     NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIHttpChannel, mHttpChannel)
00063     NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsICachingChannel, mCachingChannel)
00064     NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIUploadChannel, mUploadChannel)
00065     NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIRequest, nsIViewSourceChannel)
00066     NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIChannel, nsIViewSourceChannel)
00067     NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIViewSourceChannel)
00068 NS_INTERFACE_MAP_END_THREADSAFE
00069 
00070 nsresult
00071 nsViewSourceChannel::Init(nsIURI* uri)
00072 {
00073     mOriginalURI = uri;
00074 
00075     nsCAutoString path;
00076     nsresult rv = uri->GetPath(path);
00077     if (NS_FAILED(rv))
00078       return rv;
00079 
00080     nsCOMPtr<nsIIOService> pService(do_GetIOService(&rv));
00081     if (NS_FAILED(rv)) return rv;
00082 
00083     nsCAutoString scheme;
00084     rv = pService->ExtractScheme(path, scheme);
00085     if (NS_FAILED(rv))
00086       return rv;
00087 
00088     // prevent viewing source of javascript URIs (see bug 204779)
00089     if (scheme.LowerCaseEqualsLiteral("javascript")) {
00090       NS_WARNING("blocking view-source:javascript:");
00091       return NS_ERROR_INVALID_ARG;
00092     }
00093 
00094     rv = pService->NewChannel(path, nsnull, nsnull, getter_AddRefs(mChannel));
00095     if (NS_FAILED(rv))
00096       return rv;
00097  
00098     mChannel->SetOriginalURI(mOriginalURI);
00099     mHttpChannel = do_QueryInterface(mChannel);
00100     mCachingChannel = do_QueryInterface(mChannel);
00101     mUploadChannel = do_QueryInterface(mChannel);
00102     
00103     return NS_OK;
00104 }
00105 
00107 // nsIRequest methods:
00108 
00109 NS_IMETHODIMP
00110 nsViewSourceChannel::GetName(nsACString &result)
00111 {
00112     return NS_ERROR_NOT_IMPLEMENTED;
00113 }
00114 
00115 NS_IMETHODIMP
00116 nsViewSourceChannel::IsPending(PRBool *result)
00117 {
00118     NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
00119 
00120     return mChannel->IsPending(result);
00121 }
00122 
00123 NS_IMETHODIMP
00124 nsViewSourceChannel::GetStatus(nsresult *status)
00125 {
00126     NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
00127 
00128     return mChannel->GetStatus(status);
00129 }
00130 
00131 NS_IMETHODIMP
00132 nsViewSourceChannel::Cancel(nsresult status)
00133 {
00134     NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
00135 
00136     return mChannel->Cancel(status);
00137 }
00138 
00139 NS_IMETHODIMP
00140 nsViewSourceChannel::Suspend(void)
00141 {
00142     NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
00143 
00144     return mChannel->Suspend();
00145 }
00146 
00147 NS_IMETHODIMP
00148 nsViewSourceChannel::Resume(void)
00149 {
00150     NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
00151 
00152     return mChannel->Resume();
00153 }
00154 
00156 // nsIChannel methods:
00157 
00158 NS_IMETHODIMP
00159 nsViewSourceChannel::GetOriginalURI(nsIURI* *aURI)
00160 {
00161     NS_ASSERTION(aURI, "Null out param!");
00162     *aURI = mOriginalURI;
00163     NS_IF_ADDREF(*aURI);
00164     return NS_OK;
00165 }
00166 
00167 NS_IMETHODIMP
00168 nsViewSourceChannel::SetOriginalURI(nsIURI* aURI)
00169 {
00170     mOriginalURI = aURI;
00171     return NS_OK;
00172 }
00173 
00174 NS_IMETHODIMP
00175 nsViewSourceChannel::GetURI(nsIURI* *aURI)
00176 {
00177     NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
00178 
00179     nsCOMPtr<nsIURI> uri;
00180     nsresult rv = mChannel->GetURI(getter_AddRefs(uri));
00181     if (NS_FAILED(rv))
00182       return rv;
00183 
00184     // protect ourselves against broken channel implementations
00185     if (!uri) {
00186       NS_ERROR("inner channel returned NS_OK and a null URI");
00187       return NS_ERROR_UNEXPECTED;
00188     }
00189 
00190     nsCAutoString spec;
00191     uri->GetSpec(spec);
00192 
00193     /* XXX Gross hack -- NS_NewURI goes into an infinite loop on
00194        non-flat specs.  See bug 136980 */
00195     return NS_NewURI(aURI, nsCAutoString(NS_LITERAL_CSTRING("view-source:")+spec), nsnull);
00196 }
00197 
00198 NS_IMETHODIMP
00199 nsViewSourceChannel::Open(nsIInputStream **_retval)
00200 {
00201     NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
00202 
00203     nsresult rv = mChannel->Open(_retval);
00204     if (NS_SUCCEEDED(rv)) {
00205         mOpened = PR_TRUE;
00206     }
00207     
00208     return rv;
00209 }
00210 
00211 NS_IMETHODIMP
00212 nsViewSourceChannel::AsyncOpen(nsIStreamListener *aListener, nsISupports *ctxt)
00213 {
00214     NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
00215 
00216     mListener = aListener;
00217 
00218     /*
00219      * We want to add ourselves to the loadgroup before opening
00220      * mChannel, since we want to make sure we're in the loadgroup
00221      * when mChannel finishes and fires OnStopRequest()
00222      */
00223     
00224     nsCOMPtr<nsILoadGroup> loadGroup;
00225     mChannel->GetLoadGroup(getter_AddRefs(loadGroup));
00226     if (loadGroup)
00227         loadGroup->AddRequest(NS_STATIC_CAST(nsIViewSourceChannel*,
00228                                              this), nsnull);
00229     
00230     nsresult rv = mChannel->AsyncOpen(this, ctxt);
00231 
00232     if (NS_FAILED(rv) && loadGroup)
00233         loadGroup->RemoveRequest(NS_STATIC_CAST(nsIViewSourceChannel*,
00234                                                 this),
00235                                  nsnull, rv);
00236 
00237     if (NS_SUCCEEDED(rv)) {
00238         mOpened = PR_TRUE;
00239     }
00240     
00241     return rv;
00242 }
00243 
00244 /*
00245  * Both the view source channel and mChannel are added to the
00246  * loadgroup.  There should never be more than one request in the
00247  * loadgroup that has LOAD_DOCUMENT_URI set.  The one that has this
00248  * flag set is the request whose URI is used to refetch the document,
00249  * so it better be the viewsource channel.
00250  *
00251  * Therefore, we need to make sure that
00252  * 1) The load flags on mChannel _never_ include LOAD_DOCUMENT_URI
00253  * 2) The load flags on |this| include LOAD_DOCUMENT_URI when it was
00254  *    set via SetLoadFlags (mIsDocument keeps track of this flag).
00255  */
00256 
00257 NS_IMETHODIMP
00258 nsViewSourceChannel::GetLoadFlags(PRUint32 *aLoadFlags)
00259 {
00260     NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
00261 
00262     nsresult rv = mChannel->GetLoadFlags(aLoadFlags);
00263     if (NS_FAILED(rv))
00264       return rv;
00265 
00266     // This should actually be just LOAD_DOCUMENT_URI but the win32 compiler
00267     // fails to deal due to amiguous inheritance.  nsIChannel::LOAD_DOCUMENT_URI
00268     // also fails; the Win32 compiler thinks that's supposed to be a method.
00269     if (mIsDocument)
00270       *aLoadFlags |= ::nsIChannel::LOAD_DOCUMENT_URI;
00271 
00272     return rv;
00273 }
00274 
00275 NS_IMETHODIMP
00276 nsViewSourceChannel::SetLoadFlags(PRUint32 aLoadFlags)
00277 {
00278     NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
00279 
00280     // "View source" always wants the currently cached content.
00281     // We also want to have _this_ channel, not mChannel to be the
00282     // 'document' channel in the loadgroup. 
00283  
00284     // These should actually be just LOAD_FROM_CACHE and LOAD_DOCUMENT_URI but
00285     // the win32 compiler fails to deal due to amiguous inheritance.
00286     // nsIChannel::LOAD_DOCUMENT_URI/nsIRequest::LOAD_FROM_CACHE also fails; the
00287     // Win32 compiler thinks that's supposed to be a method.
00288     mIsDocument = (aLoadFlags & ::nsIChannel::LOAD_DOCUMENT_URI) ? PR_TRUE : PR_FALSE;
00289 
00290     return mChannel->SetLoadFlags((aLoadFlags |
00291                                    ::nsIRequest::LOAD_FROM_CACHE) &
00292                                   ~::nsIChannel::LOAD_DOCUMENT_URI);
00293 }
00294 
00295 NS_IMETHODIMP
00296 nsViewSourceChannel::GetContentType(nsACString &aContentType) 
00297 {
00298     NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
00299 
00300     aContentType.Truncate();
00301 
00302     if (mContentType.IsEmpty())
00303     {
00304         // Get the current content type
00305         nsresult rv;
00306         nsCAutoString contentType;
00307         rv = mChannel->GetContentType(contentType);
00308         if (NS_FAILED(rv)) return rv;
00309 
00310         // If we don't know our type, just say so.  The unknown
00311         // content decoder will then kick in automatically, and it
00312         // will call our SetOriginalContentType method instead of our
00313         // SetContentType method to set the type it determines.
00314         if (!contentType.Equals(UNKNOWN_CONTENT_TYPE)) {
00315           contentType = VIEWSOURCE_CONTENT_TYPE;
00316         }
00317 
00318         mContentType = contentType;
00319     }
00320 
00321     aContentType = mContentType;
00322     return NS_OK;
00323 }
00324 
00325 NS_IMETHODIMP
00326 nsViewSourceChannel::SetContentType(const nsACString &aContentType)
00327 {
00328     // Our GetContentType() currently returns VIEWSOURCE_CONTENT_TYPE
00329     //
00330     // However, during the parsing phase the parser calls our
00331     // channel's GetContentType(). Returing the string above trips up
00332     // the parser. In order to avoid messy changes and not to have the
00333     // parser depend on nsIViewSourceChannel Vidur proposed the
00334     // following solution:
00335     //
00336     // The ViewSourceChannel initially returns a content type of
00337     // VIEWSOURCE_CONTENT_TYPE.  Based on this type decisions to
00338     // create a viewer for doing a view source are made.  After the
00339     // viewer is created, nsLayoutDLF::CreateInstance() calls this
00340     // SetContentType() with the original content type.  When it's
00341     // time for the parser to find out the content type it will call
00342     // our channel's GetContentType() and it will get the original
00343     // content type, such as, text/html and everything is kosher from
00344     // then on.
00345 
00346     if (!mOpened) {
00347         // We do not take hints
00348         return NS_ERROR_NOT_AVAILABLE;
00349     }
00350     
00351     mContentType = aContentType;
00352     return NS_OK;
00353 }
00354 
00355 NS_IMETHODIMP
00356 nsViewSourceChannel::GetContentCharset(nsACString &aContentCharset)
00357 {
00358     NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
00359 
00360     return mChannel->GetContentCharset(aContentCharset);
00361 }
00362 
00363 NS_IMETHODIMP
00364 nsViewSourceChannel::SetContentCharset(const nsACString &aContentCharset)
00365 {
00366     NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
00367 
00368     return mChannel->SetContentCharset(aContentCharset);
00369 }
00370 
00371 NS_IMETHODIMP
00372 nsViewSourceChannel::GetContentLength(PRInt32 *aContentLength)
00373 {
00374     NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
00375 
00376     return mChannel->GetContentLength(aContentLength);
00377 }
00378 
00379 NS_IMETHODIMP
00380 nsViewSourceChannel::SetContentLength(PRInt32 aContentLength)
00381 {
00382     NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
00383 
00384     return mChannel->SetContentLength(aContentLength);
00385 }
00386 
00387 NS_IMETHODIMP
00388 nsViewSourceChannel::GetLoadGroup(nsILoadGroup* *aLoadGroup)
00389 {
00390     NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
00391 
00392     return mChannel->GetLoadGroup(aLoadGroup);
00393 }
00394 
00395 NS_IMETHODIMP
00396 nsViewSourceChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
00397 {
00398     NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
00399 
00400     return mChannel->SetLoadGroup(aLoadGroup);
00401 }
00402 
00403 NS_IMETHODIMP
00404 nsViewSourceChannel::GetOwner(nsISupports* *aOwner)
00405 {
00406     NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
00407 
00408     return mChannel->GetOwner(aOwner);
00409 }
00410 
00411 NS_IMETHODIMP
00412 nsViewSourceChannel::SetOwner(nsISupports* aOwner)
00413 {
00414     NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
00415 
00416     return mChannel->SetOwner(aOwner);
00417 }
00418 
00419 NS_IMETHODIMP
00420 nsViewSourceChannel::GetNotificationCallbacks(nsIInterfaceRequestor* *aNotificationCallbacks)
00421 {
00422     NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
00423 
00424     return mChannel->GetNotificationCallbacks(aNotificationCallbacks);
00425 }
00426 
00427 NS_IMETHODIMP
00428 nsViewSourceChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
00429 {
00430     NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
00431 
00432     return mChannel->SetNotificationCallbacks(aNotificationCallbacks);
00433 }
00434 
00435 NS_IMETHODIMP 
00436 nsViewSourceChannel::GetSecurityInfo(nsISupports * *aSecurityInfo)
00437 {
00438     NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
00439 
00440     return mChannel->GetSecurityInfo(aSecurityInfo);
00441 }
00442 
00443 // nsIViewSourceChannel methods
00444 NS_IMETHODIMP
00445 nsViewSourceChannel::GetOriginalContentType(nsACString &aContentType) 
00446 {
00447     NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
00448 
00449     return mChannel->GetContentType(aContentType);
00450 }
00451 
00452 NS_IMETHODIMP
00453 nsViewSourceChannel::SetOriginalContentType(const nsACString &aContentType)
00454 {
00455     NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
00456 
00457     // clear our cached content-type value
00458     mContentType.Truncate();
00459 
00460     return mChannel->SetContentType(aContentType);
00461 }
00462 
00463 // nsIRequestObserver methods
00464 NS_IMETHODIMP
00465 nsViewSourceChannel::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
00466 {
00467     NS_ENSURE_TRUE(mListener, NS_ERROR_FAILURE);
00468     // The channel may have gotten redirected... Time to update our info
00469     mChannel = do_QueryInterface(aRequest);
00470     mHttpChannel = do_QueryInterface(aRequest);
00471     mCachingChannel = do_QueryInterface(aRequest);
00472     mUploadChannel = do_QueryInterface(aRequest);
00473     
00474     return mListener->OnStartRequest(NS_STATIC_CAST(nsIViewSourceChannel*,
00475                                                     this),
00476                                      aContext);
00477 }
00478 
00479 
00480 NS_IMETHODIMP
00481 nsViewSourceChannel::OnStopRequest(nsIRequest *aRequest, nsISupports* aContext,
00482                                nsresult aStatus)
00483 {
00484     NS_ENSURE_TRUE(mListener, NS_ERROR_FAILURE);
00485     if (mChannel)
00486     {
00487         nsCOMPtr<nsILoadGroup> loadGroup;
00488         mChannel->GetLoadGroup(getter_AddRefs(loadGroup));
00489         if (loadGroup)
00490         {
00491             loadGroup->RemoveRequest(NS_STATIC_CAST(nsIViewSourceChannel*,
00492                                                     this),
00493                                      nsnull, aStatus);
00494         }
00495     }
00496     return mListener->OnStopRequest(NS_STATIC_CAST(nsIViewSourceChannel*,
00497                                                    this),
00498                                     aContext, aStatus);
00499 }
00500 
00501 
00502 // nsIStreamListener methods
00503 NS_IMETHODIMP
00504 nsViewSourceChannel::OnDataAvailable(nsIRequest *aRequest, nsISupports* aContext,
00505                                nsIInputStream *aInputStream, PRUint32 aSourceOffset,
00506                                PRUint32 aLength) 
00507 {
00508     NS_ENSURE_TRUE(mListener, NS_ERROR_FAILURE);
00509     return mListener->OnDataAvailable(NS_STATIC_CAST(nsIViewSourceChannel*,
00510                                                      this),
00511                                       aContext, aInputStream,
00512                                       aSourceOffset, aLength);
00513 }
00514 
00515 
00516 // nsIHttpChannel methods
00517 
00518 // We want to forward most of nsIHttpChannel over to mHttpChannel, but we want
00519 // to override GetRequestHeader and VisitHeaders. The reason is that we don't
00520 // want various headers like Link: and Refresh: applying to view-source.
00521 NS_IMETHODIMP
00522 nsViewSourceChannel::GetRequestMethod(nsACString & aRequestMethod)
00523 {
00524     return !mHttpChannel ? NS_ERROR_NULL_POINTER :
00525         mHttpChannel->GetRequestMethod(aRequestMethod);
00526 }
00527 
00528 NS_IMETHODIMP
00529 nsViewSourceChannel::SetRequestMethod(const nsACString & aRequestMethod)
00530 {
00531     return !mHttpChannel ? NS_ERROR_NULL_POINTER :
00532         mHttpChannel->SetRequestMethod(aRequestMethod);
00533 }
00534 
00535 NS_IMETHODIMP
00536 nsViewSourceChannel::GetReferrer(nsIURI * *aReferrer)
00537 {
00538     return !mHttpChannel ? NS_ERROR_NULL_POINTER :
00539         mHttpChannel->GetReferrer(aReferrer);
00540 }
00541 
00542 NS_IMETHODIMP
00543 nsViewSourceChannel::SetReferrer(nsIURI * aReferrer)
00544 {
00545     return !mHttpChannel ? NS_ERROR_NULL_POINTER :
00546         mHttpChannel->SetReferrer(aReferrer);
00547 }
00548 
00549 NS_IMETHODIMP
00550 nsViewSourceChannel::GetRequestHeader(const nsACString & aHeader,
00551                                       nsACString & aValue)
00552 {
00553     return !mHttpChannel ? NS_ERROR_NULL_POINTER :
00554         mHttpChannel->GetRequestHeader(aHeader, aValue);
00555 }
00556 
00557 NS_IMETHODIMP
00558 nsViewSourceChannel::SetRequestHeader(const nsACString & aHeader,
00559                                       const nsACString & aValue,
00560                                       PRBool aMerge)
00561 {
00562     return !mHttpChannel ? NS_ERROR_NULL_POINTER :
00563         mHttpChannel->SetRequestHeader(aHeader, aValue, aMerge);
00564 }
00565 
00566 NS_IMETHODIMP
00567 nsViewSourceChannel::VisitRequestHeaders(nsIHttpHeaderVisitor *aVisitor)
00568 {
00569     return !mHttpChannel ? NS_ERROR_NULL_POINTER :
00570         mHttpChannel->VisitRequestHeaders(aVisitor);
00571 }
00572 
00573 NS_IMETHODIMP
00574 nsViewSourceChannel::GetAllowPipelining(PRBool *aAllowPipelining)
00575 {
00576     return !mHttpChannel ? NS_ERROR_NULL_POINTER :
00577         mHttpChannel->GetAllowPipelining(aAllowPipelining);
00578 }
00579 
00580 NS_IMETHODIMP
00581 nsViewSourceChannel::SetAllowPipelining(PRBool aAllowPipelining)
00582 {
00583     return !mHttpChannel ? NS_ERROR_NULL_POINTER :
00584         mHttpChannel->SetAllowPipelining(aAllowPipelining);
00585 }
00586 
00587 NS_IMETHODIMP
00588 nsViewSourceChannel::GetRedirectionLimit(PRUint32 *aRedirectionLimit)
00589 {
00590     return !mHttpChannel ? NS_ERROR_NULL_POINTER :
00591         mHttpChannel->GetRedirectionLimit(aRedirectionLimit);
00592 }
00593 
00594 NS_IMETHODIMP
00595 nsViewSourceChannel::SetRedirectionLimit(PRUint32 aRedirectionLimit)
00596 {
00597     return !mHttpChannel ? NS_ERROR_NULL_POINTER :
00598         mHttpChannel->SetRedirectionLimit(aRedirectionLimit);
00599 }
00600 
00601 NS_IMETHODIMP
00602 nsViewSourceChannel::GetResponseStatus(PRUint32 *aResponseStatus)
00603 {
00604     return !mHttpChannel ? NS_ERROR_NULL_POINTER :
00605         mHttpChannel->GetResponseStatus(aResponseStatus);
00606 }
00607 
00608 NS_IMETHODIMP
00609 nsViewSourceChannel::GetResponseStatusText(nsACString & aResponseStatusText)
00610 {
00611     return !mHttpChannel ? NS_ERROR_NULL_POINTER :
00612         mHttpChannel->GetResponseStatusText(aResponseStatusText);
00613 }
00614 
00615 NS_IMETHODIMP
00616 nsViewSourceChannel::GetRequestSucceeded(PRBool *aRequestSucceeded)
00617 {
00618     return !mHttpChannel ? NS_ERROR_NULL_POINTER :
00619         mHttpChannel->GetRequestSucceeded(aRequestSucceeded);
00620 }
00621 
00622 NS_IMETHODIMP
00623 nsViewSourceChannel::GetResponseHeader(const nsACString & aHeader,
00624                                        nsACString & aValue)
00625 {
00626     if (!mHttpChannel)
00627         return NS_ERROR_NULL_POINTER;
00628 
00629     if (!aHeader.Equals(NS_LITERAL_CSTRING("Content-Type"),
00630                         nsCaseInsensitiveCStringComparator())) {
00631         aValue.Truncate();
00632         return NS_OK;
00633     }
00634         
00635     return mHttpChannel->GetResponseHeader(aHeader, aValue);
00636 }
00637 
00638 NS_IMETHODIMP
00639 nsViewSourceChannel::SetResponseHeader(const nsACString & header,
00640                                        const nsACString & value, PRBool merge)
00641 {
00642     return !mHttpChannel ? NS_ERROR_NULL_POINTER :
00643         mHttpChannel->SetResponseHeader(header, value, merge);
00644 }
00645 
00646 NS_IMETHODIMP
00647 nsViewSourceChannel::VisitResponseHeaders(nsIHttpHeaderVisitor *aVisitor)
00648 {
00649     if (!mHttpChannel)
00650         return NS_ERROR_NULL_POINTER;
00651 
00652     NS_NAMED_LITERAL_CSTRING(contentTypeStr, "Content-Type");
00653     nsCAutoString contentType;
00654     nsresult rv =
00655         mHttpChannel->GetResponseHeader(contentTypeStr, contentType);
00656     if (NS_SUCCEEDED(rv))
00657         aVisitor->VisitHeader(contentTypeStr, contentType);
00658     return NS_OK;
00659 }
00660 
00661 NS_IMETHODIMP
00662 nsViewSourceChannel::IsNoStoreResponse(PRBool *_retval)
00663 {
00664     return !mHttpChannel ? NS_ERROR_NULL_POINTER :
00665         mHttpChannel->IsNoStoreResponse(_retval);
00666 }
00667 
00668 NS_IMETHODIMP
00669 nsViewSourceChannel::IsNoCacheResponse(PRBool *_retval)
00670 {
00671     return !mHttpChannel ? NS_ERROR_NULL_POINTER :
00672         mHttpChannel->IsNoCacheResponse(_retval);
00673 }