Add legacy ASP.NET Core 3.1 version of this app
This commit is contained in:
parent
130312301e
commit
3777cb4fac
|
|
@ -0,0 +1,12 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Controllers\" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,87 @@
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using AS1024.NetworkQuality.Server;
|
||||||
|
|
||||||
|
namespace YourNamespace.Controllers
|
||||||
|
{
|
||||||
|
[ApiController]
|
||||||
|
[Route("api/v1")]
|
||||||
|
public class NetworkQualityController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly ILogger<NetworkQualityController> _logger;
|
||||||
|
private readonly JsonSerializerOptions _jsonOptions;
|
||||||
|
|
||||||
|
public NetworkQualityController(ILogger<NetworkQualityController> logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
_jsonOptions = new JsonSerializerOptions
|
||||||
|
{
|
||||||
|
PropertyNamingPolicy = new SnakeCaseNamingPolicy(), // Use snake_case naming policy
|
||||||
|
PropertyNameCaseInsensitive = true // Optional: case insensitive deserialization
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET: /api/v1/config
|
||||||
|
[HttpGet("config")]
|
||||||
|
public IActionResult GetConfig()
|
||||||
|
{
|
||||||
|
var config = new ConfigResponse
|
||||||
|
{
|
||||||
|
Urls = new Urls
|
||||||
|
{
|
||||||
|
SmallDownloadUrl = Url.Action("Small", "NetworkQuality", null, Request.Scheme),
|
||||||
|
LargeDownloadUrl = Url.Action("Large", "NetworkQuality", null, Request.Scheme),
|
||||||
|
UploadUrl = Url.Action("Upload", "NetworkQuality", null, Request.Scheme)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var json = JsonSerializer.Serialize(config, _jsonOptions); // Serialize with snake_case
|
||||||
|
return Content(json, "application/json");
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET: /api/v1/small
|
||||||
|
[HttpGet("small")]
|
||||||
|
public IActionResult Small()
|
||||||
|
{
|
||||||
|
// Return 1 byte (content is irrelevant)
|
||||||
|
Response.ContentType = "application/octet-stream";
|
||||||
|
return File(new byte[1], "application/octet-stream");
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET: /api/v1/large
|
||||||
|
[HttpGet("large")]
|
||||||
|
public IActionResult Large()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var largeStream = new LargeStreamResult();
|
||||||
|
return new FileStreamResult(largeStream, "application/octet-stream");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "An error occurred while writing the large file content.");
|
||||||
|
return StatusCode(500, JsonSerializer.Serialize(new { error = "An unexpected error occurred." }, _jsonOptions));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST: /api/v1/upload
|
||||||
|
[HttpPost("upload")]
|
||||||
|
public async Task<IActionResult> Upload()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await Request.Body.CopyToAsync(Stream.Null);
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "An unexpected error occurred.");
|
||||||
|
return StatusCode(500, JsonSerializer.Serialize(new { error = "An unexpected error occurred." }, _jsonOptions));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
namespace AS1024.NetworkQuality.Server
|
||||||
|
{
|
||||||
|
public class ConfigResponse
|
||||||
|
{
|
||||||
|
public int Version => 1;
|
||||||
|
public Urls Urls { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Urls
|
||||||
|
{
|
||||||
|
public string SmallHttpsDownloadUrl => SmallDownloadUrl;
|
||||||
|
public string LargeHttpsDownloadUrl => LargeDownloadUrl;
|
||||||
|
public string HttpsUploadUrl => UploadUrl;
|
||||||
|
public string SmallDownloadUrl { get; set; }
|
||||||
|
public string LargeDownloadUrl { get; set; }
|
||||||
|
public string UploadUrl { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace AS1024.NetworkQuality.Server.NetCore31
|
||||||
|
{
|
||||||
|
public class Program
|
||||||
|
{
|
||||||
|
public static void Main(string[] args)
|
||||||
|
{
|
||||||
|
CreateHostBuilder(args).Build().Run();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||||
|
Host.CreateDefaultBuilder(args)
|
||||||
|
.ConfigureWebHostDefaults(webBuilder =>
|
||||||
|
{
|
||||||
|
webBuilder.UseStartup<Startup>();
|
||||||
|
webBuilder.UseKestrel(options =>
|
||||||
|
{
|
||||||
|
options.Limits.MaxRequestBodySize = long.MaxValue;
|
||||||
|
options.Limits.MaxRequestBufferSize = long.MaxValue;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
{
|
||||||
|
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||||
|
"iisSettings": {
|
||||||
|
"windowsAuthentication": false,
|
||||||
|
"anonymousAuthentication": true,
|
||||||
|
"iisExpress": {
|
||||||
|
"applicationUrl": "http://localhost:13105",
|
||||||
|
"sslPort": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"profiles": {
|
||||||
|
"IIS Express": {
|
||||||
|
"commandName": "IISExpress",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"AS1024.NetworkQuality.Server.NetCore31": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "",
|
||||||
|
"applicationUrl": "https://localhost:5000",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
internal class LargeStreamResult : Stream
|
||||||
|
{
|
||||||
|
private long _position = 0;
|
||||||
|
private const long _length = 8L * 1024L * 1024L * 1024L; // 8 GB
|
||||||
|
|
||||||
|
public override bool CanRead => true;
|
||||||
|
public override bool CanSeek => true;
|
||||||
|
public override bool CanWrite => false;
|
||||||
|
public override long Length => _length;
|
||||||
|
public override long Position { get => _position; set => _position = value; }
|
||||||
|
|
||||||
|
public override void Flush() { }
|
||||||
|
|
||||||
|
public override int Read(byte[] buffer, int offset, int count)
|
||||||
|
{
|
||||||
|
int bytesToRead = (int)Math.Min(count, _length - _position);
|
||||||
|
if (bytesToRead <= 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
_position += bytesToRead;
|
||||||
|
return bytesToRead;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override long Seek(long offset, SeekOrigin origin)
|
||||||
|
{
|
||||||
|
switch (origin)
|
||||||
|
{
|
||||||
|
case SeekOrigin.Begin:
|
||||||
|
_position = offset;
|
||||||
|
break;
|
||||||
|
case SeekOrigin.Current:
|
||||||
|
_position += offset;
|
||||||
|
break;
|
||||||
|
case SeekOrigin.End:
|
||||||
|
_position = _length + offset;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return _position;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetLength(long value) { }
|
||||||
|
|
||||||
|
public override void Write(byte[] buffer, int offset, int count) { }
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace AS1024.NetworkQuality.Server.NetCore31
|
||||||
|
{
|
||||||
|
public class Startup
|
||||||
|
{
|
||||||
|
public Startup(IConfiguration configuration)
|
||||||
|
{
|
||||||
|
Configuration = configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IConfiguration Configuration { get; }
|
||||||
|
|
||||||
|
// This method gets called by the runtime. Use this method to add services to the container.
|
||||||
|
public void ConfigureServices(IServiceCollection services)
|
||||||
|
{
|
||||||
|
services.AddControllers();
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||||
|
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
||||||
|
{
|
||||||
|
if (env.IsDevelopment())
|
||||||
|
{
|
||||||
|
app.UseDeveloperExceptionPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
app.UseRouting();
|
||||||
|
|
||||||
|
app.UseAuthorization();
|
||||||
|
|
||||||
|
app.UseEndpoints(endpoints =>
|
||||||
|
{
|
||||||
|
endpoints.MapControllers();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
using System;
|
||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
|
public class SnakeCaseNamingPolicy : JsonNamingPolicy
|
||||||
|
{
|
||||||
|
public override string ConvertName(string name)
|
||||||
|
{
|
||||||
|
return string.IsNullOrEmpty(name) ? name : ToSnakeCase(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
private string ToSnakeCase(string name)
|
||||||
|
{
|
||||||
|
var stringBuilder = new System.Text.StringBuilder();
|
||||||
|
for (var i = 0; i < name.Length; i++)
|
||||||
|
{
|
||||||
|
if (char.IsUpper(name[i]))
|
||||||
|
{
|
||||||
|
if (i > 0)
|
||||||
|
{
|
||||||
|
stringBuilder.Append('_');
|
||||||
|
}
|
||||||
|
stringBuilder.Append(char.ToLowerInvariant(name[i]));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stringBuilder.Append(name[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return stringBuilder.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft": "Warning",
|
||||||
|
"Microsoft.Hosting.Lifetime": "Information"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft": "Warning",
|
||||||
|
"Microsoft.Hosting.Lifetime": "Information"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"AllowedHosts": "*"
|
||||||
|
}
|
||||||
|
|
@ -3,7 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio Version 17
|
# Visual Studio Version 17
|
||||||
VisualStudioVersion = 17.8.34408.163
|
VisualStudioVersion = 17.8.34408.163
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AS1024.NetworkQuality.Server", "AS1024.NetworkQuality.Server\AS1024.NetworkQuality.Server.csproj", "{71ABE0E0-226A-46E1-8CC9-76CDD7F5506F}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AS1024.NetworkQuality.Server", "AS1024.NetworkQuality.Server\AS1024.NetworkQuality.Server.csproj", "{71ABE0E0-226A-46E1-8CC9-76CDD7F5506F}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AS1024.NetworkQuality.Server.NetCore31", "AS1024.NetworkQuality.Server.NetCore31\AS1024.NetworkQuality.Server.NetCore31.csproj", "{FAC57638-C437-40D0-9A58-45054385FC78}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
|
@ -15,6 +17,10 @@ Global
|
||||||
{71ABE0E0-226A-46E1-8CC9-76CDD7F5506F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{71ABE0E0-226A-46E1-8CC9-76CDD7F5506F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{71ABE0E0-226A-46E1-8CC9-76CDD7F5506F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{71ABE0E0-226A-46E1-8CC9-76CDD7F5506F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{71ABE0E0-226A-46E1-8CC9-76CDD7F5506F}.Release|Any CPU.Build.0 = Release|Any CPU
|
{71ABE0E0-226A-46E1-8CC9-76CDD7F5506F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{FAC57638-C437-40D0-9A58-45054385FC78}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{FAC57638-C437-40D0-9A58-45054385FC78}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{FAC57638-C437-40D0-9A58-45054385FC78}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{FAC57638-C437-40D0-9A58-45054385FC78}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue