Skip to content

Commit

Permalink
[Build Tasks] Update CheckClientHandlerType errors (#8438)
Browse files Browse the repository at this point in the history
Context: d3e8767
Context: 311b41e

Updates the `CheckClientHandlerType` task to throw an XA1031 error when
`$(AndroidHttpClientHandlerType)` is set to a value that inherits from
`System.Net.Http.HttpClientHandler`.
  • Loading branch information
pjcollins committed Oct 19, 2023
1 parent 5df4a51 commit 1f5ae89
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 47 deletions.
5 changes: 5 additions & 0 deletions Documentation/guides/messages/xa1031.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ The 'AndroidHttpClientHandlerType' property value 'Foo.Bar.HttpHander, MyApp' mu
Please change the value to an assembly-qualifed type name which inherits from '{1}' or remove the property completely.
```

```
The 'AndroidHttpClientHandlerType' property value 'Xamarin.Android.Net.AndroidClientHandler' must not derive from 'System.Net.Htt.HttpClientHandler'.
Please change the value to an assembly-qualifed type name which inherits from 'System.Net.Http.HttpMessageHandler' or remove the property completely.
```

## Solution

Edit your csproj directly and change the 'AndroidHttpClientHandlerType' to
Expand Down
13 changes: 12 additions & 1 deletion src/Xamarin.Android.Build.Tasks/Properties/Resources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions src/Xamarin.Android.Build.Tasks/Properties/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,12 @@ Please change the value to an assembly-qualifed type name which inherits from '{
<comment>The following are literal names and should not be translated: 'AndroidHttpClientHandlerType',
{0} - The value of the property.
{1} - A type from which the AndroidHttpClientHandlerType should derive .</comment>
</data>
<data name="XA1031_HCH" xml:space="preserve">
<value>The 'AndroidHttpClientHandlerType' property value '{0}' must not derive from 'System.Net.Htt.HttpClientHandler'.
Please change the value to an assembly-qualifed type name which inherits from 'System.Net.Http.HttpMessageHandler' or remove the property completely.</value>
<comment>The following are literal names and should not be translated: 'AndroidHttpClientHandlerType', 'System.Net.Htt.HttpClientHandler', 'System.Net.Http.HttpMessageHandler',
{0} - The value of the property.</comment>
</data>
<data name="XA1032" xml:space="preserve">
<value>Failed to resolve '{0}' from '{1}'. Please check your `AndroidHttpClientHandlerType` setting.</value>
Expand Down
22 changes: 7 additions & 15 deletions src/Xamarin.Android.Build.Tasks/Tasks/CheckClientHandlerType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,12 @@ public class CheckClientHandlerType : AndroidTask

[Required]
public string ClientHandlerType { get; set; }
[Required]
public string ValidHandlerType { get; set; }

[Required]
public ITaskItem[] ResolvedAssemblies { get; set; }
public bool UsingAndroidNETSdk { get; set; }

public override bool RunTask ()
{
// Fast path for known types
if (UsingAndroidNETSdk) {
if (ClientHandlerType == "Xamarin.Android.Net.AndroidMessageHandler")
return !Log.HasLoggedErrors;
} else {
if (ClientHandlerType == "Xamarin.Android.Net.AndroidClientHandler")
return !Log.HasLoggedErrors;
}

string[] types = ClientHandlerType.Split (',');
string type = types[0].Trim ();
string assembly = "Mono.Android";
Expand Down Expand Up @@ -77,9 +66,12 @@ public override bool RunTask ()
return false;
}

string[] valueHandlerTypes = ValidHandlerType.Split (',');
if (!Extends (handlerType, valueHandlerTypes [0].Trim ())) {
Log.LogCodedError ("XA1031", Xamarin.Android.Tasks.Properties.Resources.XA1031, type, valueHandlerTypes [0]);
if (Extends (handlerType, "System.Net.Http.HttpClientHandler")) {
Log.LogCodedError ("XA1031", Xamarin.Android.Tasks.Properties.Resources.XA1031_HCH, type);
}

if (!Extends (handlerType, "System.Net.Http.HttpMessageHandler")) {
Log.LogCodedError ("XA1031", Xamarin.Android.Tasks.Properties.Resources.XA1031, type, "System.Net.Http.HttpMessageHandler");
}

return !Log.HasLoggedErrors;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,12 +161,8 @@ public void CheckHttpClientHandlerType ()
IsRelease = true,
};
var httpClientHandlerVarName = "XA_HTTP_CLIENT_HANDLER_TYPE";
var expectedDefaultValue = "System.Net.Http.HttpClientHandler, System.Net.Http";
var expectedUpdatedValue = "Xamarin.Android.Net.AndroidClientHandler";
if (Builder.UseDotNet) {
expectedDefaultValue = "System.Net.Http.SocketsHttpHandler, System.Net.Http";
expectedUpdatedValue = "Xamarin.Android.Net.AndroidMessageHandler";
}
var expectedDefaultValue = "System.Net.Http.SocketsHttpHandler, System.Net.Http";
var expectedUpdatedValue = "Xamarin.Android.Net.AndroidMessageHandler";

var supportedAbis = "armeabi-v7a;arm64-v8a";
proj.SetAndroidSupportedAbis (supportedAbis);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,47 +15,48 @@ namespace Xamarin.Android.Build.Tests
public class CheckClientHandlerTypeTests : BaseTest
{
[Test]
[TestCase ("Xamarin.Android.Net.AndroidMessageHandler", "System.Net.Http.HttpMessageHandler, System.Net.Http")]
[TestCase ("Xamarin.Android.Net.AndroidClientHandler", "System.Net.Http.HttpClientHandler, System.Net.Http")]
[TestCase ("System.Net.Http.SocketsHttpHandler, System.Net.Http", "System.Net.Http.HttpMessageHandler, System.Net.Http")]
public void ErrorIsNotRaised (string handler, string validBaseType)
[TestCase ("Xamarin.Android.Net.AndroidMessageHandler")]
[TestCase ("System.Net.Http.SocketsHttpHandler, System.Net.Http")]
public void ErrorIsNotRaised (string handler)
{
string path = Path.Combine (Root, "temp", TestName);
Directory.CreateDirectory (path);
string intermediatePath;
bool targetSkipped;
var proj = new XamarinAndroidApplicationProject () {
IsRelease = false,
};
proj.PackageReferences.Add (new Package() { Id = "System.Net.Http", Version = "*" });
proj.SetProperty ("AndroidHttpClientHandlerType", handler);
using (var b = CreateApkBuilder (path)) {
b.ThrowOnBuildFailure = false;
b.Build (proj); // we don't care it might error.
b.Build (proj);
intermediatePath = Path.Combine (path,proj.IntermediateOutputPath);
targetSkipped = b.Output.IsTargetSkipped ("_CheckAndroidHttpClientHandlerType");
}

if (handler.Contains ("Xamarin.Android.Net.AndroidMessageHandler"))
Assert.IsTrue (targetSkipped, "_CheckAndroidHttpClientHandlerType should not have run.");
else
Assert.IsFalse (targetSkipped, "_CheckAndroidHttpClientHandlerType should have run.");

string asmPath = Path.GetFullPath (Path.Combine (intermediatePath, "android", "assets"));
var errors = new List<BuildErrorEventArgs> ();
var warnings = new List<BuildWarningEventArgs> ();
List<ITaskItem> assemblies = new List<ITaskItem> ();
string[] files = Directory.GetFiles (asmPath, "*.dll");
string[] files = Directory.GetFiles (asmPath, "*.dll", SearchOption.AllDirectories);
foreach (var file in files)
assemblies.Add (new TaskItem (file));
IBuildEngine4 engine = new MockBuildEngine (System.Console.Out, errors, warnings);
var task = new CheckClientHandlerType () {
BuildEngine = engine,
ClientHandlerType = handler,
ResolvedAssemblies = assemblies.ToArray (),
ValidHandlerType = validBaseType,
};
Assert.True (task.Execute (), $"task should have succeeded. {string.Join (";", errors.Select (x => x.Message))}");
}

[Test]
#if !NET_6
[TestCase ("Xamarin.Android.Net.AndroidMessageHandler", "System.Net.Http.HttpClientHandler, System.Net.Http")]
#else
[TestCase ("Xamarin.Android.Net.AndroidClientHandler", "System.Net.Http.HttpMessageHandler, System.Net.Http")]
#endif
public void ErrorIsRaised (string handler, string validBaseType)
[TestCase ("Xamarin.Android.Net.AndroidClientHandler")]
public void ErrorIsRaised (string handler)
{
var path = Path.Combine (Root, "temp", TestName);
Directory.CreateDirectory (path);
Expand All @@ -73,18 +74,18 @@ public void ErrorIsRaised (string handler, string validBaseType)
var errors = new List<BuildErrorEventArgs> ();
var warnings = new List<BuildWarningEventArgs> ();
List<ITaskItem> assemblies = new List<ITaskItem> ();
string[] files = Directory.GetFiles (asmPath, "*.dll");
string[] files = Directory.GetFiles (asmPath, "*.dll", SearchOption.AllDirectories);
foreach (var file in files)
assemblies.Add (new TaskItem (file));
IBuildEngine4 engine = new MockBuildEngine (System.Console.Out, errors, warnings);
var task = new CheckClientHandlerType () {
BuildEngine = engine,
ClientHandlerType = handler,
ResolvedAssemblies = assemblies.ToArray (),
ValidHandlerType = validBaseType,
};
Assert.False (task.Execute (), $"task should have failed.");
Assert.AreEqual (1, errors.Count, $"An Error should have been raised. {string.Join (" ", errors.Select (e => e.Message))}");
Assert.AreEqual (1, errors.Count, $"One error should have been raised. {string.Join (" ", errors.Select (e => e.Message))}");
Assert.AreEqual ("XA1031", errors [0].Code, "Error code should have been XA1031.");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -486,15 +486,9 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved.
</Target>

<Target Name="_CheckAndroidHttpClientHandlerType"
Condition=" '$(AndroidHttpClientHandlerType)' != '' And '$(AndroidApplication)' == 'True' ">
<PropertyGroup>
<ValidAndroidHttpClientHandlerBaseType Condition="'$(UsingAndroidNETSdk)' != 'true'">System.Net.Http.HttpClientHandler, System.Net.Http</ValidAndroidHttpClientHandlerBaseType>
<ValidAndroidHttpClientHandlerBaseType Condition="'$(UsingAndroidNETSdk)' == 'true'">System.Net.Http.HttpMessageHandler, System.Net.Http</ValidAndroidHttpClientHandlerBaseType>
</PropertyGroup>
Condition=" '$(AndroidHttpClientHandlerType)' != '' And '$(AndroidHttpClientHandlerType)' != 'Xamarin.Android.Net.AndroidMessageHandler' And '$(AndroidApplication)' == 'True' ">
<CheckClientHandlerType
ClientHandlerType="$(AndroidHttpClientHandlerType)"
ValidHandlerType="$(ValidAndroidHttpClientHandlerBaseType)"
UsingAndroidNETSdk="$(UsingAndroidNETSdk)"
ResolvedAssemblies="$(OutDir)$(TargetFileName);@(ReferencePath);@(ReferenceDependencyPaths)"
/>
</Target>
Expand Down

0 comments on commit 1f5ae89

Please sign in to comment.