nsresult nsMimeHtmlDisplayEmitter::BroadcastHeaders()

in mailnews/mime/emitters/nsMimeHtmlEmitter.cpp [70:208]


nsresult nsMimeHtmlDisplayEmitter::BroadcastHeaders(int32_t aHeaderMode) {
  nsresult rv;
  nsCOMPtr<nsIMailChannel> mailChannel = do_QueryInterface(mChannel, &rv);
  NS_ENSURE_SUCCESS(rv, rv);

  nsCString extraExpandedHeaders;
  nsTArray<nsCString> extraExpandedHeadersArray;
  nsCString extraAddonHeaders;
  nsTArray<nsCString> extraAddonHeadersArray;
  nsAutoCString convertedDateString;
  bool pushAllHeaders = false;
  bool checkExtraHeaders = false;
  bool checkAddonHeaders = false;
  nsCString otherHeaders;
  nsTArray<nsCString> otherHeadersArray;
  bool checkOtherHeaders = false;

  nsCOMPtr<nsIPrefBranch> pPrefBranch(
      do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
  if (pPrefBranch) {
    pPrefBranch->GetCharPref("mailnews.headers.extraExpandedHeaders",
                             extraExpandedHeaders);
    if (!extraExpandedHeaders.IsEmpty()) {
      ToLowerCase(extraExpandedHeaders);
      ParseString(extraExpandedHeaders, ' ', extraExpandedHeadersArray);
      checkExtraHeaders = true;
    }

    pPrefBranch->GetCharPref("mailnews.headers.extraAddonHeaders",
                             extraAddonHeaders);
    if (!extraAddonHeaders.IsEmpty()) {
      // Push all headers if extraAddonHeaders is "*".
      if (extraAddonHeaders.EqualsLiteral("*")) {
        pushAllHeaders = true;
      } else {
        ToLowerCase(extraAddonHeaders);
        ParseString(extraAddonHeaders, ' ', extraAddonHeadersArray);
        checkAddonHeaders = true;
      }
    }

    pPrefBranch->GetCharPref("mail.compose.other.header", otherHeaders);
    if (!otherHeaders.IsEmpty()) {
      ToLowerCase(otherHeaders);
      ParseString(otherHeaders, ',', otherHeadersArray);
      for (uint32_t i = 0; i < otherHeadersArray.Length(); i++) {
        otherHeadersArray[i].Trim(" ");
      }

      checkOtherHeaders = true;
    }
  }

  for (size_t i = 0; i < mHeaderArray->Length(); i++) {
    headerInfoType* headerInfo = mHeaderArray->ElementAt(i);
    if ((!headerInfo) || (!headerInfo->name) || (!(*headerInfo->name)) ||
        (!headerInfo->value) || (!(*headerInfo->value)))
      continue;

    // optimization: if we aren't in view all header view mode, we only show a
    // small set of the total # of headers. don't waste time sending those out
    // to the UI since the UI is going to ignore them anyway.
    if (aHeaderMode != VIEW_ALL_HEADERS &&
        (mFormat != nsMimeOutput::nsMimeMessageFilterSniffer)) {
      bool skip = true;
      const char* headerName = headerInfo->name;
      if (pushAllHeaders) {
        skip = false;

        // Accept the following:
      } else if (!PL_strcasecmp("to", headerName) ||
                 !PL_strcasecmp("from", headerName) ||
                 !PL_strcasecmp("cc", headerName) ||
                 !PL_strcasecmp("newsgroups", headerName) ||
                 !PL_strcasecmp("bcc", headerName) ||
                 !PL_strcasecmp("followup-to", headerName) ||
                 !PL_strcasecmp("reply-to", headerName) ||
                 !PL_strcasecmp("subject", headerName) ||
                 !PL_strcasecmp("organization", headerName) ||
                 !PL_strcasecmp("user-agent", headerName) ||
                 !PL_strcasecmp("content-base", headerName) ||
                 !PL_strcasecmp("sender", headerName) ||
                 !PL_strcasecmp("date", headerName) ||
                 !PL_strcasecmp("x-mailer", headerName) ||
                 !PL_strcasecmp("content-type", headerName) ||
                 !PL_strcasecmp("message-id", headerName) ||
                 !PL_strcasecmp("x-newsreader", headerName) ||
                 !PL_strcasecmp("x-mimeole", headerName) ||
                 !PL_strcasecmp("references", headerName) ||
                 !PL_strcasecmp("in-reply-to", headerName) ||
                 !PL_strcasecmp("list-id", headerName) ||
                 !PL_strcasecmp("list-help", headerName) ||
                 !PL_strcasecmp("list-unsubscribe", headerName) ||
                 !PL_strcasecmp("list-subscribe", headerName) ||
                 !PL_strcasecmp("list-post", headerName) ||
                 !PL_strcasecmp("list-owner", headerName) ||
                 !PL_strcasecmp("list-archive", headerName) ||
                 !PL_strcasecmp("archived-at", headerName) ||
                 !PL_strcasecmp("delivered-to", headerName)) {
        skip = false;

      } else if (checkExtraHeaders || checkAddonHeaders || checkOtherHeaders) {
        // Make headerStr lowercase because
        // extraExpandedHeaders/extraAddonHeadersArray was made lowercase above.
        nsDependentCString headerStr(headerInfo->name);
        ToLowerCase(headerStr);
        // Accept if it's an "extra" header.
        if (checkExtraHeaders && extraExpandedHeadersArray.Contains(headerStr))
          skip = false;
        if (checkAddonHeaders && extraAddonHeadersArray.Contains(headerStr))
          skip = false;
        if (checkOtherHeaders && otherHeadersArray.Contains(headerStr))
          skip = false;
      }

      if (skip) continue;
    }

    const char* headerValue = headerInfo->value;
    mailChannel->AddHeaderFromMIME(nsDependentCString(headerInfo->name),
                                   nsDependentCString(headerValue));

    // Add a localized version of the date header if we encounter it.
    if (!PL_strcasecmp("Date", headerInfo->name)) {
      GenerateDateString(headerValue, convertedDateString, false);
      mailChannel->AddHeaderFromMIME("X-Mozilla-LocalizedDate"_ns,
                                     convertedDateString);
    }
  }

  // Notify the front end that the headers are ready on `mailChannel`.
  nsCOMPtr<nsIMailProgressListener> listener;
  mailChannel->GetListener(getter_AddRefs(listener));
  if (listener) {
    listener->OnHeadersComplete(mailChannel);
  }

  return rv;
}