Search Unity

UnityWebRequest Accept-Encoding issues on iOS/OSX

Discussion in 'Editor & General Support' started by vincent-savysoda, Jan 10, 2020.

  1. vincent-savysoda

    vincent-savysoda

    Joined:
    Dec 19, 2016
    Posts:
    33
    I'm not sure whether this is the right forum section to post about this issue, but has anyone gotten the Accept-Encoding/Content-Encoding headers to work properly with UnityWebRequest on iOS/OSX devices? I'm having this strange issue trying to implement Gzip decompression on our project. Basically two possible scenarios will happen:

    Scenario 1:
    SetRequestHeader("Accept-Encoding", "gzip") has been set on a web request call to our servers, which in a normal situation should return the data in the compressed format. This works on Windows/Android devices. However, on iOS/OSX devices, it will return "gzip" as the "Content-Encoding" Response header correctly, but never actually gives the compressed data/text, even though a check on the server end shows that it has been returned correctly.

    Scenario 2:
    The request header is NOT set, but it still somehow returns "gzip" as the "Content-Encoding" Response Header on iOS/OSX devices. As with the above scenario, it works fine with Android/Windows.

    In conclusion, it seems like no matter what header is set, it always returns the same header/content on iOS/OSX devices.

    The following is a snippet/example of the code for the web request implementation:

    Code (CSharp):
    1. w.SetRequestHeader("Accept-Encoding", "gzip");
    2. yield return w.SendWebRequest();
    3. string headerResponse = w.GetResponseHeader("Content-Encoding");
    4. string returnedText = w.downloadHandler.text;
    5. string returnedData = w.downloadHandler.data;
    6.  
    In the above code the "headerResponse" is always "gzip" and the returnedText/returnedData are always NOT gzip compressed regardless of what header request was set.

    Am I doing something wrong here?
     
  2. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,736
    Have you read documentation on SetRequestHeader?

    What happens depends on whether backend on given platform supports gzip compression or not. If backend does support gzip, it will by default send relevant header and handle it for you without you having to do anything.

    By overriding that header you only affect the platforms that don't have built-in support. Those, that do have gzip support will automatically decompress the received data, while on platforms without gzip support you'll get compressed data.

    Also note, that on Android this might be different on different Android versions or phones from different manufacturers.
     
  3. vincent-savysoda

    vincent-savysoda

    Joined:
    Dec 19, 2016
    Posts:
    33
    @Aurimas-Cernius So from what you're saying if I understand correctly, is that on platforms that support gzip decompression I do not have to set the request header? Or do I have to set the request header still but the decompression is handled automatically by Unity? If I don't have to set the request header, how does the client know whether the server backend supports gzip compression?

    Also in regards to Android, I'm not too clear on what you mean by that. Are you saying that certain versions/models don't support gzip? If yes, how do I know whether its supported?

    Also note that the documentation on this is not particularly clear either.
     
  4. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,736
    If you don't set the header, it will be set automatically to a list of supported compressions and it's up to server to choose from them. And yes, the data will be automatically decompressed whenever server sends data in a supported compression format, you'll get compressed data out only if it is compressed in an unsupported format.

    On Android Unity versions before 2019.2 simply uses Java APIs for HTTP requests, so with regard to compression it comes down to what those APIs support, so a newer Android version can certainly add support for compression and it will work out of the box.
    Since Unity 2019.2 we changed the implementation and I believe it should support gzip now.

    That is why we recommend to leave that header out. By setting it manually you are claiming to support compression, while implementation may not. In order to know at receiving end whether you've got compressed or uncompressed data, you should check the magic numbers in received data (a probably less reliable, but likely to succeed way it to check the size of data and compare it with Content-Length header, the later will have the size of compressed data).