static inline bool
IsEndOfHeaders(const nsCString &aLine)
{
  return aLine.IsEmpty();
}
Пример #2
0
// Finds the base domain for a host, with requested number of additional parts.
// This will fail, generating an error, if the host is an IPv4/IPv6 address,
// if more subdomain parts are requested than are available, or if the hostname
// includes characters that are not valid in a URL. Normalization is performed
// on the host string and the result will be in UTF8.
nsresult
nsEffectiveTLDService::GetBaseDomainInternal(nsCString  &aHostname,
                                             int32_t    aAdditionalParts,
                                             nsACString &aBaseDomain)
{
  if (aHostname.IsEmpty())
    return NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS;

  // chomp any trailing dot, and keep track of it for later
  bool trailingDot = aHostname.Last() == '.';
  if (trailingDot)
    aHostname.Truncate(aHostname.Length() - 1);

  // check the edge cases of the host being '.' or having a second trailing '.',
  // since subsequent checks won't catch it.
  if (aHostname.IsEmpty() || aHostname.Last() == '.')
    return NS_ERROR_INVALID_ARG;

  // Check if we're dealing with an IPv4/IPv6 hostname, and return
  PRNetAddr addr;
  PRStatus result = PR_StringToNetAddr(aHostname.get(), &addr);
  if (result == PR_SUCCESS)
    return NS_ERROR_HOST_IS_IP_ADDRESS;

  // Walk up the domain tree, most specific to least specific,
  // looking for matches at each level.  Note that a given level may
  // have multiple attributes (e.g. IsWild() and IsNormal()).
  const char *prevDomain = nullptr;
  const char *currDomain = aHostname.get();
  const char *nextDot = strchr(currDomain, '.');
  const char *end = currDomain + aHostname.Length();
  const char *eTLD = currDomain;
  while (1) {
    // sanity check the string we're about to look up: it should not begin with
    // a '.'; this would mean the hostname began with a '.' or had an
    // embedded '..' sequence.
    if (*currDomain == '.')
      return NS_ERROR_INVALID_ARG;

    // perform the hash lookup.
    nsDomainEntry *entry = mHash.GetEntry(currDomain);
    if (entry) {
      if (entry->IsWild() && prevDomain) {
        // wildcard rules imply an eTLD one level inferior to the match.
        eTLD = prevDomain;
        break;

      } else if (entry->IsNormal() || !nextDot) {
        // specific match, or we've hit the top domain level
        eTLD = currDomain;
        break;

      } else if (entry->IsException()) {
        // exception rules imply an eTLD one level superior to the match.
        eTLD = nextDot + 1;
        break;
      }
    }

    if (!nextDot) {
      // we've hit the top domain level; use it by default.
      eTLD = currDomain;
      break;
    }

    prevDomain = currDomain;
    currDomain = nextDot + 1;
    nextDot = strchr(currDomain, '.');
  }

  const char *begin, *iter;
  if (aAdditionalParts < 0) {
    NS_ASSERTION(aAdditionalParts == -1,
                 "aAdditionalParts can't be negative and different from -1");

    for (iter = aHostname.get(); iter != eTLD && *iter != '.'; iter++);

    if (iter != eTLD) {
      iter++;
    }
    if (iter != eTLD) {
      aAdditionalParts = 0;
    }
  } else {
    // count off the number of requested domains.
    begin = aHostname.get();
    iter = eTLD;

    while (1) {
      if (iter == begin)
        break;

      if (*(--iter) == '.' && aAdditionalParts-- == 0) {
        ++iter;
        ++aAdditionalParts;
        break;
      }
    }
  }

  if (aAdditionalParts != 0)
    return NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS;

  aBaseDomain = Substring(iter, end);
  // add on the trailing dot, if applicable
  if (trailingDot)
    aBaseDomain.Append('.');

  return NS_OK;
}
Пример #3
0
bool CAliasData::Process(const char *pLine, PRInt32 len)
{
  // Extract any comments first!
  nsCString  str;

  const char *pStart = pLine;
  PRInt32    tCnt = 0;
  PRInt32    cnt = 0;
  PRInt32    max = len;
  bool      endCollect = false;

    // Keep track of the full entry without any processing for potential alias
    // nickname resolution. Previously alias resolution was done with m_email,
    // but unfortunately that doesn't work for nicknames with spaces.
    // For example for the nickname "Joe Smith", "Smith" was being interpreted
    // as the potential email address and placed in m_email, but routines like
    // ResolveAlias were failing because "Smith" is not the full nickname.
    // Now we just stash the full entry for nickname resolution before processing
    // the line as a potential entry in its own right.
    m_fullEntry.Append(pLine, len);

  while (max) {
    if (*pLine == '"') {
      if (tCnt && !endCollect) {
        str.Trim(kWhitespace);
        if (!str.IsEmpty())
          str.Append(" ", 1);
        str.Append(pStart, tCnt);
      }
      cnt = nsEudoraAddress::CountQuote(pLine, max);
      if ((cnt > 2) && m_realName.IsEmpty()) {
        m_realName.Append(pLine + 1, cnt - 2);
      }
      pLine += cnt;
      max -= cnt;
      pStart = pLine;
      tCnt = 0;
    }
    else if (*pLine == '<') {
      if (tCnt && !endCollect) {
        str.Trim(kWhitespace);
        if (!str.IsEmpty())
          str.Append(" ", 1);
        str.Append(pStart, tCnt);
      }
      cnt = nsEudoraAddress::CountAngle(pLine, max);
      if ((cnt > 2) && m_email.IsEmpty()) {
        m_email.Append(pLine + 1, cnt - 2);
      }
      pLine += cnt;
      max -= cnt;
      pStart = pLine;
      tCnt = 0;
      endCollect = true;
    }
    else if (*pLine == '(') {
      if (tCnt && !endCollect) {
        str.Trim(kWhitespace);
        if (!str.IsEmpty())
          str.Append(" ", 1);
        str.Append(pStart, tCnt);
      }
      cnt = nsEudoraAddress::CountComment(pLine, max);
      if (cnt > 2) {
        if (!m_realName.IsEmpty() && m_nickName.IsEmpty())
          m_nickName = m_realName;
        m_realName.Truncate();
        m_realName.Append(pLine + 1, cnt - 2);
      }
      pLine += cnt;
      max -= cnt;
      pStart = pLine;
      tCnt = 0;
    }
    else {
      tCnt++;
      pLine++;
      max--;
    }
  }

  if (tCnt) {
    str.Trim(kWhitespace);
    if (!str.IsEmpty())
      str.Append(" ", 1);
    str.Append(pStart, tCnt);
  }

  str.Trim(kWhitespace);

  if (!m_realName.IsEmpty() && !m_email.IsEmpty())
    return true;

  // now we should have a string with any remaining non-delimitted text
  // we assume that the last token is the email
  // anything before that is realName
  if (!m_email.IsEmpty()) {
    m_realName = str;
    return true;
  }

  tCnt = str.RFindChar(' ');
  if (tCnt == -1) {
    if (!str.IsEmpty()) {
      m_email = str;
      return true;
    }
    return false;
  }

  m_email = Substring(str, tCnt + 1);
  m_realName = StringHead(str, tCnt);
  m_realName.Trim(kWhitespace);
  m_email.Trim(kWhitespace);

  return !m_email.IsEmpty();
}
Пример #4
0
bool ImportTranslate::ConvertString( const nsCString& inStr, nsCString& outStr, bool mimeHeader)
{
  if (inStr.IsEmpty()) {
    outStr = inStr;
    return( PR_TRUE);
  }

  nsImportTranslator *pTrans = GetTranslator();
  // int      maxLen = (int) pTrans->GetMaxBufferSize( inStr.Length());
  // int      hLen = 0;
  nsCString  set;
  nsCString  lang;

  if (mimeHeader) {
    // add the charset and language
    pTrans->GetCharset( set);
    pTrans->GetLanguage( lang);
  }

  // Unfortunatly, we didn't implement ConvertBuffer for all translators,
  // just ConvertToFile.  This means that this data will not always
  // be converted to the charset of pTrans.  In that case...
  // We don't always have the data in the same charset as the current
  // translator...
  // It is safer to leave the charset and language field blank
  set.Truncate();
  lang.Truncate();

  PRUint8 *  pBuf;
  /*
  pBuf = (P_U8) outStr.GetBuffer( maxLen);
  if (!pBuf) {
    delete pTrans;
    return( FALSE);
  }
  pTrans->ConvertBuffer( (PC_U8)(PC_S8)inStr, inStr.GetLength(), pBuf);
  outStr.ReleaseBuffer();
  */
  outStr = inStr;
  delete pTrans;


  // Now I need to run the string through the mime-header special char
  // encoder.

  pTrans = new CMHTranslator;
  pBuf = new PRUint8[pTrans->GetMaxBufferSize( outStr.Length())];
  pTrans->ConvertBuffer( (const PRUint8 *)(outStr.get()), outStr.Length(), pBuf);
  delete pTrans;
  outStr.Truncate();
  if (mimeHeader) {
    outStr = set;
    outStr += "'";
    outStr += lang;
    outStr += "'";
  }
  outStr += (const char *)pBuf;
  delete [] pBuf;

  return( PR_TRUE);
}
Пример #5
0
void
HttpChannelChild::OnStartRequest(const nsHttpResponseHead& responseHead,
                                 const bool& useResponseHead,
                                 const nsHttpHeaderArray& requestHeaders,
                                 const bool& isFromCache,
                                 const bool& cacheEntryAvailable,
                                 const uint32_t& cacheExpirationTime,
                                 const nsCString& cachedCharset,
                                 const nsCString& securityInfoSerialization,
                                 const NetAddr& selfAddr,
                                 const NetAddr& peerAddr)
{
  LOG(("HttpChannelChild::RecvOnStartRequest [this=%p]\n", this));

  // mFlushedForDiversion and mDivertingToParent should NEVER be set at this
  // stage, as they are set in the listener's OnStartRequest.
  MOZ_RELEASE_ASSERT(!mFlushedForDiversion,
    "mFlushedForDiversion should be unset before OnStartRequest!");
  MOZ_RELEASE_ASSERT(!mDivertingToParent,
    "mDivertingToParent should be unset before OnStartRequest!");

  if (useResponseHead && !mCanceled)
    mResponseHead = new nsHttpResponseHead(responseHead);

  if (!securityInfoSerialization.IsEmpty()) {
    NS_DeserializeObject(securityInfoSerialization,
                         getter_AddRefs(mSecurityInfo));
  }

  mIsFromCache = isFromCache;
  mCacheEntryAvailable = cacheEntryAvailable;
  mCacheExpirationTime = cacheExpirationTime;
  mCachedCharset = cachedCharset;

  AutoEventEnqueuer ensureSerialDispatch(mEventQ);

  // replace our request headers with what actually got sent in the parent
  mRequestHead.Headers() = requestHeaders;

  // Note: this is where we would notify "http-on-examine-response" observers.
  // We have deliberately disabled this for child processes (see bug 806753)
  //
  // gHttpHandler->OnExamineResponse(this);

  mTracingEnabled = false;

  nsresult rv = mListener->OnStartRequest(this, mListenerContext);
  if (NS_FAILED(rv)) {
    Cancel(rv);
    return;
  }

  if (mDivertingToParent) {
    mListener = nullptr;
    mListenerContext = nullptr;
    if (mLoadGroup) {
      mLoadGroup->RemoveRequest(this, nullptr, mStatus);
    }
  }

  if (mResponseHead)
    SetCookie(mResponseHead->PeekHeader(nsHttp::Set_Cookie));

  rv = ApplyContentConversions();
  if (NS_FAILED(rv))
    Cancel(rv);

  mSelfAddr = selfAddr;
  mPeerAddr = peerAddr;
}
Пример #6
0
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 uint32_t&            aCacheKey)
{
  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;
  } 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);
    }
  }

  rv = mChannel->AsyncOpen(mParentListener, nullptr);
  if (NS_FAILED(rv))
    return SendFailedAsyncOpen(rv);

  return true;
}
NS_IMETHODIMP
nsIncrementalDownload::OnStartRequest(nsIRequest *request,
                                      nsISupports *context)
{
  nsresult rv;

  nsCOMPtr<nsIHttpChannel> http = do_QueryInterface(request, &rv);
  if (NS_FAILED(rv))
    return rv;

  // Ensure that we are receiving a 206 response.
  uint32_t code;
  rv = http->GetResponseStatus(&code);
  if (NS_FAILED(rv))
    return rv;
  if (code != 206) {
    // We may already have the entire file downloaded, in which case
    // our request for a range beyond the end of the file would have
    // been met with an error response code.
    if (code == 416 && mTotalSize == int64_t(-1)) {
      mTotalSize = mCurrentSize;
      // Return an error code here to suppress OnDataAvailable.
      return NS_ERROR_DOWNLOAD_COMPLETE;
    }
    // The server may have decided to give us all of the data in one chunk.  If
    // we requested a partial range, then we don't want to download all of the
    // data at once.  So, we'll just try again, but if this keeps happening then
    // we'll eventually give up.
    if (code == 200) {
      if (mInterval) {
        mChannel = nullptr;
        if (++mNonPartialCount > MAX_RETRY_COUNT) {
          NS_WARNING("unable to fetch a byte range; giving up");
          return NS_ERROR_FAILURE;
        }
        // Increase delay with each failure.
        StartTimer(mInterval * mNonPartialCount);
        return NS_ERROR_DOWNLOAD_NOT_PARTIAL;
      }
      // Since we have been asked to download the rest of the file, we can deal
      // with a 200 response.  This may result in downloading the beginning of
      // the file again, but that can't really be helped.
    } else {
      NS_WARNING("server response was unexpected");
      return NS_ERROR_UNEXPECTED;
    }
  } else {
    // We got a partial response, so clear this counter in case the next chunk
    // results in a 200 response.
    mNonPartialCount = 0;

    // confirm that the content-range response header is consistent with
    // expectations on each 206. If it is not then drop this response and
    // retry with no-cache set.
    if (!mCacheBust) {
      nsAutoCString buf;
      int64_t startByte = 0;
      bool confirmedOK = false;

      rv = http->GetResponseHeader(NS_LITERAL_CSTRING("Content-Range"), buf);
      if (NS_FAILED(rv))
        return rv; // it isn't a useful 206 without a CONTENT-RANGE of some sort

      // Content-Range: bytes 0-299999/25604694
      int32_t p = buf.Find("bytes ");

      // first look for the starting point of the content-range
      // to make sure it is what we expect
      if (p != -1) {
        char *endptr = nullptr;
        const char *s = buf.get() + p + 6;
        while (*s && *s == ' ')
          s++;
        startByte = strtol(s, &endptr, 10);

        if (*s && endptr && (endptr != s) &&
            (mCurrentSize == startByte)) {

          // ok the starting point is confirmed. We still need to check the
          // total size of the range for consistency if this isn't
          // the first chunk
          if (mTotalSize == int64_t(-1)) {
            // first chunk
            confirmedOK = true;
          } else {
            int32_t slash = buf.FindChar('/');
            int64_t rangeSize = 0;
            if (slash != kNotFound &&
                (PR_sscanf(buf.get() + slash + 1, "%lld", (int64_t *) &rangeSize) == 1) &&
                rangeSize == mTotalSize) {
              confirmedOK = true;
            }
          }
        }
      }

      if (!confirmedOK) {
        NS_WARNING("unexpected content-range");
        mCacheBust = true;
        mChannel = nullptr;
        if (++mNonPartialCount > MAX_RETRY_COUNT) {
          NS_WARNING("unable to fetch a byte range; giving up");
          return NS_ERROR_FAILURE;
        }
        // Increase delay with each failure.
        StartTimer(mInterval * mNonPartialCount);
        return NS_ERROR_DOWNLOAD_NOT_PARTIAL;
      }
    }
  }

  // Do special processing after the first response.
  if (mTotalSize == int64_t(-1)) {
    // Update knowledge of mFinalURI
    rv = http->GetURI(getter_AddRefs(mFinalURI));
    if (NS_FAILED(rv))
      return rv;
    http->GetResponseHeader(NS_LITERAL_CSTRING("Etag"), mPartialValidator);
    if (StringBeginsWith(mPartialValidator, NS_LITERAL_CSTRING("W/")))
      mPartialValidator.Truncate(); // don't use weak validators
    if (mPartialValidator.IsEmpty())
      http->GetResponseHeader(NS_LITERAL_CSTRING("Last-Modified"), mPartialValidator);

    if (code == 206) {
      // OK, read the Content-Range header to determine the total size of this
      // download file.
      nsAutoCString buf;
      rv = http->GetResponseHeader(NS_LITERAL_CSTRING("Content-Range"), buf);
      if (NS_FAILED(rv))
        return rv;
      int32_t slash = buf.FindChar('/');
      if (slash == kNotFound) {
        NS_WARNING("server returned invalid Content-Range header!");
        return NS_ERROR_UNEXPECTED;
      }
      if (PR_sscanf(buf.get() + slash + 1, "%lld", (int64_t *) &mTotalSize) != 1)
        return NS_ERROR_UNEXPECTED;
    } else {
      rv = http->GetContentLength(&mTotalSize);
      if (NS_FAILED(rv))
        return rv;
      // We need to know the total size of the thing we're trying to download.
      if (mTotalSize == int64_t(-1)) {
        NS_WARNING("server returned no content-length header!");
        return NS_ERROR_UNEXPECTED;
      }
      // Need to truncate (or create, if it doesn't exist) the file since we
      // are downloading the whole thing.
      WriteToFile(mDest, nullptr, 0, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE);
      mCurrentSize = 0;
    }

    // Notify observer that we are starting...
    rv = CallOnStartRequest();
    if (NS_FAILED(rv))
      return rv;
  }

  // Adjust mChunkSize accordingly if mCurrentSize is close to mTotalSize.
  int64_t diff = mTotalSize - mCurrentSize;
  if (diff <= int64_t(0)) {
    NS_WARNING("about to set a bogus chunk size; giving up");
    return NS_ERROR_UNEXPECTED;
  }

  if (diff < int64_t(mChunkSize))
    mChunkSize = uint32_t(diff);

  mChunk = new char[mChunkSize];
  if (!mChunk)
    rv = NS_ERROR_OUT_OF_MEMORY;

  return rv;
}
Пример #8
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;
}
nsresult
nsIncrementalDownload::ProcessTimeout()
{
  NS_ASSERTION(!mChannel, "how can we have a channel?");

  // Handle existing error conditions
  if (NS_FAILED(mStatus)) {
    CallOnStopRequest();
    return NS_OK;
  }

  // Fetch next chunk
  
  nsCOMPtr<nsIChannel> channel;
  nsresult rv = NS_NewChannel(getter_AddRefs(channel),
                              mFinalURI,
                              nsContentUtils::GetSystemPrincipal(),
                              nsILoadInfo::SEC_NORMAL,
                              nsIContentPolicy::TYPE_OTHER,
                              nullptr,   // loadGroup
                              this,      // aCallbacks
                              mLoadFlags);

  if (NS_FAILED(rv))
    return rv;

  nsCOMPtr<nsIHttpChannel> http = do_QueryInterface(channel, &rv);
  if (NS_FAILED(rv))
    return rv;

  NS_ASSERTION(mCurrentSize != int64_t(-1),
      "we should know the current file size by now");

  rv = ClearRequestHeader(http);
  if (NS_FAILED(rv))
    return rv;

  // Don't bother making a range request if we are just going to fetch the
  // entire document.
  if (mInterval || mCurrentSize != int64_t(0)) {
    nsAutoCString range;
    MakeRangeSpec(mCurrentSize, mTotalSize, mChunkSize, mInterval == 0, range);

    rv = http->SetRequestHeader(NS_LITERAL_CSTRING("Range"), range, false);
    if (NS_FAILED(rv))
      return rv;

    if (!mPartialValidator.IsEmpty())
      http->SetRequestHeader(NS_LITERAL_CSTRING("If-Range"),
                             mPartialValidator, false);

    if (mCacheBust) {
      http->SetRequestHeader(NS_LITERAL_CSTRING("Cache-Control"),
                             NS_LITERAL_CSTRING("no-cache"), false);
      http->SetRequestHeader(NS_LITERAL_CSTRING("Pragma"),
                             NS_LITERAL_CSTRING("no-cache"), false);
    }
  }

  rv = channel->AsyncOpen(this, nullptr);
  if (NS_FAILED(rv))
    return rv;

  // Wait to assign mChannel when we know we are going to succeed.  This is
  // important because we don't want to introduce a reference cycle between
  // mChannel and this until we know for a fact that AsyncOpen has succeeded,
  // thus ensuring that our stream listener methods will be invoked.
  mChannel = channel;
  return NS_OK;
}
Пример #10
0
nsresult nsMsgI18NConvertToUnicode(const char* aCharset,
                                   const nsCString& inString, 
                                   nsAString& outString,
                                   bool aIsCharsetCanonical)
{
  if (inString.IsEmpty()) {
    outString.Truncate();
    return NS_OK;
  }
  else if (!*aCharset || !PL_strcasecmp(aCharset, "us-ascii") ||
           !PL_strcasecmp(aCharset, "ISO-8859-1")) {
    // Despite its name, it also works for Latin-1.
    CopyASCIItoUTF16(inString, outString);
    return NS_OK;
  }
  else if (!PL_strcasecmp(aCharset, "UTF-8")) {
    if (MsgIsUTF8(inString)) {
      nsAutoString tmp;
      CopyUTF8toUTF16(inString, tmp);
      if (!tmp.IsEmpty() && tmp.get()[0] == char16_t(0xFEFF))
        tmp.Cut(0, 1);
      outString.Assign(tmp);
      return NS_OK;
    }
    NS_WARNING("Invalid UTF-8 string");
    return NS_ERROR_UNEXPECTED;
  }

  nsresult rv;
  nsCOMPtr <nsICharsetConverterManager> ccm = do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr <nsIUnicodeDecoder> decoder;

  // get an unicode converter
  if (aIsCharsetCanonical)  // optimize for modified UTF-7 used by IMAP
    rv = ccm->GetUnicodeDecoderRaw(aCharset, getter_AddRefs(decoder));
  else
    rv = ccm->GetUnicodeDecoderInternal(aCharset, getter_AddRefs(decoder));
  NS_ENSURE_SUCCESS(rv, rv);

  const char *originalSrcPtr = inString.get();
  const char *currentSrcPtr = originalSrcPtr;
  int32_t originalLength = inString.Length();
  int32_t srcLength;
  int32_t dstLength;
  char16_t localbuf[512];
  int32_t consumedLen = 0;

  outString.Truncate();

  // convert
  while (consumedLen < originalLength) {
    srcLength = originalLength - consumedLen;  
    dstLength = 512;
    rv = decoder->Convert(currentSrcPtr, &srcLength, localbuf, &dstLength);
    if (NS_FAILED(rv) || dstLength == 0)
      break;
    outString.Append(localbuf, dstLength);

    currentSrcPtr += srcLength;
    consumedLen = currentSrcPtr - originalSrcPtr; // src length used so far
  }
  return rv;
}
Пример #11
0
/**
 * This method applies a sequence of transformations to the line.
 * 
 * It applies the following sequences in order
 * * Removes headers if the searcher doesn't want them
 *   (sets m_pastHeaders)
 * * Determines the current MIME type.
 *   (via SniffPossibleMIMEHeader)
 * * Strips any HTML if the searcher doesn't want it
 * * Strips non-text parts
 * * Decodes any base64 part
 *   (resetting part variables: m_base64part, m_pastHeaders, m_partIsHtml,
 *    m_partIsText)
 *
 * @param line        (in)    the current line
 * @param length      (in)    the length of said line
 * @param eatThisLine (out)   whether or not to ignore this line
 * @param buf         (inout) if m_base64part, the current part as needed for
 *                            decoding; else, it is treated as an out param (a
 *                            redundant version of line).
 * @return            the length of the line after applying transformations
 */
PRInt32 nsMsgBodyHandler::ApplyTransformations (const nsCString &line, PRInt32 length,
                                                bool &eatThisLine, nsCString &buf)
{
  PRInt32 newLength = length;
  eatThisLine = PR_FALSE;
  
  if (!m_pastHeaders)  // line is a line from the message headers
  {
    if (m_stripHeaders)
      eatThisLine = PR_TRUE;

    // We have already grabbed all worthwhile information from the headers,
    // so there is no need to keep track of the current lines
    buf.Assign(line);
   
    SniffPossibleMIMEHeader(buf);
    
    m_pastHeaders = buf.IsEmpty() || buf.First() == '\r' ||
      buf.First() == '\n';

    return length;
  }

  // Check to see if this is the boundary string
  if (m_isMultipart && StringBeginsWith(line, boundary))
  {
    if (m_base64part && m_partIsText) 
    {
      Base64Decode(buf);
      // Work on the parsed string
      if (!buf.Length())
      {
        NS_WARNING("Trying to transform an empty buffer");
        eatThisLine = PR_TRUE;
      }
      else
      {
        ApplyTransformations(buf, buf.Length(), eatThisLine, buf);
        // Avoid spurious failures
        eatThisLine = PR_FALSE;
      }
    }
    else
    {
      buf.Truncate();
      eatThisLine = PR_TRUE; // We have no content...
    }

    // Reset all assumed headers
    m_base64part = PR_FALSE;
    m_pastHeaders = PR_FALSE;
    m_partIsHtml = PR_FALSE;
    m_partIsText = PR_TRUE;

    return buf.Length();
  }
 
  if (!m_partIsText)
  {
    // Ignore non-text parts
    buf.Truncate();
    eatThisLine = PR_TRUE;
    return 0;
  }

  if (m_base64part)
  {
    // We need to keep track of all lines to parse base64encoded...
    buf.Append(line.get());
    eatThisLine = PR_TRUE;
    return buf.Length();
  }
    
  // ... but there's no point if we're not parsing base64.
  buf.Assign(line);
  if (m_stripHtml && m_partIsHtml)
  {
    StripHtml (buf);
    newLength = buf.Length();
  }
  
  return newLength;
}
Пример #12
0
void ConfigWebRtcLog(mozilla::LogLevel level, uint32_t trace_mask,
                     nsCString &aLogFile, bool multi_log)
{
  if (gWebRtcTraceLoggingOn) {
    return;
  }

#if defined(ANDROID)
  // Special case: use callback to pipe to NSPR logging.
  aLogFile.Assign(default_log_name);
#else

  rtc::LoggingSeverity log_level;
  switch (level) {
    case mozilla::LogLevel::Verbose:
      log_level = rtc::LoggingSeverity::LS_VERBOSE;
      break;
    case mozilla::LogLevel::Debug:
    case mozilla::LogLevel::Info:
      log_level = rtc::LoggingSeverity::LS_INFO;
      break;
    case mozilla::LogLevel::Warning:
      log_level = rtc::LoggingSeverity::LS_WARNING;
      break;
    case mozilla::LogLevel::Error:
      log_level = rtc::LoggingSeverity::LS_ERROR;
      break;
    case mozilla::LogLevel::Disabled:
      log_level = rtc::LoggingSeverity::LS_NONE;
      break;
    default:
      MOZ_ASSERT(false);
      break;
  }
  rtc::LogMessage::LogToDebug(log_level);
  if (level != mozilla::LogLevel::Disabled) {
    // always capture LOG(...) << ... logging in webrtc.org code to nspr logs
    if (!sSink) {
      sSink = new LogSinkImpl();
      rtc::LogMessage::AddLogToStream(sSink, log_level);
      // it's ok if this leaks to program end
    }
  } else if (sSink) {
    rtc::LogMessage::RemoveLogToStream(sSink);
    sSink = nullptr;
  }

  webrtc::Trace::set_level_filter(trace_mask);
  if (trace_mask != 0) {
    // default WEBRTC_TRACE logs to a rotating file, but allow redirecting to nspr
    // XXX always redirect in e10s if the sandbox blocks file access, or somehow proxy
    if (aLogFile.EqualsLiteral("nspr") || aLogFile.EqualsLiteral("moz_log")) {
      rtc::LogMessage::SetLogToStderr(false);
      webrtc::Trace::SetTraceCallback(&gWebRtcCallback);
    } else {
      rtc::LogMessage::SetLogToStderr(true);
      webrtc::Trace::SetTraceFile(aLogFile.get(), multi_log);
    }
  } else {
    rtc::LogMessage::SetLogToStderr(false);
  }

  if (aLogFile.IsEmpty()) {
    nsCOMPtr<nsIFile> tempDir;
    nsresult rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(tempDir));
    if (NS_SUCCEEDED(rv)) {
      tempDir->AppendNative(default_log_name);
#ifdef XP_WIN
      // WebRTC wants a path encoded in the native charset, not UTF-8.
      nsAutoString logFile;
      tempDir->GetPath(logFile);
      NS_CopyUnicodeToNative(logFile, aLogFile);
#else
      tempDir->GetNativePath(aLogFile);
#endif
    }
  }
#endif

  if (XRE_IsParentProcess()) {
    // Capture the final choice for the trace setting.
    mozilla::Preferences::SetCString("media.webrtc.debug.log_file", aLogFile);
  }
}
static
void UpdateMimeContentToEwsFormat(nsCString & mimeContent,
                                  bool & has_uid,
                                  nsCString & uid) {
	nsresult rv = NS_OK;
    
	nsCOMPtr<calIICSService> icsService =
			do_GetService(CAL_ICSSERVICE_CONTRACTID, &rv);
	NS_FAILED_WARN(rv);

	if (!icsService)
		return;

	nsCOMPtr<calIIcalComponent> component;
    
	rv = icsService->ParseICS(mimeContent,
	                          nullptr,
	                          getter_AddRefs(component));
	NS_FAILED_WARN(rv);

	if (!component)
		return;

	//check METHOD
	nsCString method;
	rv = component->GetMethod(method);
	NS_FAILED_WARN(rv);

	if (NS_FAILED(rv) || method.IsEmpty()) {
		component->SetMethod(NS_LITERAL_CSTRING("PUBLISH"));
	}

	//Check UID
	nsCOMPtr<calIIcalComponent> todo;
	rv = component->GetFirstSubcomponent(NS_LITERAL_CSTRING("VTODO"),
	                                     getter_AddRefs(todo));
	NS_FAILED_WARN(rv);

	if (todo) {
		rv = todo->GetUid(uid);
		NS_FAILED_WARN(rv);

		if (NS_FAILED(rv) || uid.IsEmpty()) {
			has_uid = false;
			rv = GenerateUid(uid);
			NS_FAILED_WARN(rv);

			if (NS_SUCCEEDED(rv) && !uid.IsEmpty()) {
				todo->SetUid(uid);
			}
		} else {
			has_uid = true;
		}
	} else {
		has_uid = false;
		uid.AssignLiteral("");
	}

	mailews_logger << "origianl ics:"
	               << mimeContent.get()
	               << std::endl;
    
	component->SerializeToICS(mimeContent);
    
	mailews_logger << "updated ics:"
	               << mimeContent.get()
	               << std::endl;
}