TcpRemoteForwarder: Parsing the MediaTypeHeaderValue correctly with TryParse and throwing if the parsing fails. (#92)
* Fix addresses issue #91 * added HTTP test * config parser adjustment for the HTTP RemoteForward fix
This commit is contained in:
Родитель
8e42cbbe6b
Коммит
631a3b1721
|
@ -913,7 +913,9 @@ namespace Microsoft.Azure.Relay.Bridge.Configuration
|
||||||
RemoteForward remoteForward;
|
RemoteForward remoteForward;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
remoteForward = new RemoteForward { RelayName = rf.Substring(0, firstColon), Http = true };
|
// we're not setting the Http flag here but only at the end of the method
|
||||||
|
// since we don't want a default binding to be created.
|
||||||
|
remoteForward = new RemoteForward { RelayName = rf.Substring(0, firstColon) };
|
||||||
}
|
}
|
||||||
catch (ArgumentOutOfRangeException e)
|
catch (ArgumentOutOfRangeException e)
|
||||||
{
|
{
|
||||||
|
@ -1028,6 +1030,7 @@ namespace Microsoft.Azure.Relay.Bridge.Configuration
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
remoteForward.Http = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void CheckHttpPortName(Config config, string rf, string portName)
|
private static void CheckHttpPortName(Config config, string rf, string portName)
|
||||||
|
|
|
@ -148,7 +148,28 @@ namespace Microsoft.Azure.Relay.Bridge.Configuration
|
||||||
|
|
||||||
public bool Http
|
public bool Http
|
||||||
{
|
{
|
||||||
get; set;
|
get
|
||||||
|
{
|
||||||
|
if (bindings.Count == 1)
|
||||||
|
{
|
||||||
|
return bindings[0].Http;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (bindings.Count == 0)
|
||||||
|
{
|
||||||
|
bindings.Add(new RemoteForwardBinding { Http = value });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bindings[0].Http = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -138,7 +138,14 @@ namespace Microsoft.Azure.Relay.Bridge
|
||||||
string contentType = context.Request.Headers[HttpRequestHeader.ContentType];
|
string contentType = context.Request.Headers[HttpRequestHeader.ContentType];
|
||||||
if (!string.IsNullOrEmpty(contentType))
|
if (!string.IsNullOrEmpty(contentType))
|
||||||
{
|
{
|
||||||
requestMessage.Content.Headers.ContentType = new MediaTypeHeaderValue(contentType);
|
if (MediaTypeHeaderValue.TryParse(contentType, out var mediaTypeHeaderValue))
|
||||||
|
{
|
||||||
|
requestMessage.Content.Headers.ContentType = mediaTypeHeaderValue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"Invalid Content-Type header value: {contentType}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,10 @@ namespace Microsoft.Azure.Relay.Bridge.Test
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Microsoft.Azure.Relay.Bridge.Configuration;
|
using Microsoft.Azure.Relay.Bridge.Configuration;
|
||||||
using Microsoft.Azure.Relay.Bridge.Tests;
|
using Microsoft.Azure.Relay.Bridge.Tests;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
@ -291,5 +294,85 @@ namespace Microsoft.Azure.Relay.Bridge.Test
|
||||||
host.Stop();
|
host.Stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void HttpBridge()
|
||||||
|
{
|
||||||
|
// set up the bridge first
|
||||||
|
Config cfg = new Config
|
||||||
|
{
|
||||||
|
AzureRelayConnectionString = Utilities.GetConnectionString()
|
||||||
|
};
|
||||||
|
cfg.RemoteForward.Add(new RemoteForward
|
||||||
|
{
|
||||||
|
Host = "127.0.97.2",
|
||||||
|
HostPort = 29877,
|
||||||
|
PortName = "http",
|
||||||
|
RelayName = "http",
|
||||||
|
Http = true
|
||||||
|
});
|
||||||
|
Host host = new Host(cfg);
|
||||||
|
host.Start();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
RelayConnectionStringBuilder csb = new RelayConnectionStringBuilder(Utilities.GetConnectionString());
|
||||||
|
var httpEndpoint = new UriBuilder(csb.Endpoint) { Scheme = "https", Port = 443, Path="http" }.Uri;
|
||||||
|
var httpSasToken = TokenProvider.CreateSharedAccessSignatureTokenProvider(csb.SharedAccessKeyName, csb.SharedAccessKey).GetTokenAsync(httpEndpoint.AbsoluteUri, TimeSpan.FromHours(1)).Result.TokenString;
|
||||||
|
|
||||||
|
using (var l = new HttpListener())
|
||||||
|
{
|
||||||
|
l.Prefixes.Add("http://127.0.97.2:29877/");
|
||||||
|
l.Start();
|
||||||
|
|
||||||
|
var handler = (Task<HttpListenerContext> t) =>
|
||||||
|
{
|
||||||
|
var c = t.Result;
|
||||||
|
using (var b = new StreamReader(c.Request.InputStream))
|
||||||
|
{
|
||||||
|
var text = b.ReadLine();
|
||||||
|
using (var w = new StreamWriter(c.Response.OutputStream))
|
||||||
|
{
|
||||||
|
w.WriteLine(text);
|
||||||
|
w.Flush();
|
||||||
|
}
|
||||||
|
c.Response.Close();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var testMessage = "Hello!";
|
||||||
|
|
||||||
|
|
||||||
|
using (var c = new HttpClient())
|
||||||
|
{
|
||||||
|
c.DefaultRequestHeaders.Add("Authorization", httpSasToken);
|
||||||
|
|
||||||
|
// listen for exactly one request
|
||||||
|
l.GetContextAsync().ContinueWith(handler);
|
||||||
|
|
||||||
|
var r = c.PostAsync(httpEndpoint, new StringContent(testMessage)).GetAwaiter().GetResult();
|
||||||
|
Assert.True(r.IsSuccessStatusCode);
|
||||||
|
var result = r.Content.ReadAsStringAsync().GetAwaiter().GetResult();
|
||||||
|
Assert.Equal(testMessage, result.Trim());
|
||||||
|
r.Dispose();
|
||||||
|
|
||||||
|
// listen for exactly one request
|
||||||
|
l.GetContextAsync().ContinueWith(handler);
|
||||||
|
|
||||||
|
var mtv = MediaTypeHeaderValue.Parse("application/cloudevents+json;charset=utf-8;foo=bar");
|
||||||
|
var r2 = c.PostAsync(httpEndpoint, new StringContent(testMessage, mtv)).GetAwaiter().GetResult();
|
||||||
|
Assert.True(r2.IsSuccessStatusCode);
|
||||||
|
var result2 = r2.Content.ReadAsStringAsync().GetAwaiter().GetResult();
|
||||||
|
Assert.Equal(testMessage, result2.Trim());
|
||||||
|
r2.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
host.Stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче