2020-06-02 12:31:34 +02:00
using System ;
using System.Linq ;
using System.Net ;
2021-12-28 15:43:21 +01:00
using TweetLib.Browser.Interfaces ;
2022-01-10 07:54:20 +01:00
using TweetLib.Browser.Request ;
2020-06-02 12:31:34 +02:00
using TweetLib.Core.Features.Plugins.Enums ;
2021-08-07 07:48:29 +02:00
namespace TweetLib.Core.Features.Plugins {
2022-01-10 07:54:20 +01:00
public sealed class PluginSchemeHandler : ICustomSchemeHandler {
private static readonly SchemeResource PathMustBeRelativeToRoot = new SchemeResource . Status ( HttpStatusCode . Forbidden , "File path has to be relative to the plugin root folder." ) ;
2021-12-28 15:43:21 +01:00
public string Protocol = > "tdp" ;
2020-06-02 12:31:34 +02:00
2022-01-10 07:54:20 +01:00
private readonly ResourceCache resourceCache ;
2021-12-28 15:43:21 +01:00
private readonly PluginBridge bridge ;
2020-06-02 12:31:34 +02:00
2022-01-10 07:54:20 +01:00
public PluginSchemeHandler ( ResourceCache resourceCache , PluginManager pluginManager ) {
this . resourceCache = resourceCache ;
2021-12-28 15:43:21 +01:00
this . bridge = pluginManager . bridge ;
2021-08-07 07:48:29 +02:00
}
2020-06-02 12:31:34 +02:00
2022-01-10 07:54:20 +01:00
public SchemeResource ? Resolve ( Uri uri ) {
2021-12-28 15:43:21 +01:00
if ( ! uri . IsAbsoluteUri | | uri . Scheme ! = Protocol | | ! int . TryParse ( uri . Authority , out var identifier ) ) {
2021-08-07 07:48:29 +02:00
return null ;
}
2020-06-02 12:31:34 +02:00
2021-12-28 15:43:21 +01:00
var segments = uri . Segments . Select ( static segment = > segment . TrimEnd ( '/' ) ) . Where ( static segment = > ! string . IsNullOrEmpty ( segment ) ) . ToArray ( ) ;
2020-06-02 12:31:34 +02:00
2021-08-07 07:48:29 +02:00
if ( segments . Length > 0 ) {
var handler = segments [ 0 ] switch {
"root" = > DoReadRootFile ( identifier , segments ) ,
_ = > null
} ;
2020-06-02 12:31:34 +02:00
2021-08-07 07:48:29 +02:00
if ( handler ! = null ) {
return handler ;
}
}
2020-06-02 12:31:34 +02:00
2022-01-10 07:54:20 +01:00
return new SchemeResource . Status ( HttpStatusCode . BadRequest , "Bad URL path: " + uri . AbsolutePath ) ;
2021-08-07 07:48:29 +02:00
}
2020-06-02 12:31:34 +02:00
2022-01-10 07:54:20 +01:00
private SchemeResource DoReadRootFile ( int identifier , string [ ] segments ) {
2021-08-07 07:48:29 +02:00
string path = string . Join ( "/" , segments , 1 , segments . Length - 1 ) ;
2020-06-02 12:31:34 +02:00
2021-12-28 15:43:21 +01:00
Plugin ? plugin = bridge . GetPluginFromToken ( identifier ) ;
2021-08-07 07:48:29 +02:00
string fullPath = plugin = = null ? string . Empty : plugin . GetFullPathIfSafe ( PluginFolder . Root , path ) ;
2022-01-10 07:54:20 +01:00
return fullPath . Length = = 0 ? PathMustBeRelativeToRoot : resourceCache . ReadFile ( fullPath ) ;
2021-08-07 07:48:29 +02:00
}
}
2020-06-02 12:31:34 +02:00
}