Search Unity

Best HTTP Released

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

  1. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @Blueberry
    You have several options to do this:
    1. You can manually construct a socket.io packet if you already have the json array to send.
    2. You can construct a Dictionary and add the fields and send this dictionary.
    3. If you set a more advanced Json encoder to the manager, then you don't have to construct dictionaries manually, you can pass regular objects to the Emit function, it will be serialized.
    The LitJsonEncoder is packed with the plugin, and there is a json encoder that will use JSON .NET For Unity.

    The 3rd option is the prefered way to send events, as it's the most easiest, but the others can be used too.

    Code (CSharp):
    1.  
    2. using BestHTTP.SocketIO;
    3. SocketManager manager = new SocketManager(new Uri("http://server.com/socket.io/"));
    4.  
    5. manager.Socket.On(SocketIOEventTypes.Connect, (socket, receivedPacket, args) =>
    6.     {
    7.         // 1.) Manually constructing the packet to send
    8.         Packet packet = new Packet(TransportEventTypes.Message,
    9.                                     SocketIOEventTypes.Event,
    10.                                     socket.Namespace,
    11.                                     @"['event_name', {""username"":""the_user"",""message"":""the_users_message""}",
    12.                                     0,
    13.                                     0);
    14.         (manager as BestHTTP.SocketIO.IManager).SendPacket(packet);
    15.  
    16.         // 2.) or using the default Json encoder
    17.         Dictionary<string, object> arg = new Dictionary<string, object>();
    18.         arg.Add("username", "the_user");
    19.         arg.Add("message", "the_users_message");
    20.  
    21.         socket.Emit("event_name", arg);
    22.  
    23.         // 3.) or using the more advanced LitJsonEncoder
    24.         // setting the Encoder should be done after creating the manager instance
    25.         manager.Encoder = new BestHTTP.SocketIO.JsonEncoders.LitJsonEncoder();
    26.  
    27.         var userMessage = new { username = "the_user", message = "the_users_message"};
    28.  
    29.         socket.Emit("event_name", userMessage);
    30.     });
     
    Last edited: Apr 29, 2015
    lauraaa and MrIconic like this.
  2. BestHTTP

    BestHTTP

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

    I think you already found the best way to do it - one get request with the list of files you want to upload with the response of the files that can be uploaded, then a post request with the missing files.
    BestHTTP will keep the connection alive, so the next request will be sent on the same tcp channel. I think it's still better then sending files that are possible will be discarded.

    Maybe a little better aproach would be to use WebSocket to spare the http headers of the requests, but it would add more coding to both ends(client&server).
     
  3. taehwa

    taehwa

    Joined:
    Dec 30, 2013
    Posts:
    4
    Hi BestHTTP

    We were having trouble with HTTPRequest exception error

    The authentication or decryption has failed.: at Mono.Security.Protocol.Tls.SslStreamBase.AsyncHandshakeCallback (IAsyncResult asyncResult) [0x00000] in <filename unknown>:0
    UnityEngine.Debug:LogError(Object)
    BestHTTP.HTTPRequest:CallCallback() (at Assets/Extensions/Best HTTP (Pro)/BestHTTP/HTTPRequest.cs:1012)
    BestHTTP.HTTPConnection:HandleCallback() (at Assets/Extensions/Best HTTP (Pro)/BestHTTP/HTTPConnection.cs:656)
    BestHTTP.HTTPManager:OnUpdate() (at Assets/Extensions/Best HTTP (Pro)/BestHTTP/HTTPManager.cs:537)
    BestHTTP.HTTPUpdateDelegator:Update() (at Assets/Extensions/Best HTTP (Pro)/BestHTTP/HTTPUpdateDelegator.cs:49)

    How can i fix this?
     
  4. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @taehwa
    You may want to try to use the boundled BouncyCastle implementation for handling https. It's a more advanced crypto lib than the default mono implementation.

    Code (CSharp):
    1.  
    2. HTTPRequest request = new HTTPRequest(...);
    3.  
    4. request.UseAlternateSSL = true;
    5.  
    6. request.Send();
     
  5. taehwa

    taehwa

    Joined:
    Dec 30, 2013
    Posts:
    4
    OK, thanks a lot
     
  6. gumboots

    gumboots

    Joined:
    May 24, 2011
    Posts:
    298
    So I've almost got it all working, but one thing that seems strange is that a Get request to the server with a file name request doesn't work, but a Post does. I even went into the browser and entered

    Code (CSharp):
    1. http://url/share.php?action=download&guids=288272
    And it echoed the GUID, but in Unity it only works if I do a Post.
     
    Last edited: Apr 30, 2015
  7. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @gumboots
    For your previous questions:
    You can post an array by adding square brackets to your field names:
    Code (CSharp):
    1. var request = new HTTPRequest(new Uri("http://httpbin.org/post"), HTTPMethods.Post, (req, resp) =>
    2. {
    3.     switch (req.State)
    4.     {
    5.         // The request finished without any problem.
    6.         case HTTPRequestStates.Finished:
    7.             if (resp.IsSuccess)
    8.             {
    9.                 Debug.Log("Request Finished Successfully! " + resp.DataAsText);
    10.             }
    11.             else
    12.                 Debug.LogWarning(string.Format("Request Finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}",
    13.                                                 resp.StatusCode,
    14.                                                 resp.Message,
    15.                                                 resp.DataAsText));
    16.             break;
    17.  
    18.         // The request finished with an unexpected error. The request's Exception property may contain more info about the error.
    19.         case HTTPRequestStates.Error:
    20.             Debug.LogWarning("Request Finished with Error! " + (req.Exception != null ? (req.Exception.Message + "\n" + req.Exception.StackTrace) : "No Exception"));
    21.             break;
    22.  
    23.         // The request aborted, initiated by the user.
    24.         case HTTPRequestStates.Aborted:
    25.             Debug.LogWarning("Request Aborted!");
    26.             break;
    27.  
    28.         // Ceonnecting to the server is timed out.
    29.         case HTTPRequestStates.ConnectionTimedOut:
    30.             Debug.LogError("Connection Timed Out!");
    31.             break;
    32.  
    33.         // The request didn't finished in the given time.
    34.         case HTTPRequestStates.TimedOut:
    35.             Debug.LogError("Processing the request Timed Out!");
    36.             break;
    37.     }
    38. });
    39.  
    40. for (int i = 0; i < 10; i++ )
    41.     request.AddField("files[]", "file" + i);
    42.  
    43. request.Send();
    On the server side, it should materialize as an array, and you don't have to do any string exploding this way.

    Sending multiple files at once:
    Code (CSharp):
    1. var request = new HTTPRequest(new Uri("http://httpbin.org/post"), HTTPMethods.Post, (req, resp) =>
    2. {
    3.     switch (req.State)
    4.     {
    5.         // The request finished without any problem.
    6.         case HTTPRequestStates.Finished:
    7.             if (resp.IsSuccess)
    8.             {
    9.                 Debug.Log("Request Finished Successfully! " + resp.DataAsText);
    10.             }
    11.             else
    12.                 Debug.LogWarning(string.Format("Request Finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}",
    13.                                                 resp.StatusCode,
    14.                                                 resp.Message,
    15.                                                 resp.DataAsText));
    16.             break;
    17.  
    18.         // The request finished with an unexpected error. The request's Exception property may contain more info about the error.
    19.         case HTTPRequestStates.Error:
    20.             Debug.LogWarning("Request Finished with Error! " + (req.Exception != null ? (req.Exception.Message + "\n" + req.Exception.StackTrace) : "No Exception"));
    21.             break;
    22.  
    23.         // The request aborted, initiated by the user.
    24.         case HTTPRequestStates.Aborted:
    25.             Debug.LogWarning("Request Aborted!");
    26.             break;
    27.  
    28.         // Ceonnecting to the server is timed out.
    29.         case HTTPRequestStates.ConnectionTimedOut:
    30.             Debug.LogError("Connection Timed Out!");
    31.             break;
    32.  
    33.         // The request didn't finished in the given time.
    34.         case HTTPRequestStates.TimedOut:
    35.             Debug.LogError("Processing the request Timed Out!");
    36.             break;
    37.     }
    38. });
    39.  
    40. request.AddBinaryData("zip_1", new byte[10], "filename_1.zip");
    41. request.AddBinaryData("zip_2", new byte[20], "filename_2.zip");
    42.  
    43. request.Send();
    You can call the AddBinaryData more than once. Didn't tried, but I think you can combine it with the previous array technique too:
    Code (CSharp):
    1. var request = new HTTPRequest(new Uri("http://httpbin.org/post"), HTTPMethods.Post, (req, resp) =>
    2. {
    3.     switch (req.State)
    4.     {
    5.         // The request finished without any problem.
    6.         case HTTPRequestStates.Finished:
    7.             if (resp.IsSuccess)
    8.             {
    9.                 Debug.Log("Request Finished Successfully! " + resp.DataAsText);
    10.             }
    11.             else
    12.                 Debug.LogWarning(string.Format("Request Finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}",
    13.                                                 resp.StatusCode,
    14.                                                 resp.Message,
    15.                                                 resp.DataAsText));
    16.             break;
    17.  
    18.         // The request finished with an unexpected error. The request's Exception property may contain more info about the error.
    19.         case HTTPRequestStates.Error:
    20.             Debug.LogWarning("Request Finished with Error! " + (req.Exception != null ? (req.Exception.Message + "\n" + req.Exception.StackTrace) : "No Exception"));
    21.             break;
    22.  
    23.         // The request aborted, initiated by the user.
    24.         case HTTPRequestStates.Aborted:
    25.             Debug.LogWarning("Request Aborted!");
    26.             break;
    27.  
    28.         // Ceonnecting to the server is timed out.
    29.         case HTTPRequestStates.ConnectionTimedOut:
    30.             Debug.LogError("Connection Timed Out!");
    31.             break;
    32.  
    33.         // The request didn't finished in the given time.
    34.         case HTTPRequestStates.TimedOut:
    35.             Debug.LogError("Processing the request Timed Out!");
    36.             break;
    37.     }
    38. });
    39.  
    40. request.AddBinaryData("zips[]", new byte[10], "filename_1.zip");
    41. request.AddBinaryData("zips[]", new byte[20], "filename_2.zip");
    42.  
    43. request.Send();
    I can check why your url doens't work, if you send your full url in private.
     
    Last edited: Apr 30, 2015
  8. gumboots

    gumboots

    Joined:
    May 24, 2011
    Posts:
    298
    Hey that's excellent, thanks for all of your help!

    Sorry for deleting my previous questions, I decided to try things a different way and didn't want you to waste time answering old questions, but reading your answers I'm thinking of going back to the array.

    That being said, when a client requests a number of files, I can send an array of strings for file names, but I was thinking about just zipping a single file of all the required zips and downloading that. Do you think that is more favourable that readfile() on each file to send it back to BestHTTP?
     
  9. moheji

    moheji

    Joined:
    Aug 22, 2012
    Posts:
    5
    BestHTTP Pro is used. ( Unity5.0.1 )
    When I make the attach empty GameObject and make them move, the next error goes out.
    How should it be corrected?

    get_isDebugBuild can only be called from the main thread.
    Constructors and field initializers will be executed from the loading thread when loading a scene.
    Don't use this function in the constructor or field initializers, instead move initialization code to the Awake or Start function.


    Code (CSharp):
    1. using UnityEngine;
    2. using System.Threading;
    3. using System;
    4. using BestHTTP;
    5.  
    6. public class test : MonoBehaviour {
    7.     void Start() {
    8.         HTTPLoad load = new HTTPLoad ();
    9.         Thread t = new Thread (new ThreadStart (load.exec));
    10.         t.Start ();
    11.     }
    12. }
    13.  
    14. public class HTTPLoad {
    15.     public void exec() {
    16.         new HTTPRequest (new Uri ("http://www.google.com")).Send ();
    17.     }
    18. }
     
    Last edited: May 1, 2015
  10. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @gumboots: Well, it depens I think. If it's a unfrequently used feature, then I think both can be good enough solution. But if it can be a botleneck, then you can optimize for throughput(store the files already zipped) and file access(store the files in a memory cache(memcache, redis, etc)). If these are small zips, then it can be favorable to send them in one request, becouse headers can add a noticable overhead.
    And of course you should test your solution under heavy load, and tweak it accordingly.
     
  11. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @moheji: When you want to use BestHTTP from an other thread, first you have to call the HTTPManager.Setup(); function from a Unity event(Start, Awake, etc):
    Code (CSharp):
    1.     using UnityEngine;
    2.     using System.Threading;
    3.     using System;
    4.     using BestHTTP;
    5.    
    6.     public class test : MonoBehaviour {
    7.         void Start() {
    8.            // call Setup() to initialize some internal variable
    9.            HTTPManager.Setup();
    10.  
    11.             HTTPLoad load = new HTTPLoad ();
    12.             Thread t = new Thread (new ThreadStart (load.exec));
    13.             t.Start ();
    14.         }
    15.     }
    16.    
    17.     public class HTTPLoad {
    18.         public void exec() {
    19.             new HTTPRequest (new Uri ("http://www.google.com")).Send ();
    20.         }
    21.     }
    22.  
     
  12. slumtrimpet

    slumtrimpet

    Joined:
    Mar 18, 2014
    Posts:
    372
    How would I set my encoder to JSON .NET? I only see the default and LitJson defined at BestHTTP.SocketIO.JsonEncoders.*

    Should I be setting my BestHTTP.SocketIO.SocketManager.DefaultEncoder to something in the JSON .NET library directly?
     
  13. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @slumtrimpet : there is a JsonDotNetEncoder.cs in the \Best HTTP (Pro|Basic)\Examples\SocketIO Json Encoders\ folder, but the class itself is commented out. It would give a compile error otherwise.
     
    Last edited: May 5, 2015
  14. pajamajama

    pajamajama

    Joined:
    Oct 22, 2012
    Posts:
    66
    @BestHTTP , thank you for such an extensive amazing plugin!

    I'm having a problem decoding some JSON from a socket.io event. When I print packet.Payload, I get the event and message properly:
    Code (CSharp):
    1. ["camera rotation",{"_x":0,"_y":0,"_z":0,"_order":"XYZ","id":"9ZKhV1bLF-wPbntpAAAA"}]
    But when I try to print args[0] I get "System.Collections.Generic.Dictionary`2[System.String,System.Object]", which I believe is null, and args length is always 1. The documentation says args[1] should be the JSON message, right?

    Thank you for any ideas!
     
  15. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @pajamajama I think it's the expected behavior. The "camera rotation" is the event name, and the object is the sent argument. That json object is parsed to a Dictionary<string, object> by the default json encoder.

    Your event handler should look like this:
    Code (CSharp):
    1. void OnCameraRotation(Socket socket, Packet packet, params object[] args)
    2. {
    3.   Dictionary<string, object> obj = args[0] as Dictionary<string, object>;
    4.   Vector3 rotation = new Vector3(Convert.ToSingle(obj["_x"]), Convert.ToSingle(obj["_y"]), Convert.ToSingle(obj["_z"]));
    5.   string id = obj["id"] as string;
    6.   // ...
    7. }
    Found only this part in the documentation mentioning args[1]:
    Code (CSharp):
    1. // event handler
    2. void OnMessage(Socket socket, Packet packet, params object[] args)
    3. {
    4.     // args[0] is the nick of the sender
    5.     // args[1] is the message
    6.     Debug.Log(string.Format("Message from {0}: {1}", args[0], args[1]));
    7. }
    In this example, the server sends two "objects" (strings). The first is a 'nick' and the second is the message sent by 'nick':
    Code (JavaScript):
    1. socket.emit('message', ‘MyNick’, ‘Msg to the client’);
     
  16. pajamajama

    pajamajama

    Joined:
    Oct 22, 2012
    Posts:
    66
  17. pajamajama

    pajamajama

    Joined:
    Oct 22, 2012
    Posts:
    66
    @BestHTTP I'm using the websockets implementation for another project. Mostly everything seems to be working well, but I'm having a problem reconnecting to a closed server.

    In my test, I close the server, which triggers OnClose, then in OnClose I have a loop that calls to reopen the websocket if it isn't already. I restart my server, and am expecting the client to reconnect at some point but it never does. Any ideas?

    Thank you for the excellent support!
     
  18. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @pajamajama I will try to reproduce it, but if you have a small repro project it would be handy. Also there is a high chance that it's already fixed. In my dev. branch fixed a websocket bug that might cause this.
     
  19. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    So, what's coming in the next release?
    -Finished my work on the SignalR implementation. Today the WebPlayer demo has been refreshed to include 5 new SignalR samples. All SignalR features that i know about are supported.
    -This release will also add support for Samsung Smart TV builds.
    -Lots of improvements, and bugfixes.
     
  20. kaekko

    kaekko

    Joined:
    Aug 10, 2012
    Posts:
    7
    With Unity 5.0.2f1 Personal and plugin version Best HTTP (Pro Edition) 1.7.11 if I build for Windows Store -> Universal i'm getting the following errors (Android, iOS and Editor work):
    Code (CSharp):
    1. Assets\Best HTTP (Pro)\BestHTTP\HTTPConnection.cs(20,7): error CS0246: Impossibile trovare il tipo o il nome dello spazio dei nomi 'Org'; probabilmente manca una direttiva using o un riferimento a un assembly
    2. Assets\Best HTTP (Pro)\BestHTTP\HTTPConnection.cs(17,19): error CS0246: Impossibile trovare il tipo o il nome dello spazio dei nomi 'SocketEx'; probabilmente manca una direttiva using o un riferimento a un assembly
    3. Assets\Best HTTP (Pro)\BestHTTP\HTTPManager.cs(142,23): error CS0246: Impossibile trovare il tipo o il nome dello spazio dei nomi 'Org'; probabilmente manca una direttiva using o un riferimento a un assembly
    4. Assets\Best HTTP (Pro)\BestHTTP\HTTPRequest.cs(297,16): error CS0246: Impossibile trovare il tipo o il nome dello spazio dei nomi 'Org'; probabilmente manca una direttiva using o un riferimento a un assembly
    Which translated in english means, something like:
    • The type or namespace name 'Org' could not be found (are you missing a using directive or an assembly reference?)
    • The type or namespace name 'SocketEx' could not be found (are you missing a using directive or an assembly reference?)
     
  21. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @kaekko: Please check that the /Assets/Plugins/Metro/TcpClientImplementation.dll has the correct pltform settings in the Plugin Inspector. TcpClientImplementation.dll in the Metro folder should be selected for WSAPlayer. And Dll in the WP8 folder with WP8Player.
     
  22. kaekko

    kaekko

    Joined:
    Aug 10, 2012
    Posts:
    7
    I have the following settings:

    /Assets/Plugins/TcpClientImplementation.dll:
    Schermata 2015-05-16 alle 15.21.31.png

    /Assets/Plugins/Metro/TcpClientImplementation.dll:
    Schermata 2015-05-16 alle 15.23.04.png

    /Assets/Plugins/WP8/TcpClientImplementation.dll:
    Schermata 2015-05-16 alle 15.23.43.png
     
  23. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @kaekko: Checked again with the currently installed Unity, version 5.0.1, and it's worked fine.
    While built this test, started the download of 5.0.2f1. When installed created a new project with it, and imported the plugin from the Asset Store. Checked the setup, hit the build button, and received the same errors as you.
    With a little playing, set the /Assets/Plugins/Metro/TcpClientImplementation.dll's Placeholder to /Assets/Plugins/TcpClientImplementation.dll and it's worked fine again...
    Looks like, something changed in Unity and now it have to set?
     
  24. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    Played around a little bit, and for now looks like settings that i set for dlls are included in the package and travels with it. With the next update i will make sure, that i set the correct settings to these before exporting it.
     
  25. chooser

    chooser

    Joined:
    Mar 21, 2015
    Posts:
    13
    @BestHTTP

    I want to BLOCK "self signed SSL certification".
    How can I check that site is using "non public?" ssl using

    Thank you
     
  26. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @chooser I can only help to show how you can begin to write one, but i don't know how you can determine from a cert whether it is self-signed or not.

    You can write a ICertificateVerifyer implementation where you will receive the certificates and you can decide that you accept it, or not.

    Here is a custom verifyer implementation. It will accept every certificate, but as you can see it, the IsValid function receives a X509CertificateStructure array. You can check them, and if you want, you can return with a false value.
    When you return with false, the HTTPRequest's callback function will be called, and the request's State will be HTTPRequestStates.Error.

    Code (CSharp):
    1. class CustomVerifier : Org.BouncyCastle.Crypto.Tls.ICertificateVerifyer
    2. {
    3.     public bool IsValid(Org.BouncyCastle.Asn1.X509.X509CertificateStructure[] certs)
    4.     {
    5.         // TODO: Return false, if self-signed certificate found
    6.         return true;
    7.     }
    8. }
    And, here is the code to demonstrate how you can use it:
    Code (CSharp):
    1. string strUri = "https://www.google.com";
    2. HTTPRequest request = new HTTPRequest(new Uri(strUri), (req, resp) =>
    3.     {
    4.         switch (req.State)
    5.         {
    6.             // The request finished without any problem.
    7.             case HTTPRequestStates.Finished:
    8.                 if (resp.IsSuccess)
    9.                 {
    10.                     Debug.Log("Request Finished Successfully! " + resp.DataAsText);
    11.                 }
    12.                 else
    13.                     Debug.LogWarning(string.Format("Request Finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}",
    14.                                                     resp.StatusCode,
    15.                                                     resp.Message,
    16.                                                     resp.DataAsText));
    17.                 break;
    18.  
    19.             // The request finished with an unexpected error. The request's Exception property may contain more info about the error.
    20.             case HTTPRequestStates.Error:
    21.                 Debug.LogWarning("Request Finished with Error! " + (req.Exception != null ? (req.Exception.Message + "\n" + req.Exception.StackTrace) : "No Exception"));
    22.                 break;
    23.  
    24.             // The request aborted, initiated by the user.
    25.             case HTTPRequestStates.Aborted:
    26.                 Debug.LogWarning("Request Aborted!");
    27.                 break;
    28.  
    29.             // Ceonnecting to the server is timed out.
    30.             case HTTPRequestStates.ConnectionTimedOut:
    31.                 Debug.LogError("Connection Timed Out!");
    32.                 break;
    33.  
    34.             // The request didn't finished in the given time.
    35.             case HTTPRequestStates.TimedOut:
    36.                 Debug.LogError("Processing the request Timed Out!");
    37.                 break;
    38.         }
    39.     });
    40. request.UseAlternateSSL = true;
    41. request.CustomCertificateVerifyer = new CustomVerifier();
    42. request.Send();
     
  27. chooser

    chooser

    Joined:
    Mar 21, 2015
    Posts:
    13
    I do not understand why they need to check self ssl signed or not.
    But they said it "red level security problem" according to the security inspection company's report.
    Somehow I need to add function,( I think too worried about ssl for iPhone app. really need?......)

    Anyway thank you for your reply and demo code.
    I appreciate.
     
    Last edited: May 23, 2015
  28. slumtrimpet

    slumtrimpet

    Joined:
    Mar 18, 2014
    Posts:
    372
    I almost hate to ask this... but in evaluating the feasibility of a WebGL build of our product, the BestHTTP layer has come up.

    Anything on the roadmap about supporting WebGL on your end? I know the release notes on WebGL make it sounds like I'm sure that would be a pain (i.e. I assume you'll have to roll your own js layer and that would introduce a whole world of new complexity for you).

    Not specifically asking for it at this point, but just curious what your thoughts are on that front.
     
  29. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @slumptrimet: Not an easy topic. :)
    It's on my TODO list, but for a WebGL support i should rewrite almost the whole plugin(you saw clearly what should be done). It's hard to bring myself to do it. Instead it's more inspiring to add new features, protocols that are based on features that already have.

    Thought about reversing the problem, and write a class that will mimic browser's XHR requests. On WebGL it would use the browser implementation, and on other platforms would use the plugin...

    But, at some point i will do something to support WebGL too.
     
  30. Dynamoid-Megan

    Dynamoid-Megan

    Joined:
    Apr 16, 2015
    Posts:
    72
    Hello, I am just getting started with your product but I can't seem to get the "Getting Started Quickly" section of the documents working at all. The line of code gets commented out after the // in the url string. The error is : "error CS1526: A new expression requires () or [] after type" Here is where I put the code:
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using BestHTTP;
    4. using LitJson;
    5.  
    6. public class RequestTest : MonoBehaviour {
    7.  
    8.     public void testThis()
    9.     {
    10.         new HTTPRequest(new Uri (“http://google.com”), (request, response) => Debug.Log(“Finished!”)).Send();
    11.     }
    12. }
     
  31. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @Dynamoid Megan: Thats happens becouse when i write the documentation in Google Docs, it's changes the quotation marks from programming friendly to "document friendly". You just have to delete them and manually write again.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using BestHTTP;
    4. using LitJson;
    5.  
    6. public class RequestTest : MonoBehaviour {
    7.  
    8.     public void testThis()
    9.     {
    10.         new HTTPRequest(new Uri ("http://google.com"), (request, response) => Debug.Log("Finished!")).Send();
    11.     }
    12. }
    Edit: Repleaced all in the documentation.
     
  32. Dynamoid-Megan

    Dynamoid-Megan

    Joined:
    Apr 16, 2015
    Posts:
    72
    The quotation marks work great for me now. (thank you!) However, for some reason "Uri" turns red in the script and gives this: error CS0246: The type or namespace name `Uri' could not be found. Are you missing a using directive or an assembly reference?
     
  33. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @Dynamoid Megan : You have to add a "using System;" statement too, as the Uri class can be found in the System namespace.
     
  34. codeStrider

    codeStrider

    Joined:
    Mar 24, 2014
    Posts:
    4
    So I'm working on getting a BouncyCastle SSL Certificate Checker in place, just like @chooser. I've managed to get some of the main functionality in place (check that it's not self-signed, check signing chain, checking dates, etc...) but am now working on the 2 hardest parts of this:

    1) Checking that the cert was signed for the given domain.
    2) Checking that the authority that signed the cert is trusted and valid.

    Currently for #1 I'm setting a static variable and comparing that to the CN valid of the first certificate in the chain. It works, even for wild character CNs; However, this isn't ideal when doing multiple connections, so I was wondering if there is a way to get the URI of the domain that the certificate should be checking for within the function?
    Code (csharp):
    1. public bool IsValid(Org.BouncyCastle.Asn1.X509.X509CertificateStructure[] certs) {
    2. }
     
    ayalasan likes this.
  35. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @codeStrider: Modified the ICertificateVerifyer interface. Now the IsValid function will receive the request's current uri too:
    Code (CSharp):
    1. namespace Org.BouncyCastle.Crypto.Tls
    2. {
    3.     public interface ICertificateVerifyer
    4.     {
    5.         bool IsValid(Uri targetUri, X509CertificateStructure[] certs);
    6.     }
    7. }
    8.  
    Sending a modified package in private (Edit: Private messages are disabled for your profile :)).

    Let me know how it works.
     
  36. codeStrider

    codeStrider

    Joined:
    Mar 24, 2014
    Posts:
    4
    @BestHTTP - I've enabled Private Messages and sent you one. :)
     
  37. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    Sent it.
     
  38. jkcom

    jkcom

    Joined:
    Aug 31, 2013
    Posts:
    5
    hi BestHTTP

    Unity : 5.0.1p4 BestHTTP : Pro 1.8.0
    I can create a Unity extension tools. Working, I get the following error.

    source :

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using UnityEditor;
    4. using BestHTTP;
    5. using System;
    6.  
    7. public class NetManager : EditorWindow
    8. {
    9.     [MenuItem ("Window/Net Manager")]
    10.     public static void Init()
    11.     {
    12.         var window = EditorWindow.GetWindow(typeof(NetManager));
    13.     }
    14.  
    15.     void OnGUI()
    16.     {
    17.         if(GUILayout.Button("Load Info From Server")) {
    18.             HTTPRequest request = new HTTPRequest(new Uri(UrlPath), HTTPMethods.Get, GetAsynFinished);
    19.             request.Send();
    20.         }  
    21.     }
    22.  
    23.     public void GetAsynFinished(HTTPRequest request, HTTPResponse response)
    24.     {
    25.         Debug.Log ("GetAsynFinished Request = " + request.State);      
    26.     }
    27. }
    28.  

    error :
    get_persistentDataPath can only be called from the main thread.
    Constructors and field initializers will be executed from the loading thread when loading a scene.
    Don't use this function in the constructor or field initializers, instead move initialization code to the Awake or Start function.


    W [CookieJar]: Cookie saving and loading disabled!

    Thanks for any help!
     
  39. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @jkcom: That message is almost harmless. Cookie saving will be disabled, but if you have to have cookies in your editor scripts i have a fix for it:
    In te \Assets\Best HTTP (Pro)\BestHTTP\Cookies\CookieJar.cs you have to modify the SetupFolder function to look like this:
    Code (CSharp):
    1.         internal static void SetupFolder()
    2.         {
    3.             if (!CookieJar.IsSavingSupported)
    4.                 return;
    5.  
    6.             try
    7.             {
    8.                 if (string.IsNullOrEmpty(CookieFolder) || string.IsNullOrEmpty(LibraryPath))
    9.                 {
    10.                     CookieFolder = System.IO.Path.Combine(HTTPManager.GetRootCacheFolder(), "Cookies");
    11.                     LibraryPath = System.IO.Path.Combine(CookieFolder, "Library");
    12.                 }
    13.             }
    14.             catch
    15.             { }
    16.         }
    17.  
    I will include this fix in the next release.

    Also, to use BestHTTP in editor mode you have to call the HTTPManager's OnUpdate function manually in a function that is called regularly. The OnUpdate will dispatch the callback events.

    The OnGUI event is ok for it, but you also have to request a repaint too:
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using BestHTTP;
    4. using System;
    5.  
    6. public class NetManager : EditorWindow
    7. {
    8.     [MenuItem("Window/Net Manager")]
    9.     public static void Init()
    10.     {
    11.         var window = EditorWindow.GetWindow(typeof(NetManager));
    12.     }
    13.  
    14.     void OnGUI()
    15.     {
    16.         HTTPManager.OnUpdate();
    17.  
    18.         if (GUILayout.Button("Load Info From Server"))
    19.         {
    20.             HTTPRequest request = new HTTPRequest(new Uri(UrlPath), HTTPMethods.Get, GetAsynFinished);
    21.             request.Send();
    22.         }
    23.  
    24.         this.Repaint();
    25.     }
    26.  
    27.     public void GetAsynFinished(HTTPRequest request, HTTPResponse response)
    28.     {
    29.         Debug.Log("GetAsynFinished Request = " + request.State);
    30.     }
    31.  
    32.     public string UrlPath = "http://google.com";
    33. }
     
  40. jkcom

    jkcom

    Joined:
    Aug 31, 2013
    Posts:
    5
    thank you very much!
     
  41. tatata

    tatata

    Joined:
    Jul 11, 2013
    Posts:
    12
    Hi,

    In TcpClient.cs, the getter of WriteTimeout property returns TimeSpan.FromSeconds(SendTimeout) (not ReceiveTimeout).

    Is this a bug?

    ---

    And...

    I want WriteTimeout/ReadTimeout support like the followings...

    Code (CSharp):
    1. var request = new HTTPRequest(url);
    2. request.WriteTimeout = 5f;
    3. request.ReadTimeout = 5f;
    4.  
     
  42. BestHTTP

    BestHTTP

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

    WriteTimeout: Well, yes, it can be a bug, but Write and Read Timeouts are not used by the plugin. They left in the code from previous attempts.

    Write and Read timeouts are implemented higher level in a single timeout: HTTPRequest's Timeout. This is the time that the request will spend to send and receive the data.

    As I remember Socket's Receive and Send Timeouts are not perfomed equally on all supported platforms.

    So, for you example you can say, that "My request must be done in 10(5 write + 5 read) secs":
    Code (CSharp):
    1. var request = new HTTPRequest(url);
    2. request.Timeout = TimeSpan.FromSeconds(10);
    3.  
     
    Last edited: Jun 1, 2015
  43. tatata

    tatata

    Joined:
    Jul 11, 2013
    Posts:
    12
    [/QUOTE]

    When a program downloads a large file, it requires long seconds as Timeout property.

    So a program will be kept waiting for a long time until it is timed out if the network is disconnected in early process of the large file download. (This happens sometimes with mobile network...)

    > As I remember Socket's Receive and Send Timeouts are not perfomed equally on all supported platforms.

    It is sad...
     
  44. Dynamoid-Megan

    Dynamoid-Megan

    Joined:
    Apr 16, 2015
    Posts:
    72
    I would like to know how to unpack the data sent in the HTTP request:
    If I send:
    Code (CSharp):
    1. "HTTPRequestrequest = newHTTPRequest(newUri("http://mywebsite.com/api/users/13/"), OnRequestFinished); request.Send();"
    In my console I get:
    Code (CSharp):
    1. "Request Finished! Text received: {"id":13,"username":"This_Name","email":"test-email@gmail.com"}"
    How would I go about isolating, say, just the name or just the email to fill out a text field in Unity with?
     
  45. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @Dynamoid Megan: You can use the simple json encoder located in the BestHTTP.JSON namespace:
    Code (CSharp):
    1. void OnRequestFinished(HTTPRequest req, HTTPResponse resp)
    2. {
    3.     switch (req.State)
    4.     {
    5.         // The request finished without any problem.
    6.         case HTTPRequestStates.Finished:
    7.             if (resp.IsSuccess)
    8.             {
    9.                 Debug.Log("Request Finished Successfully! " + resp.DataAsText);
    10.  
    11.                 var data = BestHTTP.JSON.Json.Decode(resp.DataAsText) as Dictionary<string, object>;
    12.                 string name = data["username"].ToString();
    13.                 string email = data["email"].ToString();
    14.  
    15.                 Debug.Log(string.Format("UserName: {0} E-Mail: {1}", name, email));
    16.             }
    17.             else
    18.                 Debug.LogWarning(string.Format("Request Finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}",
    19.                                                 resp.StatusCode,
    20.                                                 resp.Message,
    21.                                                 resp.DataAsText));
    22.             break;
    23.  
    24.         // The request finished with an unexpected error. The request's Exception property may contain more info about the error.
    25.         case HTTPRequestStates.Error:
    26.             Debug.LogWarning("Request Finished with Error! " + (req.Exception != null ? (req.Exception.Message + "\n" + req.Exception.StackTrace) : "No Exception"));
    27.             break;
    28.  
    29.         // The request aborted, initiated by the user.
    30.         case HTTPRequestStates.Aborted:
    31.             Debug.LogWarning("Request Aborted!");
    32.             break;
    33.  
    34.         // Ceonnecting to the server is timed out.
    35.         case HTTPRequestStates.ConnectionTimedOut:
    36.             Debug.LogError("Connection Timed Out!");
    37.             break;
    38.  
    39.         // The request didn't finished in the given time.
    40.         case HTTPRequestStates.TimedOut:
    41.             Debug.LogError("Processing the request Timed Out!");
    42.             break;
    43.     }
    44. }
    45.  
     
  46. Dynamoid-Megan

    Dynamoid-Megan

    Joined:
    Apr 16, 2015
    Posts:
    72
    Thank you for your help, I feel I'm close but I'm having trouble with the response success:
    Code (CSharp):
    1.     var data = BestHTTP.JSON.Json.Decode(response.DataAsText) as Dictionary<string, object>;
    2.                 string name = data["username"].ToString();
    3.                 string email = data["email"].ToString();
    And I added usingBestHTTP.JSON; to the top of the script. The "var" is red and says "unknown resolve error" when I hover over it, the error in the Unity console says CS0246: The type or namespace name `Dictionary`2' could not be found. Are you missing a using directive or an assembly reference?
    Can you tell if I missed any other requirements or why it is adding a "2"? I tried using a clean project with no other plugins.
     
  47. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @Dynamoid Megan : You have to add the System.Collections.Generic namespace too:
    Code (CSharp):
    1. using System.Collections.Generic;
     
  48. yiwushuma

    yiwushuma

    Joined:
    Jun 9, 2015
    Posts:
    2
    HI,
    I'm from Shanghai/China...For the IOS IL2CPP 64bit mode, I've bought the asset from unity asset store......

    Question: How to connect the rest api service(get, post)?

    For example:
    Url:
    http://222.73.85.52:8090/user/login
    Two parameters :
    key : name, value : zq1216
    key : passwd, value : 111111

    1.Previously (I used the UnityHTTP), the code as follow:

    Hashtable ht = new Hashtable();
    ht.Add("name", "zq1216");
    ht.Add("passwd", "111111");
    HTTP.Request request = new HTTP.Request("post", "http://222.73.85.52:8090/user/login", ht);
    request.Send(OnRequestFinished);

    The results is correct ( server feedback data is correct ).

    2.Now (I use the Best HTTP), the code as follow:

    HTTPRequest request = new HTTPRequest(new System.Uri("http://222.73.85.52:8090/user/login"), HTTPMethods.Post, OnRequestFinished);
    request.AddField("name", "zq1216");
    request.AddField("passwd", "111111");
    request.Send();

    The results is error ( server feedback data is error )..

    Why?

    Thanks.
     
  49. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @yiwushuma: As i see UnityHTTP converts the hashtabe to a json encoded string, and will send this string in the request.
    You can achive the same result with this code:
    Code (CSharp):
    1. Dictionary<string, string> fields = new Dictionary<string, string>();
    2. fields.Add("name", "zq1216");
    3. fields.Add("passwd", "111111");
    4.  
    5. HTTPRequest request = new HTTPRequest(new System.Uri("http://222.73.85.52:8090/user/login"), HTTPMethods.Post, OnRequestFinished);
    6.  
    7. request.AddHeader("Content-Type", "application/json");
    8. request.RawData = System.Text.Encoding.UTF8.GetBytes(BestHTTP.JSON.Json.Encode(fields));
    9.      
    10. request.Send();
     
  50. yiwushuma

    yiwushuma

    Joined:
    Jun 9, 2015
    Posts:
    2
    thank you, I've made it.