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); }
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); }
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); }
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); } }); }
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); }