nsresult nsZipDataStream::ReadStream(nsIInputStream *aStream) { if (!mOutput) return NS_ERROR_NOT_INITIALIZED; nsresult rv = OnStartRequest(nullptr, nullptr); NS_ENSURE_SUCCESS(rv, rv); nsAutoArrayPtr<char> buffer(new char[4096]); NS_ENSURE_TRUE(buffer, NS_ERROR_OUT_OF_MEMORY); uint32_t read = 0; uint32_t offset = 0; do { rv = aStream->Read(buffer.get(), 4096, &read); if (NS_FAILED(rv)) { OnStopRequest(nullptr, nullptr, rv); return rv; } if (read > 0) { rv = ProcessData(nullptr, nullptr, buffer.get(), offset, read); if (NS_FAILED(rv)) { OnStopRequest(nullptr, nullptr, rv); return rv; } offset += read; } } while (read > 0); return OnStopRequest(nullptr, nullptr, NS_OK); }
bool HttpChannelChild::RecvOnStartRequest(const nsHttpResponseHead& responseHead, const bool& useResponseHead, const nsHttpHeaderArray& requestHeaders, const bool& isFromCache, const bool& cacheEntryAvailable, const PRUint32& cacheExpirationTime, const nsCString& cachedCharset, const nsCString& securityInfoSerialization, const PRNetAddr& selfAddr, const PRNetAddr& peerAddr) { if (mEventQ.ShouldEnqueue()) { mEventQ.Enqueue(new StartRequestEvent(this, responseHead, useResponseHead, requestHeaders, isFromCache, cacheEntryAvailable, cacheExpirationTime, cachedCharset, securityInfoSerialization, selfAddr, peerAddr)); } else { OnStartRequest(responseHead, useResponseHead, requestHeaders, isFromCache, cacheEntryAvailable, cacheExpirationTime, cachedCharset, securityInfoSerialization, selfAddr, peerAddr); } return true; }
/* * imgIDecoderObserver impl */ NS_IMETHODIMP nsImageLoadingContent::OnStartRequest(imgIRequest* aRequest) { NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE); LOOP_OVER_OBSERVERS(OnStartRequest(aRequest)); return NS_OK; }
/* static */ void ProgressTracker::SyncNotifyInternal(ProxyArray& aProxies, bool aHasImage, Progress aProgress, const nsIntRect& aDirtyRect) { MOZ_ASSERT(NS_IsMainThread()); // OnStartRequest if (aProgress & FLAG_REQUEST_STARTED) NOTIFY_IMAGE_OBSERVERS(aProxies, OnStartRequest()); // OnStartContainer if (aProgress & FLAG_HAS_SIZE) NOTIFY_IMAGE_OBSERVERS(aProxies, OnStartContainer()); // OnStartDecode if (aProgress & FLAG_DECODE_STARTED) NOTIFY_IMAGE_OBSERVERS(aProxies, OnStartDecode()); // BlockOnload if (aProgress & FLAG_ONLOAD_BLOCKED) NOTIFY_IMAGE_OBSERVERS(aProxies, BlockOnload()); if (aHasImage) { // OnFrameUpdate // If there's any content in this frame at all (always true for // vector images, true for raster images that have decoded at // least one frame) then send OnFrameUpdate. if (!aDirtyRect.IsEmpty()) NOTIFY_IMAGE_OBSERVERS(aProxies, OnFrameUpdate(&aDirtyRect)); if (aProgress & FLAG_FRAME_STOPPED) NOTIFY_IMAGE_OBSERVERS(aProxies, OnStopFrame()); // OnImageIsAnimated if (aProgress & FLAG_IS_ANIMATED) NOTIFY_IMAGE_OBSERVERS(aProxies, OnImageIsAnimated()); } // Send UnblockOnload before OnStopDecode and OnStopRequest. This allows // observers that can fire events when they receive those notifications to do // so then, instead of being forced to wait for UnblockOnload. if (aProgress & FLAG_ONLOAD_UNBLOCKED) { NOTIFY_IMAGE_OBSERVERS(aProxies, UnblockOnload()); } if (aProgress & FLAG_DECODE_STOPPED) { MOZ_ASSERT(aHasImage, "Stopped decoding without ever having an image?"); NOTIFY_IMAGE_OBSERVERS(aProxies, OnStopDecode()); } if (aProgress & FLAG_REQUEST_STOPPED) { NOTIFY_IMAGE_OBSERVERS(aProxies, OnStopRequest(aProgress & FLAG_MULTIPART_STOPPED)); } }
bool WyciwygChannelChild::RecvOnStartRequest(const nsresult& statusCode, const PRInt32& contentLength, const PRInt32& source, const nsCString& charset, const nsCString& securityInfo) { if (mEventQ.ShouldEnqueue()) { mEventQ.Enqueue(new WyciwygStartRequestEvent(this, statusCode, contentLength, source, charset, securityInfo)); } else { OnStartRequest(statusCode, contentLength, source, charset, securityInfo); } return true; }
bool HttpChannelChild::RecvOnStartRequest(const nsHttpResponseHead& responseHead, const PRBool& useResponseHead, const PRBool& isFromCache, const PRBool& cacheEntryAvailable, const PRUint32& cacheExpirationTime, const nsCString& cachedCharset, const nsCString& securityInfoSerialization) { if (ShouldEnqueue()) { EnqueueEvent(new StartRequestEvent(this, responseHead, useResponseHead, isFromCache, cacheEntryAvailable, cacheExpirationTime, cachedCharset, securityInfoSerialization)); } else { OnStartRequest(responseHead, useResponseHead, isFromCache, cacheEntryAvailable, cacheExpirationTime, cachedCharset, securityInfoSerialization); } return true; }
NS_IMETHODIMP nsJARChannel::OnDownloadComplete(nsIDownloader *downloader, nsIRequest *request, nsISupports *context, nsresult status, nsIFile *file) { nsresult rv; nsCOMPtr<nsIChannel> channel(do_QueryInterface(request)); if (channel) { PRUint32 loadFlags; channel->GetLoadFlags(&loadFlags); if (loadFlags & LOAD_REPLACE) { mLoadFlags |= LOAD_REPLACE; if (!mOriginalURI) { SetOriginalURI(mJarURI); } nsCOMPtr<nsIURI> innerURI; rv = channel->GetURI(getter_AddRefs(innerURI)); if (NS_SUCCEEDED(rv)) { nsCOMPtr<nsIJARURI> newURI; rv = mJarURI->CloneWithJARFile(innerURI, getter_AddRefs(newURI)); if (NS_SUCCEEDED(rv)) { mJarURI = newURI; } } if (NS_SUCCEEDED(status)) { status = rv; } } } if (NS_SUCCEEDED(status) && channel) { // Grab the security info from our base channel channel->GetSecurityInfo(getter_AddRefs(mSecurityInfo)); nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel)); if (httpChannel) { // We only want to run scripts if the server really intended to // send us a JAR file. Check the server-supplied content type for // a JAR type. nsCAutoString header; httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("Content-Type"), header); nsCAutoString contentType; nsCAutoString charset; NS_ParseContentType(header, contentType, charset); nsCAutoString channelContentType; channel->GetContentType(channelContentType); mIsUnsafe = !(contentType.Equals(channelContentType) && (contentType.EqualsLiteral("application/java-archive") || contentType.EqualsLiteral("application/x-jar"))); } else { nsCOMPtr<nsIJARChannel> innerJARChannel(do_QueryInterface(channel)); if (innerJARChannel) { PRBool unsafe; innerJARChannel->GetIsUnsafe(&unsafe); mIsUnsafe = unsafe; } } channel->GetContentDisposition(mContentDisposition); } if (NS_SUCCEEDED(status) && mIsUnsafe) { PRBool allowUnpack = PR_FALSE; nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID); if (prefs) { prefs->GetBoolPref("network.jar.open-unsafe-types", &allowUnpack); } if (!allowUnpack) { status = NS_ERROR_UNSAFE_CONTENT_TYPE; } } if (NS_SUCCEEDED(status)) { // Refuse to unpack view-source: jars even if open-unsafe-types is set. nsCOMPtr<nsIViewSourceChannel> viewSource = do_QueryInterface(channel); if (viewSource) { status = NS_ERROR_UNSAFE_CONTENT_TYPE; } } if (NS_SUCCEEDED(status)) { mJarFile = file; rv = CreateJarInput(nsnull); if (NS_SUCCEEDED(rv)) { // create input stream pump rv = NS_NewInputStreamPump(getter_AddRefs(mPump), mJarInput); if (NS_SUCCEEDED(rv)) rv = mPump->AsyncRead(this, nsnull); } status = rv; } if (NS_FAILED(status)) { mStatus = status; OnStartRequest(nsnull, nsnull); OnStopRequest(nsnull, nsnull, status); } return NS_OK; }
// This is called when the channel is redirected. NS_IMETHODIMP FetchDriver::AsyncOnChannelRedirect(nsIChannel* aOldChannel, nsIChannel* aNewChannel, uint32_t aFlags, nsIAsyncVerifyRedirectCallback *aCallback) { NS_PRECONDITION(aNewChannel, "Redirect without a channel?"); nsresult rv; // HTTP Fetch step 5, "redirect status", step 1 if (NS_WARN_IF(mRequest->GetRedirectMode() == RequestRedirect::Error)) { aOldChannel->Cancel(NS_BINDING_FAILED); return NS_BINDING_FAILED; } // HTTP Fetch step 5, "redirect status", steps 2 through 6 are automatically // handled by necko before calling AsyncOnChannelRedirect() with the new // nsIChannel. // HTTP Fetch step 5, "redirect status", steps 7 and 8 enforcing a redirect // count are done by Necko. The pref used is "network.http.redirection-limit" // which is set to 20 by default. // HTTP Fetch Step 9, "redirect status". We only unset this for spec // compatibility. Any actions we take on mRequest here do not affect what the //channel does. mRequest->UnsetSameOriginDataURL(); // HTTP Fetch step 5, "redirect status", step 10 requires us to halt the // redirect, but successfully return an opaqueredirect Response to the // initiating Fetch. if (mRequest->GetRedirectMode() == RequestRedirect::Manual) { // Ideally we would simply not cancel the old channel and allow it to // be processed as normal. Unfortunately this is quite fragile and // other redirect handlers can easily break it for certain use cases. // // For example, nsCORSListenerProxy cancels vetoed redirect channels. // The HTTP cache will also error on vetoed redirects when the // redirect has been previously cached. // // Therefore simulate the completion of the channel to produce the // opaqueredirect Response and then cancel the original channel. This // will result in OnStartRequest() getting called twice, but the second // time will be with an error response (from the Cancel) which will // be ignored. mRequest->SetResponseTainting(InternalRequest::RESPONSETAINT_OPAQUEREDIRECT); unused << OnStartRequest(aOldChannel, nullptr); unused << OnStopRequest(aOldChannel, nullptr, NS_OK); aOldChannel->Cancel(NS_BINDING_FAILED); return NS_BINDING_FAILED; } // The following steps are from HTTP Fetch step 5, "redirect status", step 11 // which requires the RequestRedirect to be "follow". MOZ_ASSERT(mRequest->GetRedirectMode() == RequestRedirect::Follow); // HTTP Fetch step 5, "redirect status", steps 11.1 and 11.2 block redirecting // to a URL with credentials in CORS mode. This is implemented in // nsCORSListenerProxy. mRedirectCallback = aCallback; mOldRedirectChannel = aOldChannel; mNewRedirectChannel = aNewChannel; nsCOMPtr<nsIChannelEventSink> outer = do_GetInterface(mNotificationCallbacks); if (outer) { // The callee is supposed to call OnRedirectVerifyCallback() on success, // and nobody has to call it on failure, so we can just return after this // block. rv = outer->AsyncOnChannelRedirect(aOldChannel, aNewChannel, aFlags, this); if (NS_FAILED(rv)) { aOldChannel->Cancel(rv); mRedirectCallback = nullptr; mOldRedirectChannel = nullptr; mNewRedirectChannel = nullptr; } return rv; } (void) OnRedirectVerifyCallback(NS_OK); return NS_OK; }