UnityWebRequest downloadprogress problem

Hello there,

So here’s my problem, I have an application on Android that downloads medias from a server. To give a visual to the player I use the UnityWebRequest.downloadProgress. Everything was working fine while I was using Mono but as I wanted to release this app in the Google Play Store I had to switch my Scripting Backend to IL2CPP and that’s when things got tricky.
So I switched to IL2CPP and built an apk to test it on mobile before anything else and nothing moved on my downloading screen.
I logged the downloadprogress of my UnityWebRequest and the returning float was always 0 but all the medias were downloading correctly in the background.
This leads me to think that it’s the Scripting Backend switch that is the cause so I tried to do some researches on the internet but I couldn’t find anything helpful.
Do you guys have ever experienced this or do you have any clue on what’s going on ?

Here’s a part of my code :

private IEnumerator IEDOwnload(S3DownloadingInfo downloadInfo, Action callbackSuccess) {
        UnityWebRequest request =
        UnityWebRequest.Get(downloadInfo.url);
        request.downloadHandler = new FileDownloadHandler(new byte[256 * 1024], downloadInfo.filePath);

        request.SendWebRequest();

        if (request.isNetworkError) {
            Log.Error("S3Client - IEDownload - NetworkError : " + request.error);
            downloadInfo.status = DownloadStatus.NetworkError;
        } else if (request.error != null) {
            Log.Error("S3Client - IEDownload - RequestError : " + request.error);
            downloadInfo.status = DownloadStatus.RequestError;
        } else {
            Log.Info("S3Client - IEDownload : " + request.url + "\n" + request.downloadHandler.text);
            downloadInfo.status = DownloadStatus.Downloading;
            while (!request.isDone) {
                downloadInfo.progress = request.downloadProgress;
                yield return null;
            }
            downloadInfo.status = DownloadStatus.Done;
            callbackSuccess.Invoke();
        }
    }

Thank you for you time,

Cheers

This FileDownloadHandler that you use is your own handler, extending DownloadHandlerScript?
Did you override this:

Yes, here is my script :

public class FileDownloadHandler : DownloadHandlerScript {
    private int expected = -1;
    private int received = 0;
    private string filepath;
    private FileStream fileStream;
    private bool canceled = false;

    public FileDownloadHandler(byte[] buffer, string filepath)
        : base(buffer) {
        this.filepath = filepath;
        fileStream = new FileStream(filepath, FileMode.Create, FileAccess.Write);
    }

    protected override byte[] GetData() { return null; }

    protected override bool ReceiveData(byte[] data, int dataLength) {
        if (data == null || data.Length < 1) {
            return false;
        }
        received += dataLength;
        if (!canceled) fileStream.Write(data, 0, dataLength);
        return true;
    }

    protected override float GetProgress() {
        if (expected < 0) return 0;
        return (float)received / expected;
    }

    protected override void CompleteContent() {
        fileStream.Close();
    }

    protected override void ReceiveContentLength(int contentLength) {
        expected = contentLength;
    }

    public void Cancel() {
        canceled = true;
        fileStream.Close();
        File.Delete(filepath);
    }
}

Then check whether content length is received. Or examine all headers, maybe chunked transfer is used.

1 Like

Ok so you pointed me on the right direction and I was able to find the problem from there.

The problem was that method :

protected override void ReceiveContentLength(int contentLength) {
expected = contentLength;
}

It is actually obsolete now and therefor was never used.
So in my GetProgress method as the expected variable was -1 it would always return 0.

So to fix this I had to change ReceiveContentLength to :

protected override void ReceiveContentLengthHeader(ulong contentLength) {
expected = (int)contentLength;
}

And everything seems to work as expected after that.

I thank you for your time and good advice,

Have a good day

And it’s actually a bug. ReceiveContentLengthHeader implementation in base class calls ReceiveContentLength, but it seems code stripping was too agressive. I’ll have a looks at it, thanks for sharing.