public void _request(string endPoint, RequestData requestData)
        {
            isSending = true;

            LastRequest             = new LastRequest();
            LastRequest.EndPoint    = endPoint;
            LastRequest.RequestData = requestData;

            long tmpNonce = nonce;

            //assign general request data
            requestData.version    = Version;
            requestData.versionKey = VersionKey;
            requestData.timestamp  = PredictedServerTimestamp;

            // post
            Byte[] payload       = Encoding.UTF8.GetBytes(JsonUtility.ToJson(requestData));
            string payloadBase64 = Convert.ToBase64String(localSendInvalidRequestData?
                                                          _encryptionHelper.Encrypt_Fake(payload, nonce) :
                                                          _encryptionHelper.Encrypt(payload, nonce));
            var postForm = new RawJsonForm();

            postForm.AddField("payloadBase64", payloadBase64);
            postForm.AddField("nonce", localSendInvalidRequestData? "0":nonce.ToString());

            // signature
            Byte[] digest = md5.ComputeHash(localSendInvalidRequestData?
                                            _encryptionHelper.Encrypt_Fake(payload, nonce) :
                                            _encryptionHelper.Encrypt(payload, nonce));
            Byte[] nonceByte   = BitConverter.GetBytes(nonce);
            Byte[] signMessage = new Byte[digest.Length + nonceByte.Length];
            Array.Copy(nonceByte, signMessage, nonceByte.Length);
            if (!localSendInvalidSignBase64)
            {
                Array.Copy(digest, 0, signMessage, nonceByte.Length, digest.Length);
            }
            string signedBase64 = Convert.ToBase64String(_encryptionHelper.SignMessage(signMessage));

            // query
            Dictionary <string, string> queryDict = new Dictionary <string, string>();

            queryDict.Add("signedBase64", signedBase64);
            queryDict.Add("token", token);
            queryDict.Add("remoteTimeout", remoteTimeout? "true" : "false");
            queryDict.Add("remoteSendInvalidPayload", remoteSendInvalidPayload? "true" : "false");
            var query = getQuery(queryDict);

            // send request
            var url = $"{Host}" + endPoint + $"?{query}";

            SetTimer(Timeout);
            RespondData = new RespondData();
            HTTPRequest request = new HTTPRequest(new Uri(url), HTTPMethods.Post, (originalRequest, response) =>
            {
                if (response.Data.Length == 10)
                {
                    RespondData.errorCode = RespondData.errorCode == 0? ErrorCode.FailedToDecryptServerPayload : RespondData.errorCode;
                }
                else if (response.HasHeaderWithValue("Content-Encoding", "encrypted"))
                {
                    var decrypted = _encryptionHelper.Decrypt(response.Data, tmpNonce);
                    RespondData   = JsonUtility.FromJson <RespondData>(Encoding.UTF8.GetString(Decompress(decrypted)));
                }
                else
                {
                    RespondData = JsonUtility.FromJson <RespondData>(response.DataAsText);
                }

                //assign user
                user.userId   = RespondData.user.userId == 0 ? user.userId : RespondData.user.userId;
                user.deviceId = RespondData.user.deviceId == null ? user.deviceId : RespondData.user.deviceId;
                user.session  = RespondData.user.session == null ? user.session : RespondData.user.session;

                //assign other server return value
                cards             = RespondData.body.cards == null ? cards : RespondData.body.cards;
                card              = RespondData.body.card;
                serverTimestamp   = RespondData.timestamp;
                receivedTimestamp = CurrentTimestamp;
                token             = RespondData.token == null ? token : RespondData.token;

                isSending = false;
            });

            request.SetForm(postForm);
            request.Send();

            nonce++;
        }