1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/netwerk/protocol/wyciwyg/WyciwygChannelParent.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,327 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +#include "nsWyciwyg.h" 1.9 + 1.10 +#include "mozilla/net/WyciwygChannelParent.h" 1.11 +#include "nsWyciwygChannel.h" 1.12 +#include "nsNetUtil.h" 1.13 +#include "nsCharsetSource.h" 1.14 +#include "nsISerializable.h" 1.15 +#include "nsSerializationHelper.h" 1.16 +#include "mozilla/ipc/URIUtils.h" 1.17 +#include "mozilla/net/NeckoParent.h" 1.18 +#include "SerializedLoadContext.h" 1.19 + 1.20 +using namespace mozilla::ipc; 1.21 + 1.22 +namespace mozilla { 1.23 +namespace net { 1.24 + 1.25 +WyciwygChannelParent::WyciwygChannelParent() 1.26 + : mIPCClosed(false) 1.27 + , mReceivedAppData(false) 1.28 +{ 1.29 +#if defined(PR_LOGGING) 1.30 + if (!gWyciwygLog) 1.31 + gWyciwygLog = PR_NewLogModule("nsWyciwygChannel"); 1.32 +#endif 1.33 +} 1.34 + 1.35 +WyciwygChannelParent::~WyciwygChannelParent() 1.36 +{ 1.37 +} 1.38 + 1.39 +void 1.40 +WyciwygChannelParent::ActorDestroy(ActorDestroyReason why) 1.41 +{ 1.42 + // We may still have refcount>0 if the channel hasn't called OnStopRequest 1.43 + // yet, but we must not send any more msgs to child. 1.44 + mIPCClosed = true; 1.45 + 1.46 + // We need to force the cycle to break here 1.47 + mChannel->SetNotificationCallbacks(nullptr); 1.48 +} 1.49 + 1.50 +//----------------------------------------------------------------------------- 1.51 +// WyciwygChannelParent::nsISupports 1.52 +//----------------------------------------------------------------------------- 1.53 + 1.54 +NS_IMPL_ISUPPORTS(WyciwygChannelParent, 1.55 + nsIStreamListener, 1.56 + nsIInterfaceRequestor, 1.57 + nsIRequestObserver) 1.58 + 1.59 +//----------------------------------------------------------------------------- 1.60 +// WyciwygChannelParent::PWyciwygChannelParent 1.61 +//----------------------------------------------------------------------------- 1.62 + 1.63 +bool 1.64 +WyciwygChannelParent::RecvInit(const URIParams& aURI) 1.65 +{ 1.66 + nsresult rv; 1.67 + 1.68 + nsCOMPtr<nsIURI> uri = DeserializeURI(aURI); 1.69 + if (!uri) 1.70 + return false; 1.71 + 1.72 + nsCString uriSpec; 1.73 + uri->GetSpec(uriSpec); 1.74 + LOG(("WyciwygChannelParent RecvInit [this=%p uri=%s]\n", 1.75 + this, uriSpec.get())); 1.76 + 1.77 + nsCOMPtr<nsIIOService> ios(do_GetIOService(&rv)); 1.78 + if (NS_FAILED(rv)) 1.79 + return SendCancelEarly(rv); 1.80 + 1.81 + nsCOMPtr<nsIChannel> chan; 1.82 + rv = NS_NewChannel(getter_AddRefs(chan), uri, ios); 1.83 + if (NS_FAILED(rv)) 1.84 + return SendCancelEarly(rv); 1.85 + 1.86 + mChannel = do_QueryInterface(chan, &rv); 1.87 + if (NS_FAILED(rv)) 1.88 + return SendCancelEarly(rv); 1.89 + 1.90 + return true; 1.91 +} 1.92 + 1.93 +bool 1.94 +WyciwygChannelParent::RecvAppData(const IPC::SerializedLoadContext& loadContext, 1.95 + PBrowserParent* parent) 1.96 +{ 1.97 + LOG(("WyciwygChannelParent RecvAppData [this=%p]\n", this)); 1.98 + 1.99 + if (!SetupAppData(loadContext, parent)) 1.100 + return false; 1.101 + 1.102 + mChannel->SetNotificationCallbacks(this); 1.103 + return true; 1.104 +} 1.105 + 1.106 +bool 1.107 +WyciwygChannelParent::SetupAppData(const IPC::SerializedLoadContext& loadContext, 1.108 + PBrowserParent* aParent) 1.109 +{ 1.110 + if (!mChannel) 1.111 + return true; 1.112 + 1.113 + const char* error = NeckoParent::CreateChannelLoadContext(aParent, 1.114 + Manager()->Manager(), 1.115 + loadContext, 1.116 + mLoadContext); 1.117 + if (error) { 1.118 + printf_stderr("WyciwygChannelParent::SetupAppData: FATAL ERROR: %s\n", 1.119 + error); 1.120 + return false; 1.121 + } 1.122 + 1.123 + if (!mLoadContext && loadContext.IsPrivateBitValid()) { 1.124 + nsCOMPtr<nsIPrivateBrowsingChannel> pbChannel = do_QueryInterface(mChannel); 1.125 + if (pbChannel) 1.126 + pbChannel->SetPrivate(loadContext.mUsePrivateBrowsing); 1.127 + } 1.128 + 1.129 + mReceivedAppData = true; 1.130 + return true; 1.131 +} 1.132 + 1.133 +bool 1.134 +WyciwygChannelParent::RecvAsyncOpen(const URIParams& aOriginal, 1.135 + const uint32_t& aLoadFlags, 1.136 + const IPC::SerializedLoadContext& loadContext, 1.137 + PBrowserParent* aParent) 1.138 +{ 1.139 + nsCOMPtr<nsIURI> original = DeserializeURI(aOriginal); 1.140 + if (!original) 1.141 + return false; 1.142 + 1.143 + LOG(("WyciwygChannelParent RecvAsyncOpen [this=%p]\n", this)); 1.144 + 1.145 + if (!mChannel) 1.146 + return true; 1.147 + 1.148 + nsresult rv; 1.149 + 1.150 + rv = mChannel->SetOriginalURI(original); 1.151 + if (NS_FAILED(rv)) 1.152 + return SendCancelEarly(rv); 1.153 + 1.154 + rv = mChannel->SetLoadFlags(aLoadFlags); 1.155 + if (NS_FAILED(rv)) 1.156 + return SendCancelEarly(rv); 1.157 + 1.158 + if (!mReceivedAppData && !SetupAppData(loadContext, aParent)) { 1.159 + return false; 1.160 + } 1.161 + 1.162 + rv = mChannel->SetNotificationCallbacks(this); 1.163 + if (NS_FAILED(rv)) 1.164 + return SendCancelEarly(rv); 1.165 + 1.166 + rv = mChannel->AsyncOpen(this, nullptr); 1.167 + if (NS_FAILED(rv)) 1.168 + return SendCancelEarly(rv); 1.169 + 1.170 + return true; 1.171 +} 1.172 + 1.173 +bool 1.174 +WyciwygChannelParent::RecvWriteToCacheEntry(const nsString& data) 1.175 +{ 1.176 + if (!mReceivedAppData) { 1.177 + printf_stderr("WyciwygChannelParent::RecvWriteToCacheEntry: FATAL ERROR: didn't receive app data\n"); 1.178 + return false; 1.179 + } 1.180 + 1.181 + if (mChannel) 1.182 + mChannel->WriteToCacheEntry(data); 1.183 + 1.184 + return true; 1.185 +} 1.186 + 1.187 +bool 1.188 +WyciwygChannelParent::RecvCloseCacheEntry(const nsresult& reason) 1.189 +{ 1.190 + if (mChannel) { 1.191 + mChannel->CloseCacheEntry(reason); 1.192 + } 1.193 + 1.194 + return true; 1.195 +} 1.196 + 1.197 +bool 1.198 +WyciwygChannelParent::RecvSetCharsetAndSource(const int32_t& aCharsetSource, 1.199 + const nsCString& aCharset) 1.200 +{ 1.201 + if (mChannel) 1.202 + mChannel->SetCharsetAndSource(aCharsetSource, aCharset); 1.203 + 1.204 + return true; 1.205 +} 1.206 + 1.207 +bool 1.208 +WyciwygChannelParent::RecvSetSecurityInfo(const nsCString& aSecurityInfo) 1.209 +{ 1.210 + if (mChannel) { 1.211 + nsCOMPtr<nsISupports> securityInfo; 1.212 + NS_DeserializeObject(aSecurityInfo, getter_AddRefs(securityInfo)); 1.213 + mChannel->SetSecurityInfo(securityInfo); 1.214 + } 1.215 + 1.216 + return true; 1.217 +} 1.218 + 1.219 +bool 1.220 +WyciwygChannelParent::RecvCancel(const nsresult& aStatusCode) 1.221 +{ 1.222 + if (mChannel) 1.223 + mChannel->Cancel(aStatusCode); 1.224 + return true; 1.225 +} 1.226 + 1.227 +//----------------------------------------------------------------------------- 1.228 +// WyciwygChannelParent::nsIRequestObserver 1.229 +//----------------------------------------------------------------------------- 1.230 + 1.231 +NS_IMETHODIMP 1.232 +WyciwygChannelParent::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext) 1.233 +{ 1.234 + LOG(("WyciwygChannelParent::OnStartRequest [this=%p]\n", this)); 1.235 + 1.236 + nsresult rv; 1.237 + 1.238 + nsCOMPtr<nsIWyciwygChannel> chan = do_QueryInterface(aRequest, &rv); 1.239 + NS_ENSURE_SUCCESS(rv, rv); 1.240 + 1.241 + nsresult status; 1.242 + chan->GetStatus(&status); 1.243 + 1.244 + int64_t contentLength = -1; 1.245 + chan->GetContentLength(&contentLength); 1.246 + 1.247 + int32_t charsetSource = kCharsetUninitialized; 1.248 + nsAutoCString charset; 1.249 + chan->GetCharsetAndSource(&charsetSource, charset); 1.250 + 1.251 + nsCOMPtr<nsISupports> securityInfo; 1.252 + chan->GetSecurityInfo(getter_AddRefs(securityInfo)); 1.253 + nsCString secInfoStr; 1.254 + if (securityInfo) { 1.255 + nsCOMPtr<nsISerializable> serializable = do_QueryInterface(securityInfo); 1.256 + if (serializable) 1.257 + NS_SerializeToString(serializable, secInfoStr); 1.258 + else { 1.259 + NS_ERROR("Can't serialize security info"); 1.260 + return NS_ERROR_UNEXPECTED; 1.261 + } 1.262 + } 1.263 + 1.264 + if (mIPCClosed || 1.265 + !SendOnStartRequest(status, contentLength, charsetSource, charset, secInfoStr)) { 1.266 + return NS_ERROR_UNEXPECTED; 1.267 + } 1.268 + 1.269 + return NS_OK; 1.270 +} 1.271 + 1.272 +NS_IMETHODIMP 1.273 +WyciwygChannelParent::OnStopRequest(nsIRequest *aRequest, 1.274 + nsISupports *aContext, 1.275 + nsresult aStatusCode) 1.276 +{ 1.277 + LOG(("WyciwygChannelParent::OnStopRequest: [this=%p status=%ul]\n", 1.278 + this, aStatusCode)); 1.279 + 1.280 + if (mIPCClosed || !SendOnStopRequest(aStatusCode)) { 1.281 + return NS_ERROR_UNEXPECTED; 1.282 + } 1.283 + 1.284 + return NS_OK; 1.285 +} 1.286 + 1.287 +//----------------------------------------------------------------------------- 1.288 +// WyciwygChannelParent::nsIStreamListener 1.289 +//----------------------------------------------------------------------------- 1.290 + 1.291 +NS_IMETHODIMP 1.292 +WyciwygChannelParent::OnDataAvailable(nsIRequest *aRequest, 1.293 + nsISupports *aContext, 1.294 + nsIInputStream *aInputStream, 1.295 + uint64_t aOffset, 1.296 + uint32_t aCount) 1.297 +{ 1.298 + LOG(("WyciwygChannelParent::OnDataAvailable [this=%p]\n", this)); 1.299 + 1.300 + nsCString data; 1.301 + nsresult rv = NS_ReadInputStreamToString(aInputStream, data, aCount); 1.302 + if (NS_FAILED(rv)) 1.303 + return rv; 1.304 + 1.305 + if (mIPCClosed || !SendOnDataAvailable(data, aOffset)) { 1.306 + return NS_ERROR_UNEXPECTED; 1.307 + } 1.308 + 1.309 + return NS_OK; 1.310 +} 1.311 + 1.312 +//----------------------------------------------------------------------------- 1.313 +// WyciwygChannelParent::nsIInterfaceRequestor 1.314 +//----------------------------------------------------------------------------- 1.315 + 1.316 +NS_IMETHODIMP 1.317 +WyciwygChannelParent::GetInterface(const nsIID& uuid, void** result) 1.318 +{ 1.319 + // Only support nsILoadContext if child channel's callbacks did too 1.320 + if (uuid.Equals(NS_GET_IID(nsILoadContext)) && mLoadContext) { 1.321 + NS_ADDREF(mLoadContext); 1.322 + *result = static_cast<nsILoadContext*>(mLoadContext); 1.323 + return NS_OK; 1.324 + } 1.325 + 1.326 + return QueryInterface(uuid, result); 1.327 +} 1.328 + 1.329 + 1.330 +}} // mozilla::net