public void Execute(bool force) { if (RefreshStatus == WebCallRefreshStatus.WaitingForRefreshCallback) { if (!force) { return; } RefreshStatus = WebCallRefreshStatus.NotRefreshing; } if (force) { this.OnUnqueued(this, new WebCallUnqueuedEventArgs()); } SessionDocument sessionDocument = database.GetSessionDocument(swid); if (!force && sessionDocument != null && sessionDocument.ProtocolVersion != 3) { this.OnUnauthorized(this, new WebCallUnauthorizedEventArgs("UNAUTHORIZED_MIX_SESSION")); return; } numAttempts++; bodyBytes = Encoding.UTF8.GetBytes(body); bodyBytes = WebCallEncryptor.Encrypt(bodyBytes); wwwCall = wwwCallFactory.Create(uri, method, bodyBytes, headers, latencyWwwCallTimeout, maxWwwCallTimeout); wwwCall.OnDone += HandleWwwDone; wwwCall.Execute(); logger.Debug(HttpLogBuilder.BuildRequestLog(wwwCall.RequestId, uri, method, headers, body)); }
private void Load(Uri uri, Action <LoadAssetResult> callback, StringBuilder timeoutLogs, int numAttempts) { IWwwCall wwwCall = wwwCallFactory.Create(uri, HttpMethod.GET, null, emptyHeaders, 10000L, 30000L); logger.Debug(BuildRequestLog(uri, wwwCall.RequestId)); EventHandler <WwwDoneEventArgs> handleOnDone = null; handleOnDone = delegate { wwwCall.OnDone -= handleOnDone; Dictionary <string, string> responseHeaders = wwwCall.ResponseHeaders; uint statusCode = wwwCall.StatusCode; WwwCallResult result = GetResult(wwwCall.Error, statusCode, numAttempts); string log = BuildResponseLog(uri, result, responseHeaders, statusCode, wwwCall); byte[] responseBody = wwwCall.ResponseBody; HandleResult(result, log, responseBody, uri, timeoutLogs, numAttempts, callback, Load, logger); wwwCall.Dispose(); }; wwwCall.OnDone += handleOnDone; wwwCall.Execute(); }
private void ExecuteNextCall() { if (isExecuting || queue.Count == 0) { return; } QueueItem item = queue[0]; Dictionary <string, string> dictionary = new Dictionary <string, string>(); dictionary.Add("Content-Type", "application/json"); dictionary.Add("Accept", "application/json"); dictionary.Add("Cache-Control", "no-cache,no-store,must-revalidate"); Dictionary <string, string> dictionary2 = dictionary; if (spoofedIpAddress != null) { dictionary2["X-Forwarded-For"] = spoofedIpAddress; } switch (item.AuthType) { case GuestControllerAuthenticationType.ApiKey: { string guestControllerApiKey = database.GetGuestControllerApiKey(); if (guestControllerApiKey == null) { GetApiKeyImmediately(delegate(GuestControllerResult <GuestControllerWebCallResponse> r) { if (!r.Success) { logger.Critical("Getting API key failed"); queue.Remove(item); CallCallbackWithFailureResult(item, null, null); } ExecuteNextCall(); }); return; } dictionary2["Authorization"] = "APIKEY " + guestControllerApiKey; break; } case GuestControllerAuthenticationType.AccessToken: { SessionDocument sessionDocument = database.GetSessionDocument(swid); if (sessionDocument == null) { logger.Critical("Guest Controller web call requires access token, but no session document found"); queue.Remove(item); CallCallbackWithFailureResult(item, null, null); ExecuteNextCall(); return; } string guestControllerAccessToken = sessionDocument.GuestControllerAccessToken; if (guestControllerAccessToken == null) { logger.Critical("Guest Controller web call requires access token, session document doesn't have one"); queue.Remove(item); CallCallbackWithFailureResult(item, null, null); ExecuteNextCall(); return; } dictionary2["Authorization"] = "BEARER " + guestControllerAccessToken; break; } } item.NumAttempts++; isExecuting = true; IWwwCall wwwCall = wwwCallFactory.Create(item.Uri, item.HttpMethod, item.RequestBody, dictionary2, 60000L, 70000L); logger.Debug(HttpLogBuilder.BuildRequestLog(wwwCall.RequestId, item.Uri, item.HttpMethod, dictionary2, item.RequestBodyJson)); wwwCalls.Add(wwwCall); wwwCall.OnDone += delegate { isExecuting = false; Dictionary <string, string> responseHeaders = new Dictionary <string, string>(wwwCall.ResponseHeaders); string error = wwwCall.Error; int requestId = wwwCall.RequestId; long timeToStartUpload = wwwCall.TimeToStartUpload; long timeToFinishUpload = wwwCall.TimeToFinishUpload; float percentUploaded = wwwCall.PercentUploaded; long timeToStartDownload = wwwCall.TimeToStartDownload; long timeToFinishDownload = wwwCall.TimeToFinishDownload; float percentDownloaded = wwwCall.PercentDownloaded; string timeoutReason = wwwCall.TimeoutReason; long timeoutTime = wwwCall.TimeoutTime; uint statusCode = wwwCall.StatusCode; string responseText = (wwwCall.ResponseBody == null) ? string.Empty : stringEncoding.GetString(wwwCall.ResponseBody); GuestControllerWebCallResponse response = item.ResponseParser(responseText); if (response == null) { CallCallbackWithFailureResult(item, null, responseHeaders); } else { wwwCalls.Remove(wwwCall); wwwCall.Dispose(); if (!string.IsNullOrEmpty(error)) { string text = error.ToLower(); if (text == "couldn't connect to host" || text.Contains("timedout") || text.Contains("timed out")) { string text2 = HttpLogBuilder.BuildTimeoutLog(requestId, item.Uri, item.HttpMethod, responseHeaders, responseText, timeToStartUpload, timeToFinishUpload, percentUploaded, timeToStartDownload, timeToFinishDownload, percentDownloaded, timeoutReason, timeoutTime); item.TimeoutLogs.Append(text2); item.TimeoutLogs.Append("\n\n"); logger.Error(text2); if (item.NumAttempts > 3) { logger.Critical("Too many timeouts: " + item.Uri.AbsoluteUri + "\nPrevious logs:\n" + item.TimeoutLogs); queue.Remove(item); CallCallbackWithFailureResult(item, response, responseHeaders); } ExecuteNextCall(); return; } } if (statusCode >= 500 && statusCode <= 599) { string text2 = HttpLogBuilder.BuildResponseLog(requestId, item.Uri, item.HttpMethod, responseHeaders, responseText, statusCode); if (item.NumAttempts > 1) { logger.Critical(text2); logger.Critical("Too many server errors"); queue.Remove(item); CallCallbackWithFailureResult(item, response, responseHeaders); } else { logger.Error(text2); } ExecuteNextCall(); } else if (HasErrorCode(response, "API_KEY_INVALID")) { logger.Error(HttpLogBuilder.BuildResponseLog(requestId, item.Uri, item.HttpMethod, responseHeaders, responseText, statusCode)); if (item.RefreshedApiKey) { logger.Critical("Invalid API key. Already got new token once. Giving up."); queue.Remove(item); CallCallbackWithFailureResult(item, response, responseHeaders); ExecuteNextCall(); } else { logger.Error("Invalid API key. Getting new API key..."); GetApiKeyImmediately(delegate(GuestControllerResult <GuestControllerWebCallResponse> r) { if (!r.Success) { logger.Critical(HttpLogBuilder.BuildResponseLog(requestId, item.Uri, item.HttpMethod, responseHeaders, responseText, statusCode)); logger.Critical("Getting new API key failed."); queue.Remove(item); CallCallbackWithFailureResult(item, response, responseHeaders); } ExecuteNextCall(); }); } } else if (HasErrorCode(response, "RATE_LIMITED")) { logger.Error(HttpLogBuilder.BuildResponseLog(requestId, item.Uri, item.HttpMethod, responseHeaders, responseText, statusCode)); if (item.RefreshedApiKey) { logger.Critical("Couldn't get new API key. Already got new API key once. Giving up."); queue.Remove(item); CallCallbackWithFailureResult(item, response, responseHeaders); ExecuteNextCall(); } else { logger.Error("Rate limited. Getting new API key..."); GetApiKeyImmediately(delegate(GuestControllerResult <GuestControllerWebCallResponse> r) { if (!r.Success || HasErrorCode(r.Response, "RATE_LIMITED")) { logger.Critical(HttpLogBuilder.BuildResponseLog(requestId, item.Uri, item.HttpMethod, responseHeaders, responseText, statusCode)); logger.Critical("Getting new API key failed."); queue.Remove(item); CallCallbackWithFailureResult(item, response, responseHeaders); } ExecuteNextCall(); }); } } else if (HasErrorCode(response, "ACCESS_TOKEN_NOT_FOUND", "AUTHORIZATION_INVALID_OR_EXPIRED_TOKEN")) { logger.Error(HttpLogBuilder.BuildResponseLog(requestId, item.Uri, item.HttpMethod, responseHeaders, responseText, statusCode)); if (item.RefreshedAccessToken) { logger.Critical("Invalid access token. Already tried to refresh. Giving up."); queue.Remove(item); CallCallbackWithFailureResult(item, response, responseHeaders); ExecuteNextCall(); } else { logger.Error("Invalid access token. Refreshing..."); RefreshImmediately(delegate(GuestControllerResult <RefreshResponse> r) { if (!r.Success) { logger.Critical(HttpLogBuilder.BuildResponseLog(requestId, item.Uri, item.HttpMethod, responseHeaders, responseText, statusCode)); logger.Critical("Refreshing access token failed"); queue.Remove(item); CallCallbackWithFailureResult(item, response, responseHeaders); } ExecuteNextCall(); }); } } else if (statusCode >= 401 && statusCode <= 499) { logger.Critical(HttpLogBuilder.BuildResponseLog(requestId, item.Uri, item.HttpMethod, responseHeaders, responseText, statusCode)); queue.Remove(item); CallCallbackWithFailureResult(item, response, responseHeaders); ExecuteNextCall(); } else if (statusCode == 400 || (statusCode >= 200 && statusCode <= 299)) { logger.Debug(HttpLogBuilder.BuildResponseLog(requestId, item.Uri, item.HttpMethod, responseHeaders, responseText, statusCode)); queue.Remove(item); item.Callback(new GuestControllerResult <GuestControllerWebCallResponse>(success: true, response, responseHeaders)); ExecuteNextCall(); } else { if (!string.IsNullOrEmpty(error)) { string text = error.ToLower(); if (text.Contains("connection appears to be offline") || text.Contains("connection was lost") || text.Contains("network is unreachable")) { logger.Critical(HttpLogBuilder.BuildResponseLog(requestId, item.Uri, item.HttpMethod, responseHeaders, responseText, statusCode)); logger.Critical("Offline error = " + error); } else { logger.Critical(HttpLogBuilder.BuildResponseLog(requestId, item.Uri, item.HttpMethod, responseHeaders, responseText, statusCode)); logger.Critical("Other web call error = " + error); } } queue.Remove(item); CallCallbackWithFailureResult(item, response, responseHeaders); ExecuteNextCall(); } } }; wwwCall.Execute(); }