Issue with downloading a file through HttpRequest (Unity's web service REST API)

Godot Version

4.2.2 Mono

Question

I know this isn’t a specific Godot-related question, but I literally cannot find any information to fix this problem.

I am currently porting Unity Gaming Services to Godot 4+ Mono and currently working on the user-generated content service. One issue I am running into is downloading files from the service using HTTP requests (specifically RestSharp here, tried normal and still an error). It works fine with cloud save but fails with user-generated content.

When trying to download files from the service I keep running into an authentication error:

<?xml version='1.0' encoding='UTF-8'?><Error><Code>AuthenticationRequired</Code><Message>Authentication required.</Message></Error>

My Jwt auth token is working fine, I already call a request to get the content (method below) to get the URL to download. The getting of content in the first place wouldn’t work if there were a Jwt token-related auth issue.

Get Content Method:

public async Task<Content> GetContentAsync(GetContentArgs getContentArgs)
    {
        Validate();

        var request = new RestRequest(
            $"/v1/projects/{ProjectId}/environments/{EnvironmentId}/content/{getContentArgs.ContentId}"
        )
        {
            RequestFormat = DataFormat.Json
        }.AddQueryParameter("includeStatistics", getContentArgs.IncludeStatistics);

        var response = await ugcClient.ExecuteAsync<InternalContent>(request);
        if (response.IsSuccessful)
        {
            var content = new Content(response.Data);
            await DownloadContentDataAsync(content, getContentArgs.DownloadContent, getContentArgs.DownloadThumbnail);
            return content;
        }
        else
        {
            throw new UgcException(response.Content, response.ErrorMessage, response.ErrorException);
        }
    }

Download Content Method: (error causing method)

public async Task DownloadContentDataAsync(Content content, bool downloadContent, bool downloadThumbnail)
    {
        Validate();

        if (downloadContent) // just keep getting auth errors, both RestSharp and normal don't work
        {
            using var httpClient = new System.Net.Http.HttpClient();
            httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
                "Bearer",
                AuthenticationService.Instance.AccessToken
            );

            var response = await httpClient.GetAsync(content.DownloadUrl);
            if (response.IsSuccessStatusCode)
            {
                content.DownloadedContent = await response.Content.ReadAsByteArrayAsync();
            }
            else
            {
                throw new UgcException(await response.Content.ReadAsStringAsync(), response.ReasonPhrase, null);
            }
        }

        // if (downloadContent)
        // {
        //     var request = new RestRequest(content.DownloadUrl) { RequestFormat = DataFormat.Json };
        //     GD.Print(content.DownloadUrl);

        //     var response = await ugcClient.ExecuteAsync(request);
        //     if (response.IsSuccessful)
        //         content.DownloadedContent = response?.RawBytes ?? null;
        //     else
        //         throw new UgcException(response.Content, response.ErrorMessage, response.ErrorException);
        // }

        if (downloadThumbnail && !string.IsNullOrEmpty(content.ThumbnailUrl))
        {
            var request = new RestRequest(content.ThumbnailUrl) { RequestFormat = DataFormat.Json };

            var response = await ugcClient.ExecuteAsync(request);
            if (response.IsSuccessful)
                content.DownloadedThumbnail = response?.RawBytes ?? null;
            else
                throw new UgcException(response.Content, response.ErrorMessage, response.ErrorException);
        }
    }

No idea what is causing this. Here’s the repo (line 746) if you want to go further.

My god. I have the answer after searching and logging many resources (even Unity’s source). Remove any JWT auth headers. They break it. It’s super weird, I thought they would just be ignored.

var restClient = new RestClient();

        if (downloadContent)
        {
            var request = new RestRequest(content.DownloadUrl) { RequestFormat = DataFormat.Json };

            var response = await restClient.ExecuteAsync(request);
            if (response.IsSuccessful)
                content.DownloadedContent = response?.RawBytes ?? null;
            else
                throw new UgcException(response.Content, response.ErrorMessage, response.ErrorException);
        }

        if (downloadThumbnail && !string.IsNullOrEmpty(content.ThumbnailUrl))
        {
            var request = new RestRequest(content.ThumbnailUrl) { RequestFormat = DataFormat.Json };

            var response = await restClient.ExecuteAsync(request);
            if (response.IsSuccessful)
                content.DownloadedThumbnail = response?.RawBytes ?? null;
            else
                throw new UgcException(response.Content, response.ErrorMessage, response.ErrorException);
        }

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.