Search code examples
c#unity-game-engineunity-webglunitywebrequest

Unity WebGL UnityWebRequest Bad Body Data


I have a Unity game hosted on a web publishing platform. This game connects to several APIs, including Microsoft PlayFab, Google Analytics, and our own back end server. Sometimes (very rarely, less than 0.1% of the time) the game fails to connect to any of these services, and I'm not sure why. I have never been able to reproduce this locally. We currently have not been able to isolate it to a particular region, due to its rarity. It seems to affect specific computers/households. Multiple browsers on the same computer running the game will fail the same way. Sometimes multiple computers in the same household will also be affected.

Microsoft and Google both return a 400 error, and our own service replies with a 400. Unity notes that an 'Unknown Error' occurred during the UnityWebRequest.

I cannot look at the data sent/received with Microsoft or Google, but I can look at our own server logs, and things get strange. The UnityWebRequest is making it to our service, which is hosted on AWS and proxied by CloudFlare. The URL is correct, but the request body seems completely bizarre:

"\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\b\u0000\u0000\u0000\u0000\u0000\u0000\u0000xך\u0000\u0000\u0000\u0000\u0000`ך\u0000�\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000`ך\u0000!\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0010\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"

That's the contents of the request body. If I grab the bytes (assuming a UTF8 encoded string) then I get the following:

byte[72] { 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 120, 215, 154, 0, 0, 0, 0, 0, 96, 215, 154, 0, 239, 191, 189, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 215, 154, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }

My first guess was that AWS/CloudFlare/Google are perhaps blocked by certain firewalls or regions, but if that were the case I would not expect anything to have made it to our own AWS server to analyze. So now I am not sure...

Here's the relevant Unity (2018.2.21f1) code:

UnityWebRequest www = UnityWebRequest.Post(uri, body);
UploadHandlerRaw uploadHandler = new UploadHandlerRaw(Encoding.UTF8.GetBytes(body));
uploadHandler.contentType = "application/json";
www.uploadHandler = uploadHandler;
www.SetRequestHeader("Content-Type", "application/json");

yield return www.Send();

if (www.isNetworkError || www.isHttpError)
{
    Log(ELoggingLevel.Error, "Error while sending data: [{0}]", www.error);
}
else
{
    var contents = www.downloadHandler.text;
    // do useful stuff here
}

The logger does fire, so either isNetworkError or isHttpError are true.

[Error]: Error while sending data: [Unknown Error]

Does anyone have any thoughts on what is going on? Does anyone recognize that data being logged by the server? It appears like my Unity game just refuses to send any type of reasonable data in some sort of rare situation.

Edit: I logged the content type on the server, and am correctly getting application/json, which would suggest a solid amount of the data is arriving properly. The body data is also identical across multiple users. Unity is probably only returning an error because of the 400 being returned by the server.


Solution

  • This particular issue was caused by antivirus software. We found the affected users were using Kaspersky antivirus, and specifically a feature called 'Integrate script for interaction with websites into traffic', under the 'Traffic Processing' tab. I have no clue why Kaspersky thinks this is a reasonable thing to do, and I imagine it must break more than just our game, but there it is. The user can simply disable that option in Kaspersky and the UnityWebRequest will run as normal.