NS_IMETHODIMP
nsHostObjectProtocolHandler::NewChannel2(nsIURI* uri,
                                         nsILoadInfo* aLoadInfo,
                                         nsIChannel** result)
{
  *result = nullptr;

  nsCOMPtr<nsIURIWithBlobImpl> uriBlobImpl = do_QueryInterface(uri);
  if (!uriBlobImpl) {
    return NS_ERROR_DOM_BAD_URI;
  }

  nsCOMPtr<nsISupports> tmp;
  MOZ_ALWAYS_SUCCEEDS(uriBlobImpl->GetBlobImpl(getter_AddRefs(tmp)));
  nsCOMPtr<BlobImpl> blobImpl = do_QueryInterface(tmp);
  if (!blobImpl) {
    return NS_ERROR_DOM_BAD_URI;
  }

#ifdef DEBUG
  DataInfo* info = GetDataInfoFromURI(uri);

  // Info can be null, in case this blob URL has been revoked already.
  if (info) {
    nsCOMPtr<nsIURIWithPrincipal> uriPrinc = do_QueryInterface(uri);
    nsCOMPtr<nsIPrincipal> principal;
    uriPrinc->GetPrincipal(getter_AddRefs(principal));
    MOZ_ASSERT(info->mPrincipal == principal, "Wrong principal!");
  }
#endif

  ErrorResult rv;
  nsCOMPtr<nsIInputStream> stream;
  blobImpl->GetInternalStream(getter_AddRefs(stream), rv);
  if (NS_WARN_IF(rv.Failed())) {
    return rv.StealNSResult();
  }

  nsAutoString contentType;
  blobImpl->GetType(contentType);

  nsCOMPtr<nsIChannel> channel;
  rv = NS_NewInputStreamChannelInternal(getter_AddRefs(channel),
                                        uri,
                                        stream,
                                        NS_ConvertUTF16toUTF8(contentType),
                                        EmptyCString(), // aContentCharset
                                        aLoadInfo);
  if (NS_WARN_IF(rv.Failed())) {
    return rv.StealNSResult();
  }

  if (blobImpl->IsFile()) {
    nsString filename;
    blobImpl->GetName(filename);
    channel->SetContentDispositionFilename(filename);
  }

  uint64_t size = blobImpl->GetSize(rv);
  if (NS_WARN_IF(rv.Failed())) {
    return rv.StealNSResult();
  }

  channel->SetOriginalURI(uri);
  channel->SetContentType(NS_ConvertUTF16toUTF8(contentType));
  channel->SetContentLength(size);

  channel.forget(result);

  return NS_OK;
}
Example #2
0
nsresult
UDPSocket::Init(const nsString& aLocalAddress,
                const Nullable<uint16_t>& aLocalPort,
                const bool& aAddressReuse,
                const bool& aLoopback)
{
  MOZ_ASSERT(!mSocket && !mSocketChild);

  mLocalAddress = aLocalAddress;
  mLocalPort = aLocalPort;
  mAddressReuse = aAddressReuse;
  mLoopback = aLoopback;

  ErrorResult rv;
  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetOwner());

  mOpened = Promise::Create(global, rv);
  if (NS_WARN_IF(rv.Failed())) {
    return rv.StealNSResult();
  }

  mClosed = Promise::Create(global, rv);
  if (NS_WARN_IF(rv.Failed())) {
    return rv.StealNSResult();
  }

  class OpenSocketRunnable final : public nsRunnable
  {
  public:
    explicit OpenSocketRunnable(UDPSocket* aSocket) : mSocket(aSocket)
    { }

    NS_IMETHOD Run() override
    {
      MOZ_ASSERT(mSocket);

      if (mSocket->mReadyState != SocketReadyState::Opening) {
        return NS_OK;
      }

      uint16_t localPort = 0;
      if (!mSocket->mLocalPort.IsNull()) {
        localPort = mSocket->mLocalPort.Value();
      }

      nsresult rv;
      if (XRE_GetProcessType() != GeckoProcessType_Default) {
        rv = mSocket->InitRemote(mSocket->mLocalAddress, localPort);
      } else {
        rv = mSocket->InitLocal(mSocket->mLocalAddress, localPort);
      }

      if (NS_WARN_IF(NS_FAILED(rv))) {
        mSocket->CloseWithReason(NS_ERROR_DOM_NETWORK_ERR);
      }

      return NS_OK;
    }

  private:
    nsRefPtr<UDPSocket> mSocket;
  };

  nsCOMPtr<nsIRunnable> runnable = new OpenSocketRunnable(this);

  return NS_DispatchToMainThread(runnable);
}