Mirror of Svelto.ECS because we're a fan of it
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

StandardWebRequest.cs 5.9KB

Svelto.ECS 2.9 changes (random order of importance): New Serialization framework more thorough disposing of the EnginesRoot an EnginesRoot reference should never be held, unless it’s a weak reference. The code changed to stick to this rule IReactOnAddAndRemove callbacks are now guaranteed to be called after all the entity structs generated by the same entity have been added and before any is removed. both functions pass the EGID of the analysing entity by parameter now, so that the entity struct won’t need to implement INeedEGID for this sole purpose. The IReactOnSwap MovedFrom method has been removed, it is now redundant. Entities built or removed during the IReactOnAddAndRemove callbacks are now added and removed immediately and not on the next submission like used to happen. This avoid some awkward checks that were previously needed inside engines. EntityStreams can get (optionally) the EGID of the entity published, so that the EntityStruct won’t need an INeedEGID for this sole purpose. Groups are not trimmed anymore when they are emptied to avoid allocations. Removed a bunch of run-time allocations that weren’t supposed to happen in Release and/or when the Profile define is used in editor (for debugging reasons Svelto.ECS may need to use strings at run-time, but Svelto.ECS is allocation zero in Release and when the Profile keyword is used) A improved the DynamicEntityDescriptor and ExtendibleEntityDescriptor code and more notably, introduced the new method ExtendedWith<> to facilitate the writing of modular and reusable entity descriptors. Several minor code design improvements/optimisations
5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Net;
  4. using UnityEngine;
  5. using System.Security.Cryptography.X509Certificates;
  6. using System.Net.Security;
  7. using Svelto.Tasks;
  8. using Svelto.Tasks.Enumerators;
  9. using UnityEngine.Networking;
  10. namespace Svelto.Services
  11. {
  12. public enum Method
  13. {
  14. GET,
  15. POST
  16. }
  17. public enum Result
  18. {
  19. Success,
  20. ServerHandledError,
  21. ServerException,
  22. ClientFailure,
  23. }
  24. public sealed class StandardWebRequest
  25. {
  26. static StandardWebRequest()
  27. {
  28. ServicePointManager.ServerCertificateValidationCallback = CannotVerifyMessageCertificate;
  29. ServicePointManager.DefaultConnectionLimit = 64;
  30. }
  31. public Result result { get; private set; }
  32. public int maxAttempts = 3;
  33. public int waitOnRetrySeconds = 1;
  34. public int timeoutSeconds = 10;
  35. public Method method = Method.POST;
  36. public Func<HttpStatusCode, bool> processStatusCodes = code => false;
  37. public IResponseHandler responseHandler;
  38. public string URL;
  39. public IEnumerator<TaskContract> Execute(byte[] bodyRaw)
  40. {
  41. int attemptNumber = 0;
  42. do
  43. {
  44. using (UnityWebRequest request = new UnityWebRequest())
  45. {
  46. switch (method)
  47. {
  48. case Method.GET:
  49. request.method = UnityWebRequest.kHttpVerbGET;
  50. break;
  51. case Method.POST:
  52. request.method = UnityWebRequest.kHttpVerbPOST;
  53. break;
  54. default:
  55. request.method = UnityWebRequest.kHttpVerbPOST;
  56. break;
  57. }
  58. request.url = URL;
  59. request.uploadHandler = new UploadHandlerRaw(bodyRaw);
  60. request.downloadHandler = new UnityDownloadHandler(responseHandler);
  61. request.SetRequestHeader("Content-Type", "application/json");
  62. request.timeout = timeoutSeconds;
  63. AsyncOperation op = request.SendWebRequest();
  64. while (op.isDone == false)
  65. {
  66. yield return Yield.It;
  67. }
  68. if (request.isNetworkError == false)
  69. {
  70. if (ProcessResponse(request) == true)
  71. {
  72. result = Result.Success;
  73. Svelto.Console.LogDebug("web request completed");
  74. yield break;
  75. }
  76. else
  77. {
  78. Svelto.Console.LogDebug("web request completed with failure ", URL);
  79. try
  80. {
  81. responseHandler?.CompleteContent();
  82. result = Result.ServerHandledError;
  83. }
  84. catch
  85. {
  86. result = Result.ServerException;
  87. }
  88. yield break; //no retry on server error!
  89. }
  90. }
  91. else
  92. if (++attemptNumber < maxAttempts)
  93. {
  94. var wait = new ReusableWaitForSecondsEnumerator(waitOnRetrySeconds);
  95. while (wait.MoveNext() == true) yield return Yield.It;
  96. Svelto.Console.LogDebug("web request retry");
  97. continue; //retry on client error
  98. }
  99. else
  100. {
  101. result = Result.ClientFailure;
  102. yield break;
  103. }
  104. }
  105. }
  106. while (true);
  107. }
  108. bool ProcessResponse(UnityWebRequest request)
  109. {
  110. HttpStatusCode statusCode = (HttpStatusCode) request.responseCode;
  111. if (statusCode != HttpStatusCode.OK)
  112. if (processStatusCodes(statusCode) == false)
  113. return false;
  114. return true;
  115. }
  116. // BOC:: After turning on SSL on the gameserver we started getting certificate problems.
  117. // Found this solution on Stack Overflow with Mike R
  118. // (https://stackoverflow.com/questions/4926676/mono-https-webrequest-fails-with-the-authentication-or-decryption-has-failed)
  119. static bool CannotVerifyMessageCertificate(System.Object sender, X509Certificate certificate, X509Chain chain,
  120. SslPolicyErrors sslPolicyErrors)
  121. {
  122. bool isOk = true;
  123. // If there are errors in the certificate chain,
  124. // look at each error to determine the cause.
  125. if (sslPolicyErrors != SslPolicyErrors.None)
  126. {
  127. for (int i = 0; i < chain.ChainStatus.Length; i++)
  128. {
  129. if (chain.ChainStatus[i].Status == X509ChainStatusFlags.RevocationStatusUnknown)
  130. continue;
  131. chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain;
  132. chain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
  133. chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 1, 0);
  134. chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllFlags;
  135. bool chainIsValid = chain.Build((X509Certificate2) certificate);
  136. if (!chainIsValid)
  137. {
  138. isOk = false;
  139. break;
  140. }
  141. }
  142. }
  143. return isOk;
  144. }
  145. }
  146. }