123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- #include "nsContentSecurityManager.h"
- #include "nsSecCheckWrapChannel.h"
- #include "nsIForcePendingChannel.h"
- #include "nsIStreamListener.h"
- #include "mozilla/Logging.h"
- #include "nsCOMPtr.h"
- namespace mozilla {
- namespace net {
- static LazyLogModule gChannelWrapperLog("ChannelWrapper");
- #define CHANNELWRAPPERLOG(args) MOZ_LOG(gChannelWrapperLog, LogLevel::Debug, args)
- NS_IMPL_ADDREF(nsSecCheckWrapChannelBase)
- NS_IMPL_RELEASE(nsSecCheckWrapChannelBase)
- NS_INTERFACE_MAP_BEGIN(nsSecCheckWrapChannelBase)
- NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIHttpChannel, mHttpChannel)
- NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIHttpChannelInternal, mHttpChannelInternal)
- NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIHttpChannel)
- NS_INTERFACE_MAP_ENTRY(nsIRequest)
- NS_INTERFACE_MAP_ENTRY(nsIChannel)
- NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIUploadChannel, mUploadChannel)
- NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIUploadChannel2, mUploadChannel2)
- NS_INTERFACE_MAP_ENTRY(nsISecCheckWrapChannel)
- NS_INTERFACE_MAP_END
- //---------------------------------------------------------
- // nsSecCheckWrapChannelBase implementation
- //---------------------------------------------------------
- nsSecCheckWrapChannelBase::nsSecCheckWrapChannelBase(nsIChannel* aChannel)
- : mChannel(aChannel)
- , mHttpChannel(do_QueryInterface(aChannel))
- , mHttpChannelInternal(do_QueryInterface(aChannel))
- , mRequest(do_QueryInterface(aChannel))
- , mUploadChannel(do_QueryInterface(aChannel))
- , mUploadChannel2(do_QueryInterface(aChannel))
- {
- MOZ_ASSERT(mChannel, "can not create a channel wrapper without a channel");
- }
- nsSecCheckWrapChannelBase::~nsSecCheckWrapChannelBase()
- {
- }
- //---------------------------------------------------------
- // nsISecCheckWrapChannel implementation
- //---------------------------------------------------------
- NS_IMETHODIMP
- nsSecCheckWrapChannelBase::GetInnerChannel(nsIChannel **aInnerChannel)
- {
- NS_IF_ADDREF(*aInnerChannel = mChannel);
- return NS_OK;
- }
- //---------------------------------------------------------
- // nsSecCheckWrapChannel implementation
- //---------------------------------------------------------
- nsSecCheckWrapChannel::nsSecCheckWrapChannel(nsIChannel* aChannel,
- nsILoadInfo* aLoadInfo)
- : nsSecCheckWrapChannelBase(aChannel)
- , mLoadInfo(aLoadInfo)
- {
- {
- nsCOMPtr<nsIURI> uri;
- mChannel->GetURI(getter_AddRefs(uri));
- CHANNELWRAPPERLOG(("nsSecCheckWrapChannel::nsSecCheckWrapChannel [%p] (%s)",
- this, uri ? uri->GetSpecOrDefault().get() : ""));
- }
- }
- // static
- already_AddRefed<nsIChannel>
- nsSecCheckWrapChannel::MaybeWrap(nsIChannel* aChannel, nsILoadInfo* aLoadInfo)
- {
- // Maybe a custom protocol handler actually returns a gecko
- // http/ftpChannel - To check this we will check whether the channel
- // implements a gecko non-scriptable interface e.g. nsIForcePendingChannel.
- nsCOMPtr<nsIForcePendingChannel> isGeckoChannel = do_QueryInterface(aChannel);
- nsCOMPtr<nsIChannel> channel;
- if (isGeckoChannel) {
- // If it is a gecko channel (ftp or http) we do not need to wrap it.
- channel = aChannel;
- channel->SetLoadInfo(aLoadInfo);
- } else {
- channel = new nsSecCheckWrapChannel(aChannel, aLoadInfo);
- }
- return channel.forget();
- }
- nsSecCheckWrapChannel::~nsSecCheckWrapChannel()
- {
- }
- //---------------------------------------------------------
- // SecWrapChannelStreamListener helper
- //---------------------------------------------------------
- class SecWrapChannelStreamListener final : public nsIStreamListener
- {
- public:
- SecWrapChannelStreamListener(nsIRequest *aRequest,
- nsIStreamListener *aStreamListener)
- : mRequest(aRequest)
- , mListener(aStreamListener) {}
- NS_DECL_ISUPPORTS
- NS_DECL_NSISTREAMLISTENER
- NS_DECL_NSIREQUESTOBSERVER
- private:
- ~SecWrapChannelStreamListener() {}
- nsCOMPtr<nsIRequest> mRequest;
- nsCOMPtr<nsIStreamListener> mListener;
- };
- NS_IMPL_ISUPPORTS(SecWrapChannelStreamListener,
- nsIStreamListener,
- nsIRequestObserver)
- NS_IMETHODIMP
- SecWrapChannelStreamListener::OnStartRequest(nsIRequest *aRequest,
- nsISupports *aContext)
- {
- return mListener->OnStartRequest(mRequest, aContext);
- }
- NS_IMETHODIMP
- SecWrapChannelStreamListener::OnStopRequest(nsIRequest *aRequest,
- nsISupports *aContext,
- nsresult aStatus)
- {
- return mListener->OnStopRequest(mRequest, aContext, aStatus);
- }
- NS_IMETHODIMP
- SecWrapChannelStreamListener::OnDataAvailable(nsIRequest *aRequest,
- nsISupports *aContext,
- nsIInputStream *aInStream,
- uint64_t aOffset,
- uint32_t aCount)
- {
- return mListener->OnDataAvailable(mRequest, aContext, aInStream, aOffset, aCount);
- }
- //---------------------------------------------------------
- // nsIChannel implementation
- //---------------------------------------------------------
- NS_IMETHODIMP
- nsSecCheckWrapChannel::GetLoadInfo(nsILoadInfo** aLoadInfo)
- {
- CHANNELWRAPPERLOG(("nsSecCheckWrapChannel::GetLoadInfo() [%p]",this));
- NS_IF_ADDREF(*aLoadInfo = mLoadInfo);
- return NS_OK;
- }
- NS_IMETHODIMP
- nsSecCheckWrapChannel::SetLoadInfo(nsILoadInfo* aLoadInfo)
- {
- CHANNELWRAPPERLOG(("nsSecCheckWrapChannel::SetLoadInfo() [%p]", this));
- mLoadInfo = aLoadInfo;
- return NS_OK;
- }
- NS_IMETHODIMP
- nsSecCheckWrapChannel::AsyncOpen2(nsIStreamListener *aListener)
- {
- nsCOMPtr<nsIStreamListener> secWrapChannelListener =
- new SecWrapChannelStreamListener(this, aListener);
- nsresult rv = nsContentSecurityManager::doContentSecurityCheck(this, secWrapChannelListener);
- NS_ENSURE_SUCCESS(rv, rv);
- return AsyncOpen(secWrapChannelListener, nullptr);
- }
- NS_IMETHODIMP
- nsSecCheckWrapChannel::Open2(nsIInputStream** aStream)
- {
- nsCOMPtr<nsIStreamListener> listener;
- nsresult rv = nsContentSecurityManager::doContentSecurityCheck(this, listener);
- NS_ENSURE_SUCCESS(rv, rv);
- return Open(aStream);
- }
- } // namespace net
- } // namespace mozilla
|