Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multipart request sends and then throws NRE #2188

Open
DemonikGH opened this issue Apr 12, 2024 · 2 comments
Open

Multipart request sends and then throws NRE #2188

DemonikGH opened this issue Apr 12, 2024 · 2 comments
Labels

Comments

@DemonikGH
Copy link

DemonikGH commented Apr 12, 2024

Describe the bug
I'm trying to send request from Unity using RestSharp 110.2.0 - sending normal request works but when I make multipart request with attachment it sends requests and then immediately throws NullReferenceException from System.Net.Http.MultipartContent.Dispose. I tried attaching file using stream creating callback and file name with same results. This is an attempt to send discord webhook request with attachment and message actually appears on the server despite NRE after sending.

To Reproduce
Sending request with this code succeeds but throws exception:

request.Method = Method.Post;
request.AddFile("file1", file.FullName);
request.AddParameter("payload_json", message.ToJsonString(), ParameterType.RequestBody);
// request.AddHeader("Content-Type", "multipart/form-data");
var response = await client.ExecuteAsync(request); // Throws from ExecuteAsync

Expected behavior
Function successfully returning response after request has been sent.

Stack trace

NullReferenceException: Object reference not set to an instance of an object
System.Net.Http.MultipartContent.Dispose (System.Boolean disposing) (at <92a43029e91441ee9df5714eb5dcd209>:0)
System.Net.Http.HttpContent.Dispose () (at <92a43029e91441ee9df5714eb5dcd209>:0)
RestSharp.RequestContent.Dispose () (at <dfd03b4ab8614e549933c37db1618c06>:0)
RestSharp.RestClient.ExecuteRequestAsync (RestSharp.RestRequest request, System.Threading.CancellationToken cancellationToken) (at <dfd03b4ab8614e549933c37db1618c06>:0)
RestSharp.RestClient.ExecuteAsync (RestSharp.RestRequest request, System.Threading.CancellationToken cancellationToken) (at <dfd03b4ab8614e549933c37db1618c06>:0)
TestComponent.TestWebhookSend () (at Assets/Runtime/Scripts/TestComponent.cs:106)

Desktop (please complete the following information):

  • OS: Windows 10
  • .NET version: Unity 2023.2.16f1 (I think .NET 6 internally / .NET Standard 2.1 level), both il2cpp AOT and mono runtimes
  • Version 110.2.0
@DemonikGH DemonikGH added the bug label Apr 12, 2024
@DemonikGH
Copy link
Author

DemonikGH commented Apr 13, 2024

After debugging with dnspy I can see what's happening - it seems like RequestContent tries to dispose its content after it has been disposed already by HttpClient which I think it does after sending request. When disposing MultipartContent it does this (decompiled):

protected override void Dispose(bool disposing)
{
	if (disposing)
	{
		foreach (HttpContent httpContent in this.nested_content)
		{
			httpContent.Dispose();
		}
		this.nested_content = null;
	}
	base.Dispose(disposing);
}

So second call to that function would throw NRE while trying to enumerate nested_content. This is probably a bug in the System.Net.Http because Dispose is supposed to be safe to be called twice but that's not something I can replace. Can probably be worked around by not calling dispose on request content that has been disposed by HttpClient on .NET versions where bug is present if that is possible. This seems to have been fixed in reference source by replacing = null with .Clear() but that bug is still in version used by latest Unity.

@LiuweiY
Copy link

LiuweiY commented May 8, 2024

I encountered the same problem and resolved it by rolling back to version 110.0.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants