Search Unity

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

Discussion in 'Multiplayer' started by Wattosan, Nov 2, 2017.

  1. Wattosan

    Wattosan

    Joined:
    Mar 22, 2013
    Posts:
    460
    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. Wattosan

    Wattosan

    Joined:
    Mar 22, 2013
    Posts:
    460
    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:
    3,736
    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. Wattosan

    Wattosan

    Joined:
    Mar 22, 2013
    Posts:
    460
    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:
    3,736
    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. Wattosan

    Wattosan

    Joined:
    Mar 22, 2013
    Posts:
    460
    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:
    3,736
    Have you tried monitoring http traffic?
     
  8. guneyozsan

    guneyozsan

    Joined:
    Feb 1, 2012
    Posts:
    99
    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
  10. mitchmeyer1

    mitchmeyer1

    Joined:
    Sep 19, 2016
    Posts:
    32
    @guneyozsan @Aurimas-Cernius did you figure this out? I am struggling with this on webgl. Same headers existing. In my code i do

    Code (CSharp):
    1. var headers = www.GetResponseHeaders();
    2. //Show all the headers from UnityWebRequest
    3. for (int i = 0; i < headers.Count; i++)
    4. {
    5.     Debug.Log("KEY: " + headers.Keys.ToList()[i] + "    -    VALUE: " + headers[headers.Keys.ToList()[i]]);
    6. }
    this only returns Cache-Control and Content-Type headers

    However.... in the networking tab of my browser dev tools, if i look at the Response Headers for my request, it shows many response headers. I wrote the server and all CORS is *. The response headers are hitting my browser without being blocked, but going from the browser to unity is losing all but the 2 listed. Cant finish my feature without this. Please help!