TestHttpChannel.cpp (3615B)
1 #include "gtest/gtest.h" 2 3 #include "nsCOMPtr.h" 4 #include "mozilla/Maybe.h" 5 #include "mozilla/PreloadHashKey.h" 6 #include "mozilla/SpinEventLoopUntil.h" 7 #include "nsNetUtil.h" 8 #include "nsIChannel.h" 9 #include "nsIStreamListener.h" 10 #include "nsThreadUtils.h" 11 #include "nsStringStream.h" 12 #include "nsIPrivateBrowsingChannel.h" 13 #include "nsIInterfaceRequestor.h" 14 #include "nsContentUtils.h" 15 16 using namespace mozilla; 17 18 class FakeListener : public nsIStreamListener, public nsIInterfaceRequestor { 19 public: 20 NS_DECL_ISUPPORTS 21 NS_DECL_NSIREQUESTOBSERVER 22 NS_DECL_NSISTREAMLISTENER 23 NS_DECL_NSIINTERFACEREQUESTOR 24 25 enum { Never, OnStart, OnData, OnStop } mCancelIn = Never; 26 27 nsresult mOnStartResult = NS_OK; 28 nsresult mOnDataResult = NS_OK; 29 nsresult mOnStopResult = NS_OK; 30 31 bool mOnStart = false; 32 nsCString mOnData; 33 Maybe<nsresult> mOnStop; 34 35 private: 36 virtual ~FakeListener() = default; 37 }; 38 39 NS_IMPL_ISUPPORTS(FakeListener, nsIStreamListener, nsIRequestObserver, 40 nsIInterfaceRequestor) 41 42 NS_IMETHODIMP 43 FakeListener::GetInterface(const nsIID& aIID, void** aResult) { 44 NS_ENSURE_ARG_POINTER(aResult); 45 *aResult = nullptr; 46 return NS_NOINTERFACE; 47 } 48 49 NS_IMETHODIMP FakeListener::OnStartRequest(nsIRequest* request) { 50 EXPECT_FALSE(mOnStart); 51 mOnStart = true; 52 53 if (mCancelIn == OnStart) { 54 request->Cancel(NS_ERROR_ABORT); 55 } 56 57 return mOnStartResult; 58 } 59 60 NS_IMETHODIMP FakeListener::OnDataAvailable(nsIRequest* request, 61 nsIInputStream* input, 62 uint64_t offset, uint32_t count) { 63 nsAutoCString data; 64 data.SetLength(count); 65 66 uint32_t read; 67 input->Read(data.BeginWriting(), count, &read); 68 mOnData += data; 69 70 if (mCancelIn == OnData) { 71 request->Cancel(NS_ERROR_ABORT); 72 } 73 74 return mOnDataResult; 75 } 76 77 NS_IMETHODIMP FakeListener::OnStopRequest(nsIRequest* request, 78 nsresult status) { 79 EXPECT_FALSE(mOnStop); 80 mOnStop.emplace(status); 81 82 if (mCancelIn == OnStop) { 83 request->Cancel(NS_ERROR_ABORT); 84 } 85 86 return mOnStopResult; 87 } 88 89 // Test that nsHttpChannel::AsyncOpen properly picks up changes to 90 // loadInfo.mPrivateBrowsingId that occur after the channel was created. 91 TEST(TestHttpChannel, PBAsyncOpen) 92 { 93 nsCOMPtr<nsIURI> uri; 94 NS_NewURI(getter_AddRefs(uri), "http://localhost/"_ns); 95 96 nsCOMPtr<nsIChannel> channel; 97 nsresult rv = NS_NewChannel( 98 getter_AddRefs(channel), uri, nsContentUtils::GetSystemPrincipal(), 99 nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL, 100 nsIContentPolicy::TYPE_OTHER); 101 ASSERT_EQ(rv, NS_OK); 102 103 RefPtr<FakeListener> listener = new FakeListener(); 104 rv = channel->SetNotificationCallbacks(listener); 105 ASSERT_EQ(rv, NS_OK); 106 107 nsCOMPtr<nsIPrivateBrowsingChannel> pbchannel = do_QueryInterface(channel); 108 ASSERT_TRUE(pbchannel); 109 110 bool isPrivate = false; 111 rv = pbchannel->GetIsChannelPrivate(&isPrivate); 112 ASSERT_EQ(rv, NS_OK); 113 ASSERT_EQ(isPrivate, false); 114 115 nsCOMPtr<nsILoadInfo> loadInfo = channel->LoadInfo(); 116 OriginAttributes attrs; 117 attrs.mPrivateBrowsingId = 1; 118 rv = loadInfo->SetOriginAttributes(attrs); 119 ASSERT_EQ(rv, NS_OK); 120 121 rv = pbchannel->GetIsChannelPrivate(&isPrivate); 122 ASSERT_EQ(rv, NS_OK); 123 ASSERT_EQ(isPrivate, false); 124 125 rv = channel->AsyncOpen(listener); 126 ASSERT_EQ(rv, NS_OK); 127 128 rv = pbchannel->GetIsChannelPrivate(&isPrivate); 129 ASSERT_EQ(rv, NS_OK); 130 ASSERT_EQ(isPrivate, true); 131 132 MOZ_ALWAYS_TRUE(mozilla::SpinEventLoopUntil( 133 "TEST(TestHttpChannel, PBAsyncOpen)"_ns, 134 [&]() -> bool { return listener->mOnStop.isSome(); })); 135 }