mirror of
https://github.com/gnh1201/welsonjs.git
synced 2025-10-26 18:41:18 +00:00
Add CORS support to ResourceServer
Implemented CORS handling in ResourceServer, including preflight (OPTIONS) request handling and configurable allowed origins via the new ResourceServerAllowOrigins app setting. Updated resources and configuration files to support the new setting.
This commit is contained in:
parent
8cfff666e4
commit
b9e39dd9c7
|
|
@ -331,6 +331,15 @@ namespace WelsonJS.Launcher.Properties {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 과(와) 유사한 지역화된 문자열을 찾습니다.
|
||||
/// </summary>
|
||||
internal static string ResourceServerAllowOrigins {
|
||||
get {
|
||||
return ResourceManager.GetString("ResourceServerAllowOrigins", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// true과(와) 유사한 지역화된 문자열을 찾습니다.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -220,4 +220,7 @@
|
|||
<data name="IpQueryApiPrefix2" xml:space="preserve">
|
||||
<value>https://api.abuseipdb.com/api/v2/</value>
|
||||
</data>
|
||||
<data name="ResourceServerAllowOrigins" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
</root>
|
||||
|
|
@ -353,6 +353,11 @@ namespace WelsonJS.Launcher
|
|||
|
||||
public async Task ServeResource(HttpListenerContext context, byte[] data, string mimeType = "text/html", int statusCode = 200)
|
||||
{
|
||||
if (HandleCorsPreflight(context))
|
||||
return;
|
||||
|
||||
TryApplyCors(context);
|
||||
|
||||
string xmlHeader = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
|
||||
|
||||
if (data == null)
|
||||
|
|
@ -461,6 +466,98 @@ namespace WelsonJS.Launcher
|
|||
_logger?.Error($"Failed to fetch a blob config. Exception: {ex}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static string[] GetAllowedOrigins()
|
||||
{
|
||||
// 1. Try explicit ResourceServerAllowOrigins config
|
||||
var raw = Program.GetAppConfig("ResourceServerAllowOrigins");
|
||||
|
||||
if (string.IsNullOrEmpty(raw))
|
||||
{
|
||||
// 2. Fallback: parse from ResourceServerPrefix
|
||||
var prefix = Program.GetAppConfig("ResourceServerPrefix");
|
||||
if (!string.IsNullOrEmpty(prefix))
|
||||
{
|
||||
try
|
||||
{
|
||||
var uri = new Uri(prefix);
|
||||
var origin = uri.GetLeftPart(UriPartial.Authority); // protocol + host + port
|
||||
return new[] { origin };
|
||||
}
|
||||
catch
|
||||
{
|
||||
return Array.Empty<string>();
|
||||
}
|
||||
}
|
||||
return Array.Empty<string>();
|
||||
}
|
||||
|
||||
// Split configured list
|
||||
var parts = raw.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
|
||||
.Select(s => s.Trim())
|
||||
.Where(s => !string.IsNullOrEmpty(s))
|
||||
.ToArray();
|
||||
return parts;
|
||||
}
|
||||
|
||||
private static bool TryApplyCors(HttpListenerContext context)
|
||||
{
|
||||
var origin = context.Request.Headers["Origin"];
|
||||
if (string.IsNullOrEmpty(origin))
|
||||
return false;
|
||||
|
||||
var allowed = GetAllowedOrigins();
|
||||
if (allowed.Length == 0)
|
||||
return false;
|
||||
|
||||
var respHeaders = context.Response.Headers;
|
||||
respHeaders["Vary"] = "Origin";
|
||||
|
||||
if (allowed.Any(a => a == "*"))
|
||||
{
|
||||
respHeaders["Access-Control-Allow-Origin"] = "*";
|
||||
return true;
|
||||
}
|
||||
|
||||
if (allowed.Contains(origin, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
respHeaders["Access-Control-Allow-Origin"] = origin;
|
||||
respHeaders["Access-Control-Allow-Credentials"] = "true";
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool HandleCorsPreflight(HttpListenerContext context)
|
||||
{
|
||||
if (!string.Equals(context.Request.HttpMethod, "OPTIONS", StringComparison.OrdinalIgnoreCase))
|
||||
return false;
|
||||
|
||||
if (string.IsNullOrEmpty(context.Request.Headers["Origin"]))
|
||||
return false;
|
||||
|
||||
// Apply CORS headers once here
|
||||
TryApplyCors(context);
|
||||
|
||||
var requestHeaders = context.Request.Headers["Access-Control-Request-Headers"];
|
||||
var requestMethod = context.Request.Headers["Access-Control-Request-Method"];
|
||||
|
||||
var h = context.Response.Headers;
|
||||
h["Access-Control-Allow-Methods"] = string.IsNullOrEmpty(requestMethod)
|
||||
? "GET, POST, PUT, DELETE, OPTIONS"
|
||||
: requestMethod;
|
||||
h["Access-Control-Allow-Headers"] = string.IsNullOrEmpty(requestHeaders)
|
||||
? "Content-Type, Authorization, X-Requested-With"
|
||||
: requestHeaders;
|
||||
h["Access-Control-Max-Age"] = "600";
|
||||
|
||||
context.Response.StatusCode = 204;
|
||||
context.Response.ContentLength64 = 0;
|
||||
context.Response.OutputStream.Close();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
[XmlRoot("blobConfig")]
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<appSettings>
|
||||
<add key="ResourceServerPrefix" value="http://localhost:3000/"/>
|
||||
<add key="ResourceServerAllowOrigins" value=""/>
|
||||
<add key="ResourceServerAutoStart" value="true"/>
|
||||
<add key="ResourceServerPrefix" value="http://localhost:3000/"/>
|
||||
<add key="RepositoryUrl" value="https://github.com/gnh1201/welsonjs"/>
|
||||
<add key="CopilotUrl" value="https://copilot.microsoft.com/"/>
|
||||
<add key="ChromiumDevToolsPrefix" value="http://localhost:9222/"/>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user