DOIOU/DOIOU.Server/Controllers/MainController.cs
2024-06-14 13:49:30 +02:00

85 lines
2.4 KiB
C#

using System.Diagnostics;
using System.Text.RegularExpressions;
using DOIOU.Server.Models;
using Microsoft.AspNetCore.Mvc;
namespace DOIOU.Server.Controllers;
[Route("/")]
public class MainController : Controller
{
private readonly DataRegistry _data;
public MainController(DataRegistry data)
{
_data = data;
}
[HttpGet]
public IActionResult Index()
{
return View();
}
[HttpGet("{*doiou}")]
public async Task<IActionResult> Get(string doiou) => await Resolve(doiou);
[HttpPost]
public async Task<IActionResult> Post([FromForm] string doiou) => await Resolve(doiou);
private const string DOI_REGEX = @"^((?<scheme>[a-z]+):(\/\/)?)?(?<domain>[a-z0-9.\-]+\/)?((?<prefix>\d{1,3})\.(?<publisher>\d{4,5})\/(?<id>[\S]+[^;,.\s]))$";
[NonAction]
private async Task<IActionResult> Resolve(string doiou)
{
var match = Regex.Match(doiou, DOI_REGEX);
if (!match.Success)
{
return BadRequest("Invalid format");
}
int prefix = int.Parse(match.Groups["prefix"].Value);
int publisher = int.Parse(match.Groups["publisher"].Value);
string id = match.Groups["id"].Value;
string query = $"{prefix}.{publisher}/{id}";
// TODO further validation (use schemes?)
if (prefix == 7 || prefix == 69)
{
string? q = _data.Query(query);
return q != null ? Redirect(q) : NotFound("DOIOU not found");
}
string? urlBase = prefix switch
{
10 => "https://doi.org",
_ => null
};
if (urlBase == null)
return BadRequest($"Unsupported prefix: {prefix}");
using HttpClient client = new();
client.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", "DOIOU v1.0");
var response = await client.GetAsync($"{urlBase}/{doiou}");
if (((int)response.StatusCode / 100) == 3)
{
string location = response.Headers!.Location!.ToString();
return Redirect(location);
}
//TODO: cache
return NotFound("DOIOU not found");
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}