using System; using System.Collections.Generic; using System.IO; using System.Text; using Best.HTTP.Cookies; using Best.HTTP.Examples.Helpers; using Best.HTTP.Request.Authentication; using Best.HTTP.Request.Authenticators; using Best.HTTP.Shared.PlatformSupport.IL2CPP; using UnityEngine; namespace Best.HTTP.Examples { /// /// Collection of small samples that can be fit in one method and an additional callback. Result of the requests are logged/displayed on the UI. /// sealed class SmallSamples : SampleBase { #pragma warning disable 0649, 0169 [Header("Sample Fields")] /// /// GameObject that will be used as a root for new UI objects. /// [SerializeField] private RectTransform _contentRoot; /// /// Prefab of a UI object with two Text fields. /// [SerializeField] private MultiTextListItem _listItemPrefab; /// /// Prefab of a UI object with Text and (Raw)Image fields. /// [SerializeField] private TextWithImageListItem _listItemWithImagePrefab; #pragma warning restore /// /// Address of the used end point. /// private string _baseAddress = "https://httpbingo.org"; /// /// Queue of the samples executed sequentially. /// private Queue examples = new Queue(); private AssetBundle _assetBundleToUnload; protected override void Start() { base.Start(); this.examples.Enqueue(SimpleGet); this.examples.Enqueue(GetImageFromAssetBundle); this.examples.Enqueue(PostRaw); this.examples.Enqueue(PostUrlEncoded); this.examples.Enqueue(PostMultiPartEncoded); this.examples.Enqueue(PostJSon); this.examples.Enqueue(Redirect); this.examples.Enqueue(AbsoluteRedirect); this.examples.Enqueue(RelativeRedirect); this.examples.Enqueue(RedirectTo); this.examples.Enqueue(DecodeBase64); this.examples.Enqueue(EncodeBase64); this.examples.Enqueue(ExpectedToSucceedBasicAuth); this.examples.Enqueue(ExpectedToFailBasicAuth); this.examples.Enqueue(ExpectedToSucceedDigestAuth); this.examples.Enqueue(ExpectedToFailDigestAuth); this.examples.Enqueue(BearerTokenAuth); this.examples.Enqueue(CachedForNSeconds); this.examples.Enqueue(CachedForNSeconds); this.examples.Enqueue(SendWithETag); this.examples.Enqueue(CheckCookies); this.examples.Enqueue(SetCustomCookies); this.examples.Enqueue(RequestCookies); this.examples.Enqueue(DeleteCookies); this.examples.Enqueue(GetGZip); this.examples.Enqueue(GetDeflate); this.examples.Enqueue(GetBrotli); this.examples.Enqueue(GetJPEGResponse); this.examples.Enqueue(GetPNGResponse); this.examples.Enqueue(GetJSonResponseAsync); ExecuteNext(); } private void OnDisable() { Resources.UnloadUnusedAssets(); #if UNITY_2023_1_OR_NEWER _assetBundleToUnload?.UnloadAsync(true); #else _assetBundleToUnload?.Unload(true); #endif } void SimpleGet() { var request = HTTPRequest.CreateGet($"{_baseAddress}/get", SimpleCallback); request.Tag = CreateUIItem("Simple GET"); request.Send(); } async void GetImageFromAssetBundle() { var uiEntry = CreateUIItemWithImage($"Image from AssetBundle (using GetAssetBundleAsync with async-await)"); string url = null; #if UNITY_ANDROID && !UNITY_EDITOR url = "https://besthttpwebgldemo.azurewebsites.net/AssetBundles/Android/demobundle.assetbundle"; #else url = "https://besthttpwebgldemo.azurewebsites.net/AssetBundles/WebGL/demobundle.assetbundle"; #endif var request = HTTPRequest.CreateGet(url); try { _assetBundleToUnload = await request.GetAssetBundleAsync(); var texture = _assetBundleToUnload.LoadAsset("9443182_orig"); uiEntry.SetImage(texture); } catch (AsyncHTTPException ex) { uiEntry.SetStatusText(ex.Message); } catch (Exception ex) { uiEntry.SetStatusText(ex.Message); } finally { ExecuteNext(); } } void PostRaw() { var request = HTTPRequest.CreatePost($"{_baseAddress}/post", SimpleCallback); var data = new byte[] { 1, 2, 3, 4 }; request.UploadSettings.UploadStream = new MemoryStream(data); request.Tag = CreateUIItem("POST - Raw"); request.Send(); } void PostUrlEncoded() { var request = HTTPRequest.CreatePost($"{_baseAddress}/post", SimpleCallback); var formStream = new Best.HTTP.Request.Upload.Forms.UrlEncodedStream(); formStream.AddField("field 1", "value 1"); formStream.AddField("field 2", "value 2"); request.UploadSettings.UploadStream = formStream; request.Tag = CreateUIItem("POST - Url Encoded"); request.Send(); } void PostMultiPartEncoded() { var request = HTTPRequest.CreatePost($"{_baseAddress}/post", SimpleCallback); var formStream = new Best.HTTP.Request.Upload.Forms.MultipartFormDataStream(); formStream.AddField("field 1", "value 1"); formStream.AddField("field 2", "value 2"); var data = new byte[] { 1, 2, 3, 4 }; formStream.AddStreamField("binary field", new MemoryStream(data)); request.UploadSettings.UploadStream = formStream; request.Tag = CreateUIItem("POST - Multipart/Form-Data Encoded"); request.Send(); } class SendAsJson { public string key1, key2; } void PostJSon() { var obj = new SendAsJson { key1 = "value 1", key2 = "value 2" }; var request = HTTPRequest.CreatePost($"{_baseAddress}/post", SimpleCallback); request.UploadSettings.UploadStream = new Best.HTTP.Request.Upload.JSonDataStream(obj); request.Tag = CreateUIItem("POST - JSon"); request.Send(); } void Redirect() { var request = HTTPRequest.CreateGet($"{_baseAddress}/redirect/6", SimpleCallback); request.Tag = CreateUIItem("Redirect"); request.Send(); } void AbsoluteRedirect() { var request = HTTPRequest.CreateGet($"{_baseAddress}/absolute-redirect/6", SimpleCallback); request.Tag = CreateUIItem("Absolute Redirect"); request.Send(); } void RelativeRedirect() { var request = HTTPRequest.CreateGet($"{_baseAddress}/relative-redirect/6", SimpleCallback); request.Tag = CreateUIItem("Relative Redirect"); request.Send(); } void RedirectTo() { var request = HTTPRequest.CreateGet($"{_baseAddress}/redirect-to?status_code=307&url={Uri.EscapeUriString(_baseAddress)}", SimpleCallback); request.Tag = CreateUIItem("Redirect To"); request.Send(); } void DecodeBase64() { string base64 = "aHR0cGJpbmdvLm9yZw=="; var request = HTTPRequest.CreateGet($"{_baseAddress}/base64/decode/{base64}", TextCallback); request.Tag = CreateUIItem("Decode Base64"); request.Send(); } void EncodeBase64() { string strToEncode = "httpbingo.org"; var request = HTTPRequest.CreateGet($"{_baseAddress}/base64/encode/{Uri.EscapeUriString(strToEncode)}", TextCallback); request.Tag = CreateUIItem("Encode Base64"); request.Send(); } void ExpectedToSucceedBasicAuth() { DigestStore.Clear(); var request = HTTPRequest.CreateGet($"{_baseAddress}/basic-auth/user/passwd", SimpleCallback); request.Authenticator = new CredentialAuthenticator(new Credentials(AuthenticationTypes.Basic, "user", "passwd")); request.Tag = CreateUIItem("Basic Auth (Expected to Succeed)"); request.Send(); } void ExpectedToFailBasicAuth() { DigestStore.Clear(); var request = HTTPRequest.CreateGet($"{_baseAddress}/basic-auth/user/passwd", SimpleCallback); // Here we set a wrong password request.Authenticator = new CredentialAuthenticator(new Credentials(AuthenticationTypes.Basic, "user", "wrong passwd")); request.Tag = CreateUIItem("Basic Auth (Expected to Fail)"); request.Send(); } void ExpectedToSucceedDigestAuth() { DigestStore.Clear(); var request = HTTPRequest.CreateGet($"{_baseAddress}/digest-auth/auth/user/passwd/MD5", SimpleCallback); request.Authenticator = new CredentialAuthenticator(new Credentials(AuthenticationTypes.Digest, "user", "passwd")); request.Tag = CreateUIItem("Digest Auth (Expected to Succeed)"); request.Send(); } void ExpectedToFailDigestAuth() { DigestStore.Clear(); var request = HTTPRequest.CreateGet($"{_baseAddress}/digest-auth/auth/user/passwd/MD5", SimpleCallback); // Here we set a wrong password request.Authenticator = new CredentialAuthenticator(new Credentials(AuthenticationTypes.Digest, "user", "wrong passwd")); request.Tag = CreateUIItem("Digest Auth (Expected to Succeed)"); request.Send(); } void BearerTokenAuth() { var request = HTTPRequest.CreateGet($"{_baseAddress}/bearer", SimpleCallback); // here we create a fake token by base64 encoding some bytes. httpbingo just checks for the Authorization header and whether it's bearer or not. string bearerToken = Convert.ToBase64String(Encoding.UTF8.GetBytes("")); request.Authenticator = new BearerTokenAuthenticator(bearerToken); request.Tag = CreateUIItem("Bearer Token"); request.Send(); } void CachedForNSeconds() { const int CacheTime = 30; // By calling /cache/30 the server will send caching headers that informs the client that the content is cachable and valid for 30 seconds. // For 30 seconds, request to the same uri should return the content from the local cache. var request = HTTPRequest.CreateGet($"{_baseAddress}/cache/{CacheTime}", CheckCachedCallback); request.Tag = CreateUIItem($"Cached content for {CacheTime} seconds"); request.Send(); } void SendWithETag() { const string etag = ""; var request = HTTPRequest.CreateGet($"{_baseAddress}/etag/{etag}", CheckCachedCallback); request.Tag = CreateUIItem($"Request response with ETag"); request.Send(); } void CheckCookies() { var request = HTTPRequest.CreateGet($"{_baseAddress}/cookies", CookiesCallback); request.Tag = CreateUIItem($"Check # of Cookies"); request.Send(); } void SetCustomCookies() { var uri = new Uri($"{_baseAddress}/cookies"); CookieJar.Set(uri, new Cookie("custom1", "value1")); CookieJar.Set(uri, new Cookie("custom2", "value2")); var request = HTTPRequest.CreateGet(uri, CookiesCallback); request.Tag = CreateUIItem($"Set Custom Cookies"); request.Send(); } void RequestCookies() { // Ask the server to set a few cookies for us. var request = HTTPRequest.CreateGet($"{_baseAddress}/cookies/set?k1=v1&k2=v2", CookiesCallback); request.Tag = CreateUIItem($"Request Cookies from Server"); request.Send(); } void DeleteCookies() { var request = HTTPRequest.CreateGet($"{_baseAddress}/cookies/delete?k1=", CookiesCallback); request.Tag = CreateUIItem($"Delete One Cookie"); request.Send(); } void GetGZip() { var request = HTTPRequest.CreateGet($"{_baseAddress}/gzip", SimpleCallback); request.Tag = CreateUIItem($"gzip"); request.Send(); } void GetDeflate() { var request = HTTPRequest.CreateGet($"{_baseAddress}/deflate", SimpleCallback); request.Tag = CreateUIItem($"Deflate"); request.Send(); } void GetBrotli() { var request = HTTPRequest.CreateGet($"{_baseAddress}/brotli", SimpleCallback); request.Tag = CreateUIItem($"Brotli"); request.Send(); } void GetJPEGResponse() { var request = HTTPRequest.CreateGet($"{_baseAddress}/image/jpeg", ImageCallback); request.Tag = CreateUIItemWithImage($"Image (JPEG) response"); request.Send(); } void GetPNGResponse() { var request = HTTPRequest.CreateGet($"{_baseAddress}/image/png", ImageCallback); request.Tag = CreateUIItemWithImage($"Image (PNG) response"); request.Send(); } #pragma warning disable 0649 [Preserve] class JSonResult { [Preserve] public JSonSlideshow slideshow; } [Preserve] class JSonSlideshow { [Preserve] public string author; [Preserve] public string date; [Preserve] public string title; } #pragma warning restore async void GetJSonResponseAsync() { var request = HTTPRequest.CreateGet($"{_baseAddress}/json"); var uiEntry = CreateUIItem($"JSon response (GetFromJsonResultAsync<> with async-await)"); try { var jsonResult = await request.GetFromJsonResultAsync(); var slideshow = jsonResult.slideshow; uiEntry.SetStatusText($"{slideshow.author}: {slideshow.title} ({slideshow.date})"); } catch (AsyncHTTPException ex) { uiEntry.SetStatusText(ex.Message); } catch (Exception ex) { uiEntry.SetStatusText(ex.Message); } finally { ExecuteNext(); } } /// /// A simple callback for HTTPRequest, called when the request finished either succesfully or with an error. /// /// The original HTTPRequest instance. /// Reference to a HTTPResponse object or null in case of an error. private void SimpleCallback(HTTPRequest req, HTTPResponse resp) { var uiEntry = req.Tag as MultiTextListItem; if (resp != null) uiEntry.SetStatusText(resp.StatusCode.ToString()); else uiEntry.SetStatusText(req.State.ToString()); ExecuteNext(); } /// /// Callback to display the received content as an utf-8 text. /// /// The original HTTPRequest instance. /// Reference to a HTTPResponse object or null in case of an error. private void TextCallback(HTTPRequest req, HTTPResponse resp) { var uiEntry = req.Tag as MultiTextListItem; if (resp != null) { if (resp.IsSuccess) uiEntry.SetStatusText(resp.DataAsText); else uiEntry.SetStatusText(resp.StatusCode.ToString()); } else uiEntry.SetStatusText(req.State.ToString()); ExecuteNext(); } /// /// Callback to display whether the content is loaded from the local cache or freshly downloaded from the server. /// /// The original HTTPRequest instance. /// Reference to a HTTPResponse object or null in case of an error. private void CheckCachedCallback(HTTPRequest req, HTTPResponse resp) { var uiEntry = req.Tag as MultiTextListItem; if (resp != null) { if (resp.IsSuccess) uiEntry.SetStatusText(resp.IsFromCache ? "from cache" : "fresh from the server"); else uiEntry.SetStatusText(resp.StatusCode.ToString()); } else uiEntry.SetStatusText(req.State.ToString()); ExecuteNext(); } /// /// Callback to display the number of cookies stored for the request's uri. /// /// The original HTTPRequest instance. /// Reference to a HTTPResponse object or null in case of an error. private void CookiesCallback(HTTPRequest req, HTTPResponse resp) { var uiEntry = req.Tag as MultiTextListItem; if (resp != null) { if (resp.IsSuccess) { var cookies = CookieJar.Get(req.CurrentUri); int cookieCount = 0; if (cookies != null) cookieCount = cookies.Count; uiEntry.SetStatusText($"Cookies: {cookieCount}"); } else uiEntry.SetStatusText(resp.StatusCode.ToString()); } else uiEntry.SetStatusText(req.State.ToString()); ExecuteNext(); } /// /// Callback to display the content as image/texture. /// /// The original HTTPRequest instance. /// Reference to a HTTPResponse object or null in case of an error. private void ImageCallback(HTTPRequest req, HTTPResponse resp) { var uiEntry = req.Tag as TextWithImageListItem; if (resp != null) { if (resp.IsSuccess) { uiEntry.SetImage(resp.DataAsTexture2D); } else uiEntry.SetStatusText(resp.StatusCode.ToString()); } else uiEntry.SetStatusText(req.State.ToString()); ExecuteNext(); } void ExecuteNext() { if (this.examples.Count > 0) this.examples.Dequeue()?.Invoke(); } MultiTextListItem CreateUIItem(string str) => Instantiate(this._listItemPrefab, this._contentRoot) .SetText(str) as MultiTextListItem; TextWithImageListItem CreateUIItemWithImage(string str) => Instantiate(this._listItemWithImagePrefab, this._contentRoot) .SetText(str) as TextWithImageListItem; } }