int main(int argc, char **argv) { int i; char url[102400]; // Should be plently long for most URLs char **proxies; /* Create the proxy factory object */ pxProxyFactory *pf = px_proxy_factory_new(); if (!pf) { fprintf(stderr, "An unknown error occurred!\n"); return 1; } /* User entered some arguments on startup. skip interactive */ if (argc > 1) { for (i=1; i < argc ; i++) { /* * Get an array of proxies to use. These should be used * in the order returned. Only move on to the next proxy * if the first one fails (etc). */ proxies = px_proxy_factory_get_proxies(pf, argv[i]); print_proxies(proxies); px_proxy_factory_free_proxies(proxies); } } /* Interactive mode */ else { /* For each URL we read on STDIN, get the proxies to use */ for (url[0] = '\0' ; fgets(url, 102400, stdin) != NULL ; ) { if (url[strlen(url)-1] == '\n') url[strlen(url)-1] = '\0'; /* * Get an array of proxies to use. These should be used * in the order returned. Only move on to the next proxy * if the first one fails (etc). */ proxies = px_proxy_factory_get_proxies(pf, url); print_proxies(proxies); px_proxy_factory_free_proxies(proxies); } } /* Destroy the proxy factory object */ px_proxy_factory_free(pf); return 0; }
static void get_libproxy_proxies (GTask *task, gpointer source_object, gpointer task_data, GCancellable *cancellable) { GLibProxyResolver *resolver = source_object; const gchar *uri = task_data; GError *error = NULL; gchar **proxies; if (g_task_return_error_if_cancelled (task)) return; proxies = px_proxy_factory_get_proxies (resolver->factory, uri); if (proxies) { /* We always copy to be able to translate "socks" entry into * three entries ("socks5", "socks4a", "socks4"). */ g_task_return_pointer (task, copy_proxies (proxies), (GDestroyNotify) g_strfreev); free_libproxy_proxies (proxies); } else { g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_FAILED, _("Proxy resolver internal error.")); g_task_return_error (task, error); } }
nsresult nsUnixSystemProxySettings::GetProxyForURI(const nsACString & aSpec, const nsACString & aScheme, const nsACString & aHost, const int32_t aPort, nsACString & aResult) { nsresult rv; if (!mProxyFactory) { mProxyFactory = px_proxy_factory_new(); } NS_ENSURE_TRUE(mProxyFactory, NS_ERROR_NOT_AVAILABLE); char **proxyArray = nullptr; proxyArray = px_proxy_factory_get_proxies(mProxyFactory, PromiseFlatCString(aSpec).get()); NS_ENSURE_TRUE(proxyArray, NS_ERROR_NOT_AVAILABLE); // Translate libproxy's output to PAC string as expected // libproxy returns an array of proxies in the format: // <procotol>://[username:password@]proxy:port // or // direct:// // // PAC format: "PROXY proxy1.foo.com:8080; PROXY proxy2.foo.com:8080; DIRECT" // but nsISystemProxySettings allows "PROXY http://proxy.foo.com:8080" as well. int c = 0; while (proxyArray[c] != nullptr) { if (!aResult.IsEmpty()) { aResult.AppendLiteral("; "); } // figure out the scheme, and we can't use nsIIOService::NewURI because // this is not the main thread. char *colon = strchr (proxyArray[c], ':'); uint32_t schemelen = colon ? colon - proxyArray[c] : 0; if (schemelen < 1) { c++; continue; } if (schemelen == 6 && !strncasecmp(proxyArray[c], "direct", 6)) { aResult.AppendLiteral("DIRECT"); } else { aResult.AppendLiteral("PROXY "); aResult.Append(proxyArray[c]); } c++; } PR_Free(proxyArray); return NS_OK; }
static const void* perform_ocsp_request(char* url, void* data, long datlen, long* retlen, void** handle) { CURL *curl; CURLcode curl_res; struct curl_slist *list = NULL; char** proxies = px_proxy_factory_get_proxies(pf, url); int i; struct recvdata *dat; void* retval; dat = calloc(sizeof(struct recvdata), 1); curl_slist_append(list, "Content-Type: application/ocsp-request"); curl = curl_easy_init(); curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_POST, (long)1); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data); curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, datlen); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, appendmem); curl_easy_setopt(curl, CURLOPT_WRITEDATA, dat); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list); i=0; do { if((curl_res = curl_easy_perform(curl)) != CURLE_OK) { uilog(EID_VWR_LOG_COARSE, "Could not perform OCSP request (with proxy: %s): %s", proxies[i] ? "none" : proxies[i], curl_easy_strerror(curl_res)); } if(!strcmp(proxies[i], "direct://")) { // skip that i++; } if(proxies[i] == NULL) { curl_easy_setopt(curl, CURLOPT_PROXY, ""); } else { curl_easy_setopt(curl, CURLOPT_PROXY, proxies[i]); } } while(proxies[i++] != NULL && curl_res != CURLE_OK); for(i=0; proxies[i]; i++) { free(proxies[i]); } free(proxies); if(curl_res != CURLE_OK) { free(dat->data); dat->len = 0; dat->data = NULL; } retval = dat->data; *retlen = dat->len; free(dat); curl_easy_cleanup(curl); curl_slist_free_all(list); *handle = retval; return retval; }
static guint get_proxy_for_uri (SoupURI *uri, SoupURI **proxy_uri) { char *uristr, **proxies; gboolean got_proxy; int i; *proxy_uri = NULL; /* resolver_gnome is locked */ uristr = soup_uri_to_string (uri, FALSE); proxies = px_proxy_factory_get_proxies (libproxy_factory, uristr); g_free (uristr); if (!proxies) return SOUP_STATUS_OK; got_proxy = FALSE; for (i = 0; proxies[i]; i++) { if (!strcmp (proxies[i], "direct://")) { got_proxy = TRUE; break; } if (strncmp (proxies[i], "http://", 7) == 0) { *proxy_uri = soup_uri_new (proxies[i]); got_proxy = TRUE; break; } } for (i = 0; proxies[i]; i++) free (proxies[i]); free (proxies); if (got_proxy) { if (*proxy_uri && proxy_user) { soup_uri_set_user (*proxy_uri, proxy_user); soup_uri_set_password (*proxy_uri, proxy_password); } return SOUP_STATUS_OK; } else return SOUP_STATUS_CANT_RESOLVE_PROXY; }
int main(int argc, char *argv[]) { pxProxyFactory *pf; int i; if (argc < 2) { printf("Usage: %s <url> [url*]\n", argv[0]); return 1; } pf = px_proxy_factory_new(); if (!pf) { fprintf(stderr, "Failed to create proxy factory\n"); return 1; } for (i = 1; i < argc; i++) { char **result; int n; result = px_proxy_factory_get_proxies(pf, argv[i]); if (!result) { fprintf(stderr, "Failed to get proxy for %s\n", argv[i]); continue; } for (n = 0; result[n]; n++) { printf("%s%s", result[n], result[n + 1] ? " " : "\n"); free(result[n]); } free(result); } px_proxy_factory_free(pf); return 0; }
int connect_https_socket(struct openconnect_info *vpninfo) { int ssl_sock = -1; int err; if (!vpninfo->port) vpninfo->port = 443; if (vpninfo->peer_addr) { reconnect: #ifdef SOCK_CLOEXEC ssl_sock = socket(vpninfo->peer_addr->sa_family, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_IP); if (ssl_sock < 0) #endif { ssl_sock = socket(vpninfo->peer_addr->sa_family, SOCK_STREAM, IPPROTO_IP); if (ssl_sock < 0) goto reconn_err; set_fd_cloexec(ssl_sock); } if (cancellable_connect(vpninfo, ssl_sock, vpninfo->peer_addr, vpninfo->peer_addrlen)) { reconn_err: if (vpninfo->proxy) { vpn_progress(vpninfo, PRG_ERR, _("Failed to reconnect to proxy %s\n"), vpninfo->proxy); } else { vpn_progress(vpninfo, PRG_ERR, _("Failed to reconnect to host %s\n"), vpninfo->hostname); } if (ssl_sock >= 0) closesocket(ssl_sock); return -EINVAL; } } else { struct addrinfo hints, *result, *rp; char *hostname; char port[6]; memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV; hints.ai_protocol = 0; hints.ai_canonname = NULL; hints.ai_addr = NULL; hints.ai_next = NULL; /* The 'port' variable is a string because it's easier this way than if we pass NULL to getaddrinfo() and then try to fill in the numeric value into different types of returned sockaddr_in{6,}. */ #ifdef LIBPROXY_HDR if (vpninfo->proxy_factory) { char *url; char **proxies; int i = 0; free(vpninfo->proxy_type); vpninfo->proxy_type = NULL; free(vpninfo->proxy); vpninfo->proxy = NULL; if (vpninfo->port == 443) i = asprintf(&url, "https://%s/%s", vpninfo->hostname, vpninfo->urlpath?:""); else i = asprintf(&url, "https://%s:%d/%s", vpninfo->hostname, vpninfo->port, vpninfo->urlpath?:""); if (i == -1) return -ENOMEM; proxies = px_proxy_factory_get_proxies(vpninfo->proxy_factory, url); i = 0; while (proxies && proxies[i]) { if (!vpninfo->proxy && (!strncmp(proxies[i], "http://", 7) || !strncmp(proxies[i], "socks://", 8) || !strncmp(proxies[i], "socks5://", 9))) internal_parse_url(proxies[i], &vpninfo->proxy_type, &vpninfo->proxy, &vpninfo->proxy_port, NULL, 0); i++; } free(url); free(proxies); if (vpninfo->proxy) vpn_progress(vpninfo, PRG_DEBUG, _("Proxy from libproxy: %s://%s:%d/\n"), vpninfo->proxy_type, vpninfo->proxy, vpninfo->port); }
void ne_session_system_proxy(ne_session *sess, unsigned int flags) { #ifdef HAVE_LIBPROXY pxProxyFactory *pxf = px_proxy_factory_new(); struct host_info *hi, **lasthi; char *url, **proxies; ne_uri uri; unsigned n; free_proxies(sess); /* Create URI for session to pass off to libproxy */ memset(&uri, 0, sizeof uri); ne_fill_server_uri(sess, &uri); uri.path = "/"; /* make valid URI structure. */ url = ne_uri_unparse(&uri); uri.path = NULL; /* Get list of pseudo-URIs from libproxy: */ proxies = px_proxy_factory_get_proxies(pxf, url); for (n = 0, lasthi = &sess->proxies; proxies[n]; n++) { enum proxy_type ptype; ne_uri_free(&uri); NE_DEBUG(NE_DBG_HTTP, "sess: libproxy #%u=%s\n", n, proxies[n]); if (ne_uri_parse(proxies[n], &uri)) continue; if (!uri.scheme) continue; if (ne_strcasecmp(uri.scheme, "http") == 0) ptype = PROXY_HTTP; else if (ne_strcasecmp(uri.scheme, "socks") == 0) ptype = PROXY_SOCKS; else if (ne_strcasecmp(uri.scheme, "direct") == 0) ptype = PROXY_NONE; else continue; /* Hostname/port required for http/socks schemes. */ if (ptype != PROXY_NONE && !(uri.host && uri.port)) continue; /* Do nothing if libproxy returned only a single "direct://" * entry -- a single "direct" (noop) proxy is equivalent to * having none. */ if (n == 0 && proxies[1] == NULL && ptype == PROXY_NONE) break; NE_DEBUG(NE_DBG_HTTP, "sess: Got proxy %s://%s:%d\n", uri.scheme, uri.host ? uri.host : "(none)", uri.port); hi = *lasthi = ne_calloc(sizeof *hi); if (ptype == PROXY_NONE) { /* A "direct" URI requires an attempt to connect directly to * the origin server, so dup the server details. */ set_hostinfo(hi, ptype, sess->server.hostname, sess->server.port); } else { /* SOCKS/HTTP proxy. */ set_hostinfo(hi, ptype, uri.host, uri.port); if (ptype == PROXY_HTTP) sess->any_proxy_http = 1; else if (ptype == PROXY_SOCKS) sess->socks_ver = NE_SOCK_SOCKSV5; } lasthi = &hi->next; } /* Free up the proxies array: */ for (n = 0; proxies[n]; n++) free(proxies[n]); free(proxies[n]); ne_free(url); ne_uri_free(&uri); px_proxy_factory_free(pxf); #endif }
int trg_client_populate_with_settings(TrgClient * tc) { TrgClientPrivate *priv = tc->priv; TrgPrefs *prefs = priv->prefs; gint port; gchar *host, *path; #ifdef HAVE_LIBPROXY pxProxyFactory *pf = NULL; #endif g_mutex_lock(&priv->configMutex); trg_prefs_set_connection(prefs, trg_prefs_get_profile(prefs)); g_free(priv->url); priv->url = NULL; g_free(priv->username); priv->username = NULL; g_free(priv->password); priv->password = NULL; port = trg_prefs_get_int(prefs, TRG_PREFS_KEY_PORT, TRG_PREFS_CONNECTION); host = trg_prefs_get_string(prefs, TRG_PREFS_KEY_HOSTNAME, TRG_PREFS_CONNECTION); path = trg_prefs_get_string(prefs, TRG_PREFS_KEY_RPC_URL_PATH, TRG_PREFS_CONNECTION); if (!host || strlen(host) < 1) { g_free(host); g_mutex_unlock(&priv->configMutex); return TRG_NO_HOSTNAME_SET; } #ifndef CURL_NO_SSL priv->ssl = trg_prefs_get_bool(prefs, TRG_PREFS_KEY_SSL, TRG_PREFS_CONNECTION); priv->ssl_validate = trg_prefs_get_bool(prefs, TRG_PREFS_KEY_SSL_VALIDATE, TRG_PREFS_CONNECTION); #else priv->ssl = FALSE; #endif priv->url = g_strdup_printf("%s://%s:%d%s", priv->ssl ? HTTPS_URI_PREFIX : HTTP_URI_PREFIX, host, port, path); g_free(host); g_free(path); priv->username = trg_prefs_get_string(prefs, TRG_PREFS_KEY_USERNAME, TRG_PREFS_CONNECTION); priv->password = trg_prefs_get_string(prefs, TRG_PREFS_KEY_PASSWORD, TRG_PREFS_CONNECTION); g_free(priv->proxy); priv->proxy = NULL; #ifdef HAVE_LIBPROXY if ((pf = px_proxy_factory_new())) { char **proxies = px_proxy_factory_get_proxies(pf, priv->url); int i; for (i = 0; proxies[i]; i++) { if (g_str_has_prefix(proxies[i], HTTP_URI_PREFIX) || g_str_has_prefix(proxies[i], HTTPS_URI_PREFIX)) { g_free(priv->proxy); priv->proxy = proxies[i]; } else { g_free(proxies[i]); } } g_free(proxies); px_proxy_factory_free(pf); } #endif priv->configSerial++; g_mutex_unlock(&priv->configMutex); return 0; }
int connect_https_socket(struct openconnect_info *vpninfo) { int ssl_sock = -1; int err; if (!vpninfo->port) vpninfo->port = 443; /* If we're talking to a server which told us it has dynamic DNS, don't just re-use its previous IP address. If we're talking to a proxy, we can use *its* previous IP address. We expect it'll re-do the DNS lookup for the server anyway. */ if (vpninfo->peer_addr && (!vpninfo->is_dyndns || vpninfo->proxy)) { reconnect: #ifdef SOCK_CLOEXEC ssl_sock = socket(vpninfo->peer_addr->sa_family, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_IP); if (ssl_sock < 0) #endif { ssl_sock = socket(vpninfo->peer_addr->sa_family, SOCK_STREAM, IPPROTO_IP); if (ssl_sock < 0) { #ifdef _WIN32 err = WSAGetLastError(); #else err = -errno; #endif goto reconn_err; } set_fd_cloexec(ssl_sock); } err = cancellable_connect(vpninfo, ssl_sock, vpninfo->peer_addr, vpninfo->peer_addrlen); if (err) { char *errstr; reconn_err: #ifdef _WIN32 if (err > 0) errstr = openconnect__win32_strerror(err); else #endif errstr = strerror(-err); if (vpninfo->proxy) { vpn_progress(vpninfo, PRG_ERR, _("Failed to reconnect to proxy %s: %s\n"), vpninfo->proxy, errstr); } else { vpn_progress(vpninfo, PRG_ERR, _("Failed to reconnect to host %s: %s\n"), vpninfo->hostname, errstr); } #ifdef _WIN32 if (err > 0) free(errstr); #endif if (ssl_sock >= 0) closesocket(ssl_sock); ssl_sock = -EINVAL; goto out; } } else { struct addrinfo hints, *result, *rp; char *hostname; char port[6]; memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV; hints.ai_protocol = 0; hints.ai_canonname = NULL; hints.ai_addr = NULL; hints.ai_next = NULL; /* The 'port' variable is a string because it's easier this way than if we pass NULL to getaddrinfo() and then try to fill in the numeric value into different types of returned sockaddr_in{6,}. */ #ifdef LIBPROXY_HDR if (vpninfo->proxy_factory) { struct oc_text_buf *url_buf = buf_alloc(); char **proxies; int i = 0; free(vpninfo->proxy_type); vpninfo->proxy_type = NULL; free(vpninfo->proxy); vpninfo->proxy = NULL; buf_append(url_buf, "https://%s", vpninfo->hostname); if (vpninfo->port != 443) buf_append(url_buf, ":%d", vpninfo->port); buf_append(url_buf, "/%s", vpninfo->urlpath?:""); if (buf_error(url_buf)) { buf_free(url_buf); ssl_sock = -ENOMEM; goto out; } proxies = px_proxy_factory_get_proxies(vpninfo->proxy_factory, url_buf->data); i = 0; while (proxies && proxies[i]) { if (!vpninfo->proxy && (!strncmp(proxies[i], "http://", 7) || !strncmp(proxies[i], "socks://", 8) || !strncmp(proxies[i], "socks5://", 9))) internal_parse_url(proxies[i], &vpninfo->proxy_type, &vpninfo->proxy, &vpninfo->proxy_port, NULL, 0); i++; } buf_free(url_buf); free(proxies); if (vpninfo->proxy) vpn_progress(vpninfo, PRG_DEBUG, _("Proxy from libproxy: %s://%s:%d/\n"), vpninfo->proxy_type, vpninfo->proxy, vpninfo->port); } #endif if (vpninfo->proxy) { hostname = vpninfo->proxy; snprintf(port, 6, "%d", vpninfo->proxy_port); } else { hostname = vpninfo->hostname; snprintf(port, 6, "%d", vpninfo->port); } if (hostname[0] == '[' && hostname[strlen(hostname)-1] == ']') { hostname = strndup(hostname + 1, strlen(hostname) - 2); if (!hostname) { ssl_sock = -ENOMEM; goto out; } hints.ai_flags |= AI_NUMERICHOST; } if (vpninfo->getaddrinfo_override) err = vpninfo->getaddrinfo_override(vpninfo->cbdata, hostname, port, &hints, &result); else err = getaddrinfo(hostname, port, &hints, &result); if (err) { vpn_progress(vpninfo, PRG_ERR, _("getaddrinfo failed for host '%s': %s\n"), hostname, gai_strerror(err)); if (hints.ai_flags & AI_NUMERICHOST) free(hostname); ssl_sock = -EINVAL; /* If we were just retrying for dynamic DNS, reconnct using the previously-known IP address */ if (vpninfo->peer_addr) { vpn_progress(vpninfo, PRG_ERR, _("Reconnecting to DynDNS server using previously cached IP address\n")); goto reconnect; } goto out; } if (hints.ai_flags & AI_NUMERICHOST) free(hostname); for (rp = result; rp ; rp = rp->ai_next) { char host[80]; host[0] = 0; if (!getnameinfo(rp->ai_addr, rp->ai_addrlen, host, sizeof(host), NULL, 0, NI_NUMERICHOST)) vpn_progress(vpninfo, PRG_DEBUG, vpninfo->proxy_type ? _("Attempting to connect to proxy %s%s%s:%s\n") : _("Attempting to connect to server %s%s%s:%s\n"), rp->ai_family == AF_INET6 ? "[" : "", host, rp->ai_family == AF_INET6 ? "]" : "", port); ssl_sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); if (ssl_sock < 0) continue; set_fd_cloexec(ssl_sock); err = cancellable_connect(vpninfo, ssl_sock, rp->ai_addr, rp->ai_addrlen); if (!err) { /* Store the peer address we actually used, so that DTLS can use it again later */ free(vpninfo->ip_info.gateway_addr); vpninfo->ip_info.gateway_addr = NULL; if (host[0]) { vpninfo->ip_info.gateway_addr = strdup(host); vpn_progress(vpninfo, PRG_INFO, _("Connected to %s%s%s:%s\n"), rp->ai_family == AF_INET6 ? "[" : "", host, rp->ai_family == AF_INET6 ? "]" : "", port); } free(vpninfo->peer_addr); vpninfo->peer_addrlen = 0; vpninfo->peer_addr = malloc(rp->ai_addrlen); if (!vpninfo->peer_addr) { vpn_progress(vpninfo, PRG_ERR, _("Failed to allocate sockaddr storage\n")); closesocket(ssl_sock); ssl_sock = -ENOMEM; goto out; } vpninfo->peer_addrlen = rp->ai_addrlen; memcpy(vpninfo->peer_addr, rp->ai_addr, rp->ai_addrlen); /* If no proxy, ensure that we output *this* IP address in * authentication results because we're going to need to * reconnect to the *same* server from the rotation. And with * some trick DNS setups, it might possibly be a "rotation" * even if we only got one result from getaddrinfo() this * time. * * If there's a proxy, we're kind of screwed; we can't know * which IP address we connected to. Perhaps we ought to do * the DNS lookup locally and connect to a specific IP? */ if (!vpninfo->proxy && host[0]) { char *p = malloc(strlen(host) + 3); if (p) { free(vpninfo->unique_hostname); vpninfo->unique_hostname = p; if (rp->ai_family == AF_INET6) *p++ = '['; memcpy(p, host, strlen(host)); p += strlen(host); if (rp->ai_family == AF_INET6) *p++ = ']'; *p = 0; } } break; } if (host[0]) { char *errstr; #ifdef _WIN32 if (err > 0) errstr = openconnect__win32_strerror(err); else #endif errstr = strerror(-err); vpn_progress(vpninfo, PRG_INFO, _("Failed to connect to %s%s%s:%s: %s\n"), rp->ai_family == AF_INET6 ? "[" : "", host, rp->ai_family == AF_INET6 ? "]" : "", port, errstr); #ifdef _WIN32 if (err > 0) free(errstr); #endif } closesocket(ssl_sock); ssl_sock = -1; /* If we're in DynDNS mode but this *was* the cached IP address, * don't bother falling back to it if it didn't work. */ if (vpninfo->peer_addr && vpninfo->peer_addrlen == rp->ai_addrlen && match_sockaddr(vpninfo->peer_addr, rp->ai_addr)) { vpn_progress(vpninfo, PRG_TRACE, _("Forgetting non-functional previous peer address\n")); free(vpninfo->peer_addr); vpninfo->peer_addr = 0; vpninfo->peer_addrlen = 0; free(vpninfo->ip_info.gateway_addr); vpninfo->ip_info.gateway_addr = NULL; } } freeaddrinfo(result); if (ssl_sock < 0) { vpn_progress(vpninfo, PRG_ERR, _("Failed to connect to host %s\n"), vpninfo->proxy?:vpninfo->hostname); ssl_sock = -EINVAL; if (vpninfo->peer_addr) { vpn_progress(vpninfo, PRG_ERR, _("Reconnecting to DynDNS server using previously cached IP address\n")); goto reconnect; } goto out; } }
nsresult nsUnixSystemProxySettings::GetProxyForURI(nsIURI* aURI, nsACString& aResult) { nsresult rv; if (!mProxyFactory) { mProxyFactory = px_proxy_factory_new(); } NS_ENSURE_TRUE(mProxyFactory, NS_ERROR_NOT_AVAILABLE); nsCOMPtr<nsIIOService> ios = do_GetIOService(&rv); NS_ENSURE_SUCCESS(rv, rv); nsCAutoString spec; rv = aURI->GetSpec(spec); NS_ENSURE_SUCCESS(rv, rv); char **proxyArray = nsnull; proxyArray = px_proxy_factory_get_proxies(mProxyFactory, (char*)(spec.get())); NS_ENSURE_TRUE(proxyArray, NS_ERROR_NOT_AVAILABLE); // Translate libproxy's output to PAC string as expected // libproxy returns an array of proxies in the format: // <procotol>://[username:password@]proxy:port // or // direct:// // // PAC format: "PROXY proxy1.foo.com:8080; PROXY proxy2.foo.com:8080; DIRECT" int c = 0; while (proxyArray[c] != NULL) { if (!aResult.IsEmpty()) { aResult.AppendLiteral("; "); } bool isScheme = false; nsXPIDLCString schemeString; nsXPIDLCString hostPortString; nsCOMPtr<nsIURI> proxyURI; rv = ios->NewURI(nsDependentCString(proxyArray[c]), nsnull, nsnull, getter_AddRefs(proxyURI)); if (NS_FAILED(rv)) { c++; continue; } proxyURI->GetScheme(schemeString); if (NS_SUCCEEDED(proxyURI->SchemeIs("http", &isScheme)) && isScheme) { schemeString.AssignLiteral("proxy"); } aResult.Append(schemeString); if (NS_SUCCEEDED(proxyURI->SchemeIs("direct", &isScheme)) && !isScheme) { // Add the proxy URI only if it's not DIRECT proxyURI->GetHostPort(hostPortString); aResult.AppendLiteral(" "); aResult.Append(hostPortString); } c++; } #ifdef DEBUG printf("returned PAC proxy string: %s\n", PromiseFlatCString(aResult).get()); #endif PR_Free(proxyArray); return NS_OK; }