Ejemplo n.º 1
0
        public void GetCdnFileAsync(byte[] fileToken, int offset, int limit, Action <TLUploadCdnFileBase> callback, Action <TLRPCError> faultCallback = null)
        {
            var obj = new TLUploadGetCdnFile {
                FileToken = fileToken, Offset = offset, Limit = limit
            };

            const string caption = "upload.getCdnFile";

            SendInformativeMessage(caption, obj, callback, faultCallback);
        }
Ejemplo n.º 2
0
        public void GetCdnFileAsync(int dcId, byte[] fileToken, int offset, int limit, Action <TLUploadCdnFileBase> callback, Action <TLRPCError> faultCallback = null)
        {
            var obj = new TLUploadGetCdnFile {
                FileToken = fileToken, Offset = offset, Limit = limit
            };

            const string caption = "upload.getCdnFile";

            SendInformativeMessage(caption, obj, callback, faultCallback, null, dcId, ConnectionType.Download, RequestFlag.ForceDownload | RequestFlag.FailOnServerError, true);
        }
Ejemplo n.º 3
0
        private TLUploadFileBase GetCdnFile(TLUploadFileCdnRedirect redirect, TLFileLocation location, int offset, int limit, out TLRPCError er, out bool isCanceled)
        {
            var manualResetEvent      = new ManualResetEvent(false);
            TLUploadFileBase result   = null;
            TLRPCError       outError = null;
            var outIsCanceled         = false;

            var req = new TLUploadGetCdnFile();

            req.FileToken = redirect.FileToken;
            req.Limit     = limit;
            req.Offset    = offset;

            _mtProtoService.SendRequestAsync <TLUploadCdnFileBase>("upload.getCdnFile", req, redirect.DCId, true, callback =>
            {
                if (callback is TLUploadCdnFile file)
                {
                    var iv      = redirect.EncryptionIV;
                    var counter = offset / 16;
                    iv[15]      = (byte)(counter & 0xFF);
                    iv[14]      = (byte)((counter >> 8) & 0xFF);
                    iv[13]      = (byte)((counter >> 16) & 0xFF);
                    iv[12]      = (byte)((counter >> 24) & 0xFF);

                    var key = CryptographicBuffer.CreateFromByteArray(redirect.EncryptionKey);

                    var ecount_buf = new byte[0];
                    var num        = 0u;
                    var bytes      = Utils.AES_ctr128_encrypt(file.Bytes, key, ref iv, ref ecount_buf, ref num);

                    result = new TLUploadFile {
                        Bytes = bytes
                    };
                    manualResetEvent.Set();

                    _statsService.IncrementReceivedBytesCount(_mtProtoService.NetworkType, _dataType, file.Bytes.Length + 4);
                }
                else if (callback is TLUploadCdnFileReuploadNeeded reupload)
                {
                    result = ReuploadFile(redirect, reupload.RequestToken, location, offset, limit, out outError, out outIsCanceled);
                    while (result == null)
                    {
                        result = ReuploadFile(redirect, reupload.RequestToken, location, offset, limit, out outError, out outIsCanceled);
                        if (outIsCanceled)
                        {
                            break;
                        }
                    }

                    manualResetEvent.Set();
                }
            },
                                                                   error =>
            {
                outError = error;

                if (error.CodeEquals(TLErrorCode.INTERNAL) ||
                    (error.CodeEquals(TLErrorCode.BAD_REQUEST) && (error.TypeEquals(TLErrorType.LOCATION_INVALID) || error.TypeEquals(TLErrorType.VOLUME_LOC_NOT_FOUND))) ||
                    (error.CodeEquals(TLErrorCode.NOT_FOUND) && error.ErrorMessage != null && error.ErrorMessage.ToString().StartsWith("Incorrect dhGen")))
                {
                    outIsCanceled = true;

                    manualResetEvent.Set();
                    return;
                }

                int delay;
                lock (_randomRoot)
                {
                    delay = _random.Next(1000, 3000);
                }

                Execute.BeginOnThreadPool(TimeSpan.FromMilliseconds(delay), () => manualResetEvent.Set());
            });

            manualResetEvent.WaitOne(20 * 1000);
            er         = outError;
            isCanceled = outIsCanceled;

            return(result);
        }
Ejemplo n.º 4
0
        private void startDownloadRequest()
        {
            if (state != stateDownloading || totalBytesCount > 0 && nextDownloadOffset >= totalBytesCount || requestInfos.Count + delayedRequestInfos.Count >= currentMaxDownloadRequests)
            {
                return;
            }
            int count = 1;

            if (totalBytesCount > 0)
            {
                count = Math.Max(0, currentMaxDownloadRequests - requestInfos.Count /* - delayedRequestInfos.size()*/);
            }

            for (int a = 0; a < count; a++)
            {
                if (totalBytesCount > 0 && nextDownloadOffset >= totalBytesCount)
                {
                    break;
                }
                bool     isLast = totalBytesCount <= 0 || a == count - 1 || totalBytesCount > 0 && nextDownloadOffset + currentDownloadChunkSize >= totalBytesCount;
                TLObject request;
                int      offset;
                int      flags;
                if (isCdn)
                {
                    TLUploadGetCdnFile req = new TLUploadGetCdnFile();
                    req.FileToken = cdnToken;
                    req.Offset    = offset = nextDownloadOffset;
                    req.Limit     = currentDownloadChunkSize;
                    request       = req;
                    //!!!flags = ConnectionsManager.ConnectionTypeGeneric;
                    //flags = requestsCount % 2 == 0 ? ConnectionsManager.ConnectionTypeDownload : ConnectionsManager.ConnectionTypeDownload2;
                }
                else if (webLocation != null)
                {
                    TLUploadGetWebFile req = new TLUploadGetWebFile();
                    req.Location = webLocation;
                    req.Offset   = offset = nextDownloadOffset;
                    req.Limit    = currentDownloadChunkSize;
                    request      = req;
                    //1!!flags = ConnectionsManager.ConnectionTypeGeneric;
                    //flags = requestsCount % 2 == 0 ? ConnectionsManager.ConnectionTypeDownload : ConnectionsManager.ConnectionTypeDownload2;
                }
                else
                {
                    TLUploadGetFile req = new TLUploadGetFile();
                    req.Location = location;
                    req.Offset   = offset = nextDownloadOffset;
                    req.Limit    = currentDownloadChunkSize;
                    request      = req;
                    //flags = requestsCount % 2 == 0 ? ConnectionsManager.ConnectionTypeDownload : ConnectionsManager.ConnectionTypeDownload2;
                }
                nextDownloadOffset += currentDownloadChunkSize;
                RequestInfo requestInfo = new RequestInfo();
                requestInfos.Add(requestInfo);
                requestInfo.offset = offset;

                int dcId;
                if (isCdn)
                {
                    dcId = cdnDatacenterId;
                }
                else
                {
                    dcId = datacenter_id;
                }

                //var reset = new ManualResetEvent(false);
                MTProtoService.Current.SendRequestAsync <TLObject>("", request, dcId, isCdn, result =>
                {
                    //reset.Set();
                    if (result is TLUploadFileCdnRedirect redirect)
                    {
                        isCdn           = true;
                        cdnDatacenterId = redirect.DCId;
                        cdnIv           = redirect.EncryptionIV;
                        cdnKey          = redirect.EncryptionKey;
                        cdnToken        = redirect.FileToken;
                        ClearOperation(requestInfo);
                        startDownloadRequest();
                    }
                    else if (result is TLUploadCdnFileReuploadNeeded reuploadNeeded && !reuploadingCdn)
                    {
                        ClearOperation(requestInfo);
                        reuploadingCdn = true;
                        TLUploadReuploadCdnFile req = new TLUploadReuploadCdnFile();
                        req.FileToken    = cdnToken;
                        req.RequestToken = reuploadNeeded.RequestToken;

                        MTProtoService.Current.SendRequestAsync <TLObject>("upload.reuploadCdnFile", req, datacenter_id, isCdn, resultReupload =>
                        {
                            reuploadingCdn = false;
                            startDownloadRequest();
                        }, faultReupload =>
                        {
                            reuploadingCdn = false;
                            if (faultReupload.ErrorMessage.Equals("FILE_TOKEN_INVALID") && faultReupload.ErrorMessage.Equals("REQUEST_TOKEN_INVALID"))
                            {
                                isCdn = false;
                                ClearOperation(requestInfo);
                                startDownloadRequest();
                            }
                            else
                            {
                                onFail(false, 0);
                            }
                        });
                    }
Ejemplo n.º 5
0
        private TLUploadFileBase GetCdnFile(TLUploadFileCdnRedirect redirect, int dcId, TLInputDocumentFileLocation location, int offset, int limit, out TLRPCError er, out bool isCanceled)
        {
            var manualResetEvent      = new ManualResetEvent(false);
            TLUploadFileBase result   = null;
            TLRPCError       outError = null;
            var outIsCanceled         = false;

            var req = new TLUploadGetCdnFile();

            req.FileToken = redirect.FileToken;
            req.Limit     = limit;
            req.Offset    = offset;

            _mtProtoService.SendRequestAsync <TLUploadCdnFileBase>("upload.getCdnFile", req, redirect.DCId, true, callback =>
            {
                if (callback is TLUploadCdnFile file)
                {
                    result = new TLUploadFile {
                        Bytes = file.Bytes
                    };
                    manualResetEvent.Set();

                    _statsService.IncrementReceivedBytesCount(_mtProtoService.NetworkType, _dataType, file.Bytes.Length + 4);
                }
                else if (callback is TLUploadCdnFileReuploadNeeded reupload)
                {
                    result = ReuploadFile(redirect, reupload.RequestToken, dcId, location, offset, limit, out outError, out outIsCanceled);
                    while (result == null)
                    {
                        result = ReuploadFile(redirect, reupload.RequestToken, dcId, location, offset, limit, out outError, out outIsCanceled);
                        if (outIsCanceled)
                        {
                            break;
                        }
                    }

                    manualResetEvent.Set();
                }
            },
                                                                   error =>
            {
                outError = error;

                if (error.CodeEquals(TLErrorCode.INTERNAL) ||
                    (error.CodeEquals(TLErrorCode.BAD_REQUEST) && (error.TypeEquals(TLErrorType.LOCATION_INVALID) || error.TypeEquals(TLErrorType.VOLUME_LOC_NOT_FOUND))) ||
                    (error.CodeEquals(TLErrorCode.NOT_FOUND) && error.ErrorMessage != null && error.ErrorMessage.ToString().StartsWith("Incorrect dhGen")))
                {
                    outIsCanceled = true;

                    manualResetEvent.Set();
                    return;
                }

                int delay;
                lock (_randomRoot)
                {
                    delay = _random.Next(1000, 3000);
                }

                Execute.BeginOnThreadPool(TimeSpan.FromMilliseconds(delay), () => manualResetEvent.Set());
            });

            manualResetEvent.WaitOne(20 * 1000);
            er         = outError;
            isCanceled = outIsCanceled;

            return(result);
        }