private static string BuildResponseLog(Uri uri, WwwCallResult result, Dictionary <string, string> headers, uint statusCode, IWwwCall wwwCall) { return((result == WwwCallResult.RetryTimeout) ? HttpLogBuilder.BuildTimeoutLog(wwwCall.RequestId, uri, HttpMethod.GET, headers, string.Empty, wwwCall.TimeToStartUpload, wwwCall.TimeToFinishUpload, wwwCall.PercentUploaded, wwwCall.TimeToStartDownload, wwwCall.TimeToFinishDownload, wwwCall.PercentDownloaded, wwwCall.TimeoutReason, wwwCall.TimeoutTime) : HttpLogBuilder.BuildResponseLog(wwwCall.RequestId, uri, HttpMethod.GET, headers, string.Empty, statusCode)); }
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(); }