Search Unity

Best HTTP Released

Discussion in 'Assets and Asset Store' started by BestHTTP, Sep 11, 2013.

  1. Jribs

    Jribs

    Joined:
    Jun 10, 2014
    Posts:
    154
    @BestHTTP

    Hi, I am running into a new issue with the socket.io implementation.

    I recently upgraded this asset to the latest update and I also updated my server socket.io to the latest version of that which is 2.1.1.

    I am now having strange issues on receiving messages from my server. On messages that are larger objects, it looks like the data is being cut off.

    Lets say I have this as an example

    Server code emiting something simple like this.
    Code (JavaScript):
    1. socket.emit('eventName', largeObjectOfData);
    In Unity I have this
    Code (CSharp):
    1.  
    2. private void OnEventName(Socket s, Packet p, params object[] a)
    3. {
    4.    Debug.Log(p); // Shows my object data in the packet but the data is cut off, making it an invalid object
    5.    Debug.Log(a); // Is null
    6. }
    7.  
    Is there anything I have to do differently in the latest version?

    Another part that is strange with this is when I run my server on my local machine, the socket data gets through fine, but this issue happens when my server is on an external server on AWS.
     
  2. Ginxx009

    Ginxx009

    Joined:
    Sep 11, 2016
    Posts:
    89
    @BestHTTP

    I am facing this error right now


    Unity: Ex [HTTPRequest]: CallCallback - Message: Object reference not set to an instance of an object StackTrace: at GameTable_baccarat+<UpdateDealerInfo>c__Iterator1+<UpdateDealerInfo>c__AnonStorey2.<>m__0 (BestHTTP.HTTPRequest req, BestHTTP.HTTPResponse res) [0x0000a] in <9d42b76470c74799a5fe701e9d5f700d>:0

    It is perfectly working on the Editor but when I built it on Android Platform that error occurs and doesn't get the image from my server. Here's my UpdateDealerInfo method

    Code (CSharp):
    1. public IEnumerator UpdateDealerInfo(int i, GameTable_baccarat[] script_gametable)
    2. {
    3.     if (i >= tzPlayInfo.Instance.bc_gametablelist.Count)
    4.     {
    5.         yield break;
    6.     }
    7.  
    8.     yield return new WaitForEndOfFrame();
    9.  
    10.     string dlrimage = tzPlayInfo.Instance.bc_gametablelist[i].dlrimage;
    11.     string dlrname = tzPlayInfo.Instance.bc_gametablelist[i].dlrname;
    12.     string dlrid = tzPlayInfo.Instance.bc_gametablelist[i].dlr.ToString();
    13.     string gametable_no = tzPlayInfo.Instance.bc_gametablelist[i].gametable_no.ToString();
    14.  
    15.     string url = CheckJSonManager.Instance._DataCenterJson.dataCenter;
    16.  
    17.     new BestHTTP.HTTPRequest(new System.Uri(url + "/resources/dealer/pic/" + dlrimage),
    18.     (BestHTTP.HTTPRequest req, BestHTTP.HTTPResponse res)
    19.     =>
    20.     {
    21.         var texture = new Texture2D(20, 20);
    22.         texture.LoadImage(res.Data);
    23.         script_gametable[i].img_dealer.mainTexture = texture;
    24.  
    25.     }).Send();
    26.  
    27.     script_gametable[i].info_dealer_name.text = dlrname;
    28.     script_gametable[i].info_dealer_id.text = dlrid;
    29.     script_gametable[i].info_gametable_no.text = gametable_no;
    30. }
    So can someone help me out why it is happening on Android
     
  3. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @Jribs

    Is it possible that for some reason the plugin can't upgrade the Socket.IO protocol to the websocket transport?
    What whappens when you set up the SocketManager like this?
    Code (CSharp):
    1. SocketOptions options = new SocketOptions();
    2. options.ConnectWith = BestHTTP.SocketIO.Transports.TransportTypes.WebSocket;
    3.  
    4. Manager = new SocketManager(new Uri("http://myserver/socket.io/"), options);
    This way it should connect straight with the websocket transport. (The polliong transport has a bug that can cause an issue just what you experienced.)
     
  4. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @Ginxx009

    Is your script_gametable.img_dealer is valid when the request's callback is called?
    Also, you can use the request in a coroutine like this:
    Code (CSharp):
    1.         HTTPRequest request = new BestHTTP.HTTPRequest(new System.Uri(url + "/resources/dealer/pic/" + dlrimage));
    2.        
    3.         yield return request.Send();
    4.  
    5.         if (request.State == HTTPRequestStates.Finished && request.Response.IsSuccess)
    6.         {
    7.             var texture = new Texture2D(20, 20);
    8.             texture.LoadImage(request.Response.Data);
    9.             script_gametable[i].img_dealer.mainTexture = texture;
    10.         }
    11.         else
    12.             Debug.LogError("dealer image request failed!")
     
  5. Ginxx009

    Ginxx009

    Joined:
    Sep 11, 2016
    Posts:
    89
    it's getting me the else statement . The one script i used before your code was working actually . But it doesn't get my image when i tried to build it on android
     
  6. Ginxx009

    Ginxx009

    Joined:
    Sep 11, 2016
    Posts:
    89
    I just have a question also sir . I'm currently using 2018.2.5f1 Unity Version . On your HTTPResponse.cs it has an error on Line 131 : if(texture.LoadImage(Data) == false). So what I did to solve this is add---> using UnityEngine; After doing that. My problem on android start appearing.
     
  7. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @Ginxx009

    What version of the plugin are you using?
    LoadImage became an extension method long time ago and had to add the using UnityEngine so it can be found instead of using Texture2D by fully qualify it with the namespace. But this was, i don't know, maybe one or two year ago in the Unity 5.x era.

    To handle the else branch and log out what was the problem you can use this:
    Code (CSharp):
    1. yield return request.Send();
    2.  
    3. if (request.State == HTTPRequestStates.Finished && request.Response.IsSuccess)
    4. {
    5.     // ...
    6. }
    7. else
    8. {
    9.     var resp = request.Response;
    10.     switch (request.State)
    11.     {
    12.         // The request finished without any problem.
    13.         case HTTPRequestStates.Finished:
    14.             if (resp.IsSuccess)
    15.             {
    16.                 Debug.Log("Request Finished Successfully! Response: " + resp.DataAsText);
    17.  
    18.                 // TODO: Request finished. Process server sent data.
    19.             }
    20.             else // Internal server error?
    21.                 Debug.LogWarning(string.Format("Request Finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}",
    22.                                                 resp.StatusCode,
    23.                                                 resp.Message,
    24.                                                 resp.DataAsText));
    25.             break;
    26.  
    27.         // The request finished with an unexpected error. The request's Exception property may contain more info about the error.
    28.         case HTTPRequestStates.Error:
    29.             Debug.LogWarning("Request Finished with Error! " + (request.Exception != null ? (request.Exception.Message + "\n" + request.Exception.StackTrace) : "No Exception"));
    30.             break;
    31.  
    32.         // The request aborted, initiated by the user.
    33.         case HTTPRequestStates.Aborted:
    34.             Debug.LogWarning("Request Aborted!");
    35.             break;
    36.  
    37.         // Connecting to the server is timed out.
    38.         case HTTPRequestStates.ConnectionTimedOut:
    39.             Debug.LogError("Connection Timed Out!");
    40.             break;
    41.  
    42.         // The request didn't finished in the given time.
    43.         case HTTPRequestStates.TimedOut:
    44.             Debug.LogError("Processing the request Timed Out!");
    45.             break;
    46.     }
    47. }
     
  8. Caronte3D

    Caronte3D

    Joined:
    Sep 16, 2014
    Posts:
    43
    Hi,
    Can someone show me an easy example of a post form where I can keep the active session on the server so I can do more post in the same session?

    I bought Best HTTP PRO to not be as limited as with www and wwwform of unity, but I do not have much idea of internet protocols, so the only thing I need is to be able to login to my server (put with user-pass) and then continue loged in while the session lasts.

    Thanks in advance ;)

    UPDATE:
    Forget my question, I realized that best http keep the session active by default ;)
     
    Last edited: Aug 29, 2018
  9. bitever

    bitever

    Joined:
    Mar 4, 2012
    Posts:
    17
    Hi,

    I receive an error when opening the connection with socket.io, I receive the error just at the moment I open the connection with:

    SocketManager.Open ();

    It is an error in the function of ParseResponse:

    [636711719131243134] Ex [PollingTransport]: ParseResponse - Message: 1: Array index is out of range.   at BestHTTP.SocketIO.Transports.PollingTransport.ParseResponse (BestHTTP.HTTPResponse resp) [0x000f6] in C:\Users\bitev\Desktop\MY WORK\Unity Projects\Socket_Test\Assets\Best HTTP (Pro)\BestHTTP\SocketIO\Transports\PollingTransport.cs:389   StackTrace:   at BestHTTP.SocketIO.Transports.PollingTransport.ParseResponse (BestHTTP.HTTPResponse resp) [0x000f6] in C:\Users\bitev\Desktop\MY WORK\Unity Projects\Socket_Test\Assets\Best HTTP (Pro)\BestHTTP\SocketIO\Transports\PollingTransport.cs:389


    --ERROR: Code: Internal Message: "Array index is out of range.   at BestHTTP.SocketIO.Transports.PollingTransport.ParseResponse (BestHTTP.HTTPResponse resp) [0x000f6] in C:\Users\bitev\Desktop\MY WORK\Unity Projects\Socket_Test\Assets\Best HTTP (Pro)\BestHTTP\SocketIO\Transports\PollingTransport.cs:389 " --


    My code is very simple:

    Code (CSharp):
    1. TimeSpan miliSecForReconnect = TimeSpan.FromMilliseconds(1000);
    2.  
    3.         options = new SocketOptions();
    4.         options.ReconnectionAttempts = 3;
    5.         options.AutoConnect = false;
    6.         options.ReconnectionDelay = miliSecForReconnect;
    7.  
    8.         //Server URI
    9.         socketManagerRef = new SocketManager(new Uri("urlSocket"), options);
    10.         socketManagerRef.Socket.On(SocketIOEventTypes.Error, OnError);
    11.         socketManagerRef.Open();
    Thanks in advance

    Edit: (SOLVED)

    I think my problem is the type of transport, I have solved it with:

    Code (CSharp):
    1. options.ConnectWith = BestHTTP.SocketIO.Transports.TransportTypes.WebSocket;
    I do not know if it's the right solution, but I do not get the error.

    Thank you.
     
    Last edited: Aug 29, 2018
  10. gaillath

    gaillath

    Joined:
    Apr 20, 2017
    Posts:
    10
    Hello,

    I'm interested in Besthttp but hesitating.
    What would you say is the best selling point of the asset (I mean versus unity default solution)?

    is it faster? is it more reliable? or is it more about all the additional features?
    (or all three? :) )

    Thanks :)
     
  11. Ginxx009

    Ginxx009

    Joined:
    Sep 11, 2016
    Posts:
    89
    The version I'm using is BestHttp Pro 1.8.2 (2015.06.26)
    Hi I tried this code

    Code (CSharp):
    1.  
    2.  
    3. new HTTPRequest(new Uri(url + "/resources/dealer/pic/" + dlrimage),
    4.         (HTTPRequest req, HTTPResponse res)
    5.         =>
    6.         {
    7.             if (req.State == HTTPRequestStates.Finished && req.Response.IsSuccess)
    8.             {
    9.                 Debug.Log("Succesful Request of DealerImage");
    10.                 var texture = new Texture2D(20, 20);
    11.                 texture.LoadImage(req.Response.Data);
    12.                 //texture.LoadImage(res.Data);
    13.                 script_gametable[i].img_dealer.mainTexture = texture;
    14.             }
    15.             else
    16.             {
    17.                 var resp = req.Response;
    18.                 switch (req.State)
    19.                 {
    20.                     //The request finished without any problem.
    21.                     case HTTPRequestStates.Finished:
    22.                         if (resp.IsSuccess)
    23.                         {
    24.                             Debug.Log("Request Finished Succesfully! Response : " + resp.DataAsText);
    25.  
    26.                             //TODO: Request finished. Process server sent data.
    27.                         }
    28.                         else
    29.                         {
    30.                             //Internal server error?
    31.                             Debug.LogError(string.Format("Request Finished Succesfully, but the server sent an error. Status Code : {0} - {1} Message: {2}",
    32.                                                         resp.StatusCode,
    33.                                                         resp.Message,
    34.                                                         resp.DataAsText));
    35.                         }
    36.                         break;
    37.                     //The request Finished witha n unexpected error. The request's Exception property may contain more info about the error.
    38.                     case HTTPRequestStates.Error:
    39.                         Debug.LogError("Request Finished with Error! " + (req.Exception != null ? (req.Exception.Message + "\n" + req.Exception.StackTrace) : "No Exception"));
    40.                         break;
    41.                     //The request aborted, initiated by the user.
    42.                     case HTTPRequestStates.Aborted:
    43.                         Debug.LogError("Request Aborted");
    44.                         break;
    45.                     //Connecting to the server is timed out.
    46.                     case HTTPRequestStates.ConnectionTimedOut:
    47.                         Debug.LogError("Connection Timed Out!");
    48.                         break;
    49.                     //The request didn't finished in the given time.
    50.                     case HTTPRequestStates.TimedOut:
    51.                         Debug.LogError("Processing the request Timed Out!");
    52.                         break;
    53.  
    54.  
    55.                 }
    56.             }
    57.         }).Send();
    58.  
    59.  


    but this error occured to me

    Request Finished with Error! One or more errors occurred.
    at System.Threading.Tasks.Task.ThrowIfExceptional (System.Boolean includeTaskCanceledExceptions) [0x00011] in <f2e6809acb14476a81f399aeb800f8f2>:0
    at System.Threading.Tasks.Task.Wait (System.Int32 millisecondsTimeout, System.Threading.CancellationToken cancellationToken) [0x00043] in <f2e6809acb14476a81f399aeb800f8f2>:0
    at System.Threading.Tasks.Task.Wait () [0x00000] in <f2e6809acb14476a81f399aeb800f8f2>:0
    at Mono.Net.Security.MobileAuthenticatedStream.AuthenticateAsClient (System.String targetHost, System.Security.Cryptography.X509Certificates.X509CertificateCollection clientCertificates, System.Security.Authentication.SslProtocols enabledSslProtocols, System.Boolean checkCertificateRevocation) [0x0000d] in <60233c34ef3e4e5f892759dbfc5ae27d>:0
    at (wrapper remoting-invoke-with-check) Mono.Net.Security.MobileAuthenticatedStream.AuthenticateAsClient(string,System.Security.Cryptography.X509Certificates.X509CertificateCollection,System.Secu

    And by the way i didn't use your code like this

    Code (CSharp):
    1.  
    2. HTTPRequest request = new HTTPRequest(new Uri(url + "/resources/dealer/pic" + dlrimage));
    3. yield return request.Send();
    4.  
    because in unity 2018.2.5f1 it gives me a whole bunch of logs saying about memory allocations.
     
    Last edited: Aug 30, 2018
  12. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @gaillath

    The Unity implementation is done in native code and if possible it uses what the platform offers. The plugin is full c# and the default SSL/TLS handler is written in it too, resulting in slower encryption/decryption and in general.
    On the other hand I believe that my Websocket implementation for WebGL is better.

    I think it's on pair with Unity's one, but i'm quicker to respond and to fix bugs. :)

    This is the selling point of the plugin.
    Almost every aspect of a request can be customized by default, and if it's not enough, all source code is in the package and can be modified to your needs.
    Also the plugin has implementation for an additional four protocols on top of the regular requests and websocket.
     
    gaillath likes this.
  13. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @Ginxx009

    First I would recommend to update the plugin. 1.8.2 is more than two years old.
     
  14. Jribs

    Jribs

    Joined:
    Jun 10, 2014
    Posts:
    154
    @BestHTTP

    Thanks for the tip! Although what you mentioned didn't solve the issue I was having, once I solved that other issue it did reduce our socket lag by about 100ms!!

    My other issue was a problem with our nginx proxy on our elastic beanstalk server. I had to change some settings in the nginx configuration.

    But thanks!
     
  15. Ginxx009

    Ginxx009

    Joined:
    Sep 11, 2016
    Posts:
    89
    I updated the plugin from 1.8.2 to 1.10.9 .
    But there's too much error sir

    https://imgur.com/a/qF62vGH
     
  16. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @Ginxx009

    Try deleting the /Best HTTP (Pro)/ folder and reimporting the package.
     
  17. spiderpoison

    spiderpoison

    Joined:
    Jul 2, 2018
    Posts:
    8
    @BestHTTP
    I have a new progress.
    New error is "unexpected reserved bits 0x30", It is always "unexpected reserved bits 0x40" before.
    So I suspect that is beacuse concurrent writing data from pulgin, is it possible?

    (I have using -race on server to check whether it concurrent read data, but it is not.)
     
  18. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @spiderpoison

    The plugin sends messages one by one, it doesn't try writing multiple messages concurrently.
     
  19. Ginxx009

    Ginxx009

    Joined:
    Sep 11, 2016
    Posts:
    89
    I have one more error

    https://imgur.com/a/imcmieq

    UPDATE:

    So from this script

    Code (CSharp):
    1.  
    2. internal override bool Receive(int forceReadRawContentLength = -1, bool readPayloadData = false)
    3.         {
    4.             return base.Receive(forceReadRawContentLength, false);
    5.         }
    6.  
    I changed it to this

    Code (CSharp):
    1.  
    2. public override bool Receive(int forceReadRawContentLength = -1, bool readPayloadData = false)
    3.         {
    4.             return base.Receive(forceReadRawContentLength, false);
    5.         }
    6.  
    But now the problem is that this

    https://imgur.com/a/aEAogXt

    Error occurs
     
    Last edited: Aug 30, 2018
  20. spiderpoison

    spiderpoison

    Joined:
    Jul 2, 2018
    Posts:
    8
    @BestHTTP
    Dose the pulgin can reconnect when the net break? If so, how it work?
     
  21. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @Ginxx009

    Hmm, are you tried to restart Unity? (not kidding)
    A freshly imported package mustn't have compile errors. You can try to create a fresh project, download and import the package. If it compiles fine, you can copy the plugin to the 'old' project.
     
  22. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @spiderpoison

    Only for protocols that must support reconnection. These protocols are Socket.IO and SignalR.
     
  23. guoweisong3

    guoweisong3

    Joined:
    Jul 3, 2018
    Posts:
    2
    @BestHTTP
    I find a question : In WebSocketResponse.cs ,the Stream in SendThreadFunc and ReceiveThreadFunc is the same .so the data of Steam is maybe mixed ?
    Code (CSharp):
    1. private void SendThreadFunc(object param)
    2. {......
    3.                         while (localFrames.Count > 0)
    4.                         {
    5.                             WebSocketFrame frame = localFrames[localFrames.Count - 1];
    6.                             localFrames.RemoveAt(localFrames.Count - 1);
    7.  
    8.                             if (!closeSent)
    9.                             {
    10.                                 byte[] rawData = frame.Get();
    11.                                 Stream.Write(rawData, 0, rawData.Length);
    12.  
    13.                                 if (frame.Type == WebSocketFrameTypes.ConnectionClose)
    14.                                     closeSent = true;
    15.                             }
    16.  
    17.                             Interlocked.Add(ref this._bufferedAmount, -frame.Data.Length);
    18.                         }
    19.  
    20.                         Stream.Flush();
    21. ......
    22. }
    23.  
    24. private void ReceiveThreadFunc(object param)
    25. {......
    26. WebSocketFrameReader frame = new WebSocketFrameReader();
    27.                         frame.Read(Stream);
    28.  
    29. ......
    30. }
     
  24. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @guoweisong3

    TCP has distinct read and write buffers. Read operations can read the buffer that contains server sent data and write operations can write to the buffer that will be sent to the server. So read and write can be done in parallel without interfering each other.
     
  25. dadasoft

    dadasoft

    Joined:
    Jun 8, 2015
    Posts:
    1
    BestHttp Pro version 1.10.9 : How to make BestHttp precompiled dlls? If I build at Visual Studio 2017, just make Assembly-CSharp.dll. Do I have to Include all source file in my project?
     
    Last edited: Aug 31, 2018
  26. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @dadasoft

    The \Best HTTP (Pro)\ folder contains .csproj files that you can open with Visual Studio, fix unity dll references then build the project. When completed a new dll will be created in \Best HTTP (Pro)\Plugins\ or in a sub directory.
    Also, after you built your dlls you have to delete the \Best HTTP (Pro)\BestHTTP\ folder to do not receive compile errors.
     
  27. cruelbob

    cruelbob

    Joined:
    May 26, 2014
    Posts:
    20

    System.ArgumentNullException Argument cannot be null. Parameter name ipAddresses
    at BestHTTP.PlatformSupport.TcpClient.General.TcpClient.Connect (System.Net.IPAddress[] ipAddresses, Int32 port) [0x00000] in <filename unknown> 0
    at BestHTTP.HTTPConnection.Connect () [0x00000] in <filename unknown> 0
    at BestHTTP.HTTPConnection.ThreadFunc (System.Object param) [0x00000] in <filename unknown> 0
     
  28. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @cruelbob

    Can you give more context about the error? When it happened? Can you reproduce it?
     
  29. cruelbob

    cruelbob

    Joined:
    May 26, 2014
    Posts:
    20
    @BestHTTP We log all exceptions from our published game. This is log from one of exceptions. Can it be a bug in library?
    Unity 2018.1.7f1
    ios and android
     
  30. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @cruelbob

    The plugin uses the return value of Dns.EndGetHostAddresses in that Connect method and it seems it returned with null. MSDN doesn't mention it can return with a null value, and anyway it seems to be a non-recoverable error: it can't connect to the server to send the request.

    How frequent is this error? Any chance you are using the new runtime?
     
  31. OvidiuGhe

    OvidiuGhe

    Joined:
    Oct 1, 2012
    Posts:
    12
    Hello!

    Im trying to send a POST request to a web server and the request needs to be in this form:
    request body: {"imageBase64": "<a picture in base64 format>"}

    Im using Unity 2017.4 and the latest version of the plugin.
    Can somebody direct me a bit, I have no idea where should I start looking.

    Thanks a lot!
     
  32. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @OvidiuGhe

    You can do something like this:
    Code (CSharp):
    1. Uri uri = new Uri("http://httpbin.org/post");
    2.  
    3. HTTPRequest request = new HTTPRequest(uri, HTTPMethods.Post, (req, resp) =>
    4. {
    5.     switch (req.State)
    6.     {
    7.         // The request finished without any problem.
    8.         case HTTPRequestStates.Finished:
    9.             if (resp.IsSuccess)
    10.             {
    11.                 Debug.Log("Request Finished Successfully! Response: " + resp.DataAsText);
    12.  
    13.             }
    14.             else // Internal server error?
    15.                 Debug.LogWarning(string.Format("Request Finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}",
    16.                                                 resp.StatusCode,
    17.                                                 resp.Message,
    18.                                                 resp.DataAsText));
    19.             break;
    20.  
    21.         // The request finished with an unexpected error. The request's Exception property may contain more info about the error.
    22.         case HTTPRequestStates.Error:
    23.             Debug.LogWarning("Request Finished with Error! " + (req.Exception != null ? (req.Exception.Message + "\n" + req.Exception.StackTrace) : "No Exception"));
    24.             break;
    25.  
    26.         // The request aborted, initiated by the user.
    27.         case HTTPRequestStates.Aborted:
    28.             Debug.LogWarning("Request Aborted!");
    29.             break;
    30.  
    31.         // Ceonnecting to the server is timed out.
    32.         case HTTPRequestStates.ConnectionTimedOut:
    33.             Debug.LogError("Connection Timed Out!");
    34.             break;
    35.  
    36.         // The request didn't finished in the given time.
    37.         case HTTPRequestStates.TimedOut:
    38.             Debug.LogError("Processing the request Timed Out!");
    39.             break;
    40.     }
    41. });
    42.  
    43. request.SetHeader("Content-Type", "application/json");
    44.  
    45. var obj = new {
    46.     imageBase64 = System.Convert.ToBase64String(tex.EncodeToPNG())
    47. };
    48.  
    49. var json = Newtonsoft.Json.JsonConvert.SerializeObject(obj);
    50.  
    51. request.RawData = System.Text.Encoding.UTF8.GetBytes(json);
    52.  
    53. request.Send();
     
  33. OvidiuGhe

    OvidiuGhe

    Joined:
    Oct 1, 2012
    Posts:
    12
    @BestHTTP it worked just great!
    Thanks a lot for your quick reply and for your time! Keep up the awesome work!
     
  34. OlivierPons

    OlivierPons

    Joined:
    Sep 20, 2014
    Posts:
    28
    Hi,

    I'd like to know if you ever plan to implement Cookies (custom cookie implementation) for WebGL.

    To give the client the possibility to test mobile application through WebGL before releasing it is a killer feature: it's what could make me sell the product (almost my whole year sale!).

    Do you have a plan / workaround for this?
     
  35. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @OlivierPons

    What cookie support are you require? Just receive cookies and send back automatically, or are you want to read cookies and/or set new ones from c#?
     
  36. OlivierPons

    OlivierPons

    Joined:
    Sep 20, 2014
    Posts:
    28
    I can't use BestHTTPPro Cookies features when I deploy to WebGL it says "Cookie" not found. You've added a note about Cookie, in the WebGL section (I'm sorry I'm under Linux right now, just typing what I remember) saying that it's not implemented yet.
     
  37. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @OlivierPons

    I know, but how you want to use it? What's your current use-case?
    The plugin uses XmlHTTPRequest to send out http requests. It's easy to make it so that it will process server-sent Set-Cookie headers. But it requires more work to be able to present cookies to the c# 'side' of the plugin. And more work additionally to the previous ones to be able to set custom cookies from the c# side. But, if you can show how you are using cookies in non-webgl builds, I might be able to focus only on that feature set so you can deploy to webgl too.
     
  38. OlivierPons

    OlivierPons

    Joined:
    Sep 20, 2014
    Posts:
    28
    Here's the idea: for safety reasons:
    - I want to get a CSRF token via a GET.
    - then, once I get the CSRF, I do only POST with the CSRF token "manually" added.

    The server side is Django 2.1. I force Django to generate a cookie in the GET using a simple view like this:

    Code (Python):
    1. class JsonBase(generic.View):
    2.  
    3.     http_method_names = ['get', 'post']
    4.  
    5.     @method_decorator(ensure_csrf_cookie)
    6.     def get(self, request, *args, **kwargs):
    7.         return JsonResponse({}, safe=False)
    8.  
    9.     def post(self, request, *args, **kwargs):
    10.         return JsonResponse({}, safe=False)
    11.  
    Then from Unity, I do a GET of a JSON-Based view, which returns a Set-Cookie of the CSRF.
    What I do is a code to read it and keep it in a property:

    Code (CSharp):
    1. private string _csrfmiddlewaretoken

    So here's the callback when the GET is finished, I hope it gives enough clues to understand what I'm trying to achieve (which works perfectly on all platforms except WebGL)

    Code (CSharp):
    1.         private void GetFinished(HTTPRequest request, HTTPResponse response)
    2.         {
    3.             Debug.Log("GetFinished: entering ...");
    4.             if (_urlPost == null) {
    5.                 /* (_urlPost == null) means we wanted only Get: */
    6.                 ConvertThenCallback(response, true);
    7.             } else {
    8.                 /* if _urlPost is not null, this means we wanted to make a post */
    9.                 Debug.Log("try post");
    10.                 /* make sure there's a response */
    11.                 if (response == null) {
    12.                     _cbDisplayFatalError(_cbErrorMessageGetResponseIsNull());
    13.                     return;
    14.                 }
    15.                 /* make sure there's the cookie we need */
    16.                 if (response.Cookies == null) {
    17.                     _cbDisplayFatalError(_cbErrorMessageNoCookies());
    18.                     return;
    19.                 }
    20.                 Cookie c = response.Cookies.Find(e => e.Name == "csrftoken");
    21.                 if (c == null) {
    22.                     _cbDisplayFatalError(_cbErrorMessageNoCsrf());
    23.                     return;
    24.                 }
    25.                 HTTPRequest r = new HTTPRequest(
    26.                     new Uri(_urlPost),
    27.                     HTTPMethods.Post, /* HTTPMethods methodType */
    28.                     true, true,  /* bool isKeepAlive, bool disableCache */
    29.                     PostFinished
    30.                 );
    31.                 _csrfmiddlewaretoken = c.Value;
    32.                 Debug.Log("_csrfmiddlewaretoken = " + _csrfmiddlewaretoken);
    33.                 r.AddField("csrfmiddlewaretoken", _csrfmiddlewaretoken);
    34.                 if (_cbPostParameters != null) {
    35.                     foreach (Parameter item in _cbPostParameters()) {
    36.                         r.AddField(item.name, item.value);
    37.                     }
    38.                 }
    39.                 Debug.Log("r.Send();...");
    40.                 r.Send();
    41.             }
    42.         }
    43.  
    And as you may guess the callback here is always called under WebGL: "_cbDisplayFatalError(_cbErrorMessageNoCsrf());"

    But if you watch the answer of the GET, there's a Set-Cookie with the CSRF:

    upload_2018-9-12_22-48-14.png

    I'll do a hack and from the server site, instead of returning empty JSON object "{}" and let Django add the csrftoken in the Set-Cookie header, I'll add this in the object result itself. So GET will return things like:

    "{'csrftoken': 'tSiwPzJIHBgmwe5tWUsYQ0uwyNONdc8OLQ2KwOXs4rKp3UNfWQdVoB6hZSlowyYk'}"

    (unless you think there's a better way)
     
    Last edited: Sep 12, 2018
  39. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
  40. OlivierPons

    OlivierPons

    Joined:
    Sep 20, 2014
    Posts:
    28
    @BestHTTP Thank you very much!

    I have another problem when making WebGL version: when I get an answer from the Webserver confirming that login was successful, I make my own directory to remember cookies based on the current user logged in, like this:

    string p = Path.Combine(Application.persistentDataPath, "Cookies/");
    HTTPManager.RootCacheFolderProvider = () => Path.Combine(p, login);

    I get this error:

    `BestHTTP.HTTPManager' does not contain a definition for `RootCacheFolderProvider'

    There's no documentation about this restriction, what is the workaround (if there can be one) ?
    I'd like to open many times the WebGL in many tabs, and have a "specific" place to stock information about the user logged in (even if it's temporary) for each user (thus one unique "place" to stock information per tab).
     
  41. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @OlivierPons

    The RootCacheFolderProvider is disabled for the same reason: the plugin not using it for saving downloaded content and cookies so there's no reason to compile it into the final build.

    But, because cookies will be managed by the browser cookie saving will be still disabled, the plugin will only show you the cookies.
     
  42. Vascoptorres

    Vascoptorres

    Joined:
    Jul 26, 2012
    Posts:
    18
    @BestHTTP

    I remember having a issue similar to this before. And I don't know if I managed to fix it at the time since it was on a different project.

    Right now I'm having a CORS problem, and it only happens with BestHTTP POST requests. The GET request works fine, but the POST was giving me a CORS error. So I checked the request on chrome and it seems like the request is sent as an OPTIONS request, even though I set its MethodType as POST?

    Edit: Tested a little further and it seems like the request is only sent as OPTIONS when I add a field to the request, if the request is sent without data it is sent as POST.
     

    Attached Files:

    Last edited: Sep 19, 2018
  43. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @Vascoptorres

    There are simple requests and non-simple requests. Simple requests can go out without a preflight (eg. OPTIONS) request, while non-simple requests must have a preflight one.
    So it's perfectly valid to have a working GET request then a failing POST...

    You can read more about simple and non-simple requests here.
     
  44. Vascoptorres

    Vascoptorres

    Joined:
    Jul 26, 2012
    Posts:
    18
    Didn't know about that. So UnityWebRequest works because it doesn't send the preflight request as it is supposed?

    Anyway, it seems like the server that I'm using doesn't know how to handle those preflights, which is strange, I don't even receive the OPTIONS request on the server side... is there any way to force BestHTTP to not send those?
     
  45. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @Vascoptorres

    Preflight requests are sent by the browser and only the browser can decide when it will send it. It's matter however that how are you sending that post request, so can you share it with me? The actual uri isn't needed.
     
  46. Vascoptorres

    Vascoptorres

    Joined:
    Jul 26, 2012
    Posts:
    18
    Code (CSharp):
    1.             StringBuilder url = new StringBuilder(_fullAddress.AppendIfNotPresent('/')).Append("post");
    2.             HTTPRequest request = new HTTPRequest(new Uri(url.ToString()), HTTPMethods.Post);
    3.             request.AddField("logData", "test");
    4.             request.Send();
    Something as simple as that fails, if I remove the field "logData" it doesn't send that preflight request.
     
  47. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
  48. Vascoptorres

    Vascoptorres

    Joined:
    Jul 26, 2012
    Posts:
    18
    @BestHTTP

    I wasn't happy on having to bypass what was the correct way of handling this, so I spent some time on the server side and I managed to have it handling the OPTIONS request and adding the correct headers to the responses, and now it works fine without that modification. Thank you for the clarification and for the time you took modifying the plugin.
     
  49. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @Vascoptorres

    In the meantime I made it so that when there's no user defined upload progress callback, it will not add that event listener. This way with the next update everyone will benefit from it.
     
  50. cemozturk

    cemozturk

    Joined:
    Sep 27, 2015
    Posts:
    31
    Hello guys,

    When i try to connect ssl addr of socket.io with best http socket.io client, ( transport websocket ), i need to use bundle certificate to handshake.

    How can force/let besthttp-client to use the certificate file while connecting ?

    Thank you.