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);
}
Beispiel #2
0
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;
}
Beispiel #4
0
/* 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;
}
Beispiel #6
0
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;
}
Beispiel #7
0
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;
}
Beispiel #8
0
// 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;
}