first commit
commit
029cae75a6
|
@ -0,0 +1,9 @@
|
||||||
|
namespace ETFileServer
|
||||||
|
{
|
||||||
|
public class Appsettings
|
||||||
|
{
|
||||||
|
public string DirectoryPath;
|
||||||
|
|
||||||
|
public int Port;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
using System.IO;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.FileProviders;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace ETFileServer
|
||||||
|
{
|
||||||
|
[Route("")]
|
||||||
|
[ApiController]
|
||||||
|
public class DownLoadController : Controller
|
||||||
|
{
|
||||||
|
private readonly IFileProvider _fileProvider;
|
||||||
|
private readonly ILogger<DownLoadController> _logger;
|
||||||
|
private readonly IConfiguration _configuration;
|
||||||
|
|
||||||
|
public DownLoadController(ILogger<DownLoadController> logger, IFileProvider fileProvider, IConfiguration configuration)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
_fileProvider = fileProvider;
|
||||||
|
_configuration = configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("{*filePath}")]
|
||||||
|
public IActionResult Get(string filePath)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(filePath))
|
||||||
|
{
|
||||||
|
return BadRequest("A file path must be provided.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var fileInfo = _fileProvider.GetFileInfo(filePath);
|
||||||
|
|
||||||
|
if (!fileInfo.Exists || fileInfo.IsDirectory)
|
||||||
|
{
|
||||||
|
_logger.LogWarning($"File not found or is a directory: {filePath}");
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查文件大小是否超出限制
|
||||||
|
long maxFileSizeInBytes = _configuration.GetValue<long>("MaxFileSizeMb", 100) * 1024 * 1024;
|
||||||
|
if (fileInfo.Length > maxFileSizeInBytes)
|
||||||
|
{
|
||||||
|
_logger.LogWarning($"File '{filePath}' exceeds the size limit of {maxFileSizeInBytes} bytes.");
|
||||||
|
return new StatusCodeResult(413); // 413 Payload Too Large
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.LogInformation($"Serving file: {fileInfo.PhysicalPath}");
|
||||||
|
|
||||||
|
return PhysicalFile(fileInfo.PhysicalPath, "application/octet-stream", fileInfo.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnActionExecuting(ActionExecutingContext context)
|
||||||
|
{
|
||||||
|
var httpContext = context.HttpContext;
|
||||||
|
if (httpContext.Request.Method != "GET")
|
||||||
|
{
|
||||||
|
context.Result = new StatusCodeResult(405);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (httpContext.WebSockets.IsWebSocketRequest)
|
||||||
|
{
|
||||||
|
context.Result = new BadRequestResult();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (httpContext.Request.HasFormContentType)
|
||||||
|
{
|
||||||
|
context.Result = new BadRequestResult();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnActionExecuted(ActionExecutedContext context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net9.0</TargetFramework>
|
||||||
|
<LangVersion>latest</LangVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||||
|
<OutputPath>../../FileServer/</OutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||||
|
<OutputPath>../../FileServer/</OutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.App" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.2.0" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.2.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<_ContentIncludedByDefault Remove="Properties\launchSettings.json" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Update="appsettings.json">
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<ActiveDebugProfile>IIS Express</ActiveDebugProfile>
|
||||||
|
<NameOfLastUsedPublishProfile>FolderProfile</NameOfLastUsedPublishProfile>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
|
@ -0,0 +1,24 @@
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.5.2.0
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileServer", "FileServer.csproj", "{79759A8D-256A-D7F8-1522-9077B7D22E98}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{79759A8D-256A-D7F8-1522-9077B7D22E98}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{79759A8D-256A-D7F8-1522-9077B7D22E98}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{79759A8D-256A-D7F8-1522-9077B7D22E98}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{79759A8D-256A-D7F8-1522-9077B7D22E98}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {0C6B39F7-F6FC-4CD4-8051-EBB8EC73D9AB}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
|
@ -0,0 +1,29 @@
|
||||||
|
using System.IO;
|
||||||
|
using Microsoft.AspNetCore;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
|
||||||
|
|
||||||
|
namespace ETFileServer
|
||||||
|
{
|
||||||
|
public class Program
|
||||||
|
{
|
||||||
|
public static void Main(string[] args)
|
||||||
|
{
|
||||||
|
CreateWebHostBuilder(args).Build().Run();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IWebHostBuilder CreateWebHostBuilder(string[] args)
|
||||||
|
{
|
||||||
|
IConfigurationRoot config = new ConfigurationBuilder()
|
||||||
|
.SetBasePath(Directory.GetCurrentDirectory())
|
||||||
|
.AddJsonFile("appsettings.json", true)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
return WebHost.CreateDefaultBuilder(args)
|
||||||
|
.UseConfiguration(config)
|
||||||
|
.UseUrls(config["urls"])
|
||||||
|
.UseStartup<Startup>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.FileProviders;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
|
||||||
|
namespace ETFileServer
|
||||||
|
{
|
||||||
|
public class Startup
|
||||||
|
{
|
||||||
|
private IConfiguration Configuration { get; }
|
||||||
|
|
||||||
|
public Startup(IConfiguration configuration)
|
||||||
|
{
|
||||||
|
Configuration = configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ConfigureServices(IServiceCollection services)
|
||||||
|
{
|
||||||
|
services.AddControllers();
|
||||||
|
|
||||||
|
// 1. 从配置中获取文件根目录路径
|
||||||
|
string fileRootPath = Configuration["DirectoryPath"];
|
||||||
|
if (string.IsNullOrEmpty(fileRootPath))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("DirectoryPath is not configured in appsettings.json.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 解析为绝对路径
|
||||||
|
string fullPath = Path.GetFullPath(fileRootPath);
|
||||||
|
if (!Directory.Exists(fullPath))
|
||||||
|
{
|
||||||
|
// 在启动时检查目录是否存在,如果不存在则创建
|
||||||
|
Directory.CreateDirectory(fullPath);
|
||||||
|
Console.WriteLine($"Warning: Root directory not found. Created directory at: {fullPath}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 创建并注册一个 PhysicalFileProvider 作为单例服务
|
||||||
|
// 这样整个应用都可以安全地使用它来访问文件
|
||||||
|
var provider = new PhysicalFileProvider(fullPath);
|
||||||
|
services.AddSingleton<IFileProvider>(provider);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
||||||
|
{
|
||||||
|
if (env.IsDevelopment())
|
||||||
|
{
|
||||||
|
app.UseDeveloperExceptionPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
app.UseRouting();
|
||||||
|
|
||||||
|
app.UseEndpoints(endpoints =>
|
||||||
|
{
|
||||||
|
endpoints.MapControllers();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 对于任何未匹配到Controller的请求,直接返回404 Not Found
|
||||||
|
app.Run(context =>
|
||||||
|
{
|
||||||
|
context.Response.StatusCode = 404;
|
||||||
|
return Task.CompletedTask;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"urls": "http://*:2083",
|
||||||
|
"DirectoryPath": "PublicFiles/",
|
||||||
|
"MaxFileSizeMb": 100
|
||||||
|
}
|
Loading…
Reference in New Issue