NS_IMETHODIMP nsSmtpService::NewChannel2(nsIURI *aURI,
                                         nsILoadInfo* aLoadInfo,
                                         nsIChannel **_retval)
{
  NS_ENSURE_ARG_POINTER(aURI);
  // create an empty pipe for use with the input stream channel.
  nsCOMPtr<nsIAsyncInputStream> pipeIn;
  nsCOMPtr<nsIAsyncOutputStream> pipeOut;
  nsCOMPtr<nsIPipe> pipe = do_CreateInstance("@mozilla.org/pipe;1");
  nsresult rv = pipe->Init(false, false, 0, 0);
  if (NS_FAILED(rv)) 
    return rv;
  
  pipe->GetInputStream(getter_AddRefs(pipeIn));
  pipe->GetOutputStream(getter_AddRefs(pipeOut));

  pipeOut->Close();

  if (aLoadInfo) {
    return NS_NewInputStreamChannelInternal(_retval,
                                            aURI,
                                            pipeIn,
                                            NS_LITERAL_CSTRING("application/x-mailto"),
                                            EmptyCString(),
                                            aLoadInfo);
  }

  nsCOMPtr<nsIPrincipal> nullPrincipal =
    do_CreateInstance("@mozilla.org/nullprincipal;1", &rv);
  NS_ASSERTION(NS_SUCCEEDED(rv), "CreateInstance of nullprincipal failed.");
  if (NS_FAILED(rv))
    return rv;

  return NS_NewInputStreamChannel(_retval, aURI, pipeIn,
                                  nullPrincipal, nsILoadInfo::SEC_NORMAL,
                                  nsIContentPolicy::TYPE_OTHER,
                                  NS_LITERAL_CSTRING("application/x-mailto"));
}
NS_IMETHODIMP nsAbMDBDirectory::GetDatabaseFile(nsIFile **aResult)
{
  NS_ENSURE_ARG_POINTER(aResult);

  nsCString fileName;
  nsresult rv = GetStringValue("filename", EmptyCString(), fileName);
  NS_ENSURE_SUCCESS(rv, rv);

  if (fileName.IsEmpty())
    return NS_ERROR_NOT_INITIALIZED;

  nsCOMPtr<nsIFile> dbFile;
  rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
                              getter_AddRefs(dbFile));
  NS_ENSURE_SUCCESS(rv, rv);

  rv = dbFile->AppendNative(fileName);
  NS_ENSURE_SUCCESS(rv, rv);

  NS_ADDREF(*aResult = dbFile);

  return NS_OK;
}
Ejemplo n.º 3
0
already_AddRefed<Exception>
CreateException(JSContext* aCx, nsresult aRv, const char* aMessage)
{
  // Do we use DOM exceptions for this error code?
  switch (NS_ERROR_GET_MODULE(aRv)) {
  case NS_ERROR_MODULE_DOM:
  case NS_ERROR_MODULE_SVG:
  case NS_ERROR_MODULE_DOM_XPATH:
  case NS_ERROR_MODULE_DOM_INDEXEDDB:
  case NS_ERROR_MODULE_DOM_FILEHANDLE:
  case NS_ERROR_MODULE_DOM_BLUETOOTH:
    return DOMException::Create(aRv);
  default:
    break;
  }

  // If not, use the default.
  // aMessage can be null, so we can't use nsDependentCString on it.
  nsRefPtr<Exception> exception =
    new Exception(nsCString(aMessage), aRv,
                  EmptyCString(), nullptr, nullptr);
  return exception.forget();
}
void
WebBrowserPersistSerializeParent::ActorDestroy(ActorDestroyReason aWhy)
{
    if (mFinish) {
        MOZ_ASSERT(aWhy != Deletion);
        // See comment in WebBrowserPersistDocumentParent::ActorDestroy
        // (or bug 1202887) for why this is deferred.
        nsCOMPtr<nsIRunnable> errorLater =
          NewRunnableMethod<nsCOMPtr<nsIWebBrowserPersistDocument>,
                            nsCOMPtr<nsIOutputStream>,
                            nsCString,
                            nsresult>(
            "nsIWebBrowserPersistWriteCompletion::OnFinish",
            mFinish,
            &nsIWebBrowserPersistWriteCompletion::OnFinish,
            mDocument,
            mStream,
            EmptyCString(),
            NS_ERROR_FAILURE);
        NS_DispatchToCurrentThread(errorLater);
        mFinish = nullptr;
    }
}
nsresult
sbWatchFolderService::StartWatchingFolder()
{
  // Don't start if the service is not in the |eStarted| state or if the
  // watch path is empty.
  if (mWatchPath.IsEmpty() || mServiceState != eStarted) {
    return NS_OK;
  }

  nsresult rv;
  mFileSystemWatcher =
    do_CreateInstance("@songbirdnest.com/filesystem/watcher;1", &rv);
  NS_ENSURE_SUCCESS(rv, rv);

  if (mFileSystemWatcherGUID.Equals(EmptyCString())) {
    // Init a new file-system watcher. The session GUID for the new watcher
    // will be saved in StopWatching().
    TRACE(("%s: initiating new FS watcher for [%s]",
           __FUNCTION__,
           NS_ConvertUTF16toUTF8(mWatchPath).get()));
    rv = mFileSystemWatcher->Init(this, mWatchPath, PR_TRUE);
    NS_ENSURE_SUCCESS(rv, rv);
  }
  else {
    TRACE(("%s: initiating saved session %s",
           __FUNCTION__, mFileSystemWatcherGUID.get()));
    rv = mFileSystemWatcher->InitWithSession(mFileSystemWatcherGUID, this);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  rv = mFileSystemWatcher->StartWatching();
  NS_ENSURE_SUCCESS(rv, rv);

  // The service is now watching
  mServiceState = eWatching;
  return NS_OK;
}
nsresult nsMsgFolderCache::InitExistingDB()
{
  nsresult err = InitMDBInfo();
  if (NS_FAILED(err))
    return err;

  err = GetStore()->GetTable(GetEnv(), &m_allFoldersTableOID, &m_mdbAllFoldersTable);
  if (NS_SUCCEEDED(err) && m_mdbAllFoldersTable)
  {
    nsIMdbTableRowCursor* rowCursor = nsnull;
    err = m_mdbAllFoldersTable->GetTableRowCursor(GetEnv(), -1, &rowCursor);
    if (NS_SUCCEEDED(err) && rowCursor)
    {
      // iterate over the table rows and create nsMsgFolderCacheElements for each.
      while (PR_TRUE)
      {
        nsresult rv;
        nsIMdbRow* hdrRow;
        mdb_pos rowPos;

        rv = rowCursor->NextRow(GetEnv(), &hdrRow, &rowPos);
        if (NS_FAILED(rv) || !hdrRow)
          break;

        rv = AddCacheElement(EmptyCString(), hdrRow, nsnull);
        hdrRow->Release();
        if (NS_FAILED(rv))
          return rv;
      }
      rowCursor->Release();
    }
  }
  else
    err = NS_ERROR_FAILURE;

  return err;
}
Ejemplo n.º 7
0
void
nsPACMan::ProcessPendingQ(nsresult status)
{
  // Now, start any pending queries
  PRCList *node = PR_LIST_HEAD(&mPendingQ);
  while (node != &mPendingQ) {
    PendingPACQuery *query = static_cast<PendingPACQuery *>(node);
    node = PR_NEXT_LINK(node);
    if (NS_SUCCEEDED(status)) {
      // keep the query in the list (so we can complete it from Shutdown if
      // necessary).
      status = query->Start(nsIDNSService::RESOLVE_SPECULATE);
    }
    if (status == NS_ERROR_DNS_LOOKUP_QUEUE_FULL) {
      query->OnLookupComplete(NULL, NULL, NS_OK);
      status = NS_OK;
    } else if (NS_FAILED(status)) {
      // remove the query from the list
      PR_REMOVE_LINK(query);
      query->Complete(status, EmptyCString());
      NS_RELEASE(query);
    }
  }
}
Ejemplo n.º 8
0
nsresult
nsFontFaceLoader::CheckLoadAllowed(nsIPrincipal* aSourcePrincipal,
                                   nsIURI* aTargetURI,
                                   nsISupports* aContext)
{
  nsresult rv;
  
  if (!aSourcePrincipal)
    return NS_OK;

  // check with the security manager
  nsIScriptSecurityManager *secMan = nsContentUtils::GetSecurityManager();
  rv = secMan->CheckLoadURIWithPrincipal(aSourcePrincipal, aTargetURI,
                                        nsIScriptSecurityManager::STANDARD);
  if (NS_FAILED(rv)) {
    return rv;
  }

  // check content policy
  PRInt16 shouldLoad = nsIContentPolicy::ACCEPT;
  rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_FONT,
                                 aTargetURI,
                                 aSourcePrincipal,
                                 aContext,
                                 EmptyCString(), // mime type
                                 nsnull,
                                 &shouldLoad,
                                 nsContentUtils::GetContentPolicy(),
                                 nsContentUtils::GetSecurityManager());

  if (NS_FAILED(rv) || NS_CP_REJECTED(shouldLoad)) {
    return NS_ERROR_CONTENT_BLOCKED;
  }

  return NS_OK;
}
Ejemplo n.º 9
0
void
nsHttpConnectionInfo::CloneAsDirectRoute(nsHttpConnectionInfo **outCI)
{
    if (mRoutedHost.IsEmpty()) {
        *outCI = Clone();
        return;
    }

    RefPtr<nsHttpConnectionInfo> clone =
        new nsHttpConnectionInfo(mOrigin, mOriginPort,
                                 EmptyCString(), mUsername, mProxyInfo,
                                 mOriginAttributes, mEndToEndSSL);
    // Make sure the anonymous, insecure-scheme, and private flags are transferred
    clone->SetAnonymous(GetAnonymous());
    clone->SetPrivate(GetPrivate());
    clone->SetInsecureScheme(GetInsecureScheme());
    clone->SetNoSpdy(GetNoSpdy());
    clone->SetBeConservative(GetBeConservative());
    clone->SetTlsFlags(GetTlsFlags());
    if (!mNetworkInterfaceId.IsEmpty()) {
        clone->SetNetworkInterfaceId(mNetworkInterfaceId);
    }
    clone.forget(outCI);
}
Ejemplo n.º 10
0
nsresult
HttpBaseChannel::SetupReplacementChannel(nsIURI       *newURI, 
                                         nsIChannel   *newChannel,
                                         bool          preserveMethod,
                                         bool          forProxy)
{
  LOG(("HttpBaseChannel::SetupReplacementChannel "
     "[this=%p newChannel=%p preserveMethod=%d forProxy=%d]",
     this, newChannel, preserveMethod, forProxy));
  PRUint32 newLoadFlags = mLoadFlags | LOAD_REPLACE;
  // if the original channel was using SSL and this channel is not using
  // SSL, then no need to inhibit persistent caching.  however, if the
  // original channel was not using SSL and has INHIBIT_PERSISTENT_CACHING
  // set, then allow the flag to apply to the redirected channel as well.
  // since we force set INHIBIT_PERSISTENT_CACHING on all HTTPS channels,
  // we only need to check if the original channel was using SSL.
  if (mConnectionInfo->UsingSSL())
    newLoadFlags &= ~INHIBIT_PERSISTENT_CACHING;

  // Do not pass along LOAD_CHECK_OFFLINE_CACHE
  newLoadFlags &= ~nsICachingChannel::LOAD_CHECK_OFFLINE_CACHE;

  newChannel->SetLoadGroup(mLoadGroup); 
  newChannel->SetNotificationCallbacks(mCallbacks);
  newChannel->SetLoadFlags(newLoadFlags);

  nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(newChannel);
  if (!httpChannel)
    return NS_OK; // no other options to set

  if (preserveMethod) {
    nsCOMPtr<nsIUploadChannel> uploadChannel =
      do_QueryInterface(httpChannel);
    nsCOMPtr<nsIUploadChannel2> uploadChannel2 =
      do_QueryInterface(httpChannel);
    if (mUploadStream && (uploadChannel2 || uploadChannel)) {
      // rewind upload stream
      nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(mUploadStream);
      if (seekable)
        seekable->Seek(nsISeekableStream::NS_SEEK_SET, 0);

      // replicate original call to SetUploadStream...
      if (uploadChannel2) {
        const char *ctype = mRequestHead.PeekHeader(nsHttp::Content_Type);
        if (!ctype)
          ctype = "";
        const char *clen  = mRequestHead.PeekHeader(nsHttp::Content_Length);
        PRInt64 len = clen ? nsCRT::atoll(clen) : -1;
        uploadChannel2->ExplicitSetUploadStream(
                                  mUploadStream, nsDependentCString(ctype), len,
                                  nsDependentCString(mRequestHead.Method()),
                                  mUploadStreamHasHeaders);
      } else {
        if (mUploadStreamHasHeaders) {
          uploadChannel->SetUploadStream(mUploadStream, EmptyCString(),
                           -1);
        } else {
          const char *ctype =
            mRequestHead.PeekHeader(nsHttp::Content_Type);
          const char *clen =
            mRequestHead.PeekHeader(nsHttp::Content_Length);
          if (!ctype) {
            ctype = "application/octet-stream";
          }
          if (clen) {
            uploadChannel->SetUploadStream(mUploadStream,
                                           nsDependentCString(ctype),
                                           atoi(clen));
          }
        }
      }
    }
    // since preserveMethod is true, we need to ensure that the appropriate 
    // request method gets set on the channel, regardless of whether or not 
    // we set the upload stream above. This means SetRequestMethod() will
    // be called twice if ExplicitSetUploadStream() gets called above.

    httpChannel->SetRequestMethod(nsDependentCString(mRequestHead.Method()));
  }
  // convey the referrer if one was used for this channel to the next one
  if (mReferrer)
    httpChannel->SetReferrer(mReferrer);
  // convey the mAllowPipelining flag
  httpChannel->SetAllowPipelining(mAllowPipelining);
  // convey the new redirection limit
  httpChannel->SetRedirectionLimit(mRedirectionLimit - 1);

  nsCOMPtr<nsIHttpChannelInternal> httpInternal = do_QueryInterface(newChannel);
  if (httpInternal) {
    // convey the mForceAllowThirdPartyCookie flag
    httpInternal->SetForceAllowThirdPartyCookie(mForceAllowThirdPartyCookie);
    // convey the spdy flag
    httpInternal->SetAllowSpdy(mAllowSpdy);

    // update the DocumentURI indicator since we are being redirected.
    // if this was a top-level document channel, then the new channel
    // should have its mDocumentURI point to newURI; otherwise, we
    // just need to pass along our mDocumentURI to the new channel.
    if (newURI && (mURI == mDocumentURI))
      httpInternal->SetDocumentURI(newURI);
    else
      httpInternal->SetDocumentURI(mDocumentURI);

    // if there is a chain of keys for redirect-responses we transfer it to
    // the new channel (see bug #561276)
    if (mRedirectedCachekeys) {
        LOG(("HttpBaseChannel::SetupReplacementChannel "
             "[this=%p] transferring chain of redirect cache-keys", this));
        httpInternal->SetCacheKeysRedirectChain(mRedirectedCachekeys.forget());
    }
  }
  
  // transfer application cache information
  nsCOMPtr<nsIApplicationCacheChannel> appCacheChannel =
    do_QueryInterface(newChannel);
  if (appCacheChannel) {
    appCacheChannel->SetApplicationCache(mApplicationCache);
    appCacheChannel->SetInheritApplicationCache(mInheritApplicationCache);
    // We purposely avoid transfering mChooseApplicationCache.
  }

  // transfer any properties
  nsCOMPtr<nsIWritablePropertyBag> bag(do_QueryInterface(newChannel));
  if (bag)
    mPropertyHash.EnumerateRead(CopyProperties, bag.get());

  // transfer timed channel enabled status
  nsCOMPtr<nsITimedChannel> timed(do_QueryInterface(newChannel));
  if (timed)
    timed->SetTimingEnabled(mTimingEnabled);

  if (forProxy) {
    // Transfer all the headers from the previous channel
    //  this is needed for any headers that are not covered by the code above
    //  or have been set separately. e.g. manually setting Referer without
    //  setting up mReferrer
    PRUint32 count = mRequestHead.Headers().Count();
    for (PRUint32 i = 0; i < count; ++i) {
      nsHttpAtom header;
      const char *value = mRequestHead.Headers().PeekHeaderAt(i, header);

      httpChannel->SetRequestHeader(nsDependentCString(header),
                                    nsDependentCString(value), false);
    }
  }

  return NS_OK;
}
Ejemplo n.º 11
0
NS_IMETHODIMP
HttpBaseChannel::SetReferrer(nsIURI *referrer)
{
  ENSURE_CALLED_BEFORE_ASYNC_OPEN();

  // clear existing referrer, if any
  mReferrer = nsnull;
  mRequestHead.ClearHeader(nsHttp::Referer);

  if (!referrer)
      return NS_OK;

  // check referrer blocking pref
  PRUint32 referrerLevel;
  if (mLoadFlags & LOAD_INITIAL_DOCUMENT_URI)
    referrerLevel = 1; // user action
  else
    referrerLevel = 2; // inline content
  if (gHttpHandler->ReferrerLevel() < referrerLevel)
    return NS_OK;

  nsCOMPtr<nsIURI> referrerGrip;
  nsresult rv;
  bool match;

  //
  // Strip off "wyciwyg://123/" from wyciwyg referrers.
  //
  // XXX this really belongs elsewhere since wyciwyg URLs aren't part of necko.
  //     perhaps some sort of generic nsINestedURI could be used.  then, if an URI
  //     fails the whitelist test, then we could check for an inner URI and try
  //     that instead.  though, that might be too automatic.
  // 
  rv = referrer->SchemeIs("wyciwyg", &match);
  if (NS_FAILED(rv)) return rv;
  if (match) {
    nsCAutoString path;
    rv = referrer->GetPath(path);
    if (NS_FAILED(rv)) return rv;

    PRUint32 pathLength = path.Length();
    if (pathLength <= 2) return NS_ERROR_FAILURE;

    // Path is of the form "//123/http://foo/bar", with a variable number of digits.
    // To figure out where the "real" URL starts, search path for a '/', starting at 
    // the third character.
    PRInt32 slashIndex = path.FindChar('/', 2);
    if (slashIndex == kNotFound) return NS_ERROR_FAILURE;

    // Get the charset of the original URI so we can pass it to our fixed up URI.
    nsCAutoString charset;
    referrer->GetOriginCharset(charset);

    // Replace |referrer| with a URI without wyciwyg://123/.
    rv = NS_NewURI(getter_AddRefs(referrerGrip),
                   Substring(path, slashIndex + 1, pathLength - slashIndex - 1),
                   charset.get());
    if (NS_FAILED(rv)) return rv;

    referrer = referrerGrip.get();
  }

  //
  // block referrer if not on our white list...
  //
  static const char *const referrerWhiteList[] = {
    "http",
    "https",
    "ftp",
    "gopher",
    nsnull
  };
  match = false;
  const char *const *scheme = referrerWhiteList;
  for (; *scheme && !match; ++scheme) {
    rv = referrer->SchemeIs(*scheme, &match);
    if (NS_FAILED(rv)) return rv;
  }
  if (!match)
    return NS_OK; // kick out....

  //
  // Handle secure referrals.
  //
  // Support referrals from a secure server if this is a secure site
  // and (optionally) if the host names are the same.
  //
  rv = referrer->SchemeIs("https", &match);
  if (NS_FAILED(rv)) return rv;
  if (match) {
    rv = mURI->SchemeIs("https", &match);
    if (NS_FAILED(rv)) return rv;
    if (!match)
      return NS_OK;

    if (!gHttpHandler->SendSecureXSiteReferrer()) {
      nsCAutoString referrerHost;
      nsCAutoString host;

      rv = referrer->GetAsciiHost(referrerHost);
      if (NS_FAILED(rv)) return rv;

      rv = mURI->GetAsciiHost(host);
      if (NS_FAILED(rv)) return rv;

      // GetAsciiHost returns lowercase hostname.
      if (!referrerHost.Equals(host))
        return NS_OK;
    }
  }

  nsCOMPtr<nsIURI> clone;
  //
  // we need to clone the referrer, so we can:
  //  (1) modify it
  //  (2) keep a reference to it after returning from this function
  //
  // Use CloneIgnoringRef to strip away any fragment per RFC 2616 section 14.36
  rv = referrer->CloneIgnoringRef(getter_AddRefs(clone));
  if (NS_FAILED(rv)) return rv;

  // strip away any userpass; we don't want to be giving out passwords ;-)
  rv = clone->SetUserPass(EmptyCString());
  if (NS_FAILED(rv)) return rv;

  nsCAutoString spec;
  rv = clone->GetAsciiSpec(spec);
  if (NS_FAILED(rv)) return rv;

  // finally, remember the referrer URI and set the Referer header.
  mReferrer = clone;
  mRequestHead.SetHeader(nsHttp::Referer, spec);
  return NS_OK;
}
NS_IMETHODIMP
nsAddbookProtocolHandler::NewChannel(nsIURI *aURI, nsILoadInfo *aLoadInfo,
                                     nsIChannel **_retval) {
  nsresult rv;
  nsCOMPtr<nsIAddbookUrl> addbookUrl = do_QueryInterface(aURI, &rv);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = addbookUrl->GetAddbookOperation(&mAddbookOperation);
  NS_ENSURE_SUCCESS(rv, rv);

  if (mAddbookOperation == nsIAddbookUrlOperation::InvalidUrl) {
    nsAutoString errorString;
    errorString.AssignLiteral("Unsupported format/operation requested for ");
    nsAutoCString spec;
    rv = aURI->GetSpec(spec);
    NS_ENSURE_SUCCESS(rv, rv);

    errorString.Append(NS_ConvertUTF8toUTF16(spec));
    rv = GenerateXMLOutputChannel(errorString, addbookUrl, aURI, aLoadInfo,
                                  _retval);
    NS_ENSURE_SUCCESS(rv, rv);
    return NS_OK;
  }

  if (mAddbookOperation == nsIAddbookUrlOperation::AddVCard) {
    // create an empty pipe for use with the input stream channel.
    nsCOMPtr<nsIAsyncInputStream> pipeIn;
    nsCOMPtr<nsIAsyncOutputStream> pipeOut;
    nsCOMPtr<nsIPipe> pipe = do_CreateInstance("@mozilla.org/pipe;1");

    rv = pipe->Init(false, false, 0, 0);
    NS_ENSURE_SUCCESS(rv, rv);

    // These always succeed because the pipe is initialized above.
    MOZ_ALWAYS_SUCCEEDS(pipe->GetInputStream(getter_AddRefs(pipeIn)));
    MOZ_ALWAYS_SUCCEEDS(pipe->GetOutputStream(getter_AddRefs(pipeOut)));

    pipeOut->Close();
    if (aLoadInfo) {
      return NS_NewInputStreamChannelInternal(
          _retval, aURI, pipeIn.forget(),
          NS_LITERAL_CSTRING("application/x-addvcard"), EmptyCString(),
          aLoadInfo);
    }

    nsCOMPtr<nsIPrincipal> nullPrincipal =
        do_CreateInstance("@mozilla.org/nullprincipal;1", &rv);
    NS_ASSERTION(NS_SUCCEEDED(rv), "CreateInstance of nullprincipal failed.");
    if (NS_FAILED(rv)) return rv;

    return NS_NewInputStreamChannel(
        _retval, aURI, pipeIn.forget(), nullPrincipal,
        nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
        nsIContentPolicy::TYPE_OTHER,
        NS_LITERAL_CSTRING("application/x-addvcard"));
  }

  nsString output;
  rv = GeneratePrintOutput(addbookUrl, output);
  if (NS_FAILED(rv)) {
    output.AssignLiteral("failed to print. url=");
    nsAutoCString spec;
    rv = aURI->GetSpec(spec);
    NS_ENSURE_SUCCESS(rv, rv);
    output.Append(NS_ConvertUTF8toUTF16(spec));
  }

  rv = GenerateXMLOutputChannel(output, addbookUrl, aURI, aLoadInfo, _retval);
  NS_ENSURE_SUCCESS(rv, rv);
  return NS_OK;
}
Ejemplo n.º 13
0
nsresult
net_GetFileFromURLSpec(const nsACString &aURL, nsIFile **result)
{
  // NOTE: See also the implementation in nsURLHelperUnix.cpp
  // This matches it except for the HFS path handling and file
  // system charset conversion.

  nsresult rv;

  nsCOMPtr<nsILocalFile> localFile;
  rv = NS_NewNativeLocalFile(EmptyCString(), PR_TRUE, getter_AddRefs(localFile));
  if (NS_FAILED(rv))
    return rv;
  
  nsCAutoString directory, fileBaseName, fileExtension, path;
  PRBool bHFSPath = PR_FALSE;

  rv = net_ParseFileURL(aURL, directory, fileBaseName, fileExtension);
  if (NS_FAILED(rv))
    return rv;

  if (!directory.IsEmpty()) {
    NS_EscapeURL(directory, esc_Directory|esc_AlwaysCopy, path);

    // The canonical form of file URLs on OSX use POSIX paths:
    //   file:///path-name.
    // But, we still encounter file URLs that use HFS paths:
    //   file:///volume-name/path-name
    // Determine that here and normalize HFS paths to POSIX.
    nsCAutoString possibleVolName;
    if (pathBeginsWithVolName(directory, possibleVolName)) {        
      // Though we know it begins with a volume name, it could still
      // be a valid POSIX path if the boot drive is named "Mac HD"
      // and there is a directory "Mac HD" at its root. If such a
      // directory doesn't exist, we'll assume this is an HFS path.
      FSRef testRef;
      possibleVolName.Insert("/", 0);
      if (::FSPathMakeRef((UInt8*)possibleVolName.get(), &testRef, nsnull) != noErr)
        bHFSPath = PR_TRUE;
    }

    if (bHFSPath) {
      // "%2F"s need to become slashes, while all other slashes need to
      // become colons. If we start out by changing "%2F"s to colons, we
      // can reply on SwapSlashColon() to do what we need
      path.ReplaceSubstring("%2F", ":");
      path.Cut(0, 1); // directory begins with '/'
      SwapSlashColon((char *)path.get());
      // At this point, path is an HFS path made using the same
      // algorithm as nsURLHelperMac. We'll convert to POSIX below.
    }
  }
  if (!fileBaseName.IsEmpty())
    NS_EscapeURL(fileBaseName, esc_FileBaseName|esc_AlwaysCopy, path);
  if (!fileExtension.IsEmpty()) {
    path += '.';
    NS_EscapeURL(fileExtension, esc_FileExtension|esc_AlwaysCopy, path);
  }

  NS_UnescapeURL(path);
  if (path.Length() != strlen(path.get()))
    return NS_ERROR_FILE_INVALID_PATH;

  if (bHFSPath)
    convertHFSPathtoPOSIX(path, path);

  // assuming path is encoded in the native charset
  rv = localFile->InitWithNativePath(path);
  if (NS_FAILED(rv))
    return rv;

  NS_ADDREF(*result = localFile);
  return NS_OK;
}
Ejemplo n.º 14
0
nsresult
nsIndexedToHTML::DoOnStartRequest(nsIRequest* request, nsISupports *aContext,
                                  nsCString& aBuffer) {
    nsresult rv;

    nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
    nsCOMPtr<nsIURI> uri;
    rv = channel->GetURI(getter_AddRefs(uri));
    if (NS_FAILED(rv)) return rv;

    channel->SetContentType(NS_LITERAL_CSTRING("text/html"));

    mParser = do_CreateInstance("@mozilla.org/dirIndexParser;1",&rv);
    if (NS_FAILED(rv)) return rv;

    rv = mParser->SetListener(this);
    if (NS_FAILED(rv)) return rv;
    
    rv = mParser->OnStartRequest(request, aContext);
    if (NS_FAILED(rv)) return rv;

    nsAutoCString baseUri, titleUri;
    rv = uri->GetAsciiSpec(baseUri);
    if (NS_FAILED(rv)) return rv;
    titleUri = baseUri;

    nsCString parentStr;

    nsCString buffer;
    buffer.AppendLiteral("<!DOCTYPE html>\n<html>\n<head>\n");

    // XXX - should be using the 300: line from the parser.
    // We can't guarantee that that comes before any entry, so we'd have to
    // buffer, and do other painful stuff.
    // I'll deal with this when I make the changes to handle welcome messages
    // The .. stuff should also come from the lower level protocols, but that
    // would muck up the XUL display
    // - bbaetz

    bool isScheme = false;
    bool isSchemeFile = false;
    if (NS_SUCCEEDED(uri->SchemeIs("ftp", &isScheme)) && isScheme) {

        // strip out the password here, so it doesn't show in the page title
        // This is done by the 300: line generation in ftp, but we don't use
        // that - see above
        
        nsAutoCString pw;
        rv = uri->GetPassword(pw);
        if (NS_FAILED(rv)) return rv;
        if (!pw.IsEmpty()) {
             nsCOMPtr<nsIURI> newUri;
             rv = uri->Clone(getter_AddRefs(newUri));
             if (NS_FAILED(rv)) return rv;
             rv = newUri->SetPassword(EmptyCString());
             if (NS_FAILED(rv)) return rv;
             rv = newUri->GetAsciiSpec(titleUri);
             if (NS_FAILED(rv)) return rv;
        }

        nsAutoCString path;
        rv = uri->GetPath(path);
        if (NS_FAILED(rv)) return rv;

        if (!path.EqualsLiteral("//") && !path.LowerCaseEqualsLiteral("/%2f")) {
            rv = uri->Resolve(NS_LITERAL_CSTRING(".."),parentStr);
            if (NS_FAILED(rv)) return rv;
        }
    } else if (NS_SUCCEEDED(uri->SchemeIs("file", &isSchemeFile)) && isSchemeFile) {
        nsCOMPtr<nsIFileURL> fileUrl = do_QueryInterface(uri);
        nsCOMPtr<nsIFile> file;
        rv = fileUrl->GetFile(getter_AddRefs(file));
        if (NS_FAILED(rv)) return rv;
        file->SetFollowLinks(true);
        
        nsAutoCString url;
        rv = net_GetURLSpecFromFile(file, url);
        if (NS_FAILED(rv)) return rv;
        baseUri.Assign(url);
        
        nsCOMPtr<nsIFile> parent;
        rv = file->GetParent(getter_AddRefs(parent));
        
        if (parent && NS_SUCCEEDED(rv)) {
            net_GetURLSpecFromDir(parent, url);
            if (NS_FAILED(rv)) return rv;
            parentStr.Assign(url);
        }

        // Directory index will be always encoded in UTF-8 if this is file url
        buffer.AppendLiteral("<meta charset=\"UTF-8\">\n");

    } else if (NS_SUCCEEDED(uri->SchemeIs("jar", &isScheme)) && isScheme) {
        nsAutoCString path;
        rv = uri->GetPath(path);
        if (NS_FAILED(rv)) return rv;

        // a top-level jar directory URL is of the form jar:foo.zip!/
        // path will be of the form foo.zip!/, and its last two characters
        // will be "!/"
        //XXX this won't work correctly when the name of the directory being
        //XXX displayed ends with "!", but then again, jar: URIs don't deal
        //XXX particularly well with such directories anyway
        if (!StringEndsWith(path, NS_LITERAL_CSTRING("!/"))) {
            rv = uri->Resolve(NS_LITERAL_CSTRING(".."), parentStr);
            if (NS_FAILED(rv)) return rv;
        }
    }
    else {
        // default behavior for other protocols is to assume the channel's
        // URL references a directory ending in '/' -- fixup if necessary.
        nsAutoCString path;
        rv = uri->GetPath(path);
        if (NS_FAILED(rv)) return rv;
        if (baseUri.Last() != '/') {
            baseUri.Append('/');
            path.Append('/');
            uri->SetPath(path);
        }
        if (!path.EqualsLiteral("/")) {
            rv = uri->Resolve(NS_LITERAL_CSTRING(".."), parentStr);
            if (NS_FAILED(rv)) return rv;
        }
    }

    buffer.AppendLiteral("<style type=\"text/css\">\n"
                         ":root {\n"
                         "  font-family: sans-serif;\n"
                         "}\n"
                         "img {\n"
                         "  border: 0;\n"
                         "}\n"
                         "th {\n"
                         "  text-align: start;\n"
                         "  white-space: nowrap;\n"
                         "}\n"
                         "th > a {\n"
                         "  color: inherit;\n"
                         "}\n"
                         "table[order] > thead > tr > th {\n"
                         "  cursor: pointer;\n"
                         "}\n"
                         "table[order] > thead > tr > th::after {\n"
                         "  display: none;\n"
                         "  width: .8em;\n"
                         "  margin-inline-end: -.8em;\n"
                         "  text-align: end;\n"
                         "}\n"
                         "table[order=\"asc\"] > thead > tr > th::after {\n"
                         "  content: \"\\2193\"; /* DOWNWARDS ARROW (U+2193) */\n"
                         "}\n"
                         "table[order=\"desc\"] > thead > tr > th::after {\n"
                         "  content: \"\\2191\"; /* UPWARDS ARROW (U+2191) */\n"
                         "}\n"
                         "table[order][order-by=\"0\"] > thead > tr > th:first-child > a ,\n"
                         "table[order][order-by=\"1\"] > thead > tr > th:first-child + th > a ,\n"
                         "table[order][order-by=\"2\"] > thead > tr > th:first-child + th + th > a {\n"
                         "  text-decoration: underline;\n"
                         "}\n"
                         "table[order][order-by=\"0\"] > thead > tr > th:first-child::after ,\n"
                         "table[order][order-by=\"1\"] > thead > tr > th:first-child + th::after ,\n"
                         "table[order][order-by=\"2\"] > thead > tr > th:first-child + th + th::after {\n"
                         "  display: inline-block;\n"
                         "}\n"
                         "table.remove-hidden > tbody > tr.hidden-object {\n"
                         "  display: none;\n"
                         "}\n"
                         "td {\n"
                         "  white-space: nowrap;\n"
                         "}\n"
                         "table.ellipsis {\n"
                         "  width: 100%;\n"
                         "  table-layout: fixed;\n"
                         "  border-spacing: 0;\n"
                         "}\n"
                         "table.ellipsis > tbody > tr > td {\n"
                         "  padding: 0;\n"
                         "  overflow: hidden;\n"
                         "  text-overflow: ellipsis;\n"
                         "}\n"
                         "/* name */\n"
                         "/* name */\n"
                         "th:first-child {\n"
                         "  padding-inline-end: 2em;\n"
                         "}\n"
                         "/* size */\n"
                         "th:first-child + th {\n"
                         "  padding-inline-end: 1em;\n"
                         "}\n"
                         "td:first-child + td {\n"
                         "  text-align: end;\n"
                         "  padding-inline-end: 1em;\n"
                         "}\n"
                         "/* date */\n"
                         "td:first-child + td + td {\n"
                         "  padding-inline-start: 1em;\n"
                         "  padding-inline-end: .5em;\n"
                         "}\n"
                         "/* time */\n"
                         "td:first-child + td + td + td {\n"
                         "  padding-inline-start: .5em;\n"
                         "}\n"
                         ".symlink {\n"
                         "  font-style: italic;\n"
                         "}\n"
                         ".dir ,\n"
                         ".symlink ,\n"
                         ".file {\n"
                         "  margin-inline-start: 20px;\n"
                         "}\n"
                         ".dir::before ,\n"
                         ".file > img {\n"
                         "  margin-inline-end: 4px;\n"
                         "  margin-inline-start: -20px;\n"
                         "  max-width: 16px;\n"
                         "  max-height: 16px;\n"
                         "  vertical-align: middle;\n"
                         "}\n"
                         ".dir::before {\n"
                         "  content: url(resource://gre/res/html/folder.png);\n"
                         "}\n"
                         "</style>\n"
                         "<link rel=\"stylesheet\" media=\"screen, projection\" type=\"text/css\""
                         " href=\"chrome://global/skin/dirListing/dirListing.css\">\n"
                         "<script type=\"application/javascript\">\n"
                         "'use strict';\n"
                         "var gTable, gOrderBy, gTBody, gRows, gUI_showHidden;\n"
                         "document.addEventListener(\"DOMContentLoaded\", function() {\n"
                         "  gTable = document.getElementsByTagName(\"table\")[0];\n"
                         "  gTBody = gTable.tBodies[0];\n"
                         "  if (gTBody.rows.length < 2)\n"
                         "    return;\n"
                         "  gUI_showHidden = document.getElementById(\"UI_showHidden\");\n"
                         "  var headCells = gTable.tHead.rows[0].cells,\n"
                         "      hiddenObjects = false;\n"
                         "  function rowAction(i) {\n"
                         "    return function(event) {\n"
                         "      event.preventDefault();\n"
                         "      orderBy(i);\n"
                         "    }\n"
                         "  }\n"
                         "  for (var i = headCells.length - 1; i >= 0; i--) {\n"
                         "    var anchor = document.createElement(\"a\");\n"
                         "    anchor.href = \"\";\n"
                         "    anchor.appendChild(headCells[i].firstChild);\n"
                         "    headCells[i].appendChild(anchor);\n"
                         "    headCells[i].addEventListener(\"click\", rowAction(i), true);\n"
                         "  }\n"
                         "  if (gUI_showHidden) {\n"
                         "    gRows = Array.slice(gTBody.rows);\n"
                         "    hiddenObjects = gRows.some(row => row.className == \"hidden-object\");\n"
                         "  }\n"
                         "  gTable.setAttribute(\"order\", \"\");\n"
                         "  if (hiddenObjects) {\n"
                         "    gUI_showHidden.style.display = \"block\";\n"
                         "    updateHidden();\n"
                         "  }\n"
                         "}, \"false\");\n"
                         "function compareRows(rowA, rowB) {\n"
                         "  var a = rowA.cells[gOrderBy].getAttribute(\"sortable-data\") || \"\";\n"
                         "  var b = rowB.cells[gOrderBy].getAttribute(\"sortable-data\") || \"\";\n"
                         "  var intA = +a;\n"
                         "  var intB = +b;\n"
                         "  if (a == intA && b == intB) {\n"
                         "    a = intA;\n"
                         "    b = intB;\n"
                         "  } else {\n"
                         "    a = a.toLowerCase();\n"
                         "    b = b.toLowerCase();\n"
                         "  }\n"
                         "  if (a < b)\n"
                         "    return -1;\n"
                         "  if (a > b)\n"
                         "    return 1;\n"
                         "  return 0;\n"
                         "}\n"
                         "function orderBy(column) {\n"
                         "  if (!gRows)\n"
                         "    gRows = Array.slice(gTBody.rows);\n"
                         "  var order;\n"
                         "  if (gOrderBy == column) {\n"
                         "    order = gTable.getAttribute(\"order\") == \"asc\" ? \"desc\" : \"asc\";\n"
                         "  } else {\n"
                         "    order = \"asc\";\n"
                         "    gOrderBy = column;\n"
                         "    gTable.setAttribute(\"order-by\", column);\n"
                         "    gRows.sort(compareRows);\n"
                         "  }\n"
                         "  gTable.removeChild(gTBody);\n"
                         "  gTable.setAttribute(\"order\", order);\n"
                         "  if (order == \"asc\")\n"
                         "    for (var i = 0; i < gRows.length; i++)\n"
                         "      gTBody.appendChild(gRows[i]);\n"
                         "  else\n"
                         "    for (var i = gRows.length - 1; i >= 0; i--)\n"
                         "      gTBody.appendChild(gRows[i]);\n"
                         "  gTable.appendChild(gTBody);\n"
                         "}\n"
                         "function updateHidden() {\n"
                         "  gTable.className = gUI_showHidden.getElementsByTagName(\"input\")[0].checked ?\n"
                         "                     \"\" :\n"
                         "                     \"remove-hidden\";\n"
                         "}\n"
                         "</script>\n");

    buffer.AppendLiteral("<link rel=\"icon\" type=\"image/png\" href=\"");
    nsCOMPtr<nsIURI> innerUri = NS_GetInnermostURI(uri);
    if (!innerUri)
        return NS_ERROR_UNEXPECTED;
    nsCOMPtr<nsIFileURL> fileURL(do_QueryInterface(innerUri));
    //XXX bug 388553: can't use skinnable icons here due to security restrictions
    if (fileURL) {
        //buffer.AppendLiteral("chrome://global/skin/dirListing/local.png");
        buffer.AppendLiteral("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB"
                             "AAAAAQCAYAAAAf8%2F9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9i"
                             "ZSBJbWFnZVJlYWR5ccllPAAAAjFJREFUeNqsU8uOElEQPffR"
                             "3XQ3ONASdBJCSBxHos5%2B3Bg3rvkCv8PElS78gPkO%2FATj"
                             "QoUdO2ftrJiRh6aneTb9sOpC4weMN6lcuFV16pxDIfI8x12O"
                             "YIDhcPiu2Wx%2B%2FHF5CW1Z6Jyegt%2FTNEWSJIjjGFEUIQ"
                             "xDrFYrWFSzXC4%2FdLvd95pRKpXKy%2BpRFZ7nwaWo1%2BsG"
                             "nQG2260BKJfLKJVKGI1GEEJw7ateryd0v993W63WEwjgxfn5"
                             "obGYzgCbzcaEbdsIggDj8Riu6z6iUk9SYZMSx8W0LMsM%2FS"
                             "KK75xnJlIq80anQXdbEp0OhcPJ0eiaJnGRMEyyPDsAKKUM9c"
                             "lkYoDo3SZJzzSdp0VSKYmfV1co%2Bz580kw5KDIM8RbRfEnU"
                             "f1HzxtQyMAGcaGruTKczMzEIaqhKifV6jd%2BzGQQB5llunF"
                             "%2FM52BizC2K5sYPYvZcu653tjOM9O93wnYc08gmkgg4VAxi"
                             "xfqFUJT36AYBZGd6PJkFCZnnlBxMp38gqIgLpZB0y4Nph18l"
                             "yWh5FFbrOSxbl3V4G%2BVB7T4ajYYxTyuLtO%2BCvWGgJE1M"
                             "c7JNsJEhvgw%2FQV4fo%2F24nbEsX2u1d5sVyn8sJO0ZAQiI"
                             "YnFh%2BxrfLz%2Fj29cBS%2FO14zg3i8XigW3ZkErDtmKoeM"
                             "%2BAJGRMnXeEPGKf0nCD1ydvkDzU9Jbc6OpR7WIw6L8lQ%2B"
                             "4pQ1%2FlPF0RGM9Ns91Wmptk0GfB4EJkt77vXYj%2F8m%2B8"
                             "y%2FkrwABHbz2H9V68DQAAAABJRU5ErkJggg%3D%3D");
    } else {
        //buffer.AppendLiteral("chrome://global/skin/dirListing/remote.png");
        buffer.AppendLiteral("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB"
                             "AAAAAQCAYAAAAf8%2F9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9i"
                             "ZSBJbWFnZVJlYWR5ccllPAAAAeBJREFUeNqcU81O20AQ%2Ft"
                             "Z2AgQSYQRqL1UPVG2hAUQkxLEStz4DrXpLpD5Drz31Cajax%"
                             "2Bghhx6qHIJURBTxIwQRwopCBbZjHMcOTrzermPipsSt1Iw0"
                             "3p3ZmW%2B%2B2R0TxhgOD34wjCHZlQ0iDYz9yvEfhxMTCYhE"
                             "QDIZhkxKd2sqzX2TOD2vBQCQhpPefng1ZP2dVPlLLdpL8SEM"
                             "cxng%2Fbs0RIHhtgs4twxOh%2BHjZxvzDx%2F3GQQiDFISiR"
                             "BLFMPKTRMollzcWECrDVhtxtdRVsL9youPxGj%2FbdfFlUZh"
                             "tDyYbYqWRUdai1oQRZ5oHeHl2gNM%2B01Uqio8RlH%2Bnsaz"
                             "JzNwXcq1B%2BiXPHprlEEymeBfXs1w8XxxihfyuXqoHqpoGj"
                             "ZM04bddgG%2F9%2B8WGj87qDdsrK9m%2BoA%2BpbhQTDh2l1"
                             "%2Bi2weNbSHMZyjvNXmVbqh9Fj5Oz27uEoP%2BSTxANruJs9"
                             "L%2FT6P0ewqPx5nmiAG5f6AoCtN1PbJzuRyJAyDBzzSQYvEr"
                             "f06yYxhGXlEa8H2KVGoasjwLx3Ewk858opQWXm%2B%2Fib9E"
                             "QrBzclLLLy89xYvlpchvtixcX6uo1y%2FzsiwHrkIsgKbp%2"
                             "BYWFOWicuqppoNTnStHzPFCPQhBEBOyGAX4JMADFetubi4BS"
                             "YAAAAABJRU5ErkJggg%3D%3D");
    }
    buffer.AppendLiteral("\">\n<title>");

    // Everything needs to end in a /,
    // otherwise we end up linking to file:///foo/dirfile

    if (!mTextToSubURI) {
        mTextToSubURI = do_GetService(NS_ITEXTTOSUBURI_CONTRACTID, &rv);
        if (NS_FAILED(rv)) return rv;
    }

    nsXPIDLCString encoding;
    rv = uri->GetOriginCharset(encoding);
    if (NS_FAILED(rv)) return rv;
    if (encoding.IsEmpty()) {
      encoding.AssignLiteral("UTF-8");
    }

    nsXPIDLString unEscapeSpec;
    rv = mTextToSubURI->UnEscapeAndConvert(encoding, titleUri.get(),
                                           getter_Copies(unEscapeSpec));
    // unescape may fail because
    // 1. file URL may be encoded in platform charset for backward compatibility
    // 2. query part may not be encoded in UTF-8 (see bug 261929)
    // so try the platform's default if this is file url
    if (NS_FAILED(rv) && isSchemeFile) {
        nsCOMPtr<nsIPlatformCharset> platformCharset(do_GetService(NS_PLATFORMCHARSET_CONTRACTID, &rv));
        NS_ENSURE_SUCCESS(rv, rv);
        nsAutoCString charset;
        rv = platformCharset->GetCharset(kPlatformCharsetSel_FileName, charset);
        NS_ENSURE_SUCCESS(rv, rv);

        rv = mTextToSubURI->UnEscapeAndConvert(charset.get(), titleUri.get(),
                                               getter_Copies(unEscapeSpec));
    }
    if (NS_FAILED(rv)) return rv;

    nsXPIDLString htmlEscSpec;
    htmlEscSpec.Adopt(nsEscapeHTML2(unEscapeSpec.get(),
                                    unEscapeSpec.Length()));

    nsXPIDLString title;
    const char16_t* formatTitle[] = {
        htmlEscSpec.get()
    };

    rv = mBundle->FormatStringFromName(MOZ_UTF16("DirTitle"),
                                       formatTitle,
                                       sizeof(formatTitle)/sizeof(char16_t*),
                                       getter_Copies(title));
    if (NS_FAILED(rv)) return rv;

    // we want to convert string bundle to NCR
    // to ensure they're shown in any charsets
    AppendNonAsciiToNCR(title, buffer);

    buffer.AppendLiteral("</title>\n");    

    // If there is a quote character in the baseUri, then
    // lets not add a base URL.  The reason for this is that
    // if we stick baseUri containing a quote into a quoted
    // string, the quote character will prematurely close
    // the base href string.  This is a fall-back check;
    // that's why it is OK to not use a base rather than
    // trying to play nice and escaping the quotes.  See bug
    // 358128.

    if (!baseUri.Contains('"'))
    {
        // Great, the baseUri does not contain a char that
        // will prematurely close the string.  Go ahead an
        // add a base href, but only do so if we're not
        // dealing with a resource URI.
        nsCOMPtr<nsIURI> originalUri;
        rv = channel->GetOriginalURI(getter_AddRefs(originalUri));
        bool wasResource = false;
        if (NS_FAILED(rv) ||
            NS_FAILED(originalUri->SchemeIs("resource", &wasResource)) ||
            !wasResource) {
            buffer.AppendLiteral("<base href=\"");
            nsAdoptingCString htmlEscapedUri(nsEscapeHTML(baseUri.get()));
            buffer.Append(htmlEscapedUri);
            buffer.AppendLiteral("\" />\n");
        }
    }
    else
    {
        NS_ERROR("broken protocol handler didn't escape double-quote.");
    }

    nsCString direction(NS_LITERAL_CSTRING("ltr"));
    nsCOMPtr<nsIXULChromeRegistry> reg =
      mozilla::services::GetXULChromeRegistryService();
    if (reg) {
      bool isRTL = false;
      reg->IsLocaleRTL(NS_LITERAL_CSTRING("global"), &isRTL);
      if (isRTL) {
        direction.AssignLiteral("rtl");
      }
    }

    buffer.AppendLiteral("</head>\n<body dir=\"");
    buffer.Append(direction);
    buffer.AppendLiteral("\">\n<h1>");
    
    const char16_t* formatHeading[] = {
        htmlEscSpec.get()
    };

    rv = mBundle->FormatStringFromName(MOZ_UTF16("DirTitle"),
                                       formatHeading,
                                       sizeof(formatHeading)/sizeof(char16_t*),
                                       getter_Copies(title));
    if (NS_FAILED(rv)) return rv;
    
    AppendNonAsciiToNCR(title, buffer);
    buffer.AppendLiteral("</h1>\n");

    if (!parentStr.IsEmpty()) {
        nsXPIDLString parentText;
        rv = mBundle->GetStringFromName(MOZ_UTF16("DirGoUp"),
                                        getter_Copies(parentText));
        if (NS_FAILED(rv)) return rv;

        buffer.AppendLiteral("<p id=\"UI_goUp\"><a class=\"up\" href=\"");

        nsAdoptingCString htmlParentStr(nsEscapeHTML(parentStr.get()));
        buffer.Append(htmlParentStr);
        buffer.AppendLiteral("\">");
        AppendNonAsciiToNCR(parentText, buffer);
        buffer.AppendLiteral("</a></p>\n");
    }

    if (isSchemeFile) {
        nsXPIDLString showHiddenText;
        rv = mBundle->GetStringFromName(MOZ_UTF16("ShowHidden"),
                                        getter_Copies(showHiddenText));
        if (NS_FAILED(rv)) return rv;

        buffer.AppendLiteral("<p id=\"UI_showHidden\" style=\"display:none\"><label><input type=\"checkbox\" checked onchange=\"updateHidden()\">");
        AppendNonAsciiToNCR(showHiddenText, buffer);
        buffer.AppendLiteral("</label></p>\n");
    }

    buffer.AppendLiteral("<table>\n");

    nsXPIDLString columnText;

    buffer.AppendLiteral(" <thead>\n"
                         "  <tr>\n"
                         "   <th>");

    rv = mBundle->GetStringFromName(MOZ_UTF16("DirColName"),
                                    getter_Copies(columnText));
    if (NS_FAILED(rv)) return rv;
    AppendNonAsciiToNCR(columnText, buffer);
    buffer.AppendLiteral("</th>\n"
                         "   <th>");

    rv = mBundle->GetStringFromName(MOZ_UTF16("DirColSize"),
                                    getter_Copies(columnText));
    if (NS_FAILED(rv)) return rv;
    AppendNonAsciiToNCR(columnText, buffer);
    buffer.AppendLiteral("</th>\n"
                         "   <th colspan=\"2\">");

    rv = mBundle->GetStringFromName(MOZ_UTF16("DirColMTime"),
                                    getter_Copies(columnText));
    if (NS_FAILED(rv)) return rv;
    AppendNonAsciiToNCR(columnText, buffer);
    buffer.AppendLiteral("</th>\n"
                         "  </tr>\n"
                         " </thead>\n");
    buffer.AppendLiteral(" <tbody>\n");

    aBuffer = buffer;
    return rv;
}
Ejemplo n.º 15
0
nsresult
nsXREDirProvider::GetUserDataDirectoryHome(nsIFile** aFile, bool aLocal)
{
  // Copied from nsAppFileLocationProvider (more or less)
  nsresult rv;
  nsCOMPtr<nsIFile> localDir;

#if defined(XP_MACOSX)
  FSRef fsRef;
  OSType folderType;
  if (aLocal) {
    folderType = kCachedDataFolderType;
  } else {
#ifdef MOZ_THUNDERBIRD
    folderType = kDomainLibraryFolderType;
#else
    folderType = kApplicationSupportFolderType;
#endif
  }
  OSErr err = ::FSFindFolder(kUserDomain, folderType, kCreateFolder, &fsRef);
  NS_ENSURE_FALSE(err, NS_ERROR_FAILURE);

  rv = NS_NewNativeLocalFile(EmptyCString(), true, getter_AddRefs(localDir));
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<nsILocalFileMac> dirFileMac = do_QueryInterface(localDir);
  NS_ENSURE_TRUE(dirFileMac, NS_ERROR_UNEXPECTED);

  rv = dirFileMac->InitWithFSRef(&fsRef);
  NS_ENSURE_SUCCESS(rv, rv);

  localDir = do_QueryInterface(dirFileMac, &rv);
#elif defined(XP_IOS)
  nsAutoCString userDir;
  if (GetUIKitDirectory(aLocal, userDir)) {
    rv = NS_NewNativeLocalFile(userDir, true, getter_AddRefs(localDir));
  } else {
    rv = NS_ERROR_FAILURE;
  }
  NS_ENSURE_SUCCESS(rv, rv);
#elif defined(XP_WIN)
  nsString path;
  if (aLocal) {
    rv = GetShellFolderPath(CSIDL_LOCAL_APPDATA, path);
    if (NS_FAILED(rv))
      rv = GetRegWindowsAppDataFolder(aLocal, path);
  }
  if (!aLocal || NS_FAILED(rv)) {
    rv = GetShellFolderPath(CSIDL_APPDATA, path);
    if (NS_FAILED(rv)) {
      if (!aLocal)
        rv = GetRegWindowsAppDataFolder(aLocal, path);
    }
  }
  NS_ENSURE_SUCCESS(rv, rv);

  rv = NS_NewLocalFile(path, true, getter_AddRefs(localDir));
#elif defined(MOZ_WIDGET_GONK)
  rv = NS_NewNativeLocalFile(NS_LITERAL_CSTRING("/data/b2g"), true,
                             getter_AddRefs(localDir));
#elif defined(XP_UNIX)
  const char* homeDir = getenv("HOME");
  if (!homeDir || !*homeDir)
    return NS_ERROR_FAILURE;

#ifdef ANDROID /* We want (ProfD == ProfLD) on Android. */
  aLocal = false;
#endif

  if (aLocal) {
    // If $XDG_CACHE_HOME is defined use it, otherwise use $HOME/.cache.
    const char* cacheHome = getenv("XDG_CACHE_HOME");
    if (cacheHome && *cacheHome) {
      rv = NS_NewNativeLocalFile(nsDependentCString(cacheHome), true,
                                 getter_AddRefs(localDir));
    } else {
      rv = NS_NewNativeLocalFile(nsDependentCString(homeDir), true,
                                 getter_AddRefs(localDir));
      if (NS_SUCCEEDED(rv))
        rv = localDir->AppendNative(NS_LITERAL_CSTRING(".cache"));
    }
  } else {
    rv = NS_NewNativeLocalFile(nsDependentCString(homeDir), true,
                               getter_AddRefs(localDir));
  }
#else
#error "Don't know how to get product dir on your platform"
#endif

  NS_IF_ADDREF(*aFile = localDir);
  return rv;
}
Ejemplo n.º 16
0
nsresult
nsHttpTransaction::ParseHead(char *buf,
                             PRUint32 count,
                             PRUint32 *countRead)
{
    nsresult rv;
    PRUint32 len;
    char *eol;

    LOG(("nsHttpTransaction::ParseHead [count=%u]\n", count));

    *countRead = 0;

    NS_PRECONDITION(!mHaveAllHeaders, "oops");
        
    // allocate the response head object if necessary
    if (!mResponseHead) {
        mResponseHead = new nsHttpResponseHead();
        if (!mResponseHead)
            return NS_ERROR_OUT_OF_MEMORY;

        // report that we have a least some of the response
        if (mActivityDistributor)
            mActivityDistributor->ObserveActivity(
                mChannel,
                NS_HTTP_ACTIVITY_TYPE_HTTP_TRANSACTION,
                NS_HTTP_ACTIVITY_SUBTYPE_RESPONSE_START,
                PR_Now(), LL_ZERO, EmptyCString());
    }

    // if we don't have a status line and the line buf is empty, then
    // this must be the first time we've been called.
    if (!mHaveStatusLine && mLineBuf.IsEmpty()) {
        // tolerate some junk before the status line
        char *p = LocateHttpStart(buf, PR_MIN(count, 8));
        if (!p) {
            // Treat any 0.9 style response of a put as a failure.
            if (mRequestHead->Method() == nsHttp::Put)
                return NS_ERROR_ABORT;

            mResponseHead->ParseStatusLine("");
            mHaveStatusLine = PR_TRUE;
            mHaveAllHeaders = PR_TRUE;
            return NS_OK;
        }
        if (p > buf) {
            // skip over the junk
            *countRead = p - buf;
            buf = p;
        }
    }
    // otherwise we can assume that we don't have a HTTP/0.9 response.

    while ((eol = static_cast<char *>(memchr(buf, '\n', count - *countRead))) != nsnull) {
        // found line in range [buf:eol]
        len = eol - buf + 1;

        *countRead += len;

        // actually, the line is in the range [buf:eol-1]
        if ((eol > buf) && (*(eol-1) == '\r'))
            len--;

        buf[len-1] = '\n';
        rv = ParseLineSegment(buf, len);
        if (NS_FAILED(rv))
            return rv;

        if (mHaveAllHeaders)
            return NS_OK;

        // skip over line
        buf = eol + 1;
    }

    // do something about a partial header line
    if (!mHaveAllHeaders && (len = count - *countRead)) {
        *countRead = count;
        // ignore a trailing carriage return, and don't bother calling
        // ParseLineSegment if buf only contains a carriage return.
        if ((buf[len-1] == '\r') && (--len == 0))
            return NS_OK;
        rv = ParseLineSegment(buf, len);
        if (NS_FAILED(rv))
            return rv;
    }
    return NS_OK;
}
Ejemplo n.º 17
0
void
nsHttpTransaction::OnTransportStatus(nsresult status, PRUint64 progress)
{
    LOG(("nsHttpTransaction::OnSocketStatus [this=%x status=%x progress=%llu]\n",
        this, status, progress));

    if (!mTransportSink)
        return;
    
    NS_ASSERTION(PR_GetCurrentThread() == gSocketThread, "wrong thread");

    // Need to do this before the STATUS_RECEIVING_FROM check below, to make
    // sure that the activity distributor gets told about all status events.
    if (mActivityDistributor) {
        // upon STATUS_WAITING_FOR; report request body sent
        if ((mHasRequestBody) &&
            (status == nsISocketTransport::STATUS_WAITING_FOR))
            mActivityDistributor->ObserveActivity(
                mChannel,
                NS_HTTP_ACTIVITY_TYPE_HTTP_TRANSACTION,
                NS_HTTP_ACTIVITY_SUBTYPE_REQUEST_BODY_SENT,
                PR_Now(), LL_ZERO, EmptyCString());

        // report the status and progress
        mActivityDistributor->ObserveActivity(
            mChannel,
            NS_HTTP_ACTIVITY_TYPE_SOCKET_TRANSPORT,
            static_cast<PRUint32>(status),
            PR_Now(),
            progress,
            EmptyCString());
    }

    // nsHttpChannel synthesizes progress events in OnDataAvailable
    if (status == nsISocketTransport::STATUS_RECEIVING_FROM)
        return;

    PRUint64 progressMax;

    if (status == nsISocketTransport::STATUS_SENDING_TO) {
        // suppress progress when only writing request headers
        if (!mHasRequestBody)
            return;

        nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(mRequestStream);
        NS_ASSERTION(seekable, "Request stream isn't seekable?!?");

        PRInt64 prog = 0;
        seekable->Tell(&prog);
        progress = prog;

        // when uploading, we include the request headers in the progress
        // notifications.
        progressMax = mRequestSize; // XXX mRequestSize is 32-bit!
    }
    else {
        progress = LL_ZERO;
        progressMax = 0;
    }

    mTransportSink->OnTransportStatus(nsnull, status, progress, progressMax);
}
Ejemplo n.º 18
0
nsresult
CacheStorageService::AddStorageEntry(nsCSubstring const& aContextKey,
                                     nsIURI* aURI,
                                     const nsACString & aIdExtension,
                                     bool aWriteToDisk,
                                     bool aCreateIfNotExist,
                                     bool aReplace,
                                     CacheEntryHandle** aResult)
{
  NS_ENSURE_ARG(aURI);

  nsresult rv;

  nsAutoCString entryKey;
  rv = CacheEntry::HashingKey(EmptyCString(), aIdExtension, aURI, entryKey);
  NS_ENSURE_SUCCESS(rv, rv);

  LOG(("CacheStorageService::AddStorageEntry [entryKey=%s, contextKey=%s]",
    entryKey.get(), aContextKey.BeginReading()));

  nsRefPtr<CacheEntry> entry;
  nsRefPtr<CacheEntryHandle> handle;

  {
    mozilla::MutexAutoLock lock(mLock);

    NS_ENSURE_FALSE(mShutdown, NS_ERROR_NOT_INITIALIZED);

    // Ensure storage table
    CacheEntryTable* entries;
    if (!sGlobalEntryTables->Get(aContextKey, &entries)) {
      entries = new CacheEntryTable(CacheEntryTable::ALL_ENTRIES);
      sGlobalEntryTables->Put(aContextKey, entries);
      LOG(("  new storage entries table for context %s", aContextKey.BeginReading()));
    }

    bool entryExists = entries->Get(entryKey, getter_AddRefs(entry));

    // check whether the file is already doomed
    if (entryExists && entry->IsFileDoomed() && !aReplace) {
      aReplace = true;
    }

    // If truncate is demanded, delete and doom the current entry
    if (entryExists && aReplace) {
      entries->Remove(entryKey);

      LOG(("  dooming entry %p for %s because of OPEN_TRUNCATE", entry.get(), entryKey.get()));
      // On purpose called under the lock to prevent races of doom and open on I/O thread
      // No need to remove from both memory-only and all-entries tables.  The new entry
      // will overwrite the shadow entry in its ctor.
      entry->DoomAlreadyRemoved();

      entry = nullptr;
      entryExists = false;
    }

    if (entryExists && entry->SetUsingDisk(aWriteToDisk)) {
      RecordMemoryOnlyEntry(entry, !aWriteToDisk, true /* overwrite */);
    }

    // Ensure entry for the particular URL, if not read/only
    if (!entryExists && (aCreateIfNotExist || aReplace)) {
      // Entry is not in the hashtable or has just been truncated...
      entry = new CacheEntry(aContextKey, aURI, aIdExtension, aWriteToDisk);
      entries->Put(entryKey, entry);
      LOG(("  new entry %p for %s", entry.get(), entryKey.get()));
    }

    if (entry) {
      // Here, if this entry was not for a long time referenced by any consumer,
      // gets again first 'handles count' reference.
      handle = entry->NewHandle();
    }
  }

  handle.forget(aResult);
  return NS_OK;
}
Ejemplo n.º 19
0
nsresult
CacheStorageService::DoomStorageEntry(CacheStorage const* aStorage,
                                      nsIURI *aURI,
                                      const nsACString & aIdExtension,
                                      nsICacheEntryDoomCallback* aCallback)
{
  LOG(("CacheStorageService::DoomStorageEntry"));

  NS_ENSURE_ARG(aStorage);
  NS_ENSURE_ARG(aURI);

  nsAutoCString contextKey;
  CacheFileUtils::AppendKeyPrefix(aStorage->LoadInfo(), contextKey);

  nsAutoCString entryKey;
  nsresult rv = CacheEntry::HashingKey(EmptyCString(), aIdExtension, aURI, entryKey);
  NS_ENSURE_SUCCESS(rv, rv);

  nsRefPtr<CacheEntry> entry;
  {
    mozilla::MutexAutoLock lock(mLock);

    NS_ENSURE_FALSE(mShutdown, NS_ERROR_NOT_INITIALIZED);

    CacheEntryTable* entries;
    if (sGlobalEntryTables->Get(contextKey, &entries)) {
      if (entries->Get(entryKey, getter_AddRefs(entry))) {
        if (aStorage->WriteToDisk() || !entry->IsUsingDiskLocked()) {
          // When evicting from disk storage, purge
          // When evicting from memory storage and the entry is memory-only, purge
          LOG(("  purging entry %p for %s [storage use disk=%d, entry use disk=%d]",
            entry.get(), entryKey.get(), aStorage->WriteToDisk(), entry->IsUsingDiskLocked()));
          entries->Remove(entryKey);
        }
        else {
          // Otherwise, leave it
          LOG(("  leaving entry %p for %s [storage use disk=%d, entry use disk=%d]",
            entry.get(), entryKey.get(), aStorage->WriteToDisk(), entry->IsUsingDiskLocked()));
          entry = nullptr;
        }
      }
    }
  }

  if (entry) {
    LOG(("  dooming entry %p for %s", entry.get(), entryKey.get()));
    return entry->AsyncDoom(aCallback);
  }

  LOG(("  no entry loaded for %s", entryKey.get()));

  if (aStorage->WriteToDisk()) {
    nsAutoCString contextKey;
    CacheFileUtils::AppendKeyPrefix(aStorage->LoadInfo(), contextKey);

    rv = CacheEntry::HashingKey(contextKey, aIdExtension, aURI, entryKey);
    NS_ENSURE_SUCCESS(rv, rv);

    LOG(("  dooming file only for %s", entryKey.get()));

    nsRefPtr<CacheEntryDoomByKeyCallback> callback(
      new CacheEntryDoomByKeyCallback(aCallback));
    rv = CacheFileIOManager::DoomFileByKey(entryKey, callback);
    NS_ENSURE_SUCCESS(rv, rv);

    return NS_OK;
  }

  if (aCallback)
    aCallback->OnCacheEntryDoomed(NS_ERROR_NOT_AVAILABLE);

  return NS_OK;
}
static nsresult
DoContentSecurityChecks(nsIURI* aURI, nsILoadInfo* aLoadInfo)
{
  nsContentPolicyType contentPolicyType =
    aLoadInfo->GetExternalContentPolicyType();
  nsContentPolicyType internalContentPolicyType =
    aLoadInfo->InternalContentPolicyType();
  nsCString mimeTypeGuess;
  nsCOMPtr<nsINode> requestingContext = nullptr;

  switch(contentPolicyType) {
    case nsIContentPolicy::TYPE_OTHER: {
      mimeTypeGuess = EmptyCString();
      requestingContext = aLoadInfo->LoadingNode();
      break;
    }

    case nsIContentPolicy::TYPE_SCRIPT: {
      mimeTypeGuess = NS_LITERAL_CSTRING("application/javascript");
      requestingContext = aLoadInfo->LoadingNode();
      break;
    }

    case nsIContentPolicy::TYPE_IMAGE: {
      MOZ_ASSERT(false, "contentPolicyType not supported yet");
      break;
    }

    case nsIContentPolicy::TYPE_STYLESHEET: {
      mimeTypeGuess = NS_LITERAL_CSTRING("text/css");
      requestingContext = aLoadInfo->LoadingNode();
      break;
    }

    case nsIContentPolicy::TYPE_OBJECT:
    case nsIContentPolicy::TYPE_DOCUMENT: {
      MOZ_ASSERT(false, "contentPolicyType not supported yet");
      break;
    }

    case nsIContentPolicy::TYPE_SUBDOCUMENT: {
      mimeTypeGuess = NS_LITERAL_CSTRING("text/html");
      requestingContext = aLoadInfo->LoadingNode();
      MOZ_ASSERT(!requestingContext ||
                 requestingContext->NodeType() == nsIDOMNode::DOCUMENT_NODE,
                 "type_subdocument requires requestingContext of type Document");
      break;
    }

    case nsIContentPolicy::TYPE_REFRESH: {
      MOZ_ASSERT(false, "contentPolicyType not supported yet");
      break;
    }

    case nsIContentPolicy::TYPE_XBL: {
      mimeTypeGuess = EmptyCString();
      requestingContext = aLoadInfo->LoadingNode();
      break;
    }

    case nsIContentPolicy::TYPE_PING: {
      mimeTypeGuess = EmptyCString();
      requestingContext = aLoadInfo->LoadingNode();
      break;
    }

    case nsIContentPolicy::TYPE_XMLHTTPREQUEST: {
      // alias nsIContentPolicy::TYPE_DATAREQUEST:
      requestingContext = aLoadInfo->LoadingNode();
      MOZ_ASSERT(!requestingContext ||
                 requestingContext->NodeType() == nsIDOMNode::DOCUMENT_NODE,
                 "type_xml requires requestingContext of type Document");

      // We're checking for the external TYPE_XMLHTTPREQUEST here in case
      // an addon creates a request with that type.
      if (internalContentPolicyType ==
            nsIContentPolicy::TYPE_INTERNAL_XMLHTTPREQUEST ||
          internalContentPolicyType ==
            nsIContentPolicy::TYPE_XMLHTTPREQUEST) {
        mimeTypeGuess = EmptyCString();
      }
      else {
        MOZ_ASSERT(internalContentPolicyType ==
                   nsIContentPolicy::TYPE_INTERNAL_EVENTSOURCE,
                   "can not set mime type guess for unexpected internal type");
        mimeTypeGuess = NS_LITERAL_CSTRING(TEXT_EVENT_STREAM);
      }
      break;
    }

    case nsIContentPolicy::TYPE_OBJECT_SUBREQUEST: {
      mimeTypeGuess = EmptyCString();
      requestingContext = aLoadInfo->LoadingNode();
      MOZ_ASSERT(!requestingContext ||
                 requestingContext->NodeType() == nsIDOMNode::ELEMENT_NODE,
                 "type_subrequest requires requestingContext of type Element");
      break;
    }

    case nsIContentPolicy::TYPE_DTD: {
      mimeTypeGuess = EmptyCString();
      requestingContext = aLoadInfo->LoadingNode();
      MOZ_ASSERT(!requestingContext ||
                 requestingContext->NodeType() == nsIDOMNode::DOCUMENT_NODE,
                 "type_dtd requires requestingContext of type Document");
      break;
    }

    case nsIContentPolicy::TYPE_FONT: {
      mimeTypeGuess = EmptyCString();
      requestingContext = aLoadInfo->LoadingNode();
      break;
    }

    case nsIContentPolicy::TYPE_MEDIA: {
      if (internalContentPolicyType == nsIContentPolicy::TYPE_INTERNAL_TRACK) {
        mimeTypeGuess = NS_LITERAL_CSTRING("text/vtt");
      }
      else {
        mimeTypeGuess = EmptyCString();
      }
      requestingContext = aLoadInfo->LoadingNode();
      MOZ_ASSERT(!requestingContext ||
                 requestingContext->NodeType() == nsIDOMNode::ELEMENT_NODE,
                 "type_media requires requestingContext of type Element");
      break;
    }

    case nsIContentPolicy::TYPE_WEBSOCKET: {
      MOZ_ASSERT(false, "contentPolicyType not supported yet");
      break;
    }

    case nsIContentPolicy::TYPE_CSP_REPORT: {
      mimeTypeGuess = EmptyCString();
      requestingContext = aLoadInfo->LoadingNode();
      break;
    }

    case nsIContentPolicy::TYPE_XSLT: {
      mimeTypeGuess = NS_LITERAL_CSTRING("application/xml");
      requestingContext = aLoadInfo->LoadingNode();
      MOZ_ASSERT(!requestingContext ||
                 requestingContext->NodeType() == nsIDOMNode::DOCUMENT_NODE,
                 "type_xslt requires requestingContext of type Document");
      break;
    }

    case nsIContentPolicy::TYPE_BEACON: {
      mimeTypeGuess = EmptyCString();
      requestingContext = aLoadInfo->LoadingNode();
      MOZ_ASSERT(!requestingContext ||
                 requestingContext->NodeType() == nsIDOMNode::DOCUMENT_NODE,
                 "type_beacon requires requestingContext of type Document");
      break;
    }

    case nsIContentPolicy::TYPE_FETCH: {
      mimeTypeGuess = EmptyCString();
      requestingContext = aLoadInfo->LoadingNode();
      break;
    }

    case nsIContentPolicy::TYPE_IMAGESET: {
      MOZ_ASSERT(false, "contentPolicyType not supported yet");
      break;
    }

    default:
      // nsIContentPolicy::TYPE_INVALID
      MOZ_ASSERT(false, "can not perform security check without a valid contentType");
  }

  int16_t shouldLoad = nsIContentPolicy::ACCEPT;
  nsresult rv = NS_CheckContentLoadPolicy(internalContentPolicyType,
                                          aURI,
                                          aLoadInfo->LoadingPrincipal(),
                                          requestingContext,
                                          mimeTypeGuess,
                                          nullptr,        //extra,
                                          &shouldLoad,
                                          nsContentUtils::GetContentPolicy(),
                                          nsContentUtils::GetSecurityManager());
  NS_ENSURE_SUCCESS(rv, rv);
  if (NS_CP_REJECTED(shouldLoad)) {
    return NS_ERROR_CONTENT_BLOCKED;
  }
  return NS_OK;
}
Ejemplo n.º 21
0
void
nsHttpTransaction::Close(nsresult reason)
{
    LOG(("nsHttpTransaction::Close [this=%x reason=%x]\n", this, reason));

    NS_ASSERTION(PR_GetCurrentThread() == gSocketThread, "wrong thread");

    if (mClosed) {
        LOG(("  already closed\n"));
        return;
    }

    if (mActivityDistributor) {
        // report the reponse is complete if not already reported
        if (!mResponseIsComplete)
            mActivityDistributor->ObserveActivity(
                mChannel,
                NS_HTTP_ACTIVITY_TYPE_HTTP_TRANSACTION,
                NS_HTTP_ACTIVITY_SUBTYPE_RESPONSE_COMPLETE,
                PR_Now(),
                static_cast<PRUint64>(mContentRead.mValue),
                EmptyCString());

        // report that this transaction is closing
        mActivityDistributor->ObserveActivity(
            mChannel,
            NS_HTTP_ACTIVITY_TYPE_HTTP_TRANSACTION,
            NS_HTTP_ACTIVITY_SUBTYPE_TRANSACTION_CLOSE,
            PR_Now(), LL_ZERO, EmptyCString());
    }

    // we must no longer reference the connection!  find out if the 
    // connection was being reused before letting it go.
    PRBool connReused = PR_FALSE;
    if (mConnection)
        connReused = mConnection->IsReused();
    mConnected = PR_FALSE;

    //
    // if the connection was reset or closed before we wrote any part of the
    // request or if we wrote the request but didn't receive any part of the
    // response and the connection was being reused, then we can (and really
    // should) assume that we wrote to a stale connection and we must therefore
    // repeat the request over a new connection.
    //
    // NOTE: the conditions under which we will automatically retry the HTTP
    // request have to be carefully selected to avoid duplication of the
    // request from the point-of-view of the server.  such duplication could
    // have dire consequences including repeated purchases, etc.
    //
    // NOTE: because of the way SSL proxy CONNECT is implemented, it is
    // possible that the transaction may have received data without having
    // sent any data.  for this reason, mSendData == FALSE does not imply
    // mReceivedData == FALSE.  (see bug 203057 for more info.)
    //
    if (reason == NS_ERROR_NET_RESET || reason == NS_OK) {
        if (!mReceivedData && (!mSentData || connReused)) {
            // if restarting fails, then we must proceed to close the pipe,
            // which will notify the channel that the transaction failed.
            if (NS_SUCCEEDED(Restart()))
                return;
        }
    }

    PRBool relConn = PR_TRUE;
    if (NS_SUCCEEDED(reason)) {
        // the server has not sent the final \r\n terminating the header
        // section, and there may still be a header line unparsed.  let's make
        // sure we parse the remaining header line, and then hopefully, the
        // response will be usable (see bug 88792).  related to that, we may
        // also have an empty response containing no headers.  we should treat
        // that as an empty HTTP/0.9 response (see bug 300613).
        if (!mHaveAllHeaders) {
            char data = '\n';
            PRUint32 unused;
            ParseHead(&data, 1, &unused);
        }

        // honor the sticky connection flag...
        if (mCaps & NS_HTTP_STICKY_CONNECTION)
            relConn = PR_FALSE;
    }
    if (relConn && mConnection)
        NS_RELEASE(mConnection);

    mStatus = reason;
    mTransactionDone = PR_TRUE; // forcibly flag the transaction as complete
    mClosed = PR_TRUE;

    // release some resources that we no longer need
    mRequestStream = nsnull;
    mReqHeaderBuf.Truncate();
    mLineBuf.Truncate();
    if (mChunkedDecoder) {
        delete mChunkedDecoder;
        mChunkedDecoder = nsnull;
    }

    // closing this pipe triggers the channel's OnStopRequest method.
    mPipeOut->CloseWithStatus(reason);
}
Ejemplo n.º 22
0
nsresult
nsHttpTransaction::ParseHead(char *buf,
                             PRUint32 count,
                             PRUint32 *countRead)
{
    nsresult rv;
    PRUint32 len;
    char *eol;

    LOG(("nsHttpTransaction::ParseHead [count=%u]\n", count));

    *countRead = 0;

    NS_PRECONDITION(!mHaveAllHeaders, "oops");
        
    // allocate the response head object if necessary
    if (!mResponseHead) {
        mResponseHead = new nsHttpResponseHead();
        if (!mResponseHead)
            return NS_ERROR_OUT_OF_MEMORY;

        // report that we have a least some of the response
        if (mActivityDistributor)
            mActivityDistributor->ObserveActivity(
                mChannel,
                NS_HTTP_ACTIVITY_TYPE_HTTP_TRANSACTION,
                NS_HTTP_ACTIVITY_SUBTYPE_RESPONSE_START,
                PR_Now(), LL_ZERO, EmptyCString());
    }

    if (!mHttpResponseMatched) {
        // Normally we insist on seeing HTTP/1.x in the first few bytes,
        // but if we are on a persistent connection and the previous transaction
        // was not supposed to have any content then we need to be prepared
        // to skip over a response body that the server may have sent even
        // though it wasn't allowed.
        if (!mConnection || !mConnection->LastTransactionExpectedNoContent()) {
            // tolerate only minor junk before the status line
            mHttpResponseMatched = true;
            char *p = LocateHttpStart(buf, NS_MIN<PRUint32>(count, 11), true);
            if (!p) {
                // Treat any 0.9 style response of a put as a failure.
                if (mRequestHead->Method() == nsHttp::Put)
                    return NS_ERROR_ABORT;

                mResponseHead->ParseStatusLine("");
                mHaveStatusLine = true;
                mHaveAllHeaders = true;
                return NS_OK;
            }
            if (p > buf) {
                // skip over the junk
                mInvalidResponseBytesRead += p - buf;
                *countRead = p - buf;
                buf = p;
            }
        }
        else {
            char *p = LocateHttpStart(buf, count, false);
            if (p) {
                mInvalidResponseBytesRead += p - buf;
                *countRead = p - buf;
                buf = p;
                mHttpResponseMatched = true;
            } else {
                mInvalidResponseBytesRead += count;
                *countRead = count;
                if (mInvalidResponseBytesRead > MAX_INVALID_RESPONSE_BODY_SIZE) {
                    LOG(("nsHttpTransaction::ParseHead() "
                         "Cannot find Response Header\n"));
                    // cannot go back and call this 0.9 anymore as we
                    // have thrown away a lot of the leading junk
                    return NS_ERROR_ABORT;
                }
                return NS_OK;
            }
        }
    }
    // otherwise we can assume that we don't have a HTTP/0.9 response.

    NS_ABORT_IF_FALSE (mHttpResponseMatched, "inconsistent");
    while ((eol = static_cast<char *>(memchr(buf, '\n', count - *countRead))) != nsnull) {
        // found line in range [buf:eol]
        len = eol - buf + 1;

        *countRead += len;

        // actually, the line is in the range [buf:eol-1]
        if ((eol > buf) && (*(eol-1) == '\r'))
            len--;

        buf[len-1] = '\n';
        rv = ParseLineSegment(buf, len);
        if (NS_FAILED(rv))
            return rv;

        if (mHaveAllHeaders)
            return NS_OK;

        // skip over line
        buf = eol + 1;

        if (!mHttpResponseMatched) {
            // a 100 class response has caused us to throw away that set of
            // response headers and look for the next response
            return NS_ERROR_NET_INTERRUPT;
        }
    }

    // do something about a partial header line
    if (!mHaveAllHeaders && (len = count - *countRead)) {
        *countRead = count;
        // ignore a trailing carriage return, and don't bother calling
        // ParseLineSegment if buf only contains a carriage return.
        if ((buf[len-1] == '\r') && (--len == 0))
            return NS_OK;
        rv = ParseLineSegment(buf, len);
        if (NS_FAILED(rv))
            return rv;
    }
    return NS_OK;
}
Ejemplo n.º 23
0
// called on the socket thread
nsresult
nsHttpTransaction::HandleContent(char *buf,
                                 PRUint32 count,
                                 PRUint32 *contentRead,
                                 PRUint32 *contentRemaining)
{
    nsresult rv;

    LOG(("nsHttpTransaction::HandleContent [this=%x count=%u]\n", this, count));

    *contentRead = 0;
    *contentRemaining = 0;

    NS_ASSERTION(mConnection, "no connection");

    if (!mDidContentStart) {
        rv = HandleContentStart();
        if (NS_FAILED(rv)) return rv;
        // Do not write content to the pipe if we haven't started streaming yet
        if (!mDidContentStart)
            return NS_OK;
    }

    if (mChunkedDecoder) {
        // give the buf over to the chunked decoder so it can reformat the
        // data and tell us how much is really there.
        rv = mChunkedDecoder->HandleChunkedContent(buf, count, contentRead, contentRemaining);
        if (NS_FAILED(rv)) return rv;
    }
    else if (mContentLength >= nsInt64(0)) {
        // HTTP/1.0 servers have been known to send erroneous Content-Length
        // headers. So, unless the connection is persistent, we must make
        // allowances for a possibly invalid Content-Length header. Thus, if
        // NOT persistent, we simply accept everything in |buf|.
        if (mConnection->IsPersistent()) {
            nsInt64 remaining = mContentLength - mContentRead;
            nsInt64 count64 = count;
            *contentRead = PR_MIN(count64, remaining);
            *contentRemaining = count - *contentRead;
        }
        else {
            *contentRead = count;
            // mContentLength might need to be increased...
            nsInt64 position = mContentRead + nsInt64(count);
            if (position > mContentLength) {
                mContentLength = position;
                //mResponseHead->SetContentLength(mContentLength);
            }
        }
    }
    else {
        // when we are just waiting for the server to close the connection...
        // (no explicit content-length given)
        *contentRead = count;
    }

    if (*contentRead) {
        // update count of content bytes read and report progress...
        mContentRead += *contentRead;
        /* when uncommenting, take care of 64-bit integers w/ PR_MAX...
        if (mProgressSink)
            mProgressSink->OnProgress(nsnull, nsnull, mContentRead, PR_MAX(0, mContentLength));
        */
    }

    LOG(("nsHttpTransaction::HandleContent [this=%x count=%u read=%u mContentRead=%lld mContentLength=%lld]\n",
        this, count, *contentRead, mContentRead.mValue, mContentLength.mValue));

    // check for end-of-file
    if ((mContentRead == mContentLength) ||
        (mChunkedDecoder && mChunkedDecoder->ReachedEOF())) {
        // the transaction is done with a complete response.
        mTransactionDone = PR_TRUE;
        mResponseIsComplete = PR_TRUE;

        // report the entire response has arrived
        if (mActivityDistributor)
            mActivityDistributor->ObserveActivity(
                mChannel,
                NS_HTTP_ACTIVITY_TYPE_HTTP_TRANSACTION,
                NS_HTTP_ACTIVITY_SUBTYPE_RESPONSE_COMPLETE,
                PR_Now(),
                static_cast<PRUint64>(mContentRead.mValue),
                EmptyCString());
    }

    return NS_OK;
}
NS_IMETHODIMP
nsUrlClassifierStreamUpdater::DownloadUpdates(
  const nsACString &aRequestTables,
  const nsACString &aRequestBody,
  const nsACString &aUpdateUrl,
  nsIUrlClassifierCallback *aSuccessCallback,
  nsIUrlClassifierCallback *aUpdateErrorCallback,
  nsIUrlClassifierCallback *aDownloadErrorCallback,
  bool *_retval)
{
  NS_ENSURE_ARG(aSuccessCallback);
  NS_ENSURE_ARG(aUpdateErrorCallback);
  NS_ENSURE_ARG(aDownloadErrorCallback);

  if (mIsUpdating) {
    LOG(("Already updating, queueing update %s from %s", aRequestBody.Data(),
         aUpdateUrl.Data()));
    *_retval = false;
    PendingRequest *request = mPendingRequests.AppendElement();
    request->mTables = aRequestTables;
    request->mRequest = aRequestBody;
    request->mUrl = aUpdateUrl;
    request->mSuccessCallback = aSuccessCallback;
    request->mUpdateErrorCallback = aUpdateErrorCallback;
    request->mDownloadErrorCallback = aDownloadErrorCallback;
    return NS_OK;
  }

  if (aUpdateUrl.IsEmpty()) {
    NS_ERROR("updateUrl not set");
    return NS_ERROR_NOT_INITIALIZED;
  }

  nsresult rv;

  if (!mInitialized) {
    // Add an observer for shutdown so we can cancel any pending list
    // downloads.  quit-application is the same event that the download
    // manager listens for and uses to cancel pending downloads.
    nsCOMPtr<nsIObserverService> observerService =
      mozilla::services::GetObserverService();
    if (!observerService)
      return NS_ERROR_FAILURE;

    observerService->AddObserver(this, gQuitApplicationMessage, false);

    mDBService = do_GetService(NS_URLCLASSIFIERDBSERVICE_CONTRACTID, &rv);
    NS_ENSURE_SUCCESS(rv, rv);

    mInitialized = true;
  }

  rv = mDBService->BeginUpdate(this, aRequestTables);
  if (rv == NS_ERROR_NOT_AVAILABLE) {
    LOG(("Service busy, already updating, queuing update %s from %s",
         aRequestBody.Data(), aUpdateUrl.Data()));
    *_retval = false;
    PendingRequest *request = mPendingRequests.AppendElement();
    request->mTables = aRequestTables;
    request->mRequest = aRequestBody;
    request->mUrl = aUpdateUrl;
    request->mSuccessCallback = aSuccessCallback;
    request->mUpdateErrorCallback = aUpdateErrorCallback;
    request->mDownloadErrorCallback = aDownloadErrorCallback;
    return NS_OK;
  }

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

  mSuccessCallback = aSuccessCallback;
  mUpdateErrorCallback = aUpdateErrorCallback;
  mDownloadErrorCallback = aDownloadErrorCallback;

  mIsUpdating = true;
  *_retval = true;

  LOG(("FetchUpdate: %s", aUpdateUrl.Data()));
  //LOG(("requestBody: %s", aRequestBody.Data()));

  return FetchUpdate(aUpdateUrl, aRequestBody, EmptyCString());
}
Ejemplo n.º 25
0
nsresult nsMsgTagService::MigrateLabelsToTags()
{
  nsCString prefString;

  int32_t prefVersion = 0;
  nsresult rv = m_tagPrefBranch->GetIntPref(TAG_PREF_VERSION, &prefVersion);
  if (NS_SUCCEEDED(rv) && prefVersion > 1)
    return rv;
  else if (prefVersion == 1)
  {
    gMigratingKeys = true;
  // need to convert the keys to lower case
    nsIMsgTag **tagArray;
    uint32_t numTags;
    GetAllTags(&numTags, &tagArray);
    for (uint32_t tagIndex = 0; tagIndex < numTags; tagIndex++)
    {
      nsCAutoString key, color, ordinal;
      nsAutoString tagStr;
      nsIMsgTag *tag = tagArray[tagIndex];
      tag->GetKey(key);
      tag->GetTag(tagStr);
      tag->GetOrdinal(ordinal);
      tag->GetColor(color);
      DeleteKey(key);
      ToLowerCase(key);
      AddTagForKey(key, tagStr, color, ordinal);
    }
    NS_FREE_XPCOM_ISUPPORTS_POINTER_ARRAY(numTags, tagArray);
    gMigratingKeys = false;
  }
  else 
  {
    nsCOMPtr<nsIPrefBranch> prefRoot(do_GetService(NS_PREFSERVICE_CONTRACTID));
    nsCOMPtr<nsIPrefLocalizedString> pls;
    nsString ucsval;
    nsCAutoString labelKey("$label1");
    for(int32_t i = 0; i < PREF_LABELS_MAX; )
    {
      prefString.Assign(PREF_LABELS_DESCRIPTION);
      prefString.AppendInt(i + 1);
      rv = prefRoot->GetComplexValue(prefString.get(),
                                     NS_GET_IID(nsIPrefLocalizedString),
                                     getter_AddRefs(pls));
      NS_ENSURE_SUCCESS(rv, rv);
      pls->ToString(getter_Copies(ucsval));

      prefString.Assign(PREF_LABELS_COLOR);
      prefString.AppendInt(i + 1);
      nsCString csval;
      rv = prefRoot->GetCharPref(prefString.get(), getter_Copies(csval));
      NS_ENSURE_SUCCESS(rv, rv);

      rv = AddTagForKey(labelKey, ucsval, csval, EmptyCString());
      NS_ENSURE_SUCCESS(rv, rv);
      labelKey.SetCharAt(++i + '1', 6);
    }
  }
  m_tagPrefBranch->SetIntPref(TAG_PREF_VERSION, 2);
  return rv;
}
Ejemplo n.º 26
0
bool
InternalHeaders::IsForbiddenRequestNoCorsHeader(const nsACString& aName) const
{
  return mGuard == HeadersGuardEnum::Request_no_cors &&
         !IsSimpleHeader(aName, EmptyCString());
}
Ejemplo n.º 27
0
void
SVGAElement::GetReferrerPolicy(nsAString& aPolicy)
{
  GetEnumAttr(nsGkAtoms::referrerpolicy, EmptyCString().get(), aPolicy);
}
nsresult
nsNetscapeProfileMigratorBase::GetProfileDataFromProfilesIni(nsILocalFile* aDataDir,
                                                             nsIMutableArray* aProfileNames,
                                                             nsIMutableArray* aProfileLocations)
{
  nsCOMPtr<nsIFile> dataDir;
  nsresult rv = aDataDir->Clone(getter_AddRefs(dataDir));
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<nsILocalFile> profileIni(do_QueryInterface(dataDir, &rv));
  NS_ENSURE_SUCCESS(rv, rv);

  profileIni->Append(NS_LITERAL_STRING("profiles.ini"));

  // Does it exist?
  bool profileFileExists = false;
  rv = profileIni->Exists(&profileFileExists);
  NS_ENSURE_SUCCESS(rv, rv);

  if (!profileFileExists)
    return NS_ERROR_FILE_NOT_FOUND;

  nsINIParser parser;
  rv = parser.Init(profileIni);
  NS_ENSURE_SUCCESS(rv, rv);

  nsCAutoString buffer, filePath;
  bool isRelative;

  // This is an infinite loop that is broken when we no longer find profiles
  // for profileID with IsRelative option.
  for (unsigned int c = 0; true; ++c) {
    nsCAutoString profileID("Profile");
    profileID.AppendInt(c);

    if (NS_FAILED(parser.GetString(profileID.get(), "IsRelative", buffer)))
      break;

    isRelative = buffer.EqualsLiteral("1");

    rv = parser.GetString(profileID.get(), "Path", filePath);
    if (NS_FAILED(rv)) {
      NS_ERROR("Malformed profiles.ini: Path= not found");
      continue;
    }

    rv = parser.GetString(profileID.get(), "Name", buffer);
    if (NS_FAILED(rv)) {
      NS_ERROR("Malformed profiles.ini: Name= not found");
      continue;
    }

    nsCOMPtr<nsILocalFile> rootDir;
    rv = NS_NewNativeLocalFile(EmptyCString(), true, getter_AddRefs(rootDir));
    NS_ENSURE_SUCCESS(rv, rv);

    rv = isRelative ? rootDir->SetRelativeDescriptor(aDataDir, filePath) :
                      rootDir->SetPersistentDescriptor(filePath);
    if (NS_FAILED(rv))
      continue;

    bool exists = false;
    rootDir->Exists(&exists);

    if (exists) {
      aProfileLocations->AppendElement(rootDir, false);

      nsCOMPtr<nsISupportsString> profileNameString(
        do_CreateInstance("@mozilla.org/supports-string;1"));

      profileNameString->SetData(NS_ConvertUTF8toUTF16(buffer));
      aProfileNames->AppendElement(profileNameString, false);
    }
  }
  return NS_OK;
}
Ejemplo n.º 29
0
NS_IMETHODIMP
InterceptedChannelBase::SaveTimeStamps()
{
  MOZ_ASSERT(NS_IsMainThread());

  nsCOMPtr<nsIChannel> underlyingChannel;
  nsresult rv = GetChannel(getter_AddRefs(underlyingChannel));
  MOZ_ASSERT(NS_SUCCEEDED(rv));

  nsCOMPtr<nsITimedChannel> timedChannel =
    do_QueryInterface(underlyingChannel);
  MOZ_ASSERT(timedChannel);

  rv = timedChannel->SetLaunchServiceWorkerStart(mLaunchServiceWorkerStart);
  MOZ_ASSERT(NS_SUCCEEDED(rv));

  rv = timedChannel->SetLaunchServiceWorkerEnd(mLaunchServiceWorkerEnd);
  MOZ_ASSERT(NS_SUCCEEDED(rv));

  rv = timedChannel->SetDispatchFetchEventStart(mDispatchFetchEventStart);
  MOZ_ASSERT(NS_SUCCEEDED(rv));

  rv = timedChannel->SetDispatchFetchEventEnd(mDispatchFetchEventEnd);
  MOZ_ASSERT(NS_SUCCEEDED(rv));

  rv = timedChannel->SetHandleFetchEventStart(mHandleFetchEventStart);
  MOZ_ASSERT(NS_SUCCEEDED(rv));

  rv = timedChannel->SetHandleFetchEventEnd(mHandleFetchEventEnd);
  MOZ_ASSERT(NS_SUCCEEDED(rv));

  nsCOMPtr<nsIChannel> channel;
  GetChannel(getter_AddRefs(channel));
  if (NS_WARN_IF(!channel)) {
    return NS_ERROR_FAILURE;
  }

  bool isNonSubresourceRequest = nsContentUtils::IsNonSubresourceRequest(channel);
  nsCString navigationOrSubresource = isNonSubresourceRequest ?
    NS_LITERAL_CSTRING("navigation") : NS_LITERAL_CSTRING("subresource");

  nsAutoCString subresourceKey(EmptyCString());
  GetSubresourceTimeStampKey(channel, subresourceKey);

  // We may have null timestamps if the fetch dispatch runnable was cancelled
  // and we defaulted to resuming the request.
  if (!mFinishResponseStart.IsNull() && !mFinishResponseEnd.IsNull()) {
    MOZ_ASSERT(mSynthesizedOrReset != Invalid);

    Telemetry::HistogramID id = (mSynthesizedOrReset == Synthesized) ?
      Telemetry::SERVICE_WORKER_FETCH_EVENT_FINISH_SYNTHESIZED_RESPONSE_MS :
      Telemetry::SERVICE_WORKER_FETCH_EVENT_CHANNEL_RESET_MS;
    Telemetry::Accumulate(id, navigationOrSubresource,
      static_cast<uint32_t>((mFinishResponseEnd - mFinishResponseStart).ToMilliseconds()));
    if (!isNonSubresourceRequest && !subresourceKey.IsEmpty()) {
      Telemetry::Accumulate(id, subresourceKey,
        static_cast<uint32_t>((mFinishResponseEnd - mFinishResponseStart).ToMilliseconds()));
    }
  }

  Telemetry::Accumulate(Telemetry::SERVICE_WORKER_FETCH_EVENT_DISPATCH_MS,
    navigationOrSubresource,
    static_cast<uint32_t>((mHandleFetchEventStart - mDispatchFetchEventStart).ToMilliseconds()));

  if (!isNonSubresourceRequest && !subresourceKey.IsEmpty()) {
    Telemetry::Accumulate(Telemetry::SERVICE_WORKER_FETCH_EVENT_DISPATCH_MS,
      subresourceKey,
      static_cast<uint32_t>((mHandleFetchEventStart - mDispatchFetchEventStart).ToMilliseconds()));
  }

  if (!mFinishResponseEnd.IsNull()) {
    Telemetry::Accumulate(Telemetry::SERVICE_WORKER_FETCH_INTERCEPTION_DURATION_MS,
      navigationOrSubresource,
      static_cast<uint32_t>((mFinishResponseEnd - mDispatchFetchEventStart).ToMilliseconds()));
    if (!isNonSubresourceRequest && !subresourceKey.IsEmpty()) {
      Telemetry::Accumulate(Telemetry::SERVICE_WORKER_FETCH_INTERCEPTION_DURATION_MS,
        subresourceKey,
        static_cast<uint32_t>((mFinishResponseEnd - mDispatchFetchEventStart).ToMilliseconds()));
    }
  }

  return rv;
}
Ejemplo n.º 30
0
NS_IMETHODIMP
nsSmtpServer::GetPassword(nsACString& aPassword)
{
    if (m_password.IsEmpty() && !m_logonFailed)
    {
      // try to avoid prompting the user for another password. If the user has set
      // the appropriate pref, we'll use the password from an incoming server, if
      // the user has already logged onto that server.

      // if this is set, we'll only use this, and not the other prefs
      // user_pref("mail.smtpserver.smtp1.incomingAccount", "server1");

      // if this is set, we'll accept an exact match of user name and server
      // user_pref("mail.smtp.useMatchingHostNameServer", true);

      // if this is set, and we don't find an exact match of user and host name,
      // we'll accept a match of username and domain, where domain
      // is everything after the first '.'
      // user_pref("mail.smtp.useMatchingDomainServer", true);

      nsCString accountKey;
      bool useMatchingHostNameServer = false;
      bool useMatchingDomainServer = false;
      mPrefBranch->GetCharPref("incomingAccount", getter_Copies(accountKey));

      nsCOMPtr<nsIMsgAccountManager> accountManager = do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID);
      nsCOMPtr<nsIMsgIncomingServer> incomingServerToUse;
      if (accountManager)
      {
        if (!accountKey.IsEmpty())
          accountManager->GetIncomingServer(accountKey, getter_AddRefs(incomingServerToUse));
        else
        {
          nsresult rv;
          nsCOMPtr<nsIPrefBranch> prefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
          NS_ENSURE_SUCCESS(rv,rv);
          prefBranch->GetBoolPref("mail.smtp.useMatchingHostNameServer", &useMatchingHostNameServer);
          prefBranch->GetBoolPref("mail.smtp.useMatchingDomainServer", &useMatchingDomainServer);
          if (useMatchingHostNameServer || useMatchingDomainServer)
          {
            nsCString userName;
            nsCString hostName;
            GetHostname(hostName);
            GetUsername(userName);
            if (useMatchingHostNameServer)
              // pass in empty type and port=0, to match imap and pop3.
              accountManager->FindRealServer(userName, hostName, EmptyCString(), 0, getter_AddRefs(incomingServerToUse));
            int32_t dotPos = -1;
            if (!incomingServerToUse && useMatchingDomainServer
              && (dotPos = hostName.FindChar('.')) != kNotFound)
            {
              hostName.Cut(0, dotPos);
              nsCOMPtr<nsISupportsArray> allServers;
              accountManager->GetAllServers(getter_AddRefs(allServers));
              if (allServers)
              {
                uint32_t count = 0;
                allServers->Count(&count);
                uint32_t i;
                for (i = 0; i < count; i++)
                {
                  nsCOMPtr<nsIMsgIncomingServer> server = do_QueryElementAt(allServers, i);
                  if (server)
                  {
                    nsCString serverUserName;
                    nsCString serverHostName;
                    server->GetRealUsername(serverUserName);
                    server->GetRealHostName(serverHostName);
                    if (serverUserName.Equals(userName))
                    {
                      int32_t serverDotPos = serverHostName.FindChar('.');
                      if (serverDotPos != kNotFound)
                      {
                        serverHostName.Cut(0, serverDotPos);
                        if (serverHostName.Equals(hostName))
                        {
                          incomingServerToUse = server;
                          break;
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
      if (incomingServerToUse)
        return incomingServerToUse->GetPassword(aPassword);
    }
    aPassword = m_password;
    return NS_OK;
}