nsresult
nsUnixSystemProxySettings::SetProxyResultFromGSettings(const char* aKeyBase, const char* aType,
                                                       nsACString& aResult)
{
  nsDependentCString key(aKeyBase);

  nsCOMPtr<nsIGSettingsCollection> proxy_settings = mSchemeProxySettings.Get(key);
  nsresult rv;
  if (!proxy_settings) {
    rv = mGSettings->GetCollectionForSchema(key, getter_AddRefs(proxy_settings));
    NS_ENSURE_SUCCESS(rv, rv);

    mSchemeProxySettings.Put(key, proxy_settings);
  }

  nsAutoCString host;
  rv = proxy_settings->GetString(NS_LITERAL_CSTRING("host"), host);
  NS_ENSURE_SUCCESS(rv, rv);
  if (host.IsEmpty())
    return NS_ERROR_FAILURE;
  
  int32_t port;
  rv = proxy_settings->GetInt(NS_LITERAL_CSTRING("port"), &port);
  NS_ENSURE_SUCCESS(rv, rv);
    
  /* When port is 0, proxy is not considered as enabled even if host is set. */
  if (port == 0)
    return NS_ERROR_FAILURE;

  SetProxyResult(aType, host, port, aResult);
  return NS_OK;
}
nsresult
nsUnixSystemProxySettings::SetProxyResultFromGConf(const char* aKeyBase, const char* aType,
                                                   nsACString& aResult)
{
  nsAutoCString hostKey;
  hostKey.AppendASCII(aKeyBase);
  hostKey.AppendLiteral("host");
  nsAutoCString host;
  nsresult rv = mGConf->GetString(hostKey, host);
  NS_ENSURE_SUCCESS(rv, rv);
  if (host.IsEmpty())
    return NS_ERROR_FAILURE;
  
  nsAutoCString portKey;
  portKey.AppendASCII(aKeyBase);
  portKey.AppendLiteral("port");
  int32_t port;
  rv = mGConf->GetInt(portKey, &port);
  NS_ENSURE_SUCCESS(rv, rv);

  /* When port is 0, proxy is not considered as enabled even if host is set. */
  if (port == 0)
    return NS_ERROR_FAILURE;

  SetProxyResult(aType, host, port, aResult);
  return NS_OK;
}
static nsresult
GetProxyFromEnvironment(const nsACString& aScheme,
                        const nsACString& aHost,
                        PRInt32 aPort,
                        nsACString& aResult)
{
  nsCAutoString envVar;
  envVar.Append(aScheme);
  envVar.AppendLiteral("_proxy");
  const char* proxyVal = PR_GetEnv(envVar.get());
  if (!proxyVal) {
    proxyVal = PR_GetEnv("all_proxy");
    if (!proxyVal) {
      // Return failure so that the caller can detect the failure and
      // fall back to other proxy detection (e.g., WPAD)
      return NS_ERROR_FAILURE;
    }
  }
  
  const char* noProxyVal = PR_GetEnv("no_proxy");
  if (noProxyVal && IsInNoProxyList(aHost, aPort, noProxyVal)) {
    aResult.AppendLiteral("DIRECT");
    return NS_OK;
  }
  
  // Use our URI parser to crack the proxy URI
  nsCOMPtr<nsIURI> proxyURI;
  nsresult rv = NS_NewURI(getter_AddRefs(proxyURI), proxyVal);
  NS_ENSURE_SUCCESS(rv, rv);

  // Is there a way to specify "socks://" or something in these environment
  // variables? I can't find any documentation.
  PRBool isHTTP;
  rv = proxyURI->SchemeIs("http", &isHTTP);
  NS_ENSURE_SUCCESS(rv, rv);
  if (!isHTTP)
    return NS_ERROR_UNKNOWN_PROTOCOL;

  nsCAutoString proxyHost;
  rv = proxyURI->GetHost(proxyHost);
  NS_ENSURE_SUCCESS(rv, rv);

  PRInt32 proxyPort;
  rv = proxyURI->GetPort(&proxyPort);
  NS_ENSURE_SUCCESS(rv, rv);

  SetProxyResult("PROXY", proxyHost, proxyPort, aResult);
  return NS_OK;
}
static void SetProxyResult(const char* aType, const nsACString& aHostPort,
                           nsACString& aResult)
{
    nsCOMPtr<nsIURI> uri;
    nsCAutoString host;
    PRInt32 port;

    // Try parsing it as a URI.
    if (NS_SUCCEEDED(NS_NewURI(getter_AddRefs(uri), aHostPort)) &&
        NS_SUCCEEDED(uri->GetHost(host)) && !host.IsEmpty() &&
        NS_SUCCEEDED(uri->GetPort(&port))) {
        SetProxyResult(aType, host, port, aResult);
    } else {
        aResult.AssignASCII(aType);
        aResult.Append(' ');
        aResult.Append(aHostPort);
    }
}
nsresult
nsUnixSystemProxySettings::SetProxyResultFromGConf(const char* aKeyBase, const char* aType,
                                                   nsACString& aResult)
{
  nsCAutoString hostKey;
  hostKey.AppendASCII(aKeyBase);
  hostKey.AppendLiteral("host");
  nsCAutoString host;
  nsresult rv = mGConf->GetString(hostKey, host);
  NS_ENSURE_SUCCESS(rv, rv);
  if (host.IsEmpty())
    return NS_ERROR_FAILURE;
  
  nsCAutoString portKey;
  portKey.AppendASCII(aKeyBase);
  portKey.AppendLiteral("port");
  PRInt32 port;
  rv = mGConf->GetInt(portKey, &port);
  NS_ENSURE_SUCCESS(rv, rv);
    
  SetProxyResult(aType, host, port, aResult);
  return NS_OK;
}