Dracon
Dracon

Reputation: 81

Set UTF-8 Encoding on Azure Functions Http Trigger

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);
            }
        }

Upvotes: 1

Views: 4662

Answers (1)

Jack Jia
Jack Jia

Reputation: 5549

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);
    }

}

Upvotes: 1

Related Questions