-
Notifications
You must be signed in to change notification settings - Fork 475
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
8bb6fa9
commit 467f18d
Showing
2 changed files
with
125 additions
and
127 deletions.
There are no files selected for viewing
149 changes: 74 additions & 75 deletions
149
Tools/LambdaTestTool-v2/src/Amazon.Lambda.TestTool/Utilities/HttpRequestUtility.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,92 +1,91 @@ | ||
namespace Amazon.Lambda.TestTool | ||
namespace Amazon.Lambda.TestTool.Utilities; | ||
|
||
/// <summary> | ||
/// Utility class for handling HTTP requests in the context of API Gateway emulation. | ||
/// </summary> | ||
public static class HttpRequestUtility | ||
{ | ||
/// <summary> | ||
/// Utility class for handling HTTP requests in the context of API Gateway emulation. | ||
/// Determines whether the specified content type represents binary content. | ||
/// </summary> | ||
public static class HttpRequestUtility | ||
/// <param name="contentType">The content type to check.</param> | ||
/// <returns>True if the content type represents binary content; otherwise, false.</returns> | ||
public static bool IsBinaryContent(string? contentType) | ||
{ | ||
/// <summary> | ||
/// Determines whether the specified content type represents binary content. | ||
/// </summary> | ||
/// <param name="contentType">The content type to check.</param> | ||
/// <returns>True if the content type represents binary content; otherwise, false.</returns> | ||
public static bool IsBinaryContent(string? contentType) | ||
{ | ||
if (string.IsNullOrEmpty(contentType)) | ||
return false; | ||
if (string.IsNullOrEmpty(contentType)) | ||
return false; | ||
|
||
return contentType.StartsWith("image/", StringComparison.OrdinalIgnoreCase) || | ||
contentType.StartsWith("audio/", StringComparison.OrdinalIgnoreCase) || | ||
contentType.StartsWith("video/", StringComparison.OrdinalIgnoreCase) || | ||
contentType.Equals("application/octet-stream", StringComparison.OrdinalIgnoreCase); | ||
} | ||
return contentType.StartsWith("image/", StringComparison.OrdinalIgnoreCase) || | ||
contentType.StartsWith("audio/", StringComparison.OrdinalIgnoreCase) || | ||
contentType.StartsWith("video/", StringComparison.OrdinalIgnoreCase) || | ||
contentType.Equals("application/octet-stream", StringComparison.OrdinalIgnoreCase); | ||
} | ||
|
||
/// <summary> | ||
/// Reads the body of the HTTP request as a string. | ||
/// </summary> | ||
/// <param name="request">The HTTP request.</param> | ||
/// <returns>The body of the request as a string.</returns> | ||
public static string ReadRequestBody(HttpRequest request) | ||
/// <summary> | ||
/// Reads the body of the HTTP request as a string. | ||
/// </summary> | ||
/// <param name="request">The HTTP request.</param> | ||
/// <returns>The body of the request as a string.</returns> | ||
public static string ReadRequestBody(HttpRequest request) | ||
{ | ||
using (var reader = new StreamReader(request.Body)) | ||
{ | ||
using (var reader = new StreamReader(request.Body)) | ||
{ | ||
return reader.ReadToEnd(); | ||
} | ||
return reader.ReadToEnd(); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Extracts headers from the request, separating them into single-value and multi-value dictionaries. | ||
/// </summary> | ||
/// <param name="headers">The request headers.</param> | ||
/// <returns>A tuple containing single-value and multi-value header dictionaries.</returns> | ||
/// <example> | ||
/// For headers: | ||
/// Accept: text/html | ||
/// Accept: application/xhtml+xml | ||
/// X-Custom-Header: value1 | ||
/// | ||
/// The method will return: | ||
/// singleValueHeaders: { "Accept": "application/xhtml+xml", "X-Custom-Header": "value1" } | ||
/// multiValueHeaders: { "Accept": ["text/html", "application/xhtml+xml"], "X-Custom-Header": ["value1"] } | ||
/// </example> | ||
public static (IDictionary<string, string>, IDictionary<string, IList<string>>) ExtractHeaders(IHeaderDictionary headers) | ||
{ | ||
var singleValueHeaders = new Dictionary<string, string>(); | ||
var multiValueHeaders = new Dictionary<string, IList<string>>(); | ||
|
||
foreach (var header in headers) | ||
{ | ||
singleValueHeaders[header.Key] = header.Value.Last() ?? ""; | ||
multiValueHeaders[header.Key] = [.. header.Value]; | ||
} | ||
/// <summary> | ||
/// Extracts headers from the request, separating them into single-value and multi-value dictionaries. | ||
/// </summary> | ||
/// <param name="headers">The request headers.</param> | ||
/// <returns>A tuple containing single-value and multi-value header dictionaries.</returns> | ||
/// <example> | ||
/// For headers: | ||
/// Accept: text/html | ||
/// Accept: application/xhtml+xml | ||
/// X-Custom-Header: value1 | ||
/// | ||
/// The method will return: | ||
/// singleValueHeaders: { "Accept": "application/xhtml+xml", "X-Custom-Header": "value1" } | ||
/// multiValueHeaders: { "Accept": ["text/html", "application/xhtml+xml"], "X-Custom-Header": ["value1"] } | ||
/// </example> | ||
public static (IDictionary<string, string>, IDictionary<string, IList<string>>) ExtractHeaders(IHeaderDictionary headers) | ||
{ | ||
var singleValueHeaders = new Dictionary<string, string>(); | ||
var multiValueHeaders = new Dictionary<string, IList<string>>(); | ||
|
||
return (singleValueHeaders, multiValueHeaders); | ||
foreach (var header in headers) | ||
{ | ||
singleValueHeaders[header.Key] = header.Value.Last() ?? ""; | ||
multiValueHeaders[header.Key] = [.. header.Value]; | ||
} | ||
|
||
/// <summary> | ||
/// Extracts query string parameters from the request, separating them into single-value and multi-value dictionaries. | ||
/// </summary> | ||
/// <param name="query">The query string collection.</param> | ||
/// <returns>A tuple containing single-value and multi-value query parameter dictionaries.</returns> | ||
/// <example> | ||
/// For query string: ?param1=value1&param2=value2&param2=value3 | ||
/// | ||
/// The method will return: | ||
/// singleValueParams: { "param1": "value1", "param2": "value3" } | ||
/// multiValueParams: { "param1": ["value1"], "param2": ["value2", "value3"] } | ||
/// </example> | ||
public static (IDictionary<string, string>, IDictionary<string, IList<string>>) ExtractQueryStringParameters(IQueryCollection query) | ||
{ | ||
var singleValueParams = new Dictionary<string, string>(); | ||
var multiValueParams = new Dictionary<string, IList<string>>(); | ||
return (singleValueHeaders, multiValueHeaders); | ||
} | ||
|
||
foreach (var param in query) | ||
{ | ||
singleValueParams[param.Key] = param.Value.Last() ?? ""; | ||
multiValueParams[param.Key] = [.. param.Value]; | ||
} | ||
/// <summary> | ||
/// Extracts query string parameters from the request, separating them into single-value and multi-value dictionaries. | ||
/// </summary> | ||
/// <param name="query">The query string collection.</param> | ||
/// <returns>A tuple containing single-value and multi-value query parameter dictionaries.</returns> | ||
/// <example> | ||
/// For query string: ?param1=value1&param2=value2&param2=value3 | ||
/// | ||
/// The method will return: | ||
/// singleValueParams: { "param1": "value1", "param2": "value3" } | ||
/// multiValueParams: { "param1": ["value1"], "param2": ["value2", "value3"] } | ||
/// </example> | ||
public static (IDictionary<string, string>, IDictionary<string, IList<string>>) ExtractQueryStringParameters(IQueryCollection query) | ||
{ | ||
var singleValueParams = new Dictionary<string, string>(); | ||
var multiValueParams = new Dictionary<string, IList<string>>(); | ||
|
||
return (singleValueParams, multiValueParams); | ||
foreach (var param in query) | ||
{ | ||
singleValueParams[param.Key] = param.Value.Last() ?? ""; | ||
multiValueParams[param.Key] = [.. param.Value]; | ||
} | ||
|
||
return (singleValueParams, multiValueParams); | ||
} | ||
} |
103 changes: 51 additions & 52 deletions
103
Tools/LambdaTestTool-v2/src/Amazon.Lambda.TestTool/Utilities/RouteTemplateUtility.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,67 +1,66 @@ | ||
using Microsoft.AspNetCore.Routing.Template; | ||
namespace Amazon.Lambda.TestTool.Utilities; | ||
|
||
namespace Amazon.Lambda.TestTool.Utilities | ||
using Microsoft.AspNetCore.Routing.Template; | ||
|
||
/// <summary> | ||
/// Provides utility methods for working with route templates and extracting path parameters. | ||
/// </summary> | ||
public static class RouteTemplateUtility | ||
{ | ||
/// <summary> | ||
/// Provides utility methods for working with route templates and extracting path parameters. | ||
/// Extracts path parameters from an actual path based on a route template. | ||
/// </summary> | ||
public static class RouteTemplateUtility | ||
/// <param name="routeTemplate">The route template to match against.</param> | ||
/// <param name="actualPath">The actual path to extract parameters from.</param> | ||
/// <returns>A dictionary of extracted path parameters and their values.</returns> | ||
/// <example> | ||
/// Using this method: | ||
/// <code> | ||
/// var routeTemplate = "/users/{id}/orders/{orderId}"; | ||
/// var actualPath = "/users/123/orders/456"; | ||
/// var parameters = RouteTemplateUtility.ExtractPathParameters(routeTemplate, actualPath); | ||
/// // parameters will contain: { {"id", "123"}, {"orderId", "456"} } | ||
/// </code> | ||
/// </example> | ||
public static Dictionary<string, string> ExtractPathParameters(string routeTemplate, string actualPath) | ||
{ | ||
/// <summary> | ||
/// Extracts path parameters from an actual path based on a route template. | ||
/// </summary> | ||
/// <param name="routeTemplate">The route template to match against.</param> | ||
/// <param name="actualPath">The actual path to extract parameters from.</param> | ||
/// <returns>A dictionary of extracted path parameters and their values.</returns> | ||
/// <example> | ||
/// Using this method: | ||
/// <code> | ||
/// var routeTemplate = "/users/{id}/orders/{orderId}"; | ||
/// var actualPath = "/users/123/orders/456"; | ||
/// var parameters = RouteTemplateUtility.ExtractPathParameters(routeTemplate, actualPath); | ||
/// // parameters will contain: { {"id", "123"}, {"orderId", "456"} } | ||
/// </code> | ||
/// </example> | ||
public static Dictionary<string, string> ExtractPathParameters(string routeTemplate, string actualPath) | ||
var template = TemplateParser.Parse(routeTemplate); | ||
var matcher = new TemplateMatcher(template, GetDefaults(template)); | ||
var routeValues = new RouteValueDictionary(); | ||
|
||
if (matcher.TryMatch(actualPath, routeValues)) | ||
{ | ||
var template = TemplateParser.Parse(routeTemplate); | ||
var matcher = new TemplateMatcher(template, GetDefaults(template)); | ||
var routeValues = new RouteValueDictionary(); | ||
return routeValues.ToDictionary(rv => rv.Key, rv => rv.Value?.ToString() ?? string.Empty); | ||
} | ||
|
||
if (matcher.TryMatch(actualPath, routeValues)) | ||
{ | ||
return routeValues.ToDictionary(rv => rv.Key, rv => rv.Value?.ToString() ?? string.Empty); | ||
} | ||
return new Dictionary<string, string>(); | ||
} | ||
|
||
return new Dictionary<string, string>(); | ||
} | ||
/// <summary> | ||
/// Gets the default values for parameters in a parsed route template. | ||
/// </summary> | ||
/// <param name="parsedTemplate">The parsed route template.</param> | ||
/// <returns>A dictionary of default values for the template parameters.</returns> | ||
/// <example> | ||
/// Using this method: | ||
/// <code> | ||
/// var template = TemplateParser.Parse("/api/{version=v1}/users/{id}"); | ||
/// var defaults = RouteTemplateUtility.GetDefaults(template); | ||
/// // defaults will contain: { {"version", "v1"} } | ||
/// </code> | ||
/// </example> | ||
public static RouteValueDictionary GetDefaults(RouteTemplate parsedTemplate) | ||
{ | ||
var result = new RouteValueDictionary(); | ||
|
||
/// <summary> | ||
/// Gets the default values for parameters in a parsed route template. | ||
/// </summary> | ||
/// <param name="parsedTemplate">The parsed route template.</param> | ||
/// <returns>A dictionary of default values for the template parameters.</returns> | ||
/// <example> | ||
/// Using this method: | ||
/// <code> | ||
/// var template = TemplateParser.Parse("/api/{version=v1}/users/{id}"); | ||
/// var defaults = RouteTemplateUtility.GetDefaults(template); | ||
/// // defaults will contain: { {"version", "v1"} } | ||
/// </code> | ||
/// </example> | ||
public static RouteValueDictionary GetDefaults(RouteTemplate parsedTemplate) | ||
foreach (var parameter in parsedTemplate.Parameters) | ||
{ | ||
var result = new RouteValueDictionary(); | ||
|
||
foreach (var parameter in parsedTemplate.Parameters) | ||
if (parameter.DefaultValue != null) | ||
{ | ||
if (parameter.DefaultValue != null) | ||
{ | ||
if (parameter.Name != null) result.Add(parameter.Name, parameter.DefaultValue); | ||
} | ||
if (parameter.Name != null) result.Add(parameter.Name, parameter.DefaultValue); | ||
} | ||
|
||
return result; | ||
} | ||
|
||
return result; | ||
} | ||
} |