private void Download(ResourceUrl url, CancellationToken cancellationToken) { DebugLogger.Log(string.Format("Trying to download from {0}", url)); long offset = CurrentFileSize(); DebugLogger.LogVariable(offset, "offset"); var downloadJobQueue = BuildDownloadJobQueue(url, offset); foreach (DownloadJob downloadJob in downloadJobQueue) { BaseHttpDownloader baseHttpDownloader = new BaseHttpDownloader(downloadJob.Url, _timeout); baseHttpDownloader.SetBytesRange(downloadJob.Offset); baseHttpDownloader.DataAvailable += (bytes, length) => { bool retry = !_fileStream.Write(bytes, 0, length); if (retry) { throw new DownloaderException("Corrupt data.", DownloaderExceptionStatus.CorruptData); } OnDownloadProgressChanged(CurrentFileSize(), _resource.Size); }; baseHttpDownloader.Download(cancellationToken); } if (_fileStream.RemainingLength > 0) { throw new DownloaderException("Data download hasn't been completed.", DownloaderExceptionStatus.Other); } }
/// <summary> /// Builds downloads queue based on url, part sizes, file size and current offset. /// </summary> /// <param name="resourceUrl"></param> /// <param name="currentOffset"></param> /// <returns></returns> private List <DownloadJob> BuildDownloadJobQueue(ResourceUrl resourceUrl, long currentOffset) { long totalSize = _resource.Size; long partSize = resourceUrl.PartSize == 0 ? totalSize : resourceUrl.PartSize; int partCount = (int)(totalSize / partSize); partCount += totalSize % partSize != 0 ? 1 : 0; List <DownloadJob> queue = new List <DownloadJob>(); for (int i = 0; i < partCount; i++) { string url = resourceUrl.Url; if (i > 0) { // second and later indices should have index numebr at the end url += "." + i; } long offset = Math.Max(currentOffset - partSize * i, 0); if (offset < partSize) { queue.Add(new DownloadJob { Url = url, Offset = offset }); } } return(queue); }
/// <summary> /// Executes the specified javascript function on the Loader module. /// </summary> /// <param name="functionName"></param> /// <param name="args"></param> private void ExecuteLoaderFunction(string functionName, params string[] args) { // using setimeout we make sure the function is already defined var loaderUrl = new ResourceUrl(ResourcesAssembly, ReactViewResources.Resources.LoaderUrl); ViewRender.WebView.ExecuteScript($"import('{loaderUrl}').then(m => m.default.Loader.{functionName}({string.Join(",", args)}))"); }
public override int GetHashCode() { int hash = 1; if (Version.Length != 0) { hash ^= Version.GetHashCode(); } if (DiscoveryDocumentUri.Length != 0) { hash ^= DiscoveryDocumentUri.GetHashCode(); } if (DiscoveryName.Length != 0) { hash ^= DiscoveryName.GetHashCode(); } if (ResourceUrl.Length != 0) { hash ^= ResourceUrl.GetHashCode(); } if (Parent.Length != 0) { hash ^= Parent.GetHashCode(); } if (data_ != null) { hash ^= Data.GetHashCode(); } if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } return(hash); }
public ReactViewRender(ResourceUrl defaultStyleSheet, Func <IViewModule[]> initializePlugins, bool preloadWebView, bool enableDebugMode, Uri devServerUri = null) { UserCallingAssembly = WebView.GetUserCallingMethod().ReflectedType.Assembly; var urlParams = new string[] { new ResourceUrl(ResourcesAssembly).ToString(), enableDebugMode ? "1" : "0", ModulesObjectName, Listener.EventListenerObjName, ViewInitializedEventName, ViewDestroyedEventName, ViewLoadedEventName, ResourceUrl.CustomScheme + Uri.SchemeDelimiter + CustomResourceBaseUrl }; var url = new ResourceUrl(ResourcesAssembly, ReactViewResources.Resources.DefaultUrl + "?" + string.Join("&", urlParams)); // must useSharedDomain for the local storage to be shared WebView = new WebView(new ResourceUrl("about:blank"), useSharedDomain: true) { DisableBuiltinContextMenus = true, IsSecurityDisabled = true, IgnoreMissingResources = false, IsHistoryDisabled = true }; Loader = new LoaderModule(this); DefaultStyleSheet = defaultStyleSheet; PluginsFactory = initializePlugins; EnableDebugMode = enableDebugMode; DevServerUri = devServerUri; GetOrCreateFrame(MainViewFrameName); // creates the main frame var loadedListener = WebView.AttachListener(ViewLoadedEventName); loadedListener.Handler += OnViewLoaded; loadedListener.UIHandler += OnViewLoadedUIHandler; WebView.AttachListener(ViewInitializedEventName).Handler += OnViewInitialized; WebView.AttachListener(ViewDestroyedEventName).Handler += OnViewDestroyed; WebView.Disposed += OnWebViewDisposed; WebView.JavascriptContextReleased += OnWebViewJavascriptContextReleased; WebView.BeforeResourceLoad += OnWebViewBeforeResourceLoad; WebView.LoadFailed += OnWebViewLoadFailed; WebView.FilesDragging += OnWebViewFilesDragging; WebView.TextDragging += OnWebViewTextDragging; Content = WebView; // load url after event listeners have been attached WebView.LoadResource(url); if (preloadWebView) { WebView.InitializeBrowser(); } }
public override int GetHashCode() { int hash = 1; if (VersionTag.Length != 0) { hash ^= VersionTag.GetHashCode(); } if (Ips.Length != 0) { hash ^= Ips.GetHashCode(); } if (Ports.Length != 0) { hash ^= Ports.GetHashCode(); } if (ResourceUrl.Length != 0) { hash ^= ResourceUrl.GetHashCode(); } if (VersionUrl.Length != 0) { hash ^= VersionUrl.GetHashCode(); } if (ShowState != false) { hash ^= ShowState.GetHashCode(); } if (SelectServer != false) { hash ^= SelectServer.GetHashCode(); } return(hash); }
private IEnumerable <DownloadJob> BuildDownloadJobQueue(ResourceUrl resourceUrl, long currentOffset) { long partSize = resourceUrl.PartSize == 0 ? _size : resourceUrl.PartSize; int partCount = (int)(_size / partSize); partCount += _size % partSize != 0 ? 1 : 0; for (int i = 0; i < partCount; i++) { string url = resourceUrl.Url; if (i > 0) { // second and later indices should have index numebr at the end url += "." + i; } long offset = Math.Max(currentOffset - partSize * i, 0); if (offset < partSize) { yield return(new DownloadJob { Url = url, Offset = offset }); } } }
public void SetUp() { _url = new ResourceUrl { Url = "test.com/someData", MetaUrl = "test.com/someMetaData", Country = "GB", PartSize = PartSize }; List <Chunk> chunks = new List <Chunk>(); for (int i = 0; i < (DataSize / ChunkSize); i++) { chunks.Add(new Chunk { Hash = new byte[] { 0x20 } // TODO: Generate random bytes here }); } _chunksData = new ChunksData { ChunkSize = ChunkSize, Chunks = chunks.ToArray() }; }
/// <summary> /// Executes the specified javascript function on the Loader module. /// </summary> /// <param name="functionName"></param> /// <param name="args"></param> private void ExecuteLoaderFunction(string functionName, params string[] args) { // using setimeout we make sure the function is already defined var loaderUrl = new ResourceUrl(ResourcesAssembly, ReactViewResources.Resources.LoaderUrl); var script = $"import('{loaderUrl}').then(m => m.default.{LoaderModuleName}).then({LoaderModuleName} => {LoaderModuleName}.{functionName}({string.Join(",", args)}))"; ViewRender.WebView.ExecuteScript(script); ViewRender.executeWebScriptFunctionWithSerializedParams(script, null); }
public void EmbeddedFilesWithDashesInFilenameLoad() { var embeddedResourceUrl = new ResourceUrl(GetType().Assembly, "Resources", "dash-folder", "EmbeddedJavascriptFile-With-Dashes.js"); LoadAndWaitReady($"<html><script src='{embeddedResourceUrl}'></script></html>"); var embeddedFileLoaded = TargetView.EvaluateScript <bool>("embeddedFileLoaded"); Assert.IsTrue(embeddedFileLoaded); }
public async Task EmbeddedFilesWithDashesInFilenameLoad() { await Run(async() => { var embeddedResourceUrl = new ResourceUrl(GetType().Assembly, "Resources", "dash-folder", "EmbeddedJavascriptFile-With-Dashes.js"); await Load($"<html><script src='{embeddedResourceUrl}'></script></html>"); var embeddedFileLoaded = TargetView.EvaluateScript <bool>("embeddedFileLoaded"); Assert.IsTrue(embeddedFileLoaded); }); }
public ReactViewRender(ResourceUrl defaultStyleSheet, Func <IViewModule[]> initializePlugins, bool preloadWebView, int maxNativeMethodsParallelCalls, bool enableDebugMode, Uri devServerUri = null, Func <string, object, Func <Func <object>, object>, bool, bool> registerWebJavaScriptObject = null, Action <string> unregisterWebJavaScriptObject = null, Action <string, object[]> executeWebScriptFunctionWithSerializedParams = null) { UserCallingAssembly = GetUserCallingMethod().ReflectedType.Assembly; this.registerWebJavaScriptObject = registerWebJavaScriptObject; this.unregisterWebJavaScriptObject = unregisterWebJavaScriptObject; this.executeWebScriptFunctionWithSerializedParams = executeWebScriptFunctionWithSerializedParams; // must useSharedDomain for the local storage to be shared WebView = new ExtendedWebView(useSharedDomain: true) { DisableBuiltinContextMenus = true, IsSecurityDisabled = true, IgnoreMissingResources = false, IsHistoryDisabled = true, MaxNativeMethodsParallelCalls = maxNativeMethodsParallelCalls }; NativeAPI.Initialize(this, registerWebJavaScriptObject, unregisterWebJavaScriptObject); Loader = new LoaderModule(this); DefaultStyleSheet = defaultStyleSheet; PluginsFactory = initializePlugins; EnableDebugMode = enableDebugMode; DevServerUri = devServerUri; GetOrCreateFrame(FrameInfo.MainViewFrameName); // creates the main frame WebView.Disposed += Dispose; WebView.BeforeNavigate += OnWebViewBeforeNavigate; WebView.BeforeResourceLoad += OnWebViewBeforeResourceLoad; WebView.LoadFailed += OnWebViewLoadFailed; WebView.FilesDragging += fileNames => FilesDragging?.Invoke(fileNames); WebView.TextDragging += textContent => TextDragging?.Invoke(textContent); WebView.KeyPressed += OnWebViewKeyPressed; ExtraInitialize(); var urlParams = new string[] { new ResourceUrl(ResourcesAssembly).ToString(), enableDebugMode ? "true" : "false", ExecutionEngine.ModulesObjectName, NativeAPI.NativeObjectName, ResourceUrl.CustomScheme + Uri.SchemeDelimiter + CustomResourceBaseUrl }; WebView.LoadResource(new ResourceUrl(ResourcesAssembly, ReactViewResources.Resources.DefaultUrl + "?" + string.Join("&", urlParams))); if (preloadWebView) { PreloadWebView(); } EditCommands = new EditCommands(WebView); }
public void GetUrl_BuildsUrlUsingBuilder() { var resourceUrlBuilderStub = MockRepository.GenerateStub <IResourcePathBuilder>(); var resourceUrl = new ResourceUrl(resourceUrlBuilderStub, typeof(ResourceUrlTest), ResourceType.Html, "theRelativeUrl.js"); resourceUrlBuilderStub .Stub(_ => _.BuildAbsolutePath(typeof(ResourceUrlTest).Assembly, new[] { "Html", "theRelativeUrl.js" })) .Return("expectedUrl"); Assert.That(resourceUrl.GetUrl(), Is.EqualTo("expectedUrl")); }
public virtual HttpRequestBuilder Resource(string resourceUrl) { if (!ResourceUrl.IsNotNullOrWhiteSpace() || resourceUrl.StartsWith("/")) { ResourceUrl = resourceUrl.TrimStart('/'); } else { ResourceUrl = string.Format("{0}/{1}", ResourceUrl.TrimEnd('/'), resourceUrl); } return(this); }
public PottyTrackerApiClientBase(string resourceName) { if (_httpClient == null) { _httpClient = new HttpClient(); } ResourceUrl = BASE_API_URL + resourceName; if (!ResourceUrl.EndsWith('/')) { ResourceUrl.Append('/'); } }
public async Task ResourceFile() { await Run(async() => { var embeddedResourceUrl = new ResourceUrl(GetType().Assembly, "Resources", "ResourceJavascriptFile.js"); await Load($"<html><script src='{embeddedResourceUrl}'></script></html>"); var resourceFileLoaded = TargetView.EvaluateScript <bool>("resourceFileLoaded"); Assert.IsTrue(resourceFileLoaded); Stream missingResource = null; Assert.DoesNotThrow(() => missingResource = ResourcesManager.TryGetResourceWithFullPath(GetType().Assembly, new[] { "Resources", "Missing.txt" })); Assert.IsNull(missingResource); }); }
public static ResourceUrl GetTileResourceUrl(this LayerType layerType) { ResourceUrl resourceUrl = null; URLTemplateType templateType = layerType.ResourceURL?.FirstOrDefault(x => x.resourceType == URLTemplateTypeResourceType.tile); if (templateType != null) { resourceUrl = new ResourceUrl() { Template = templateType.template, Format = templateType.format, ResourceType = templateType.resourceType }; } return(resourceUrl); }
public override int GetHashCode() { int hash = 1; if (ResourceUrl.Length != 0) { hash ^= ResourceUrl.GetHashCode(); } if (fingerprint_ != null) { hash ^= Fingerprint.GetHashCode(); } if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } return(hash); }
public void GetUrl_DoesNotCacheUrls() { var resourceUrlBuilderStub = MockRepository.GenerateStub <IResourcePathBuilder>(); var resourceUrl = new ResourceUrl(resourceUrlBuilderStub, typeof(ResourceUrlTest), ResourceType.Html, "theRelativeUrl.js"); int count = 0; resourceUrlBuilderStub .Stub(_ => _.BuildAbsolutePath(typeof(ResourceUrlTest).Assembly, new[] { "Html", "theRelativeUrl.js" })) .Return(null) .WhenCalled( mi => { mi.ReturnValue = "expectedUrl " + count; count++; }); Assert.That(resourceUrl.GetUrl(), Is.EqualTo("expectedUrl 0")); Assert.That(resourceUrl.GetUrl(), Is.EqualTo("expectedUrl 1")); }
public async Task LoadCustomScheme() { await Run(async() => { var embeddedResourceUrl = new ResourceUrl(GetType().Assembly, "Resources", "EmbeddedHtml.html"); var taskCompletionSource = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously); void OnNavigated(string url, string frameName) { if (url != UrlHelper.AboutBlankUrl) { TargetView.Navigated -= OnNavigated; taskCompletionSource.SetResult(true); } } TargetView.Navigated += OnNavigated; TargetView.LoadResource(embeddedResourceUrl); await taskCompletionSource.Task; var content = await TargetView.EvaluateScript <string>("document.documentElement.innerText"); Assert.AreEqual("test", content); }); }
public static IEnumerable <DownloadJob> BuildDownloadJobQueue(ResourceUrl resourceUrl, long currentOffset, BytesRange range, long dataSize, ChunksData chunksData) { // The effective range is the original range contained within multiples of chunk size BytesRange effectiveRange = range.Chunkify(chunksData); var dataBounds = new BytesRange(currentOffset, -1); BytesRange bounds = effectiveRange.ContainIn(dataBounds); // An uncommon edge case might occur, in which bounds.Start is equal to dataSize, // this would cause the download to continue forever, with every request crashing due to invalid range header if (bounds.Start >= dataSize) { yield break; } if (resourceUrl.PartSize == 0) { yield return(new DownloadJob(resourceUrl.Url, bounds.Start, bounds.End)); yield break; } long partSize = resourceUrl.PartSize; int firstPart = (int)(bounds.Start / partSize); int totalPartCount = (int)(dataSize / partSize); if (dataSize % partSize != 0) { totalPartCount += 1; } int lastPart = totalPartCount; if (bounds.End != -1) { lastPart = (int)(bounds.End / partSize); if (bounds.End % partSize != 0) { lastPart += 1; } } long lastByte = dataSize - 1; for (int i = firstPart; i < lastPart; i++) { string url = resourceUrl.Url; if (i > 0) { // second and later indices should have index numebr at the end url += "." + i; } BytesRange partRange = BytesRangeUtils.Make(i * partSize, (i + 1) * partSize - 1, lastByte); BytesRange localBounds = bounds.LocalizeTo(partRange); yield return(new DownloadJob(url, localBounds.Start, localBounds.End)); } }
private IEnumerable <DownloadJob> BuildDownloadJobQueue(ResourceUrl resourceUrl, long currentOffset) { return(BuildDownloadJobQueue(resourceUrl, currentOffset, _range, _size, _chunksData)); }
private bool TryDownload(ResourceUrl url, ChunkedFileStream fileStream, CancellationToken cancellationToken) { try { _logger.LogDebug(string.Format("Trying to download from {0}", url.Url)); _logger.LogTrace("fileStream.VerifiedLength = " + fileStream.VerifiedLength); var downloadJobQueue = BuildDownloadJobQueue(url, fileStream.VerifiedLength); foreach (var downloadJob in downloadJobQueue) { _logger.LogDebug(string.Format("Executing download job {0} with offest {1}", downloadJob.Url, downloadJob.Range.Start)); _logger.LogTrace("fileStream.VerifiedLength = " + fileStream.VerifiedLength); _logger.LogTrace("fileStream.SavedLength = " + fileStream.SavedLength); var baseHttpDownloader = new BaseHttpDownloader(downloadJob.Url, 30000); baseHttpDownloader.SetBytesRange(downloadJob.Range); const long downloadStatusLogInterval = 5000L; var stopwatch = Stopwatch.StartNew(); long downloadedBytes = 0; var job = downloadJob; baseHttpDownloader.DataAvailable += (bytes, length) => { fileStream.Write(bytes, 0, length); downloadedBytes += length; if (stopwatch.ElapsedMilliseconds > downloadStatusLogInterval) { stopwatch.Reset(); stopwatch.Start(); _logger.LogDebug(string.Format("Downloaded {0} from {1}", downloadedBytes, job.Url)); _logger.LogTrace("fileStream.VerifiedLength = " + fileStream.VerifiedLength); _logger.LogTrace("fileStream.SavedLength = " + fileStream.SavedLength); } OnDownloadProgressChanged(fileStream.VerifiedLength); }; baseHttpDownloader.Download(cancellationToken); _logger.LogDebug("Download job execution success."); _logger.LogTrace("fileStream.VerifiedLength = " + fileStream.VerifiedLength); _logger.LogTrace("fileStream.SavedLength = " + fileStream.SavedLength); } if (fileStream.RemainingLength != 0) { throw new IncompleteDataException("Chunks downloading must finish downloading whole file"); } _logger.LogDebug(string.Format("Download from {0} has been successful.", url.Url)); return(true); } catch (IncompleteDataException e) { _logger.LogWarning(string.Format("Unable to download from {0}", url.Url), e); return(false); } catch (InvalidChunkDataException e) { _logger.LogWarning(string.Format("Unable to download from {0}", url.Url), e); return(false); } catch (DataNotAvailableException e) { _logger.LogWarning(string.Format("Unable to download from {0}", url.Url), e); return(false); } catch (ServerErrorException e) { _logger.LogWarning(string.Format("Unable to download from {0}", url.Url), e); return(false); } catch (ConnectionFailureException e) { _logger.LogWarning(string.Format("Unable to download from {0}", url.Url), e); return(false); } }
public void Download(CancellationToken cancellationToken) { Assert.MethodCalledOnlyOnce(ref _downloadHasBeenCalled, "Download"); DebugLogger.Log("Downloading."); List <ResourceUrl> validUrls = new List <ResourceUrl>(_resource.ResourceUrls); // getting through urls list backwards, because urls may be removed during the process, // and it's easier to iterate that way validUrls.Reverse(); int retry = RetriesAmount; while (validUrls.Count > 0 && retry > 0) { for (int i = validUrls.Count - 1; i >= 0 && retry-- > 0; --i) { ResourceUrl url = validUrls[i]; try { OpenFileStream(); Download(url, cancellationToken); CloseFileStream(); var validator = new DownloadedResourceValidator(); validator.Validate(_destinationFilePath, _resource); return; } catch (WebException e) { // Isn't this catching too much? DebugLogger.LogException(e); // try again break; } catch (DownloaderException downloaderException) { DebugLogger.LogException(downloaderException); switch (downloaderException.Status) { case DownloaderExceptionStatus.EmptyStream: // try another one break; case DownloaderExceptionStatus.CorruptData: // try another one break; case DownloaderExceptionStatus.NotFound: // remove url and try another one validUrls.Remove(url); break; case DownloaderExceptionStatus.Other: // try another one break; default: throw new ArgumentOutOfRangeException(); } } finally { CloseFileStream(); } } DebugLogger.Log("Waiting 10 seconds before trying again..."); Thread.Sleep(10000); } if (retry <= 0) { throw new DownloaderException("Too many retries, aborting.", DownloaderExceptionStatus.Other); } throw new DownloaderException("Cannot download resource.", DownloaderExceptionStatus.Other); }
public SimpleViewModule(string moduleName, ResourceUrl url) { this.moduleName = moduleName; source = url.ToString(); }
/// <summary> /// Loads the specified stylesheet. /// </summary> /// <param name="stylesheet"></param> public void LoadDefaultStyleSheet(ResourceUrl stylesheet) { ExecuteLoaderFunction("loadDefaultStyleSheet", SerializeResourceUrl(stylesheet)); }
private string SerializeResourceUrl(ResourceUrl resource) { return(JavascriptSerializer.Serialize(NormalizeUrl(ViewRender.ToFullUrl(resource.ToString())))); }
public ViewFactoryWithStyleSheet(bool loadPrimaryStyleSheet) : base() { defaultStyleSheet = loadPrimaryStyleSheet ? new ResourceUrl(typeof(DefaultStyleSheetLoadTests).Assembly, "Generated", "Default.css") : new ResourceUrl(typeof(DefaultStyleSheetLoadTests).Assembly, "Generated", "Default_2.css"); }