nsSecCheckWrapChannel.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. #include "nsContentSecurityManager.h"
  6. #include "nsSecCheckWrapChannel.h"
  7. #include "nsIForcePendingChannel.h"
  8. #include "nsIStreamListener.h"
  9. #include "mozilla/Logging.h"
  10. #include "nsCOMPtr.h"
  11. namespace mozilla {
  12. namespace net {
  13. static LazyLogModule gChannelWrapperLog("ChannelWrapper");
  14. #define CHANNELWRAPPERLOG(args) MOZ_LOG(gChannelWrapperLog, LogLevel::Debug, args)
  15. NS_IMPL_ADDREF(nsSecCheckWrapChannelBase)
  16. NS_IMPL_RELEASE(nsSecCheckWrapChannelBase)
  17. NS_INTERFACE_MAP_BEGIN(nsSecCheckWrapChannelBase)
  18. NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIHttpChannel, mHttpChannel)
  19. NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIHttpChannelInternal, mHttpChannelInternal)
  20. NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIHttpChannel)
  21. NS_INTERFACE_MAP_ENTRY(nsIRequest)
  22. NS_INTERFACE_MAP_ENTRY(nsIChannel)
  23. NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIUploadChannel, mUploadChannel)
  24. NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIUploadChannel2, mUploadChannel2)
  25. NS_INTERFACE_MAP_ENTRY(nsISecCheckWrapChannel)
  26. NS_INTERFACE_MAP_END
  27. //---------------------------------------------------------
  28. // nsSecCheckWrapChannelBase implementation
  29. //---------------------------------------------------------
  30. nsSecCheckWrapChannelBase::nsSecCheckWrapChannelBase(nsIChannel* aChannel)
  31. : mChannel(aChannel)
  32. , mHttpChannel(do_QueryInterface(aChannel))
  33. , mHttpChannelInternal(do_QueryInterface(aChannel))
  34. , mRequest(do_QueryInterface(aChannel))
  35. , mUploadChannel(do_QueryInterface(aChannel))
  36. , mUploadChannel2(do_QueryInterface(aChannel))
  37. {
  38. MOZ_ASSERT(mChannel, "can not create a channel wrapper without a channel");
  39. }
  40. nsSecCheckWrapChannelBase::~nsSecCheckWrapChannelBase()
  41. {
  42. }
  43. //---------------------------------------------------------
  44. // nsISecCheckWrapChannel implementation
  45. //---------------------------------------------------------
  46. NS_IMETHODIMP
  47. nsSecCheckWrapChannelBase::GetInnerChannel(nsIChannel **aInnerChannel)
  48. {
  49. NS_IF_ADDREF(*aInnerChannel = mChannel);
  50. return NS_OK;
  51. }
  52. //---------------------------------------------------------
  53. // nsSecCheckWrapChannel implementation
  54. //---------------------------------------------------------
  55. nsSecCheckWrapChannel::nsSecCheckWrapChannel(nsIChannel* aChannel,
  56. nsILoadInfo* aLoadInfo)
  57. : nsSecCheckWrapChannelBase(aChannel)
  58. , mLoadInfo(aLoadInfo)
  59. {
  60. {
  61. nsCOMPtr<nsIURI> uri;
  62. mChannel->GetURI(getter_AddRefs(uri));
  63. CHANNELWRAPPERLOG(("nsSecCheckWrapChannel::nsSecCheckWrapChannel [%p] (%s)",
  64. this, uri ? uri->GetSpecOrDefault().get() : ""));
  65. }
  66. }
  67. // static
  68. already_AddRefed<nsIChannel>
  69. nsSecCheckWrapChannel::MaybeWrap(nsIChannel* aChannel, nsILoadInfo* aLoadInfo)
  70. {
  71. // Maybe a custom protocol handler actually returns a gecko
  72. // http/ftpChannel - To check this we will check whether the channel
  73. // implements a gecko non-scriptable interface e.g. nsIForcePendingChannel.
  74. nsCOMPtr<nsIForcePendingChannel> isGeckoChannel = do_QueryInterface(aChannel);
  75. nsCOMPtr<nsIChannel> channel;
  76. if (isGeckoChannel) {
  77. // If it is a gecko channel (ftp or http) we do not need to wrap it.
  78. channel = aChannel;
  79. channel->SetLoadInfo(aLoadInfo);
  80. } else {
  81. channel = new nsSecCheckWrapChannel(aChannel, aLoadInfo);
  82. }
  83. return channel.forget();
  84. }
  85. nsSecCheckWrapChannel::~nsSecCheckWrapChannel()
  86. {
  87. }
  88. //---------------------------------------------------------
  89. // SecWrapChannelStreamListener helper
  90. //---------------------------------------------------------
  91. class SecWrapChannelStreamListener final : public nsIStreamListener
  92. {
  93. public:
  94. SecWrapChannelStreamListener(nsIRequest *aRequest,
  95. nsIStreamListener *aStreamListener)
  96. : mRequest(aRequest)
  97. , mListener(aStreamListener) {}
  98. NS_DECL_ISUPPORTS
  99. NS_DECL_NSISTREAMLISTENER
  100. NS_DECL_NSIREQUESTOBSERVER
  101. private:
  102. ~SecWrapChannelStreamListener() {}
  103. nsCOMPtr<nsIRequest> mRequest;
  104. nsCOMPtr<nsIStreamListener> mListener;
  105. };
  106. NS_IMPL_ISUPPORTS(SecWrapChannelStreamListener,
  107. nsIStreamListener,
  108. nsIRequestObserver)
  109. NS_IMETHODIMP
  110. SecWrapChannelStreamListener::OnStartRequest(nsIRequest *aRequest,
  111. nsISupports *aContext)
  112. {
  113. return mListener->OnStartRequest(mRequest, aContext);
  114. }
  115. NS_IMETHODIMP
  116. SecWrapChannelStreamListener::OnStopRequest(nsIRequest *aRequest,
  117. nsISupports *aContext,
  118. nsresult aStatus)
  119. {
  120. return mListener->OnStopRequest(mRequest, aContext, aStatus);
  121. }
  122. NS_IMETHODIMP
  123. SecWrapChannelStreamListener::OnDataAvailable(nsIRequest *aRequest,
  124. nsISupports *aContext,
  125. nsIInputStream *aInStream,
  126. uint64_t aOffset,
  127. uint32_t aCount)
  128. {
  129. return mListener->OnDataAvailable(mRequest, aContext, aInStream, aOffset, aCount);
  130. }
  131. //---------------------------------------------------------
  132. // nsIChannel implementation
  133. //---------------------------------------------------------
  134. NS_IMETHODIMP
  135. nsSecCheckWrapChannel::GetLoadInfo(nsILoadInfo** aLoadInfo)
  136. {
  137. CHANNELWRAPPERLOG(("nsSecCheckWrapChannel::GetLoadInfo() [%p]",this));
  138. NS_IF_ADDREF(*aLoadInfo = mLoadInfo);
  139. return NS_OK;
  140. }
  141. NS_IMETHODIMP
  142. nsSecCheckWrapChannel::SetLoadInfo(nsILoadInfo* aLoadInfo)
  143. {
  144. CHANNELWRAPPERLOG(("nsSecCheckWrapChannel::SetLoadInfo() [%p]", this));
  145. mLoadInfo = aLoadInfo;
  146. return NS_OK;
  147. }
  148. NS_IMETHODIMP
  149. nsSecCheckWrapChannel::AsyncOpen2(nsIStreamListener *aListener)
  150. {
  151. nsCOMPtr<nsIStreamListener> secWrapChannelListener =
  152. new SecWrapChannelStreamListener(this, aListener);
  153. nsresult rv = nsContentSecurityManager::doContentSecurityCheck(this, secWrapChannelListener);
  154. NS_ENSURE_SUCCESS(rv, rv);
  155. return AsyncOpen(secWrapChannelListener, nullptr);
  156. }
  157. NS_IMETHODIMP
  158. nsSecCheckWrapChannel::Open2(nsIInputStream** aStream)
  159. {
  160. nsCOMPtr<nsIStreamListener> listener;
  161. nsresult rv = nsContentSecurityManager::doContentSecurityCheck(this, listener);
  162. NS_ENSURE_SUCCESS(rv, rv);
  163. return Open(aStream);
  164. }
  165. } // namespace net
  166. } // namespace mozilla