forked from mirrors/gecko-dev
		
	 e0845722c3
			
		
	
	
		e0845722c3
		
	
	
	
	
		
			
			This patch introduces: - a second nsICancelable out param in nsBaseChannel::BeginAsyncRead, which is meant to be non-null when the subclass is unable to set the nsIRequest out param right away (e.g because there is some async work needed before the subclass is able to get an nsIRequest instance). The nsICancelable does only allow the channel to cancel the underlying request (and stream pump), but it doesn't allow the channel to be suspended and resumed, but that was already the case for the subclasses that were already not returning an nsIRequest instance (e.g. like the ExtensionProtocolHandler was doing when it is asynchrously retriving a stream from the parent process). - require NotNull<nsCOMPtr<...>> in the SimpleChannel's BeginAsyncRead callback signature, to make harder to overlook the requirement of returning an nsIRequest or nsICancelable. - a diagnostic assertion (from SimpleChannel's BeginAsyncRead method) to more visible fail if we still end up with neither an nsIRequest or nsICancelable result as SimpleChannel callback result. - changes to ExtensionProtocolHandler, PageThumbProtocolHandler and nsAnnoProtocolHandler to adapt them to the new nsBaseChannel::BeginAsyncRead signature. Differential Revision: https://phabricator.services.mozilla.com/D125545
		
			
				
	
	
		
			135 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			135 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 | |
| /* 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 "SimpleChannel.h"
 | |
| 
 | |
| #include "nsBaseChannel.h"
 | |
| #include "nsIChannel.h"
 | |
| #include "nsIChildChannel.h"
 | |
| #include "nsIInputStream.h"
 | |
| #include "nsIRequest.h"
 | |
| #include "nsISupportsImpl.h"
 | |
| #include "nsNetUtil.h"
 | |
| 
 | |
| #include "mozilla/Unused.h"
 | |
| #include "mozilla/dom/ContentChild.h"
 | |
| #include "mozilla/net/NeckoChild.h"
 | |
| #include "mozilla/net/PSimpleChannelChild.h"
 | |
| 
 | |
| namespace mozilla {
 | |
| namespace net {
 | |
| 
 | |
| SimpleChannel::SimpleChannel(UniquePtr<SimpleChannelCallbacks>&& aCallbacks)
 | |
|     : mCallbacks(std::move(aCallbacks)) {
 | |
|   EnableSynthesizedProgressEvents(true);
 | |
| }
 | |
| 
 | |
| nsresult SimpleChannel::OpenContentStream(bool async,
 | |
|                                           nsIInputStream** streamOut,
 | |
|                                           nsIChannel** channel) {
 | |
|   NS_ENSURE_TRUE(mCallbacks, NS_ERROR_UNEXPECTED);
 | |
| 
 | |
|   nsCOMPtr<nsIInputStream> stream;
 | |
|   MOZ_TRY_VAR(stream, mCallbacks->OpenContentStream(async, this));
 | |
|   MOZ_ASSERT(stream);
 | |
| 
 | |
|   mCallbacks = nullptr;
 | |
| 
 | |
|   *channel = nullptr;
 | |
|   stream.forget(streamOut);
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| nsresult SimpleChannel::BeginAsyncRead(nsIStreamListener* listener,
 | |
|                                        nsIRequest** request,
 | |
|                                        nsICancelable** cancelableRequest) {
 | |
|   NS_ENSURE_TRUE(mCallbacks, NS_ERROR_UNEXPECTED);
 | |
| 
 | |
|   RequestOrReason res = mCallbacks->StartAsyncRead(listener, this);
 | |
| 
 | |
|   if (res.isErr()) {
 | |
|     return res.propagateErr();
 | |
|   }
 | |
| 
 | |
|   mCallbacks = nullptr;
 | |
| 
 | |
|   RequestOrCancelable value = res.unwrap();
 | |
| 
 | |
|   if (value.is<NotNullRequest>()) {
 | |
|     nsCOMPtr<nsIRequest> req = value.as<NotNullRequest>().get();
 | |
|     req.forget(request);
 | |
|   } else if (value.is<NotNullCancelable>()) {
 | |
|     nsCOMPtr<nsICancelable> cancelable = value.as<NotNullCancelable>().get();
 | |
|     cancelable.forget(cancelableRequest);
 | |
|   } else {
 | |
|     MOZ_ASSERT_UNREACHABLE(
 | |
|         "StartAsyncRead didn't return a NotNull nsIRequest or nsICancelable.");
 | |
|     return NS_ERROR_UNEXPECTED;
 | |
|   }
 | |
| 
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| NS_IMPL_ISUPPORTS_INHERITED(SimpleChannelChild, SimpleChannel, nsIChildChannel)
 | |
| 
 | |
| SimpleChannelChild::SimpleChannelChild(
 | |
|     UniquePtr<SimpleChannelCallbacks>&& aCallbacks)
 | |
|     : SimpleChannel(std::move(aCallbacks)) {}
 | |
| 
 | |
| NS_IMETHODIMP
 | |
| SimpleChannelChild::ConnectParent(uint32_t aId) {
 | |
|   MOZ_ASSERT(NS_IsMainThread());
 | |
|   mozilla::dom::ContentChild* cc =
 | |
|       static_cast<mozilla::dom::ContentChild*>(gNeckoChild->Manager());
 | |
|   if (cc->IsShuttingDown()) {
 | |
|     return NS_ERROR_FAILURE;
 | |
|   }
 | |
| 
 | |
|   // Reference freed in DeallocPSimpleChannelChild.
 | |
|   if (!gNeckoChild->SendPSimpleChannelConstructor(do_AddRef(this).take(),
 | |
|                                                   aId)) {
 | |
|     return NS_ERROR_FAILURE;
 | |
|   }
 | |
| 
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP
 | |
| SimpleChannelChild::CompleteRedirectSetup(nsIStreamListener* aListener) {
 | |
|   if (CanSend()) {
 | |
|     MOZ_ASSERT(NS_IsMainThread());
 | |
|   }
 | |
| 
 | |
|   nsresult rv;
 | |
|   rv = AsyncOpen(aListener);
 | |
|   if (NS_WARN_IF(NS_FAILED(rv))) {
 | |
|     return rv;
 | |
|   }
 | |
| 
 | |
|   if (CanSend()) {
 | |
|     Unused << Send__delete__(this);
 | |
|   }
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| already_AddRefed<nsIChannel> NS_NewSimpleChannelInternal(
 | |
|     nsIURI* aURI, nsILoadInfo* aLoadInfo,
 | |
|     UniquePtr<SimpleChannelCallbacks>&& aCallbacks) {
 | |
|   RefPtr<SimpleChannel> chan;
 | |
|   if (IsNeckoChild()) {
 | |
|     chan = new SimpleChannelChild(std::move(aCallbacks));
 | |
|   } else {
 | |
|     chan = new SimpleChannel(std::move(aCallbacks));
 | |
|   }
 | |
| 
 | |
|   chan->SetURI(aURI);
 | |
| 
 | |
|   MOZ_ALWAYS_SUCCEEDS(chan->SetLoadInfo(aLoadInfo));
 | |
| 
 | |
|   return chan.forget();
 | |
| }
 | |
| 
 | |
| }  // namespace net
 | |
| }  // namespace mozilla
 |