Skip to content

Commit

Permalink
Adds option to CocoonProxyOptions to control the request Host header …
Browse files Browse the repository at this point in the history
…value. Fixes VisualReCode#30
  • Loading branch information
conficient committed Apr 13, 2023
1 parent 41b7f53 commit 56b3613
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 6 deletions.
53 changes: 47 additions & 6 deletions main/src/ReCode.Cocoon.Proxy/Proxy/CocoonProxy.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
using System;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.ModelBinding.Binders;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Yarp.ReverseProxy.Forwarder;

namespace ReCode.Cocoon.Proxy.Proxy
Expand All @@ -19,6 +19,8 @@ public class CocoonProxy
private readonly RedirectTransformer _transformer;
private readonly ForwarderRequestConfig _requestConfig;
private readonly string _destinationPrefix;
private readonly HostHeaderOptions _hostHeaderOption;
private readonly string _host;

public CocoonProxy(IConfiguration configuration, ILogger<CocoonProxy> logger, IHttpForwarder httpForwarder, CocoonProxyOptions? proxyOptions)
{
Expand All @@ -36,7 +38,11 @@ public CocoonProxy(IConfiguration configuration, ILogger<CocoonProxy> logger, IH
throw new InvalidOperationException("Invalid DestinationPrefix");
}

logger.LogInformation($"Cocoon Proxy backend: {destinationPrefixUri}");
logger.LogInformation("Cocoon Proxy backend: {destinationPrefixUri}", destinationPrefixUri);

// save the host
_host = destinationPrefixUri.Host;
logger.LogInformation("Cocoon Proxy backend: host is {host}", _host);

_backendUrls = CocoonProxyExclusions.CreateExclusionSet(configuration);

Expand All @@ -57,6 +63,9 @@ public CocoonProxy(IConfiguration configuration, ILogger<CocoonProxy> logger, IH
_httpClient = new HttpMessageInvoker(socketsHttpHandler);
_transformer = new RedirectTransformer(destinationPrefixUri);

// save the host header option, or use default option
_hostHeaderOption = proxyOptions?.HostHeaderOption ?? HostHeaderOptions.None;

if (!TimeSpan.TryParse(configuration.GetValue<string>("Cocoon:Proxy:Timeout"), out var timeout))
{
timeout = TimeSpan.FromSeconds(30);
Expand All @@ -75,10 +84,42 @@ public async Task ProxyAsync(HttpContext httpContext)
return;
}

// amend the HOST value in the request based on _hostHeaderOption
switch (_hostHeaderOption)
{
case HostHeaderOptions.None:
// HostHeader unchanged
break;

case HostHeaderOptions.SetDefault:
// HostHeader set to default
SetHost(httpContext.Request.Headers, default);
break;

case HostHeaderOptions.UseHost:
// HostHeader set to _host
SetHost(httpContext.Request.Headers, _host);
break;

default:
// unhandled options not supported
throw new NotSupportedException($"Unhandled HostHeaderOption {_hostHeaderOption}");
}

using var activity = ProxyActivitySource.StartActivity("Proxy");
activity?.SetTag("path", httpContext.Request.Path.ToString());

await _httpForwarder.SendAsync(httpContext, _destinationPrefix, _httpClient, _requestConfig, _transformer);
}

/// <summary>
/// NET6 has useful
/// </summary>
/// <param name="headers"></param>
/// <param name="host"></param>
private static void SetHost(IHeaderDictionary headers, string? host)
{
headers["Host"] = host;
}
}
}
5 changes: 5 additions & 0 deletions main/src/ReCode.Cocoon.Proxy/Proxy/CocoonProxyOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,10 @@ namespace ReCode.Cocoon.Proxy.Proxy
public class CocoonProxyOptions
{
public RemoteCertificateValidationCallback? RemoteCertificateValidationCallback { get; set; }

/// <summary>
/// Set Host header behaviour
/// </summary>
public HostHeaderOptions HostHeaderOption { get; set; } = HostHeaderOptions.None;
}
}
30 changes: 30 additions & 0 deletions main/src/ReCode.Cocoon.Proxy/Proxy/HostHeaderOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ReCode.Cocoon.Proxy.Proxy
{
/// <summary>
/// Host Header options when proxying request
/// </summary>
/// <remarks>
/// Fixes #30 https://github.com/VisualReCode/Cocoon/issues/30
/// </remarks>
public enum HostHeaderOptions
{
/// <summary>
/// Default operation: no changes to Host header
/// </summary>
None,
/// <summary>
/// Used on Azure hosting: sets the Host header to `default` (null)
/// </summary>
SetDefault,
/// <summary>
/// Copies the host header from the request to the Cocoon proxy
/// </summary>
UseHost
}
}

0 comments on commit 56b3613

Please sign in to comment.