protected virtual async Task <ViewFileObjectInitUnderlayFileResultParam> CreateUnderlayFileImplAsync(FileParameters option, CancellationToken cancel = default) { FileObject obj = await UnderlayFileSystem.CreateFileAsync(option, cancel); try { ViewFileObjectInitUnderlayFileResultParam result = new ViewFileObjectInitUnderlayFileResultParam( obj, obj.FileParams.Flags.Bit(FileFlags.RandomAccessOnly) ? 0 : obj.Position, obj.Size); return(result); } catch { obj._DisposeSafe(); throw; } }
public Stream CreateReadStream() { if (this.Exists && this.IsDirectory == false) { FileObject obj = FileSystem.Open(this.FullPath); try { return(obj.GetStream(true)); } catch { obj._DisposeSafe(); throw; } } else { throw new FileNotFoundException(this.FullPath); } }
public async Task <HttpResult> ProcessRequestAsync(IPAddress clientIpAddress, string requestPathAndQueryString, CancellationToken cancel = default) { clientIpAddress = clientIpAddress._UnmapIPv4(); try { // クライアント IP による ACL のチェック if (Options.ClientIpAcl(clientIpAddress) == false) { // ACL error return(new HttpStringResult("403 Forbidden", statusCode: 403)); } // URL のチェック requestPathAndQueryString._ParseUrl(out Uri uri, out QueryStringList qsList); string relativePath; if (this.AbsolutePathPrefix._IsFilled()) { // AbsolutePathPrefix の検査 if (uri.AbsolutePath._TryTrimStartWith(out relativePath, StringComparison.OrdinalIgnoreCase, this.AbsolutePathPrefix) == false) { // Not found return(new HttpStringResult("404 Not Found", statusCode: 404)); } } else { relativePath = uri.AbsolutePath; } if (relativePath.StartsWith("/") == false) { relativePath = "/" + relativePath; } relativePath = PathParser.Linux.NormalizeUnixStylePathWithRemovingRelativeDirectoryElements(relativePath); if (RootFs.IsDirectoryExists(relativePath, cancel)) { // Directory string htmlBody = BuildDirectoryHtml(new DirectoryPath(relativePath, RootFs)); return(new HttpStringResult(htmlBody, contentType: Consts.MimeTypes.HtmlUtf8)); } else if (RootFs.IsFileExists(relativePath, cancel)) { // File string extension = RootFs.PathParser.GetExtension(relativePath); string mimeType = MasterData.ExtensionToMime.Get(extension); FileObject file = await RootFs.OpenAsync(relativePath, cancel : cancel); try { long fileSize = file.Size; long head = qsList._GetStrFirst("head")._ToInt()._NonNegative(); long tail = qsList._GetStrFirst("tail")._ToInt()._NonNegative(); if (head != 0 && tail != 0) { throw new ApplicationException("You can specify either head or tail."); } head = head._Min(fileSize); tail = tail._Min(fileSize); long readStart = 0; long readSize = fileSize; if (head != 0) { readStart = 0; readSize = head; } else if (tail != 0) { readStart = fileSize - tail; readSize = tail; } if (tail != 0) { mimeType = Consts.MimeTypes.Text; } byte[] preData = new byte[0]; if (readSize != 0 && fileSize >= 3) { try { // 元のファイルの先頭に BOM が付いていて、先頭をスキップする場合は、 // 応答データに先頭にも BOM を付ける byte[] bom = new byte[3]; if (await file.ReadRandomAsync(0, bom, cancel) == 3) { if (Str.BOM_UTF_8._MemEquals(bom)) { preData = bom; } } } catch { } } return(new HttpFileResult(file, readStart, readSize, mimeType, preData: preData)); } catch { file._DisposeSafe(); throw; } } else { // Not found return(new HttpStringResult("404 Not Found", statusCode: 404)); } } catch (Exception ex) { return(new HttpStringResult($"HTTP Status Code: 500\r\n" + ex.ToString(), statusCode: 500)); } }