Example #1
0
static void
rdf_EscapeAmpersandsAndAngleBrackets(nsCString& s)
{
    uint32_t newLength, origLength;
    newLength = origLength = s.Length();

    // Compute the length of the result string.
    const char* start = s.BeginReading();
    const char* end = s.EndReading();
    const char* c = start;
    while (c != end) {
        switch (*c) {
        case '&' :
            newLength += sizeof(amp) - 2;
            break;
        case '<':
        case '>':
            newLength += sizeof(gt) - 2;
            break;
        default:
            break;
        }
        ++c;
    }
    if (newLength == origLength) {
        // nothing to escape
        return;
    }

    // escape the chars from the end back to the front.
    s.SetLength(newLength);

    // Buffer might have changed, get the pointers again
    start = s.BeginReading(); // begin of string
    c = start + origLength - 1; // last char in original string
    char* w = s.EndWriting() - 1; // last char in grown buffer
    while (c >= start) {
        switch (*c) {
        case '&' :
            w -= 4;
            nsCharTraits<char>::copy(w, amp, sizeof(amp) - 1);
            break;
        case '<':
            w -= 3;
            nsCharTraits<char>::copy(w, lt, sizeof(lt) - 1);
            break;
        case '>':
            w -= 3;
            nsCharTraits<char>::copy(w, gt, sizeof(gt) - 1);
            break;
        default:
            *w = *c;
        }
        --w;
        --c;
    }
}
nsresult nsDOMOfflineResourceList::GetCacheKey(nsIURI* aURI, nsCString& aKey) {
  nsresult rv = aURI->GetAsciiSpec(aKey);
  NS_ENSURE_SUCCESS(rv, rv);

  // url fragments aren't used in cache keys
  nsAutoCString::const_iterator specStart, specEnd;
  aKey.BeginReading(specStart);
  aKey.EndReading(specEnd);
  if (FindCharInReadable('#', specStart, specEnd)) {
    aKey.BeginReading(specEnd);
    aKey = Substring(specEnd, specStart);
  }

  return NS_OK;
}
Example #3
0
void nsMsgI18NConvertRawBytesToUTF16(const nsCString& inString, 
                                     const char* charset,
                                     nsAString& outString)
{
  if (MsgIsUTF8(inString))
  {
    CopyUTF8toUTF16(inString, outString);
    return;
  }

  nsresult rv = ConvertToUnicode(charset, inString, outString);
  if (NS_SUCCEEDED(rv))
    return;

  const char* cur = inString.BeginReading();
  const char* end = inString.EndReading();
  outString.Truncate();
  while (cur < end) {
    char c = *cur++;
    if (c & char(0x80))
      outString.Append(UCS2_REPLACEMENT_CHAR);
    else
      outString.Append(c);
  }
}
nsresult UDPSocketParent::ConnectInternal(const nsCString& aHost,
                                          const uint16_t& aPort) {
  nsresult rv;

  UDPSOCKET_LOG(("%s: %s:%u", __FUNCTION__, nsCString(aHost).get(), aPort));

  if (!mSocket) {
    return NS_ERROR_NOT_AVAILABLE;
  }

  PRNetAddr prAddr;
  memset(&prAddr, 0, sizeof(prAddr));
  PR_InitializeNetAddr(PR_IpAddrAny, aPort, &prAddr);
  PRStatus status = PR_StringToNetAddr(aHost.BeginReading(), &prAddr);
  if (status != PR_SUCCESS) {
    return NS_ERROR_FAILURE;
  }

  mozilla::net::NetAddr addr;
  PRNetAddrToNetAddr(&prAddr, &addr);

  rv = mSocket->Connect(&addr);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  return NS_OK;
}
/**
 * Check if the host name starts with ftp\d*\. and it's not directly followed
 * by the tld.
 */
bool nsDefaultURIFixup::IsLikelyFTP(const nsCString &aHostSpec)
{
    bool likelyFTP = false;
    if (aHostSpec.EqualsIgnoreCase("ftp", 3)) {
        nsACString::const_iterator iter;
        nsACString::const_iterator end;
        aHostSpec.BeginReading(iter);
        aHostSpec.EndReading(end);
        iter.advance(3); // move past the "ftp" part

        while (iter != end)
        {
            if (*iter == '.') {
                // now make sure the name has at least one more dot in it
                ++iter;
                while (iter != end)
                {
                    if (*iter == '.') {
                        likelyFTP = true;
                        break;
                    }
                    ++iter;
                }
                break;
            }
            else if (!nsCRT::IsAsciiDigit(*iter)) {
                break;
            }
            ++iter;
        }
    }
    return likelyFTP;
}
Example #6
0
void nsMsgI18NConvertRawBytesToUTF8(const nsCString& inString, 
                                    const char* charset,
                                    nsACString& outString)
{
  if (MsgIsUTF8(inString))
  {
    outString.Assign(inString);
    return;
  }

  nsAutoString utf16Text;
  nsresult rv = ConvertToUnicode(charset, inString, utf16Text);
  if (NS_SUCCEEDED(rv))
  {
    CopyUTF16toUTF8(utf16Text, outString);
    return;
  }

  // EF BF BD (UTF-8 encoding of U+FFFD)
  NS_NAMED_LITERAL_CSTRING(utf8ReplacementChar, "\357\277\275");
  const char* cur = inString.BeginReading();
  const char* end = inString.EndReading();
  outString.Truncate();
  while (cur < end) {
    char c = *cur++;
    if (c & char(0x80))
      outString.Append(utf8ReplacementChar);
    else
      outString.Append(c);
  }
}
static void
MorkUnescape(const nsCSubstring &aString, nsCString &aResult)
{
    PRUint32 len = aString.Length();

    // We optimize for speed over space here -- size the result buffer to
    // the size of the source, which is an upper bound on the size of the
    // unescaped string.
    // FIXME: Mork assume there will never be errors
    if (!EnsureStringLength(aResult, len)) {
        aResult.Truncate();
        return; // out of memory.
    }

    char *result = aResult.BeginWriting();
    const char *source = aString.BeginReading();
    const char *sourceEnd = source + len;

    const char *startPos = nsnull;
    PRUint32 bytes;
    for (; source < sourceEnd; ++source) {
        char c = *source;
        if (c == '\\') {
            if (startPos) {
                bytes = source - startPos;
                memcpy(result, startPos, bytes);
                result += bytes;
                startPos = nsnull;
            }
            if (source < sourceEnd - 1) {
                *(result++) = *(++source);
            }
        } else if (c == '$') {
            if (startPos) {
                bytes = source - startPos;
                memcpy(result, startPos, bytes);
                result += bytes;
                startPos = nsnull;
            }
            if (source < sourceEnd - 2) {
                // Would be nice to use ToInteger() here, but it currently
                // requires a null-terminated string.
                char c2 = *(++source);
                char c3 = *(++source);
                if (ConvertChar(&c2) && ConvertChar(&c3)) {
                    *(result++) = ((c2 << 4) | c3);
                }
            }
        } else if (!startPos) {
            startPos = source;
        }
    }
    if (startPos) {
        bytes = source - startPos;
        memcpy(result, startPos, bytes);
        result += bytes;
    }
    aResult.SetLength(result - aResult.BeginReading());
}
Example #8
0
static void ReplaceChar(nsCString& str, const nsACString& character,
                        const nsACString& replacement)
{
  nsCString::const_iterator start, end;

  str.BeginReading(start);
  str.EndReading(end);

  while (FindInReadable(character, start, end)) {
    PRInt32 pos = end.size_backward();
    str.Replace(pos - 1, 1, replacement);

    str.BeginReading(start);
    start.advance(pos + replacement.Length() - 1);
    str.EndReading(end);
  }
}
nsMediaFragmentURIParser::nsMediaFragmentURIParser(const nsCString& aSpec)
{
  nsReadingIterator<char> start, end;
  aSpec.BeginReading(start);
  aSpec.EndReading(end);
  if (FindCharInReadable('#', start, end)) {
    mHash = Substring(++start, end);
  }
}
Example #10
0
bool
GMPChild::RecvSetNodeId(const nsCString& aNodeId)
{
  // Store the per origin salt for the node id. Note: we do this in a
  // separate message than RecvStartPlugin() so that the string is not
  // sitting in a string on the IPC code's call stack.
  mNodeId = std::string(aNodeId.BeginReading(), aNodeId.EndReading());
  return true;
}
Example #11
0
bool
UDPSocketParent::Init(const nsCString &aHost, const uint16_t aPort)
{
  nsresult rv;
  NS_ASSERTION(mFilter, "No packet filter");

  nsCOMPtr<nsIUDPSocket> sock =
      do_CreateInstance("@mozilla.org/network/udp-socket;1", &rv);
  if (NS_FAILED(rv)) {
    FireInternalError(this, __LINE__);
    return true;
  }

  if (aHost.IsEmpty()) {
    rv = sock->Init(aPort, false);
  } else {
    PRNetAddr prAddr;
    PR_InitializeNetAddr(PR_IpAddrAny, aPort, &prAddr);
    PRStatus status = PR_StringToNetAddr(aHost.BeginReading(), &prAddr);
    if (status != PR_SUCCESS) {
      FireInternalError(this, __LINE__);
      return true;
    }

    mozilla::net::NetAddr addr;
    PRNetAddrToNetAddr(&prAddr, &addr);
    rv = sock->InitWithAddress(&addr);
  }

  if (NS_FAILED(rv)) {
    FireInternalError(this, __LINE__);
    return true;
  }

  mSocket = sock;

  net::NetAddr localAddr;
  mSocket->GetAddress(&localAddr);

  uint16_t port;
  nsCString addr;
  rv = ConvertNetAddrToString(localAddr, &addr, &port);

  if (NS_FAILED(rv)) {
    FireInternalError(this, __LINE__);
    return true;
  }

  // register listener
  mSocket->AsyncListen(this);
  mozilla::unused <<
      PUDPSocketParent::SendCallback(NS_LITERAL_CSTRING("onopen"),
                                     UDPAddressInfo(addr, port),
                                     NS_LITERAL_CSTRING("connected"));

  return true;
}
Example #12
0
void
WebGLShader::BindAttribLocation(GLuint prog, const nsCString& userName,
                                GLuint index) const
{
    std::string userNameStr(userName.BeginReading());

    const std::string* mappedNameStr = &userNameStr;
    if (mValidator)
        mValidator->FindAttribMappedNameByUserName(userNameStr, &mappedNameStr);

    mContext->gl->fBindAttribLocation(prog, index, mappedNameStr->c_str());
}
Example #13
0
nsresult
UDPSocketParent::BindInternal(const nsCString& aHost, const uint16_t& aPort,
                              const bool& aAddressReuse, const bool& aLoopback)
{
  nsresult rv;

  UDPSOCKET_LOG(("%s: %s:%u", __FUNCTION__, nsCString(aHost).get(), aPort));

  nsCOMPtr<nsIUDPSocket> sock =
      do_CreateInstance("@mozilla.org/network/udp-socket;1", &rv);

  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  if (aHost.IsEmpty()) {
    rv = sock->Init(aPort, false, mPrincipal, aAddressReuse,
                    /* optional_argc = */ 1);
  } else {
    PRNetAddr prAddr;
    PR_InitializeNetAddr(PR_IpAddrAny, aPort, &prAddr);
    PRStatus status = PR_StringToNetAddr(aHost.BeginReading(), &prAddr);
    if (status != PR_SUCCESS) {
      return NS_ERROR_FAILURE;
    }

    mozilla::net::NetAddr addr;
    PRNetAddrToNetAddr(&prAddr, &addr);
    rv = sock->InitWithAddress(&addr, mPrincipal, aAddressReuse,
                               /* optional_argc = */ 1);
  }

  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  rv = sock->SetMulticastLoopback(aLoopback);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  // register listener
  rv = sock->AsyncListen(this);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  mSocket = sock;

  return NS_OK;
}
Example #14
0
bool
NeckoParent::RecvRemoveRequestContext(const nsCString& rcid)
{
  nsCOMPtr<nsIRequestContextService> rcsvc =
    do_GetService("@mozilla.org/network/request-context-service;1");
  if (!rcsvc) {
    return true;
  }

  nsID id;
  id.Parse(rcid.BeginReading());
  rcsvc->RemoveRequestContext(id);

  return true;
}
Example #15
0
bool
NeckoParent::RecvRemoveSchedulingContext(const nsCString& scid)
{
  nsCOMPtr<nsISchedulingContextService> scsvc =
    do_GetService("@mozilla.org/network/scheduling-context-service;1");
  if (!scsvc) {
    return true;
  }

  nsID id;
  id.Parse(scid.BeginReading());
  scsvc->RemoveSchedulingContext(id);

  return true;
}
Example #16
0
VRControllerOpenVR::VRControllerOpenVR(dom::GamepadHand aHand, uint32_t aDisplayID,
                                       uint32_t aNumButtons, uint32_t aNumTriggers,
                                       uint32_t aNumAxes, const nsCString& aId)
  : VRControllerHost(VRDeviceType::OpenVR, aHand, aDisplayID)
  , mVibrateThread(nullptr)
  , mIsVibrateStopped(false)
{
  MOZ_COUNT_CTOR_INHERITED(VRControllerOpenVR, VRControllerHost);

  VRControllerState& state = mControllerInfo.mControllerState;
  strncpy(state.mControllerName, aId.BeginReading(), kVRControllerNameMaxLen);
  state.mNumButtons = aNumButtons;
  state.mNumAxes = aNumAxes;
  state.mNumTriggers = aNumTriggers;
  state.mNumHaptics = kNumOpenVRHaptcs;
}
Example #17
0
void
WebGLShader::ShaderSource(const nsAString& source)
{
    StripComments stripComments(source);
    const nsAString& cleanSource = Substring(stripComments.result().Elements(),
                                             stripComments.length());
    if (!ValidateGLSLString(cleanSource, mContext, "shaderSource"))
        return;

    // We checked that the source stripped of comments is in the
    // 7-bit ASCII range, so we can skip the NS_IsAscii() check.
    const NS_LossyConvertUTF16toASCII sourceCString(cleanSource);

    if (mContext->gl->WorkAroundDriverBugs()) {
        const size_t maxSourceLength = 0x3ffff;
        if (sourceCString.Length() > maxSourceLength) {
            mContext->ErrorInvalidValue("shaderSource: Source has more than %d"
                                        " characters. (Driver workaround)",
                                        maxSourceLength);
            return;
        }
    }

    if (PR_GetEnv("MOZ_WEBGL_DUMP_SHADERS")) {
        printf_stderr("////////////////////////////////////////\n");
        printf_stderr("// MOZ_WEBGL_DUMP_SHADERS:\n");

        // Wow - Roll Your Own Foreach-Lines because printf_stderr has a hard-coded
        // internal size, so long strings are truncated.

        int32_t start = 0;
        int32_t end = sourceCString.Find("\n", false, start, -1);
        while (end > -1) {
            const nsCString line(sourceCString.BeginReading() + start, end - start);
            printf_stderr("%s\n", line.BeginReading());
            start = end + 1;
            end = sourceCString.Find("\n", false, start, -1);
        }

        printf_stderr("////////////////////////////////////////\n");
    }

    mSource = source;
    mCleanSource = sourceCString;
}
Example #18
0
nsresult
ClientKeyFromCacheKey(const nsCString& key, nsACString &result)
{
    nsresult  rv = NS_OK;

    nsReadingIterator<char> start;
    key.BeginReading(start);
        
    nsReadingIterator<char> end;
    key.EndReading(end);
        
    if (FindCharInReadable(':', start, end)) {
        ++start;  // advance past clientID ':' delimiter
        result.Assign(Substring(start, end));
    } else {
        NS_ASSERTION(false, "FindCharInRead failed to find ':'");
        rv = NS_ERROR_UNEXPECTED;
        result.Truncate(0);
    }
    return rv;
}
Example #19
0
/* static */
void PrioEncoder::Encode(GlobalObject& aGlobal, const nsCString& aBatchID,
                         const PrioParams& aPrioParams,
                         RootedDictionary<PrioEncodedData>& aData,
                         ErrorResult& aRv) {
  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
  if (!global) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return;
  }

  SECStatus prio_rv = SECSuccess;

  if (!sSingleton) {
    nsresult rv;

    nsAutoCStringN<CURVE25519_KEY_LEN_HEX + 1> prioKeyA;
    rv = Preferences::GetCString("prio.publicKeyA", prioKeyA);
    if (NS_FAILED(rv)) {
      aRv.Throw(NS_ERROR_UNEXPECTED);
      return;
    }

    nsAutoCStringN<CURVE25519_KEY_LEN_HEX + 1> prioKeyB;
    rv = Preferences::GetCString("prio.publicKeyB", prioKeyB);
    if (NS_FAILED(rv)) {
      aRv.Throw(NS_ERROR_UNEXPECTED);
      return;
    }

    // Check that both public keys are of the right length
    // and contain only hex digits 0-9a-fA-f
    if (!PrioEncoder::IsValidHexPublicKey(prioKeyA) ||
        !PrioEncoder::IsValidHexPublicKey(prioKeyB)) {
      aRv.Throw(NS_ERROR_UNEXPECTED);
      return;
    }

    prio_rv = Prio_init();

    if (prio_rv != SECSuccess) {
      aRv.Throw(NS_ERROR_UNEXPECTED);
      return;
    }

    prio_rv = PublicKey_import_hex(
        &sPublicKeyA,
        reinterpret_cast<const unsigned char*>(prioKeyA.BeginReading()),
        CURVE25519_KEY_LEN_HEX);
    if (prio_rv != SECSuccess) {
      aRv.Throw(NS_ERROR_UNEXPECTED);
      return;
    }

    prio_rv = PublicKey_import_hex(
        &sPublicKeyB,
        reinterpret_cast<const unsigned char*>(prioKeyB.BeginReading()),
        CURVE25519_KEY_LEN_HEX);
    if (prio_rv != SECSuccess) {
      aRv.Throw(NS_ERROR_UNEXPECTED);
      return;
    }

    sSingleton = new PrioEncoder();
    ClearOnShutdown(&sSingleton);
  }

  nsTArray<bool> dataItems = aPrioParams.mBooleans;
  if (dataItems.Length() > gNumBooleans) {
    aRv.ThrowRangeError<MSG_VALUE_OUT_OF_RANGE>(
        NS_LITERAL_STRING("Maximum boolean value exceeded"));
    return;
  }

  PrioConfig prioConfig = PrioConfig_new(
      dataItems.Length(), sPublicKeyA, sPublicKeyB,
      reinterpret_cast<const unsigned char*>(aBatchID.BeginReading()),
      aBatchID.Length());

  if (!prioConfig) {
    aRv.Throw(NS_ERROR_FAILURE);
    return;
  }

  auto configGuard = MakeScopeExit([&] { PrioConfig_clear(prioConfig); });

  unsigned char* forServerA = nullptr;
  unsigned int lenA = 0;
  unsigned char* forServerB = nullptr;
  unsigned int lenB = 0;

  prio_rv = PrioClient_encode(prioConfig, dataItems.Elements(), &forServerA,
                              &lenA, &forServerB, &lenB);

  nsTArray<uint8_t> arrayForServerA;
  nsTArray<uint8_t> arrayForServerB;

  if (!arrayForServerA.AppendElements(reinterpret_cast<uint8_t*>(forServerA),
                                      lenA, fallible)) {
    aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    return;
  }

  free(forServerA);

  if (!arrayForServerB.AppendElements(reinterpret_cast<uint8_t*>(forServerB),
                                      lenB, fallible)) {
    aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    return;
  }

  free(forServerB);

  if (prio_rv != SECSuccess) {
    aRv.Throw(NS_ERROR_FAILURE);
    return;
  }

  JS::Rooted<JS::Value> valueA(aGlobal.Context());
  if (!ToJSValue(aGlobal.Context(),
                 TypedArrayCreator<Uint8Array>(arrayForServerA), &valueA)) {
    aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    return;
  }

  aData.mA.Construct().Init(&valueA.toObject());

  JS::Rooted<JS::Value> valueB(aGlobal.Context());
  if (!ToJSValue(aGlobal.Context(),
                 TypedArrayCreator<Uint8Array>(arrayForServerB), &valueB)) {
    aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    return;
  }

  aData.mB.Construct().Init(&valueB.toObject());
}
Example #20
0
nsresult
UDPSocketParent::BindInternal(const nsCString& aHost, const uint16_t& aPort,
                              const bool& aAddressReuse, const bool& aLoopback,
                              const uint32_t& recvBufferSize,
                              const uint32_t& sendBufferSize)
{
  nsresult rv;

  UDPSOCKET_LOG(("%s: [this=%p] %s:%u addressReuse: %d loopback: %d recvBufferSize: %lu, sendBufferSize: %lu",
                __FUNCTION__, this, nsCString(aHost).get(), aPort,
                aAddressReuse, aLoopback, recvBufferSize, sendBufferSize));

  nsCOMPtr<nsIUDPSocket> sock =
      do_CreateInstance("@mozilla.org/network/udp-socket;1", &rv);

  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  if (aHost.IsEmpty()) {
    rv = sock->Init(aPort, false, mPrincipal, aAddressReuse,
                    /* optional_argc = */ 1);
  } else {
    PRNetAddr prAddr;
    PR_InitializeNetAddr(PR_IpAddrAny, aPort, &prAddr);
    PRStatus status = PR_StringToNetAddr(aHost.BeginReading(), &prAddr);
    if (status != PR_SUCCESS) {
      return NS_ERROR_FAILURE;
    }

    mozilla::net::NetAddr addr;
    PRNetAddrToNetAddr(&prAddr, &addr);
    rv = sock->InitWithAddress(&addr, mPrincipal, aAddressReuse,
                               /* optional_argc = */ 1);
  }

  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  nsCOMPtr<nsINetAddr> laddr;
  rv = sock->GetLocalAddr(getter_AddRefs(laddr));
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }
  uint16_t family;
  rv = laddr->GetFamily(&family);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }
  if (family == nsINetAddr::FAMILY_INET) {
    rv = sock->SetMulticastLoopback(aLoopback);
    if (NS_WARN_IF(NS_FAILED(rv))) {
      return rv;
    }
  }
  // TODO: once bug 1252759 is fixed query buffer first and only increase
  if (recvBufferSize != 0) {
    rv = sock->SetRecvBufferSize(recvBufferSize);
    if (NS_WARN_IF(NS_FAILED(rv))) {
      UDPSOCKET_LOG(("%s: [this=%p] %s:%u failed to set recv buffer size to: %lu", __FUNCTION__, this, nsCString(aHost).get(), aPort, recvBufferSize));
    }
  }
  if (sendBufferSize != 0) {
    rv = sock->SetSendBufferSize(sendBufferSize);
    if (NS_WARN_IF(NS_FAILED(rv))) {
      UDPSOCKET_LOG(("%s: [this=%p] %s:%u failed to set send buffer size to: %lu", __FUNCTION__, this, nsCString(aHost).get(), aPort, sendBufferSize));
    }
  }

  // register listener
  rv = sock->AsyncListen(this);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  mSocket = sock;

  return NS_OK;
}
bool
HttpChannelParent::DoAsyncOpen(  const URIParams&           aURI,
                                 const OptionalURIParams&   aOriginalURI,
                                 const OptionalURIParams&   aDocURI,
                                 const OptionalURIParams&   aReferrerURI,
                                 const uint32_t&            aReferrerPolicy,
                                 const OptionalURIParams&   aAPIRedirectToURI,
                                 const OptionalURIParams&   aTopWindowURI,
                                 const uint32_t&            aLoadFlags,
                                 const RequestHeaderTuples& requestHeaders,
                                 const nsCString&           requestMethod,
                                 const OptionalInputStreamParams& uploadStream,
                                 const bool&                uploadStreamHasHeaders,
                                 const uint16_t&            priority,
                                 const uint32_t&            classOfService,
                                 const uint8_t&             redirectionLimit,
                                 const bool&                allowPipelining,
                                 const bool&                allowSTS,
                                 const uint32_t&            thirdPartyFlags,
                                 const bool&                doResumeAt,
                                 const uint64_t&            startPos,
                                 const nsCString&           entityID,
                                 const bool&                chooseApplicationCache,
                                 const nsCString&           appCacheClientID,
                                 const bool&                allowSpdy,
                                 const bool&                allowAltSvc,
                                 const OptionalFileDescriptorSet& aFds,
                                 const OptionalLoadInfoArgs& aLoadInfoArgs,
                                 const OptionalHttpResponseHead& aSynthesizedResponseHead,
                                 const nsCString&           aSecurityInfoSerialization,
                                 const uint32_t&            aCacheKey,
                                 const nsCString&           aSchedulingContextID)
{
  nsCOMPtr<nsIURI> uri = DeserializeURI(aURI);
  if (!uri) {
    // URIParams does MOZ_ASSERT if null, but we need to protect opt builds from
    // null deref here.
    return false;
  }
  nsCOMPtr<nsIURI> originalUri = DeserializeURI(aOriginalURI);
  nsCOMPtr<nsIURI> docUri = DeserializeURI(aDocURI);
  nsCOMPtr<nsIURI> referrerUri = DeserializeURI(aReferrerURI);
  nsCOMPtr<nsIURI> apiRedirectToUri = DeserializeURI(aAPIRedirectToURI);
  nsCOMPtr<nsIURI> topWindowUri = DeserializeURI(aTopWindowURI);

  nsCString uriSpec;
  uri->GetSpec(uriSpec);
  LOG(("HttpChannelParent RecvAsyncOpen [this=%p uri=%s]\n",
       this, uriSpec.get()));

  nsresult rv;

  nsCOMPtr<nsIIOService> ios(do_GetIOService(&rv));
  if (NS_FAILED(rv))
    return SendFailedAsyncOpen(rv);

  bool appOffline = false;
  uint32_t appId = GetAppId();
  if (appId != NECKO_UNKNOWN_APP_ID &&
      appId != NECKO_NO_APP_ID) {
    gIOService->IsAppOffline(appId, &appOffline);
  }

  uint32_t loadFlags = aLoadFlags;
  if (appOffline) {
    loadFlags |= nsICachingChannel::LOAD_ONLY_FROM_CACHE;
    loadFlags |= nsIRequest::LOAD_FROM_CACHE;
    loadFlags |= nsICachingChannel::LOAD_NO_NETWORK_IO;
  }

  nsCOMPtr<nsILoadInfo> loadInfo;
  rv = mozilla::ipc::LoadInfoArgsToLoadInfo(aLoadInfoArgs,
                                            getter_AddRefs(loadInfo));
  if (NS_FAILED(rv)) {
    return SendFailedAsyncOpen(rv);
  }

  nsCOMPtr<nsIChannel> channel;
  rv = NS_NewChannelInternal(getter_AddRefs(channel), uri, loadInfo,
                             nullptr, nullptr, loadFlags, ios);

  if (NS_FAILED(rv))
    return SendFailedAsyncOpen(rv);

  mChannel = static_cast<nsHttpChannel *>(channel.get());
  mChannel->SetWarningReporter(this);
  mChannel->SetTimingEnabled(true);
  if (mPBOverride != kPBOverride_Unset) {
    mChannel->SetPrivate(mPBOverride == kPBOverride_Private ? true : false);
  }

  if (doResumeAt)
    mChannel->ResumeAt(startPos, entityID);

  if (originalUri)
    mChannel->SetOriginalURI(originalUri);
  if (docUri)
    mChannel->SetDocumentURI(docUri);
  if (referrerUri)
    mChannel->SetReferrerWithPolicyInternal(referrerUri, aReferrerPolicy);
  if (apiRedirectToUri)
    mChannel->RedirectTo(apiRedirectToUri);
  if (topWindowUri)
    mChannel->SetTopWindowURI(topWindowUri);
  if (loadFlags != nsIRequest::LOAD_NORMAL)
    mChannel->SetLoadFlags(loadFlags);

  for (uint32_t i = 0; i < requestHeaders.Length(); i++) {
    mChannel->SetRequestHeader(requestHeaders[i].mHeader,
                               requestHeaders[i].mValue,
                               requestHeaders[i].mMerge);
  }

  mParentListener = new HttpChannelParentListener(this);

  mChannel->SetNotificationCallbacks(mParentListener);

  mChannel->SetRequestMethod(nsDependentCString(requestMethod.get()));

  nsTArray<mozilla::ipc::FileDescriptor> fds;
  if (aFds.type() == OptionalFileDescriptorSet::TPFileDescriptorSetParent) {
    FileDescriptorSetParent* fdSetActor =
      static_cast<FileDescriptorSetParent*>(aFds.get_PFileDescriptorSetParent());
    MOZ_ASSERT(fdSetActor);

    fdSetActor->ForgetFileDescriptors(fds);
    MOZ_ASSERT(!fds.IsEmpty());

    unused << fdSetActor->Send__delete__(fdSetActor);
  } else if (aFds.type() == OptionalFileDescriptorSet::TArrayOfFileDescriptor) {
    const_cast<OptionalFileDescriptorSet&>(aFds).
      get_ArrayOfFileDescriptor().SwapElements(fds);
  }

  nsCOMPtr<nsIInputStream> stream = DeserializeInputStream(uploadStream, fds);
  if (stream) {
    mChannel->InternalSetUploadStream(stream);
    mChannel->SetUploadStreamHasHeaders(uploadStreamHasHeaders);
  }

  if (aSynthesizedResponseHead.type() == OptionalHttpResponseHead::TnsHttpResponseHead) {
    mSynthesizedResponseHead = new nsHttpResponseHead(aSynthesizedResponseHead.get_nsHttpResponseHead());
    mShouldIntercept = true;

    if (!aSecurityInfoSerialization.IsEmpty()) {
      nsCOMPtr<nsISupports> secInfo;
      NS_DeserializeObject(aSecurityInfoSerialization, getter_AddRefs(secInfo));
      mChannel->OverrideSecurityInfo(secInfo);
    }

  } else {
    mChannel->ForceNoIntercept();
  }

  nsCOMPtr<nsISupportsPRUint32> cacheKey =
    do_CreateInstance(NS_SUPPORTS_PRUINT32_CONTRACTID, &rv);
  if (NS_FAILED(rv)) {
    return SendFailedAsyncOpen(rv);
  }

  rv = cacheKey->SetData(aCacheKey);
  if (NS_FAILED(rv)) {
    return SendFailedAsyncOpen(rv);
  }

  mChannel->SetCacheKey(cacheKey);

  if (priority != nsISupportsPriority::PRIORITY_NORMAL) {
    mChannel->SetPriority(priority);
  }
  if (classOfService) {
    mChannel->SetClassFlags(classOfService);
  }
  mChannel->SetRedirectionLimit(redirectionLimit);
  mChannel->SetAllowPipelining(allowPipelining);
  mChannel->SetAllowSTS(allowSTS);
  mChannel->SetThirdPartyFlags(thirdPartyFlags);
  mChannel->SetAllowSpdy(allowSpdy);
  mChannel->SetAllowAltSvc(allowAltSvc);

  nsCOMPtr<nsIApplicationCacheChannel> appCacheChan =
    do_QueryObject(mChannel);
  nsCOMPtr<nsIApplicationCacheService> appCacheService =
    do_GetService(NS_APPLICATIONCACHESERVICE_CONTRACTID);

  bool setChooseApplicationCache = chooseApplicationCache;
  if (appCacheChan && appCacheService) {
    // We might potentially want to drop this flag (that is TRUE by default)
    // after we successfully associate the channel with an application cache
    // reported by the channel child.  Dropping it here may be too early.
    appCacheChan->SetInheritApplicationCache(false);
    if (!appCacheClientID.IsEmpty()) {
      nsCOMPtr<nsIApplicationCache> appCache;
      rv = appCacheService->GetApplicationCache(appCacheClientID,
                                                getter_AddRefs(appCache));
      if (NS_SUCCEEDED(rv)) {
        appCacheChan->SetApplicationCache(appCache);
        setChooseApplicationCache = false;
      }
    }

    if (setChooseApplicationCache) {
      bool inBrowser = false;
      if (mLoadContext) {
        mLoadContext->GetIsInBrowserElement(&inBrowser);
      }

      bool chooseAppCache = false;
      nsCOMPtr<nsIScriptSecurityManager> secMan =
        do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID);
      if (secMan) {
        nsCOMPtr<nsIPrincipal> principal;
        secMan->GetAppCodebasePrincipal(uri, appId, inBrowser, getter_AddRefs(principal));

        // This works because we've already called SetNotificationCallbacks and
        // done mPBOverride logic by this point.
        chooseAppCache = NS_ShouldCheckAppCache(principal, NS_UsePrivateBrowsing(mChannel));
      }

      appCacheChan->SetChooseApplicationCache(chooseAppCache);
    }
  }

  nsID schedulingContextID;
  schedulingContextID.Parse(aSchedulingContextID.BeginReading());
  mChannel->SetSchedulingContextID(schedulingContextID);

  if (loadInfo && loadInfo->GetEnforceSecurity()) {
    rv = mChannel->AsyncOpen2(mParentListener);
  }
  else {
    rv = mChannel->AsyncOpen(mParentListener, nullptr);
  }
  if (NS_FAILED(rv))
    return SendFailedAsyncOpen(rv);

  return true;
}
Example #22
0
bool
TCPSocketParent::RecvOpenBind(const nsCString& aRemoteHost,
                              const uint16_t& aRemotePort,
                              const nsCString& aLocalAddr,
                              const uint16_t& aLocalPort,
                              const bool&     aUseSSL,
                              const bool&     aUseArrayBuffers,
                              const nsCString& aFilter)
{
  if (net::UsingNeckoIPCSecurity() &&
      !AssertAppProcessPermission(Manager()->Manager(), "tcp-socket")) {
    FireInteralError(this, __LINE__);
    return true;
  }

  nsresult rv;
  nsCOMPtr<nsISocketTransportService> sts =
    do_GetService("@mozilla.org/network/socket-transport-service;1", &rv);
  if (NS_FAILED(rv)) {
    FireInteralError(this, __LINE__);
    return true;
  }

  nsCOMPtr<nsISocketTransport> socketTransport;
  rv = sts->CreateTransport(nullptr, 0,
                            aRemoteHost, aRemotePort,
                            nullptr, getter_AddRefs(socketTransport));
  if (NS_FAILED(rv)) {
    FireInteralError(this, __LINE__);
    return true;
  }

  PRNetAddr prAddr;
  if (PR_SUCCESS != PR_InitializeNetAddr(PR_IpAddrAny, aLocalPort, &prAddr)) {
    FireInteralError(this, __LINE__);
    return true;
  }
  if (PR_SUCCESS != PR_StringToNetAddr(aLocalAddr.BeginReading(), &prAddr)) {
    FireInteralError(this, __LINE__);
    return true;
  }

  mozilla::net::NetAddr addr;
  PRNetAddrToNetAddr(&prAddr, &addr);
  rv = socketTransport->Bind(&addr);
  if (NS_FAILED(rv)) {
    FireInteralError(this, __LINE__);
    return true;
  }

  if (!aFilter.IsEmpty()) {
    nsAutoCString contractId(NS_NETWORK_TCP_SOCKET_FILTER_HANDLER_PREFIX);
    contractId.Append(aFilter);
    nsCOMPtr<nsISocketFilterHandler> filterHandler =
      do_GetService(contractId.get());
    if (!filterHandler) {
      NS_ERROR("Content doesn't have a valid filter");
      FireInteralError(this, __LINE__);
      return true;
    }
    rv = filterHandler->NewFilter(getter_AddRefs(mFilter));
    if (NS_FAILED(rv)) {
      NS_ERROR("Cannot create filter that content specified");
      FireInteralError(this, __LINE__);
      return true;
    }
  }

  // Obtain App ID
  uint32_t appId = nsIScriptSecurityManager::NO_APP_ID;
  bool     inIsolatedMozBrowser = false;
  const PContentParent *content = Manager()->Manager();
  if (PBrowserParent* browser = SingleManagedOrNull(content->ManagedPBrowserParent())) {
    // appId's are for B2G only currently, where managees.Count() == 1
    // This is not guaranteed currently in Desktop, so skip this there.
    TabParent *tab = TabParent::GetFrom(browser);
    appId = tab->OwnAppId();
    inIsolatedMozBrowser = tab->IsIsolatedMozBrowserElement();
  }

  mSocket = new TCPSocket(nullptr, NS_ConvertUTF8toUTF16(aRemoteHost), aRemotePort, aUseSSL, aUseArrayBuffers);
  mSocket->SetAppIdAndBrowser(appId, inIsolatedMozBrowser);
  mSocket->SetSocketBridgeParent(this);
  rv = mSocket->InitWithUnconnectedTransport(socketTransport);
  NS_ENSURE_SUCCESS(rv, true);
  return true;
}