forked from LittleBigRefresh/Refresh
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRequestContextExtensions.cs
More file actions
89 lines (69 loc) · 3.25 KB
/
Copy pathRequestContextExtensions.cs
File metadata and controls
89 lines (69 loc) · 3.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
using System.Net;
using Bunkum.Core;
using JetBrains.Annotations;
namespace Refresh.Common.Extensions;
public static class RequestContextExtensions
{
[Pure]
public static (int, int) GetPageData(this RequestContext context, int maxCount = 100)
{
bool api = context.IsApi();
bool parsed = int.TryParse(context.QueryString[api ? "skip" : "pageStart"], out int skip);
if (parsed) skip--; // If we parsed, subtract the number of items to skip by one to prevent an off-by-one.
parsed = int.TryParse(context.QueryString[api ? "count" : "pageSize"], out int count);
if (!parsed) count = 20; // Default items in a page
count = Math.Clamp(count, 0, maxCount);
return (skip, count);
}
[Pure]
public static bool IsPSP(this RequestContext context) => context.RequestHeaders.Get("User-Agent") == "LBPPSP CLIENT";
[Pure]
public static bool IsApi(this RequestContext context) => context.Url.AbsolutePath.StartsWith("/api/");
[Pure]
public static bool IsPatchworkVersionValid(this RequestContext context, int requiredMajor, int requiredMinor)
{
ReadOnlySpan<char> userAgent = context.RequestHeaders.Get("User-Agent").AsSpan();
if (userAgent.IsEmpty)
return false;
return IsPatchworkVersionValid(userAgent, requiredMajor, requiredMinor);
}
[Pure]
public static bool IsPatchworkVersionValid(ReadOnlySpan<char> userAgent, int requiredMajor, int requiredMinor)
{
// example: PatchworkLBP2 1.0
const string namePrefix = "PatchworkLBP";
int versionPos = namePrefix.Length + 2;
// does the useragent even match patchwork's name?
if (!userAgent.StartsWith(namePrefix))
return false;
// is the game version valid?
char gameVersion = userAgent[namePrefix.Length];
if (gameVersion is not '1' and not '2' and not '3' and not 'V')
return false;
// HTTP library on Vita adds extra data. Handle that scenario here
// example: PatchworkLBPV 1.0 libhttp/3.74 (PS Vita)
// I believe LBP3 PS4 also might do this, but we don't support that and I don't know the format.
ReadOnlySpan<char> versionString = userAgent[versionPos..];
if (gameVersion == 'V')
{
int spaceIndex = versionString.IndexOf(' ');
if (spaceIndex == -1)
return false;
versionString = versionString[..spaceIndex];
// validate libhttp string
ReadOnlySpan<char> libraryVersion = userAgent[(versionPos + spaceIndex)..];
if (!libraryVersion.StartsWith(" libhttp/") || !libraryVersion.EndsWith(" (PS Vita)"))
return false;
}
// does the version string parse out?
if (!Version.TryParse(versionString, out Version? version))
return false;
// are we on a supported version?
if (version.Major < requiredMajor || version.Minor < requiredMinor)
return false;
// if everything held up, this client is up to date on security patches!
return true;
}
[Pure]
public static string RemoteIp(this RequestContext context) => ((IPEndPoint)context.RemoteEndpoint).Address.ToString();
}