<commit_before>using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;

namespace CotcSdk {
	/**
	 * Better HTTP client based on UnityEngine.Experimental.Networking.UnityWebRequest.
	 */
	internal class UnityHttpClientV2 : HttpClient {

		/// <summary>Asynchronous request state.</summary>
		private class UnityRequest : WebRequest {
			// This class stores the State of the request.
			private string ContentType;
			public UnityHttpClientV2 self;
			private UnityWebRequest Request;
			private bool WasAborted = false;

			public UnityRequest(UnityHttpClientV2 inst, string url, HttpRequest request, object previousUserData, int requestId) : base(inst, request) {
                self = inst;
                OriginalRequest = request;
                RequestId = requestId;
                PreviousUserData = previousUserData;

                Request = new UnityWebRequest(url);
                // Auto-choose HTTP method
                Request.method = request.Method ?? (request.Body != null ? "POST" : "GET");
                // TODO Missing functionality (currently unsupported by UnityWebRequest).
                //				req.SetRequestHeader("User-agent", request.UserAgent);
                //				req.keepAlive = true;
                foreach (var pair in request.Headers)
                {
                    Request.SetRequestHeader(pair.Key, pair.Value);
                }

                if (OriginalRequest.Body != null)
                {
                    UploadHandler uploader = new UploadHandlerRaw(OriginalRequest.Body);
                    if (ContentType != null) uploader.contentType = ContentType;
                    Request.uploadHandler = uploader;
                }
                Request.downloadHandler = new DownloadHandlerBuffer();
			}

			public override void AbortRequest() {
				WasAborted = true;
				if (Request != null) {
                    Request.Abort();
				}
			}

			/// <summary>Prints the current request for user convenience.</summary>
			internal void LogRequest() {
				if (!VerboseMode) { return; }

				StringBuilder sb = new StringBuilder();
				sb.AppendLine("[" + RequestId + "] " + Request.method + "ing on " + Request.url);
				sb.AppendLine("Headers (Unity):");
				foreach (var pair in OriginalRequest.Headers) {
					sb.AppendLine("\t" + pair.Key + ": " + pair.Value);
				}
				if (OriginalRequest.HasBody) {
					sb.AppendLine("Body: " + OriginalRequest.BodyString);
				}
				Common.Log(sb.ToString());
			}

			/// <summary>Prints information about the response for debugging purposes.</summary>
			internal void LogResponse(HttpResponse response) {
				if (!VerboseMode) { return; }

				StringBuilder sb = new StringBuilder();
				sb.AppendLine("[" + RequestId + "] " + response.StatusCode + " on " + Request.method + "ed on " + Request.url);
				sb.AppendLine("Recv. headers:");
				foreach (var pair in response.Headers) {
					if (String.Compare(pair.Key, "Content-Type", true) == 0) {
						ContentType = pair.Value;
					}
					else {
						sb.AppendLine("\t" + pair.Key + ": " + pair.Value);
					}
				}
				if (response.HasBody) {
					sb.AppendLine("Body: " + response.BodyString);
				}
				Common.Log(sb.ToString());
			}

            private IEnumerator ProcessRequest(UnityWebRequest req) {
                yield return req.Send();

                if (req.isError)
                {
                    Debug.Log("Request error: " + req.error);
                    if (!WasAborted)
                    {
                        string errorMessage = "Failed web request: " + req.error;
                        Common.Log(errorMessage);
                        self.FinishWithRequest(this, new HttpResponse(new Exception(errorMessage)));
                    }
                }
                else
                {
                    // Extracts asset bundle
                    HttpResponse response = new HttpResponse();
                    response.Body = Request.downloadHandler.data;
                    response.StatusCode = (int)Request.responseCode;
                    Debug.Log("Status code: " + response.StatusCode);
                    Dictionary<string, string> dict = Request.GetResponseHeaders();
                    if (Application.platform == RuntimePlatform.IPhonePlayer && response.StatusCode <= 0 /*&& dict == null*/)
                    {
                        // Nice bug in the iOS UnityWebRequest implementation. When you abort a request, in fact it doesn't
                        // abort the request. Instead of receiving an error (req.isError and req.error can check that), you
                        // just receive a funny responseCode (like 0 or -1001) and an empty dictionary of response headers.
                        Debug.Log("Unity iOS bug for UnityWebRequest...");
                    }
                    else
                    {
                        foreach (var pair in dict)
                        {
                            response.Headers[pair.Key] = pair.Value;
                        }
                        LogResponse(response);
                        self.FinishWithRequest(this, response);
                    }
                }
            }

			public override void Start() {
				// Configure & perform the request
				LogRequest();
				Cotc.RunCoroutine(ProcessRequest(Request));
			}
		}

		protected override WebRequest CreateRequest(HttpRequest request, string url, object previousUserData) {
			return new UnityRequest(this, url, request, previousUserData, (RequestCount += 1));
		}
	}<commit_msg>Manage a specific case where Unity on iOS "breaks" an http request after 1 minute, no matter what, returning funny error codes. Intercepting now this case to relaunch a "long poll" http request.<commit_after>using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;

namespace CotcSdk {
	/**
	 * Better HTTP client based on UnityEngine.Experimental.Networking.UnityWebRequest.
	 */
	internal class UnityHttpClientV2 : HttpClient {

		/// <summary>Asynchronous request state.</summary>
		private class UnityRequest : WebRequest {
			// This class stores the State of the request.
			private string ContentType;
			public UnityHttpClientV2 self;
			private UnityWebRequest Request;
			private bool WasAborted = false;

			public UnityRequest(UnityHttpClientV2 inst, string url, HttpRequest request, object previousUserData, int requestId) : base(inst, request) {
                self = inst;
                OriginalRequest = request;
                RequestId = requestId;
                PreviousUserData = previousUserData;

                Request = new UnityWebRequest(url);
                // Auto-choose HTTP method
                Request.method = request.Method ?? (request.Body != null ? "POST" : "GET");
                // TODO Missing functionality (currently unsupported by UnityWebRequest).
                //				req.SetRequestHeader("User-agent", request.UserAgent);
                //				req.keepAlive = true;
                foreach (var pair in request.Headers)
                {
                    Request.SetRequestHeader(pair.Key, pair.Value);
                }

                if (OriginalRequest.Body != null)
                {
                    UploadHandler uploader = new UploadHandlerRaw(OriginalRequest.Body);
                    if (ContentType != null) uploader.contentType = ContentType;
                    Request.uploadHandler = uploader;
                }
                Request.downloadHandler = new DownloadHandlerBuffer();
			}

			public override void AbortRequest() {
				WasAborted = true;
				if (Request != null) {
                    Request.Abort();
				}
			}

			/// <summary>Prints the current request for user convenience.</summary>
			internal void LogRequest() {
				if (!VerboseMode) { return; }

				StringBuilder sb = new StringBuilder();
				sb.AppendLine("[" + RequestId + "] " + Request.method + "ing on " + Request.url);
				sb.AppendLine("Headers (Unity):");
				foreach (var pair in OriginalRequest.Headers) {
					sb.AppendLine("\t" + pair.Key + ": " + pair.Value);
				}
				if (OriginalRequest.HasBody) {
					sb.AppendLine("Body: " + OriginalRequest.BodyString);
				}
				Common.Log(sb.ToString());
			}

			/// <summary>Prints information about the response for debugging purposes.</summary>
			internal void LogResponse(HttpResponse response) {
				if (!VerboseMode) { return; }

				StringBuilder sb = new StringBuilder();
				sb.AppendLine("[" + RequestId + "] " + response.StatusCode + " on " + Request.method + "ed on " + Request.url);
				sb.AppendLine("Recv. headers:");
				foreach (var pair in response.Headers) {
					if (String.Compare(pair.Key, "Content-Type", true) == 0) {
						ContentType = pair.Value;
					}
					else {
						sb.AppendLine("\t" + pair.Key + ": " + pair.Value);
					}
				}
				if (response.HasBody) {
					sb.AppendLine("Body: " + response.BodyString);
				}
				Common.Log(sb.ToString());
			}

            private IEnumerator ProcessRequest(UnityWebRequest req) {
                yield return req.Send();

                if (req.isError)
                {

                    if (!WasAborted)
                    {
                        string errorMessage = "Failed web request: " + req.error + " - Status code: " + Request.responseCode;
                        Common.Log(errorMessage);
                        self.FinishWithRequest(this, new HttpResponse(new Exception(errorMessage)));
                    }
                    else
                    {
                        Common.Log("Request aborted");
                    }
                }
                else
                {
                    // Extracts asset bundle
                    HttpResponse response = new HttpResponse();
                    response.StatusCode = (int)Request.responseCode;
                    if (Application.platform == RuntimePlatform.IPhonePlayer && response.StatusCode <= 0)
                    {
                        // Nice bug in the iOS UnityWebRequest implementation. When you abort a request, in fact it doesn't
                        // abort the request. Instead of receiving an error (req.isError and req.error can check that), you
                        // just receive a funny responseCode (like 0 or -1001) and an empty dictionary of response headers.
                        Common.Log("Request aborted - Unity iOS bug for UnityWebRequest...");
                    }
                    else
                    {
                        response.Body = Request.downloadHandler.data;
                        Dictionary<string, string> dict = Request.GetResponseHeaders();
                        foreach (var pair in dict)
                        {
                            response.Headers[pair.Key] = pair.Value;
                        }
                        LogResponse(response);
                        self.FinishWithRequest(this, response);
                    }
                }
            }

			public override void Start() {
				// Configure & perform the request
				LogRequest();
				Cotc.RunCoroutine(ProcessRequest(Request));
			}
		}

		protected override WebRequest CreateRequest(HttpRequest request, string url, object previousUserData) {
			return new UnityRequest(this, url, request, previousUserData, (RequestCount += 1));
		}
	}
{'fraction_non_alphanumeric': 0.09738737956774586, 'fraction_numerical': 0.001996354483117785, 'mean_word_length': 1.7911821705426356, 'pattern_counts': {'":': 4, '<': 19, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4734300', 'n_tokens_mistral': 3238, 'n_tokens_neox': 2724, 'n_words': 750}