diff --git a/examples/Elastic.Ephemeral.Example/Elastic.Ephemeral.Example.csproj b/examples/Elastic.Ephemeral.Example/Elastic.Ephemeral.Example.csproj
index 3745a2f..bc13e1f 100644
--- a/examples/Elastic.Ephemeral.Example/Elastic.Ephemeral.Example.csproj
+++ b/examples/Elastic.Ephemeral.Example/Elastic.Ephemeral.Example.csproj
@@ -9,7 +9,11 @@
-
+
+
+
+
+
diff --git a/examples/Elastic.Ephemeral.Example/Program.cs b/examples/Elastic.Ephemeral.Example/Program.cs
index 5d03b9b..efd2487 100644
--- a/examples/Elastic.Ephemeral.Example/Program.cs
+++ b/examples/Elastic.Ephemeral.Example/Program.cs
@@ -3,7 +3,12 @@
// See the LICENSE file in the project root for more information
using Elastic.Elasticsearch.Ephemeral;
+using Elastic.Elasticsearch.Managed;
+using Elastic.Transport;
+using Elastic.Transport.Products.Elasticsearch;
+using static Elastic.Elasticsearch.Ephemeral.ClusterAuthentication;
using static Elastic.Elasticsearch.Ephemeral.ClusterFeatures;
+using HttpMethod = Elastic.Transport.HttpMethod;
var config = new EphemeralClusterConfiguration("8.7.0", XPack | Security | SSL);
@@ -16,4 +21,18 @@
exitEvent.Set();
};
using var started = cluster.Start();
+
+var pool = new StaticNodePool(cluster.NodesUris());
+var transportConfig = new TransportConfiguration(pool, productRegistration: ElasticsearchProductRegistration.Default)
+ .Authentication(new BasicAuthentication(Admin.Username, Admin.Password))
+ .ServerCertificateValidationCallback(CertificateValidations.AllowAll);
+if (cluster.DetectedProxy != DetectedProxySoftware.None)
+ transportConfig = transportConfig.Proxy(new Uri("http://localhost:8080"), null!, null!);
+
+var transport = new DefaultHttpTransport(transportConfig);
+
+var response = await transport.RequestAsync(HttpMethod.GET, "/");
+Console.WriteLine(response);
+
+
exitEvent.WaitOne();
diff --git a/examples/ScratchPad/Program.cs b/examples/ScratchPad/Program.cs
index aa5b2e4..5ff29df 100644
--- a/examples/ScratchPad/Program.cs
+++ b/examples/ScratchPad/Program.cs
@@ -39,7 +39,7 @@ private static void ManualConfigRun()
var features = Security | XPack | SSL;
var config = new EphemeralClusterConfiguration(version, features, plugins, 1)
{
- HttpFiddlerAware = true,
+ AutoWireKnownProxies = true,
ShowElasticsearchOutputAfterStarted = true,
CacheEsHomeInstallation = false,
TrialMode = XPackTrialMode.Trial,
diff --git a/examples/ScratchPad/ValidateCombinations.cs b/examples/ScratchPad/ValidateCombinations.cs
index d29ed92..acb3c78 100644
--- a/examples/ScratchPad/ValidateCombinations.cs
+++ b/examples/ScratchPad/ValidateCombinations.cs
@@ -38,7 +38,7 @@ public static void Run()
Console.WriteLine($"{v} {f}");
Console.ForegroundColor = reset;
- var config = new EphemeralClusterConfiguration(v, f, plugins, 1) {HttpFiddlerAware = true,};
+ var config = new EphemeralClusterConfiguration(v, f, plugins, 1) {AutoWireKnownProxies = true,};
using (var cluster = new EphemeralCluster(config))
try
diff --git a/src/Elastic.Elasticsearch.Ephemeral/EphemeralCluster.cs b/src/Elastic.Elasticsearch.Ephemeral/EphemeralCluster.cs
index 5a84f5d..4f64e16 100644
--- a/src/Elastic.Elasticsearch.Ephemeral/EphemeralCluster.cs
+++ b/src/Elastic.Elasticsearch.Ephemeral/EphemeralCluster.cs
@@ -37,9 +37,13 @@ protected EphemeralCluster(TConfiguration clusterConfiguration) : base(clusterCo
public virtual ICollection NodesUris(string hostName = null)
{
- hostName = hostName ?? (ClusterConfiguration.HttpFiddlerAware && Process.GetProcessesByName("fiddler").Any()
- ? "ipv4.fiddler"
- : "localhost");
+ hostName ??= "localhost";
+ if (hostName == "localhost" && ClusterConfiguration.AutoWireKnownProxies)
+ {
+ if (DetectedProxy == DetectedProxySoftware.Fiddler)
+ hostName = "ipv4.fiddler"; //magic reverse proxy address for fiddler
+ }
+
var ssl = ClusterConfiguration.EnableSsl ? "s" : "";
return Nodes
.Select(n => $"http{ssl}://{hostName}:{n.Port ?? 9200}")
diff --git a/src/Elastic.Elasticsearch.Ephemeral/EphemeralClusterConfiguration.cs b/src/Elastic.Elasticsearch.Ephemeral/EphemeralClusterConfiguration.cs
index 87d15cb..a81dabe 100644
--- a/src/Elastic.Elasticsearch.Ephemeral/EphemeralClusterConfiguration.cs
+++ b/src/Elastic.Elasticsearch.Ephemeral/EphemeralClusterConfiguration.cs
@@ -89,8 +89,14 @@ public EphemeralClusterConfiguration(ElasticVersion version, ClusterFeatures fea
///
public XPackTrialMode TrialMode { get; set; }
- /// Bootstrapping HTTP calls should attempt to auto route traffic through fiddler if its running
- public bool HttpFiddlerAware { get; set; }
+ ///
+ /// Bootstrapping HTTP calls should attempt to auto route traffic through known proxy software if they are running
+ ///
+ /// - Fiddler, typically on Windows
+ /// - mitmproxy, typically on non Windows OS's
+ ///
+ ///
+ public bool AutoWireKnownProxies { get; set; }
protected virtual string NodePrefix => "ephemeral";
diff --git a/src/Elastic.Elasticsearch.Ephemeral/Tasks/IClusterComposeTask.cs b/src/Elastic.Elasticsearch.Ephemeral/Tasks/IClusterComposeTask.cs
index ebfdbf6..536c22d 100644
--- a/src/Elastic.Elasticsearch.Ephemeral/Tasks/IClusterComposeTask.cs
+++ b/src/Elastic.Elasticsearch.Ephemeral/Tasks/IClusterComposeTask.cs
@@ -16,6 +16,7 @@
using System.Text;
using System.Threading;
using System.Threading.Tasks;
+using Elastic.Elasticsearch.Managed;
using Elastic.Elasticsearch.Managed.ConsoleWriters;
using ICSharpCode.SharpZipLib.GZip;
using ICSharpCode.SharpZipLib.Tar;
@@ -87,6 +88,9 @@ private HttpResponseMessage Call(
AutomaticDecompression =
DecompressionMethods.Deflate | DecompressionMethods.GZip | DecompressionMethods.None,
};
+ if (cluster.DetectedProxy != DetectedProxySoftware.None)
+ handler.Proxy = new WebProxy { Address = new Uri("http://localhost:8080") };
+
cluster.Writer.WriteDiagnostic(
$"{{{nameof(Call)}}} [{statusUrl}] SSL: {cluster.ClusterConfiguration.EnableSsl} Security: {cluster.ClusterConfiguration.EnableSecurity}");
if (cluster.ClusterConfiguration.EnableSsl)
@@ -98,39 +102,37 @@ private HttpResponseMessage Call(
#endif
}
- using (var client = new HttpClient(handler) {Timeout = TimeSpan.FromSeconds(20)})
+ using var client = new HttpClient(handler) {Timeout = TimeSpan.FromSeconds(20)};
+ if (cluster.ClusterConfiguration.EnableSecurity)
{
- if (cluster.ClusterConfiguration.EnableSecurity)
- {
- var byteArray =
- Encoding.ASCII.GetBytes(
- $"{ClusterAuthentication.Admin.Username}:{ClusterAuthentication.Admin.Password}");
- client.DefaultRequestHeaders.Authorization =
- new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
- }
+ var byteArray =
+ Encoding.ASCII.GetBytes(
+ $"{ClusterAuthentication.Admin.Username}:{ClusterAuthentication.Admin.Password}");
+ client.DefaultRequestHeaders.Authorization =
+ new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
+ }
- try
- {
- var response = verb(client, statusUrl, tokenSource.Token).ConfigureAwait(false).GetAwaiter()
- .GetResult();
- if (response.StatusCode == HttpStatusCode.OK) return response;
- cluster.Writer.WriteDiagnostic(
- $"{{{nameof(Call)}}} [{statusUrl}] Bad status code: [{(int) response.StatusCode}]");
- var body = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
- foreach (var l in (body ?? string.Empty).Split('\n', '\r'))
- cluster.Writer.WriteDiagnostic($"{{{nameof(Call)}}} [{statusUrl}] returned [{l}]");
- }
- catch (Exception e)
- {
- cluster.Writer.WriteError($"{{{nameof(Call)}}} [{statusUrl}] exception: {e}");
- // ignored
- }
- finally
- {
+ try
+ {
+ var response = verb(client, statusUrl, tokenSource.Token).ConfigureAwait(false).GetAwaiter()
+ .GetResult();
+ if (response.StatusCode == HttpStatusCode.OK) return response;
+ cluster.Writer.WriteDiagnostic(
+ $"{{{nameof(Call)}}} [{statusUrl}] Bad status code: [{(int) response.StatusCode}]");
+ var body = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
+ foreach (var l in (body ?? string.Empty).Split('\n', '\r'))
+ cluster.Writer.WriteDiagnostic($"{{{nameof(Call)}}} [{statusUrl}] returned [{l}]");
+ }
+ catch (Exception e)
+ {
+ cluster.Writer.WriteError($"{{{nameof(Call)}}} [{statusUrl}] exception: {e}");
+ // ignored
+ }
+ finally
+ {
#if !NETSTANDARD
ServicePointManager.ServerCertificateValidationCallback -= ServerCertificateValidationCallback;
#endif
- }
}
return null;
diff --git a/src/Elastic.Elasticsearch.Ephemeral/Tasks/InstallationTasks/PrintConfiguration.cs b/src/Elastic.Elasticsearch.Ephemeral/Tasks/InstallationTasks/PrintConfiguration.cs
index f15d9c5..d088ce4 100644
--- a/src/Elastic.Elasticsearch.Ephemeral/Tasks/InstallationTasks/PrintConfiguration.cs
+++ b/src/Elastic.Elasticsearch.Ephemeral/Tasks/InstallationTasks/PrintConfiguration.cs
@@ -50,7 +50,7 @@ string F(ClusterFeatures feature)
cluster.Writer?.WriteDiagnostic(
$"{{{nameof(PrintConfiguration)}}} {{{nameof(c.SkipBuiltInAfterStartTasks)}}} [{c.SkipBuiltInAfterStartTasks}]");
cluster.Writer?.WriteDiagnostic(
- $"{{{nameof(PrintConfiguration)}}} {{{nameof(c.HttpFiddlerAware)}}} [{c.HttpFiddlerAware}]");
+ $"{{{nameof(PrintConfiguration)}}} {{{nameof(c.AutoWireKnownProxies)}}} [{c.AutoWireKnownProxies}]");
cluster.Writer?.WriteDiagnostic(
$"{{{nameof(PrintConfiguration)}}} {{{nameof(c.NoCleanupAfterNodeStopped)}}} [{c.NoCleanupAfterNodeStopped}]");
}
diff --git a/src/Elastic.Elasticsearch.Managed/ClusterBase.cs b/src/Elastic.Elasticsearch.Managed/ClusterBase.cs
index 502e5b8..8f8f28c 100644
--- a/src/Elastic.Elasticsearch.Managed/ClusterBase.cs
+++ b/src/Elastic.Elasticsearch.Managed/ClusterBase.cs
@@ -5,6 +5,7 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
+using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
@@ -12,6 +13,7 @@
using Elastic.Elasticsearch.Managed.ConsoleWriters;
using Elastic.Elasticsearch.Managed.FileSystem;
using ProcNet.Std;
+using static Elastic.Elasticsearch.Managed.DetectedProxySoftware;
namespace Elastic.Elasticsearch.Managed
{
@@ -30,6 +32,11 @@ public interface ICluster : IDisposable
IDisposable Start(TimeSpan waitForStarted);
IDisposable Start(IConsoleLineHandler writer, TimeSpan waitForStarted);
+
+ ///
+ /// Whether known proxies were detected as running during startup
+ ///
+ DetectedProxySoftware DetectedProxy { get; }
}
@@ -75,8 +82,18 @@ NodeConfiguration Modify(NodeConfiguration n, int p)
node.NodeConfiguration.InitialMasterNodes(initialMasterNodes);
Nodes = new ReadOnlyCollection(nodes);
+
+ if (Process.GetProcessesByName("fiddler").Any()) DetectedProxy = Fiddler;
+ else if (Process.GetProcessesByName("mitmproxy").Any()) DetectedProxy = MitmProxy;
+ else DetectedProxy = None;
}
+ ///
+ /// Whether known proxies were detected as running during startup
+ ///
+ public DetectedProxySoftware DetectedProxy { get; }
+
+
///
/// A short name to identify the cluster defaults to the subclass name with Cluster
/// removed
diff --git a/src/Elastic.Elasticsearch.Managed/Configuration/ClusterConfiguration.cs b/src/Elastic.Elasticsearch.Managed/Configuration/ClusterConfiguration.cs
index c5cf01f..ddc4a97 100644
--- a/src/Elastic.Elasticsearch.Managed/Configuration/ClusterConfiguration.cs
+++ b/src/Elastic.Elasticsearch.Managed/Configuration/ClusterConfiguration.cs
@@ -80,6 +80,7 @@ public ClusterConfiguration(ElasticVersion version, Func