Search Unity

WWW.responseHeaders not returning all of the values. Or returning incorrect ones.

Discussion in 'Connected Games' started by F-R-O-S-T-Y, Nov 2, 2017.

  1. F-R-O-S-T-Y

    F-R-O-S-T-Y

    Joined:
    Mar 22, 2013
    Posts:
    234
    Hey,

    I've come across a problem that the WWW class seems to work correctly in the Unity Editor but not in the Android or the WebGL (using Chrome) builds.
    I make a request to the server using the WWW class. I get back a response, which's headers I can access through the WWW.responseHeaders. What I need to get is a "Set-Cookie" header and it needs to include "PHPSESSID: ...".

    Inside the editor, everything works fine. When I use a for loop to go through the WWW.responseHeaders, one of the headers is "Set-Cookie" and it contains "PHPSESSID" plus some other attributes. This can be seen on the following image:

    However, on android or webgl, the results are different.
    Set-Cookie header is present but only the returningMinTimer part gets through (is listed with the for loop) as seen on the following picture:
    Plus 2 more fields (X-Android-Sent-Millis:150... & X-Powered-By: PHP/5.6.30).

    In WebGL, the WWW.responseHeaders does not contain the "Set-Cookie" header at all. The WebGL debug.log can be seen in the following image:

    What is interesting with the WebGL build however, is that when I use the developers tools and go to the Networking tab to see the requests I sent and look at the header returned to the browser...
    My request was split into two requests. Originally, the request was supposed to be a POST request. But instead, first an OPTIONS request is sent and then a POST request right afterwards. In the OPTIONS request's response headers, the "Set-Cookie" is missing:
    And the POST request DOES not only contain the "Set-Cookie" header but also has the "PHPSESSID" parameter (you can ignore the fact that there are multiple PHPSESSID-s):

    All of this leads me to believe that the WebGL and Android builds process WWW headers differently from the Unity build. The android version only receives one parameter of the Set-Cookie, while the WebGL build separates the request into two (OPTIONS and POST) and the responseHeaders are taken from the OPTIONS headers. And this is incorrect.

    Any help would be very much appreciated!
    Thank you!
     
  2. F-R-O-S-T-Y

    F-R-O-S-T-Y

    Joined:
    Mar 22, 2013
    Posts:
    234
    I believe one of the reasons things fail on Unity side when using the WebGL build, is that my request is split into two parts: OPTIONS and POST. The response from the OPTIONS is what I get back. And this is the response where Set-Cookie is missing. The POST gets finished but I never recieve that response because I already received the OPTIONS response.

    About android I'm not sure if the request gets split as well or not.
     
  3. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    2,279
    There is a known bug on Android that headers are not available, when response has no body. It's been fixed, but the patch release with the fix is not yet out (i.e. the fix was included into upcoming 2017.1 just yesterday, so it will be out probably late next week or so).
     
  4. F-R-O-S-T-Y

    F-R-O-S-T-Y

    Joined:
    Mar 22, 2013
    Posts:
    234
    Thank you for the answer.

    But what about the WebGL build? Any ideas why the request gets split up and the WWW class is able to receive only the first response (if that indeed is the case)?
     
  5. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    2,279
    I can't answer that. Is it really the case that your request is split into two? Can you examine it using some proxy (like fiddler), to make sure it is the case and that you indeed get data from OPTIONS request despite you actually sending POST?
     
  6. F-R-O-S-T-Y

    F-R-O-S-T-Y

    Joined:
    Mar 22, 2013
    Posts:
    234
    I'd have to mention that we also have CORS setup on our server. So, the reason for OPTIONS is to notify the server of an incoming POST request. It's however very weird that the result headers in the WWW object seem to be from the OPTIONS response headers, rather than the POST response headers. And this is only a problem in WebGL builds (mozilla, chrome, edge). They all have the same error.

    Or perhaps, the response headers are indeed from the POST response, but just like with android, some of the header data is dropped/lost for some reason.
     
  7. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    2,279
    Have you tried monitoring http traffic?
     
  8. guneyozsan

    guneyozsan

    Joined:
    Feb 1, 2012
    Posts:
    63
    I hit the same issue with 2018.2.11f and 2018.2.13f for WebGL builds. In the editor it works fine.
    Backend sends this headers but GetResponseHeaders() gets only Cache-Control and Content-Type headers. Using GetResponseHeader() for an other specific header returns null.

    About http traffic, on Firefox console I can confirm I receive other headers correctly, also as I mentioned editor works fine with the same server connection.

    Server headers:
    Code (PHP):
    1. header($_SERVER["SERVER_PROTOCOL"] . " 200 OK");
    2. header("Cache-Control: private"); // needed for internet explorer
    3. header("Content-Transfer-Encoding: Binary");
    4. header("Content-Length:".filesize($attachment_location));
    5. header("Content-Disposition: attachment; fileName=" . $file_name);
    6. header('Access-Control-Allow-Origin: *');
    7. readfile($attachment_location);
    Here GetResponseHeader returns null on WebGL build but works fine on editor:
    Code (CSharp):
    1. public static string GetFileName(UnityWebRequest www)
    2. {
    3.     string contentDispositionString = www.GetResponseHeader("Content-Disposition");
    4.     contentDispositionString = Uri.EscapeDataString(contentDispositionString);
    5.     ContentDisposition contentDisposition =
    6.         new ContentDisposition(contentDispositionString);
    7.     return contentDisposition.FileName;
    8. }
     
  9. fwalkerCirca

    fwalkerCirca

    Joined:
    Apr 10, 2017
    Posts:
    57
    Yes, exact same problem here. Has anyone heard of any solutions.
    I imagine this is associate with CORS.
     
    Last edited: Mar 29, 2019