Skip to content

Commit 9f7dbd8

Browse files
committed
refactored config compiling, cleaned up project
1 parent 2f27228 commit 9f7dbd8

6 files changed

Lines changed: 54 additions & 64 deletions

File tree

LinkRouter/App/Configuration/Config.cs

Lines changed: 25 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ public class Config
1111

1212
public NotFoundBehaviorConfig NotFoundBehavior { get; set; } = new();
1313

14-
public RedirectRoute[] Routes { get; set; } = [
14+
public RedirectRoute[] Routes { get; set; } =
15+
[
1516
new RedirectRoute()
1617
{
1718
Route = "/instagram",
@@ -23,89 +24,82 @@ public class Config
2324
RedirectUrl = "https://example.com"
2425
},
2526
];
26-
27+
2728
public class NotFoundBehaviorConfig
2829
{
2930
public bool RedirectOn404 { get; set; } = false;
3031
public string RedirectUrl { get; set; } = "https://example.com/404";
3132
}
3233

33-
[JsonIgnore]
34-
public static Regex PlaceholderPattern => new(@"\\\{(\d|\w+)\}");
35-
36-
[JsonIgnore]
37-
public CompiledRoute[]? CompiledRoutes { get; set; }
38-
34+
[JsonIgnore] public CompiledRoute[]? CompiledRoutes { get; set; }
35+
3936
public void CompileRoutes()
4037
{
4138
var compiledRoutes = new List<CompiledRoute>();
42-
39+
4340
foreach (var route in Routes)
4441
{
4542
if (!route.Route.StartsWith("/"))
4643
route.Route = "/" + route.Route;
47-
44+
4845
if (!route.Route.EndsWith("/"))
4946
route.Route += "/";
50-
47+
5148
var compiled = new CompiledRoute
5249
{
5350
Route = route.Route,
5451
RedirectUrl = route.RedirectUrl
5552
};
56-
53+
5754
var replacements = new List<(int Index, int Length, string NewText)>();
5855

5956
var escaped = Regex.Escape(route.Route);
60-
61-
var matches = PlaceholderPattern.Matches(escaped);
62-
63-
57+
58+
var pattern = new Regex(@"\\{(\d|\w+)\}");
59+
60+
var matches = pattern.Matches(escaped);
61+
6462
foreach (var match in matches.Select(x => x))
6563
{
6664
// Check if the placeholder is immediately followed by another placeholder
67-
68-
Console.WriteLine("matchlenght: "+ (match.Index + match.Length + 2) + " route lenght" + escaped.Length);
69-
70-
if (escaped.Length >= match.Index + match.Length + 2 && escaped.Substring(match.Index + match.Length, 2) == "\\{")
71-
throw new InvalidOperationException(
72-
$"Placeholder {match.Groups[1].Value} cannot be immediately followed by another placeholder. " +
73-
$"Please add a string literal as separator.");
65+
if (escaped.Length >= match.Index + match.Length + 2
66+
&& escaped.Substring(match.Index + match.Length, 2) == "\\{")
67+
throw new InvalidOperationException(
68+
$"Placeholder {match.Groups[1].Value} cannot be immediately followed by another placeholder. " +
69+
$"Please add any separator.");
7470

7571
replacements.Add((match.Index, match.Length, "(.+)"));
7672
}
77-
73+
7874
var compiledRouteBuilder = new StringBuilder(escaped);
79-
75+
8076
foreach (var replacement in replacements.OrderByDescending(r => r.Index))
8177
{
8278
compiledRouteBuilder.Remove(replacement.Index, replacement.Length);
8379
compiledRouteBuilder.Insert(replacement.Index, replacement.NewText);
8480
}
8581

86-
compiled.CompiledPattern = new Regex(compiledRouteBuilder.ToString(), RegexOptions.Compiled);
82+
compiled.CompiledPattern = new Regex(compiledRouteBuilder.ToString(),
83+
RegexOptions.Compiled | RegexOptions.CultureInvariant);
8784

88-
Console.WriteLine(compiled.CompiledPattern.ToString());
89-
9085
var duplicate = matches
9186
.Select((m, i) => m.Groups[1].Value)
9287
.GroupBy(x => x)
9388
.FirstOrDefault(x => x.Count() > 1);
9489

9590
if (duplicate != null)
9691
throw new InvalidOperationException("Cannot use a placeholder twice in the route: " + duplicate.Key);
97-
92+
9893
compiled.Placeholders = matches
9994
.Select((m, i) => m.Groups[1].Value)
10095
.Distinct()
10196
.Select((name, i) => (name, i))
10297
.ToDictionary(x => x.name, x => x.i + 1);
103-
98+
10499
compiledRoutes.Add(compiled);
105100
}
106101

107102
CompiledRoutes = compiledRoutes
108103
.ToArray();
109104
}
110-
111105
}

LinkRouter/App/Http/Controllers/RedirectController.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,6 @@ public async Task<ActionResult> RedirectToExternalUrl(string path)
6363

6464
var match = redirectRoute.CompiledPattern.Match(path);
6565

66-
Console.WriteLine(redirectRoute.CompiledPattern);
67-
6866
string redirectUrl = redirectRoute.RedirectUrl;
6967

7068
foreach (var placeholder in redirectRoute.Placeholders)

LinkRouter/App/Models/CompiledRoute.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ namespace LinkRouter.App.Models;
55
public class CompiledRoute : RedirectRoute
66
{
77
public Regex CompiledPattern { get; set; }
8-
8+
99
public Dictionary<string, int> Placeholders { get; set; } = new();
1010
}

LinkRouter/App/Models/RedirectRoute.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33
public class RedirectRoute
44
{
55
public string Route { get; set; }
6-
6+
77
public string RedirectUrl { get; set; }
88
}

LinkRouter/App/Services/ConfigWatcher.cs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,44 +18,44 @@ public ConfigWatcher(ILogger<ConfigWatcher> logger, Config config)
1818

1919
protected override Task ExecuteAsync(CancellationToken stoppingToken)
2020
{
21-
2221
if (!File.Exists(ConfigPath))
2322
{
2423
Logger.LogWarning("Watched file does not exist: {FilePath}", ConfigPath);
2524
}
26-
25+
2726
Watcher = new FileSystemWatcher(Path.GetDirectoryName(ConfigPath) ?? throw new InvalidOperationException())
2827
{
2928
Filter = Path.GetFileName(ConfigPath),
3029
NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.Size | NotifyFilters.CreationTime
3130
};
32-
31+
3332
OnChanged(Watcher, new FileSystemEventArgs(WatcherChangeTypes.Created, string.Empty, string.Empty));
34-
33+
3534
Watcher.Changed += OnChanged;
36-
35+
3736
Watcher.EnableRaisingEvents = true;
38-
37+
3938
return Task.CompletedTask;
4039
}
41-
40+
4241
private void OnChanged(object sender, FileSystemEventArgs e)
4342
{
4443
try
4544
{
4645
var content = File.ReadAllText(ConfigPath);
47-
46+
4847
var config = JsonSerializer.Deserialize<Config>(content);
49-
48+
5049
Config.Routes = config?.Routes ?? [];
5150
Config.RootRoute = config?.RootRoute ?? "https://example.com";
52-
51+
5352
Logger.LogInformation("Config file changed.");
5453

5554
try
5655
{
5756
Config.CompileRoutes();
58-
} catch (InvalidOperationException ex)
57+
}
58+
catch (InvalidOperationException ex)
5959
{
6060
Logger.LogError("Failed to compile routes: " + ex.Message);
6161
Environment.Exit(1);

LinkRouter/Program.cs

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,46 +12,44 @@ public abstract class Program
1212
public static void Main(string[] args)
1313
{
1414
var builder = WebApplication.CreateBuilder(args);
15-
15+
1616
Directory.CreateDirectory(PathBuilder.Dir("data"));
17-
17+
1818
builder.Services.AddControllers();
19-
19+
2020
var loggerProviders = LoggerBuildHelper.BuildFromConfiguration(configuration =>
2121
{
2222
configuration.Console.Enable = true;
2323
configuration.Console.EnableAnsiMode = true;
2424
});
25-
25+
2626
builder.Logging.ClearProviders();
2727
builder.Logging.AddProviders(loggerProviders);
2828

2929
builder.Services.AddHostedService<ConfigWatcher>();
30-
30+
3131
var configPath = Path.Combine("data", "config.json");
32-
32+
3333
if (!File.Exists(configPath))
3434
File.WriteAllText(
35-
configPath,
36-
JsonSerializer.Serialize(new Config(), new JsonSerializerOptions {WriteIndented = true}
35+
configPath,
36+
JsonSerializer.Serialize(new Config(), new JsonSerializerOptions { WriteIndented = true }
3737
));
38-
38+
3939
Config config = JsonSerializer.Deserialize<Config>(File.ReadAllText(configPath)) ?? new Config();
4040

41-
File.WriteAllText(configPath, JsonSerializer.Serialize(config, new JsonSerializerOptions {WriteIndented = true}));
42-
41+
File.WriteAllText(configPath,
42+
JsonSerializer.Serialize(config, new JsonSerializerOptions { WriteIndented = true }));
43+
4344
builder.Services.AddSingleton(config);
44-
45-
builder.Services.AddMetricServer(options =>
46-
{
47-
options.Port = 5000;
48-
});
49-
45+
46+
builder.Services.AddMetricServer(options => { options.Port = 5000; });
47+
5048
var app = builder.Build();
5149

5250
app.UseMetricServer();
5351
app.MapControllers();
5452

5553
app.Run();
5654
}
57-
}
55+
}

0 commit comments

Comments
 (0)