Beispiel #1
0
        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));
        }
Beispiel #2
0
        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();
    }