1

EDIT Just in case im misdiagnosing, Here is an example of what is sent: T6NLmFUZdYYdvhxmq67WD/TiShKbE0rK0xdHXJGo5sVx9/CrmBTViiQxjqLEQN66HkAUB9LvXW6C55maPLMd7u2cwNc8OlNuPTvZfx63Aawso/2mvewXQauUytGZ1Q8D

And what is received: T6NLmFUZdYYdvhxmq67WD%2fTiShKbE0rK0xdHXJGo5sVx9%2fCrmBTViiQxjqLEQN66HkAUB9LvXW6C55maPLMd7u2cwNc8OlNuPTvZfx63Aawso%2f2mvewXQauUytGZ1Q8D

The '%2' instead of the backslash is the best example of what im talking about

EDIT2 For those who come after: the upload handler raw did the trick, and fixed it. However, if you then want to be able to access the servers reply, you need to create a download handler. For text, use DownloadHandlerBuffer, e.g

www.downloadHandler = new DownloadHandlerBuffer();

Then once you have sent the request, use this to get a string response:

string response = System.Text.Encoding.UTF8.GetString(www.downloadHandler.data);

Im sending a REST call using Unity's UnityWebRequest, to the Azure functions HttpTrigger type functionality.

Now, both of these functions do not expose bytes, they do that in the backend and hand me strings. However, when my function is receiving my data, it is containing a lot of escaped characters, and I believe its not encoded properly. I am not sure HOW to encode it properly, considering I cant just convert my string to a byte[] with UTF8.GetBytes, and vis versa.

Apologies if duplicate, I searched and couldnt find a similar enough issue.

See unity and azure code here: https://pastebin.com/pE4dYSfF

//UNITY SIDE
IEnumerator Foo()
    {
        var N = JSON.Parse("{}");
        N["input1"] = input1.text;
        N["input2"] = input2.text;
        string encrypted = Encrypt(N.ToString(), GenerateEncryptionKey);

        print("ENSEND: \n" + encrypted);
        using (UnityWebRequest www = UnityWebRequest.Post(targetURL, encrypted))
        {
            yield return www.SendWebRequest();

            if (www.isHttpError || www.isNetworkError)
            {
                Debug.LogError(www.error + "\n" + www.downloadHandler.text);
                onFail?.Invoke();
            }
            else
            {
                onSuccess?.Invoke();
                print(www.responseCode + " : " + www.downloadHandler.text);
            }

        }
        yield break;
    }

//FUNCTION SIDE 
[FunctionName("UserAuthentication")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");

            string name = req.Query["name"];

            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            try
            {
                requestBody = Decrypt(requestBody, "Dracon");
            } catch (Exception e)
            {
//Throwing exception here due to escaped characters
                return new BadRequestObjectResult(e.Message + "\n" + requestBody + "\n" + Regex.Unescape(requestBody));
            }

            JSONNode N = null;
            try
            {
                N = JSON.Parse(requestBody);
                if (N["input1"] != "")
                {
                    name = N["username"];
                    return (ActionResult)new OkObjectResult($"Hello, {name}");
                } else if (name != "")
                {
                    return (ActionResult)new OkObjectResult($"Hello, {name}");
                } else
                {
                    return new BadRequestObjectResult("Invalid object syntax");
                }
            } catch (Exception e)
            {
                return new BadRequestObjectResult("Invalid JSON provided. N = " + (N != null).ToString() + "\n" + requestBody + "\n" + e.Message);
            }
        }
Dracon
  • 81
  • 1
  • 7
  • Is this your are looking? https://stackoverflow.com/questions/5864272/understanding-text-encoding-in-net – Pankaj Rawat Apr 07 '20 at 05:22
  • @PankajRawat while this does shed some light on some UTF-8 things I hadnt known recently, its not so useful around instruction to convert to UTF-8, or from UTF-8 to another encoding type. I am going to try simply converting my string to a byte array and parsing that array with my chosen encoding type, but I would definitely like to know if theres a wider-spread technique for this – Dracon Apr 07 '20 at 05:43

1 Answers1

1

I see that there is an Encrypt function in your Unity side and a Decrypt function in your Azure function side.

So, you need to figure out if the encrypted contents were all normal characters. If they were normal characters, you may try to set Content-Type as the following:

using (UnityWebRequest www = UnityWebRequest.Post(targetURL, encrypted))
{
    www.SetRequestHeader("Content-Type", "text/plain; charset=UTF-8");
    yield return www.SendWebRequest();

    if (www.isHttpError || www.isNetworkError)
    {
        Debug.LogError(www.error + "\n" + www.downloadHandler.text);
        onFail?.Invoke();
    }
    else
    {
        onSuccess?.Invoke();
        print(www.responseCode + " : " + www.downloadHandler.text);
    }

}

www.SetRequestHeader("Content-Type", "text/plain; charset=UTF-8"); will ensure that all bytes will be encoded in utf-8.

However, if there were some special characters, I suggest you set the Content-Type as application/octet-stream. In this way, the Azure function will just keep all bytes of the request body for you.


Use UploadHandlerRaw

using (UnityWebRequest www = new UnityWebRequest(url,"POST"))
{
    byte[] body = Encoding.UTF8.GetBytes(encrypted);
    www.uploadHandler = new UploadHandlerRaw(body);
    www.SetRequestHeader("Content-Type", "text/plain; charset=UTF-8");
    yield return www.SendWebRequest();

    if (www.isHttpError || www.isNetworkError)
    {
        Debug.LogError(www.error + "\n" + www.downloadHandler.text);
        onFail?.Invoke();
    }
    else
    {
        onSuccess?.Invoke();
        print(www.responseCode + " : " + www.downloadHandler.text);
    }

}
Jack Jia
  • 5,268
  • 1
  • 12
  • 14
  • I had tried the text/plain with utf-8 content type header before, with no effect, but I hadnt yet tried octet-stream! I'll give that a go! The encrypt/decrypt are just a basic AES encryption laid on top of the content, so possibly some special characters there – Dracon Apr 07 '20 at 06:09
  • No luck unfortunately. I added www.SetRequestHeader("Content-Type", "application/octet-stream"); But still got escaped characters in return – Dracon Apr 07 '20 at 06:17
  • From `Decrypt` function? – Jack Jia Apr 07 '20 at 06:21
  • nope, from the azure side. I added an edit up the top so you can see the before and after. The before is a print just before its sent, the after im attaching to the error and reading from the response – Dracon Apr 07 '20 at 06:32
  • It seems that `UnityWebRequest.Post` is trying to send a form urlencoded body. – Jack Jia Apr 07 '20 at 06:38
  • Try to use [UploadHandlerRaw](https://docs.unity3d.com/ScriptReference/Networking.UploadHandlerRaw.html) – Jack Jia Apr 07 '20 at 06:43
  • Ah. Hmmm ill have to do some research on how to get around that **EDIT** didnt see your other commend :) Will do! – Dracon Apr 07 '20 at 06:45
  • You are a god amonst mortals :) Worked! Im getting a null ref on the success print, but im sure I can figure it out. Thank you so much. Havent been this stumped on a problem for a long while. – Dracon Apr 07 '20 at 06:53