/// <summary> /// Create intersection with another option /// </summary> /// <param name="option"></param> /// <returns>this if <paramref name="option"/> is null or new instance with intersection</returns> public virtual AllOptions Intersection(IOption option) { if (option == null) { return(this); } AllOptions result = new AllOptions(); result.CanBrowse = this.CanBrowse | option.CanBrowse(); result.CanGetEntry = this.CanGetEntry | option.CanGetEntry(); result.CanObserve = this.CanObserve | option.CanObserve(); result.CanOpen = this.CanOpen | option.CanOpen(); result.CanRead = this.CanRead | option.CanRead(); result.CanWrite = this.CanWrite | option.CanWrite(); result.CanCreateFile = this.CanCreateFile | option.CanCreateFile(); result.CanDelete = this.CanDelete | option.CanDelete(); result.CanSetFileAttribute = this.CanSetFileAttribute | option.CanSetFileAttribute(); result.CanMount = this.CanMount | option.CanMount(); result.CanCreateFile = this.CanCreateFile | option.CanCreateFile(); result.CanDelete = this.CanDelete | option.CanDelete(); result.CanMove = this.CanMove | option.CanMove(); result.CanCreateDirectory = this.CanCreateDirectory | option.CanCreateDirectory(); result.CanMount = this.CanMount | option.CanMount(); result.CanUnmount = this.CanUnmount | option.CanUnmount(); result.CanListMountPoints = this.CanListMountPoints | option.CanListMountPoints(); result.SubPath = this.SubPath ?? option.SubPath(); return(result); }
/// <summary> /// Browse a directory for file and subdirectory entries. /// </summary> /// <param name="path">path to directory, "" is root, separator is "/"</param> /// <param name="option">(optional) operation specific option; capability constraint, a session, security token or credential. Used for authenticating, authorizing or restricting the operation.</param> /// <returns>a snapshot of file and directory entries</returns> /// <exception cref="IOException">On unexpected IO error</exception> /// <exception cref="SecurityException">If caller did not have permission</exception> /// <exception cref="ArgumentNullException"><paramref name="path"/> is null</exception> /// <exception cref="ArgumentException"><paramref name="path"/> contains only white space, or contains one or more invalid characters</exception> /// <exception cref="NotSupportedException">The <see cref="IFileSystem"/> doesn't support browse</exception> /// <exception cref="UnauthorizedAccessException">The access requested is not permitted by the operating system for the specified path, such as when access is Write or ReadWrite and the file or directory is set for read-only access.</exception> /// <exception cref="PathTooLongException">The specified path, file name, or both exceed the system-defined maximum length. For example, on Windows-based platforms, paths must be less than 248 characters.</exception> /// <exception cref="InvalidOperationException">If <paramref name="path"/> refers to a non-file device, such as "con:", "com1:", "lpt1:", etc.</exception> /// <exception cref="ObjectDisposedException"/> public IDirectoryContent Browse(string path, IOption option = null) { // Assert supported if (!CanBrowse || !option.CanBrowse(true)) { throw new NotSupportedException(nameof(Browse)); } // Make path if (isPhysicalFileProvider && path.Contains(@"\")) { path = path.Replace(@"\", "/"); } // Is disposed? IFileProvider fp = fileProvider; if (fp == null) { throw new ObjectDisposedException(nameof(FileProviderSystem)); } // Browse IDirectoryContents contents = fp.GetDirectoryContents(path); // Not found if (!contents.Exists) { return(new DirectoryNotFound(this, path)); } // Convert result StructList24 <IEntry> list = new StructList24 <IEntry>(); foreach (IFileInfo info in contents) { if (info.IsDirectory) { IEntry e = new DirectoryEntry(this, String.IsNullOrEmpty(path) ? info.Name + "/" : (path.EndsWith("/") ?path + info.Name + "/":path + "/" + info.Name + "/"), info.Name, info.LastModified, DateTimeOffset.MinValue, info.PhysicalPath); list.Add(e); } else { IEntry e = new FileEntry(this, String.IsNullOrEmpty(path) ? info.Name : (path.EndsWith("/") ? path + info.Name : path + "/" + info.Name), info.Name, info.LastModified, DateTimeOffset.MinValue, info.Length, info.PhysicalPath); list.Add(e); } } // Return contents return(new DirectoryContent(this, path, list.ToArray())); }
/// <summary> /// Read options from <paramref name="option"/> and return flattened object. /// </summary> /// <param name="option"></param> /// <returns></returns> public virtual void ReadFrom(IOption option) { this.CanBrowse = option.CanBrowse(); this.CanGetEntry = option.CanGetEntry(); this.CanObserve = option.CanObserve(); this.CanOpen = option.CanOpen(); this.CanRead = option.CanRead(); this.CanWrite = option.CanWrite(); this.CanCreateFile = option.CanCreateFile(); this.CanDelete = option.CanDelete(); this.CanMove = option.CanMove(); this.CanCreateDirectory = option.CanCreateDirectory(); this.CanMount = option.CanMount(); this.CanUnmount = option.CanUnmount(); this.CanListMountPoints = option.CanListMountPoints(); this.SubPath = option.SubPath(); this.CanSetFileAttribute = option.CanSetFileAttribute(); }
/// <summary> /// Read <paramref name="uri"/> and parse anchors for file references. /// </summary> /// <param name="uri"></param> /// <param name="option"></param> /// <returns>child links</returns> public async Task <IDirectoryContent> BrowseAsync(string uri, IOption option = null) { // Take reference var _httpClient = httpClient; // Assert not disposed if (_httpClient == null || IsDisposing) { throw new ObjectDisposedException(nameof(HttpFileSystem)); } // Assert allowed if (!options.CanBrowse || !option.CanBrowse(true)) { throw new NotSupportedException(nameof(BrowseAsync)); } // Path converter IPathConverter pathConverter; // Append subpath string _subpath = this.options.SubPath; string __subpath = option.SubPath(); string uri_ = uri; if (_subpath != null || __subpath != null) { uri_ = _subpath + __subpath + uri; pathConverter = new PathConverter("", _subpath + __subpath); } else { pathConverter = new PathConverter("", ""); } // Cancel token CancellationToken cancel = default; option.TryGetToken(uri, out cancel); try { // Request object using (var request = new HttpRequestMessage(HttpMethod.Get, uri_)) { // Read token ReadTokenToHeaders(uri_, option, request.Headers); // Read authentication token AuthenticationHeaderValue authenticationHeader; if (this.token.TryGetToken(uri_, out authenticationHeader) || option.TryGetToken(uri_, out authenticationHeader)) { request.Headers.Authorization = authenticationHeader; } // Start GET HttpResponseMessage response = await _httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead); // Not found if (response.StatusCode == HttpStatusCode.NotFound) { return(new DirectoryNotFound(this, uri)); } // Assert ok if (!response.IsSuccessStatusCode) { throw new FileSystemException(this, uri, response.StatusCode.ToString()); } // Stream Task using (var s = await response.Content.ReadAsStreamAsync()) { // Read document fully string document = await StreamUtils.ReadTextFullyAsync(s); // Parse files IEntry[] entries = ReadEntries(uri, document, pathConverter).ToArray(); // Return entries return(new DirectoryContent(this, uri, entries)); } } } catch (Exception e) when(e is FileSystemException == false) { throw new FileSystemException(this, uri, e.Message, e); } }