-
Notifications
You must be signed in to change notification settings - Fork 180
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* add RegexEntrySanitizer and accompanying tests * Update tools/test-proxy/Azure.Sdk.Tools.TestProxy/Sanitizers/RegexEntrySanitizer.cs
- Loading branch information
Showing
3 changed files
with
201 additions
and
0 deletions.
There are no files selected for viewing
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
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
83 changes: 83 additions & 0 deletions
83
tools/test-proxy/Azure.Sdk.Tools.TestProxy/Sanitizers/RegexEntrySanitizer.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 |
---|---|---|
@@ -0,0 +1,83 @@ | ||
using Azure.Sdk.Tools.TestProxy.Common; | ||
using Azure.Sdk.Tools.TestProxy.Common.Exceptions; | ||
using System.Linq; | ||
using System.Text.RegularExpressions; | ||
|
||
namespace Azure.Sdk.Tools.TestProxy.Sanitizers | ||
{ | ||
/// <summary> | ||
/// This sanitizer applies at the session level, just before saving a recording to disk. | ||
/// | ||
/// It cleans out all request/response pairs that that match the defined settings. A match against URI, Header, or Body regex will result in the entire RecordEntry being omit from the recording. | ||
/// </summary> | ||
public class RegexEntrySanitizer : RecordedTestSanitizer | ||
{ | ||
private Regex rx; | ||
private string section; | ||
private string[] validValues = new string[] { "uri", "header", "body" }; | ||
|
||
public string ValidValues | ||
{ | ||
get { return string.Join(", ", validValues.Select(x => "\"" + x + "\"")); } | ||
} | ||
|
||
/// <summary> | ||
/// During sanitization, each RecordEntry within a session is checked against a target (URI, Header, Body) and a regex. If there is any match within the request, the whole request/response pair is omitted from the recording. | ||
/// </summary> | ||
/// <param name="target">Possible values are [ "URI", "Header", "Body"]. Only requests with text-like body values will be checked when targeting "Body". The value is NOT case-sensitive.</param> | ||
/// <param name="regex">During sanitization, any entry where the 'target' is matched by the regex will be fully omitted. Request/Reponse both.</param> | ||
public RegexEntrySanitizer(string target, string regex) | ||
{ | ||
section = target.ToLowerInvariant(); | ||
|
||
if (!validValues.Contains(section)) | ||
{ | ||
throw new HttpException(System.Net.HttpStatusCode.BadRequest, $"When defining which section of a request the regex should target, only values [ {ValidValues} ] are valid."); | ||
} | ||
|
||
rx = StringSanitizer.GetRegex(regex); | ||
} | ||
|
||
public bool CheckMatch(RecordEntry x) | ||
{ | ||
switch (section) | ||
{ | ||
case "uri": | ||
return rx.IsMatch(x.RequestUri); | ||
case "header": | ||
foreach (var headerKey in x.Request.Headers.Keys) | ||
{ | ||
// Accessing 0th key safe due to the fact that we force header values in without splitting them on ;. | ||
// We do this because letting .NET split and then reassemble header values introduces a space into the header itself | ||
// Ex: "application/json;odata=minimalmetadata" with .NET default header parsing becomes "application/json; odata=minimalmetadata" | ||
// Given this breaks signature verification, we have to avoid it. | ||
var originalValue = x.Request.Headers[headerKey][0]; | ||
|
||
if (rx.IsMatch(originalValue)) | ||
{ | ||
return true; | ||
} | ||
} | ||
break; | ||
case "body": | ||
if (x.Request.TryGetBodyAsText(out string text)) | ||
{ | ||
return rx.IsMatch(text); | ||
} | ||
else | ||
{ | ||
return false; | ||
} | ||
default: | ||
throw new HttpException(System.Net.HttpStatusCode.BadRequest, $"The RegexEntrySanitizer can only match against a target of [ {ValidValues} ]."); | ||
} | ||
|
||
return false; | ||
} | ||
|
||
public override void Sanitize(RecordSession session) | ||
{ | ||
session.Entries.RemoveAll(x => CheckMatch(x)); | ||
} | ||
} | ||
} |