Add legacy ASP.NET Core 3.1 version of this app

This commit is contained in:
Jeff Leung 2024-09-11 21:53:17 -07:00
parent 130312301e
commit 3777cb4fac
11 changed files with 330 additions and 1 deletions

View File

@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Folder Include="Controllers\" />
</ItemGroup>
</Project>

View File

@ -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));
}
}
}
}

View File

@ -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; }
}
}

View File

@ -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;
});
});
}
}

View File

@ -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"
}
}
}
}

View File

@ -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) { }
}

View File

@ -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();
});
}
}
}

View File

@ -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();
}
}

View File

@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}

View File

@ -0,0 +1,10 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}

View File

@ -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