Constantin Ziesche | fa61208 | 2020-04-03 09:54:56 +0200 | [diff] [blame] | 1 | /******************************************************************************* |
| 2 | * Copyright (c) 2020 Robert Bosch GmbH |
| 3 | * Author: Constantin Ziesche (constantin.ziesche@bosch.com) |
| 4 | * |
| 5 | * This program and the accompanying materials are made available under the |
| 6 | * terms of the Eclipse Public License 2.0 which is available at |
| 7 | * http://www.eclipse.org/legal/epl-2.0 |
| 8 | * |
| 9 | * SPDX-License-Identifier: EPL-2.0 |
| 10 | *******************************************************************************/ |
Constantin Ziesche | ce27660 | 2020-10-27 09:36:00 +0100 | [diff] [blame] | 11 | using BaSyx.Components.Common.Abstractions; |
Constantin Ziesche | 0399d41 | 2020-09-24 14:31:15 +0200 | [diff] [blame] | 12 | using BaSyx.Utils.AssemblyHandling; |
Constantin Ziesche | 687f888 | 2020-10-02 16:17:44 +0200 | [diff] [blame] | 13 | using BaSyx.Utils.DependencyInjection; |
Constantin Ziesche | fa61208 | 2020-04-03 09:54:56 +0200 | [diff] [blame] | 14 | using BaSyx.Utils.Settings.Types; |
| 15 | using Microsoft.AspNetCore.Builder; |
| 16 | using Microsoft.AspNetCore.Hosting; |
Constantin Ziesche | 687f888 | 2020-10-02 16:17:44 +0200 | [diff] [blame] | 17 | using Microsoft.AspNetCore.Http; |
| 18 | using Microsoft.AspNetCore.Rewrite; |
Constantin Ziesche | fa61208 | 2020-04-03 09:54:56 +0200 | [diff] [blame] | 19 | using Microsoft.Extensions.DependencyInjection; |
Constantin Ziesche | 0399d41 | 2020-09-24 14:31:15 +0200 | [diff] [blame] | 20 | using Microsoft.Extensions.FileProviders; |
| 21 | using Microsoft.Extensions.Hosting; |
Constantin Ziesche | fa61208 | 2020-04-03 09:54:56 +0200 | [diff] [blame] | 22 | using Microsoft.Extensions.Logging; |
| 23 | using NLog; |
| 24 | using NLog.Web; |
| 25 | using System; |
Constantin Ziesche | 687f888 | 2020-10-02 16:17:44 +0200 | [diff] [blame] | 26 | using System.Collections.Generic; |
| 27 | using System.Diagnostics; |
Constantin Ziesche | fa61208 | 2020-04-03 09:54:56 +0200 | [diff] [blame] | 28 | using System.IO; |
| 29 | using System.Linq; |
Constantin Ziesche | 02817f1 | 2020-08-04 21:40:43 +0200 | [diff] [blame] | 30 | using System.Reflection; |
Constantin Ziesche | 687f888 | 2020-10-02 16:17:44 +0200 | [diff] [blame] | 31 | using System.Text.RegularExpressions; |
Constantin Ziesche | fa61208 | 2020-04-03 09:54:56 +0200 | [diff] [blame] | 32 | using System.Threading; |
| 33 | using System.Threading.Tasks; |
Constantin Ziesche | 687f888 | 2020-10-02 16:17:44 +0200 | [diff] [blame] | 34 | using System.Web; |
Constantin Ziesche | 02817f1 | 2020-08-04 21:40:43 +0200 | [diff] [blame] | 35 | using static BaSyx.Utils.Settings.Types.ServerSettings; |
Constantin Ziesche | fa61208 | 2020-04-03 09:54:56 +0200 | [diff] [blame] | 36 | |
| 37 | namespace BaSyx.Components.Common |
| 38 | { |
Constantin Ziesche | ce27660 | 2020-10-27 09:36:00 +0100 | [diff] [blame] | 39 | public abstract class ServerApplication : IServerApplication |
Constantin Ziesche | fa61208 | 2020-04-03 09:54:56 +0200 | [diff] [blame] | 40 | { |
| 41 | private static readonly Logger logger = NLogBuilder.ConfigureNLog("NLog.config").GetCurrentClassLogger(); |
| 42 | |
Constantin Ziesche | 0399d41 | 2020-09-24 14:31:15 +0200 | [diff] [blame] | 43 | private string _contentRoot; |
| 44 | private string _webRoot; |
Constantin Ziesche | 687f888 | 2020-10-02 16:17:44 +0200 | [diff] [blame] | 45 | private bool _secure = false; |
| 46 | |
Constantin Ziesche | 09dcb6b | 2020-10-07 13:47:39 +0200 | [diff] [blame] | 47 | private readonly List<Action<IApplicationBuilder>> AppBuilderPipeline; |
| 48 | private readonly List<Action<IServiceCollection>> ServiceBuilderPipeline; |
Constantin Ziesche | 0399d41 | 2020-09-24 14:31:15 +0200 | [diff] [blame] | 49 | |
| 50 | public const string DEFAULT_CONTENT_ROOT = "Content"; |
| 51 | public const string DEFAULT_WEB_ROOT = "wwwroot"; |
Constantin Ziesche | 687f888 | 2020-10-02 16:17:44 +0200 | [diff] [blame] | 52 | public const string UI_RELATIVE_PATH = "/ui"; |
| 53 | public const string CONTROLLER_ASSEMBLY_NAME = "BaSyx.API.Http.Controllers"; |
Constantin Ziesche | 0399d41 | 2020-09-24 14:31:15 +0200 | [diff] [blame] | 54 | |
Constantin Ziesche | 687f888 | 2020-10-02 16:17:44 +0200 | [diff] [blame] | 55 | public Assembly ControllerAssembly { get; private set; } |
Constantin Ziesche | fa61208 | 2020-04-03 09:54:56 +0200 | [diff] [blame] | 56 | public ServerSettings Settings { get; protected set; } |
| 57 | public IWebHostBuilder WebHostBuilder { get; protected set; } |
Constantin Ziesche | 687f888 | 2020-10-02 16:17:44 +0200 | [diff] [blame] | 58 | |
Constantin Ziesche | 0399d41 | 2020-09-24 14:31:15 +0200 | [diff] [blame] | 59 | public string ExecutionPath { get; } |
Constantin Ziesche | fa61208 | 2020-04-03 09:54:56 +0200 | [diff] [blame] | 60 | |
| 61 | public Action ApplicationStarted { get; set; } |
| 62 | |
| 63 | public Action ApplicationStopping { get; set; } |
| 64 | |
| 65 | public Action ApplicationStopped { get; set; } |
| 66 | |
Constantin Ziesche | 687f888 | 2020-10-02 16:17:44 +0200 | [diff] [blame] | 67 | protected ServerApplication() : this(null, null) |
Constantin Ziesche | fa61208 | 2020-04-03 09:54:56 +0200 | [diff] [blame] | 68 | { } |
| 69 | |
Constantin Ziesche | 687f888 | 2020-10-02 16:17:44 +0200 | [diff] [blame] | 70 | protected ServerApplication(ServerSettings settings) : this(settings, null) |
Constantin Ziesche | fa61208 | 2020-04-03 09:54:56 +0200 | [diff] [blame] | 71 | { } |
| 72 | |
Constantin Ziesche | 687f888 | 2020-10-02 16:17:44 +0200 | [diff] [blame] | 73 | protected ServerApplication(ServerSettings settings, string[] webHostBuilderArgs) |
Constantin Ziesche | fa61208 | 2020-04-03 09:54:56 +0200 | [diff] [blame] | 74 | { |
Constantin Ziesche | 0399d41 | 2020-09-24 14:31:15 +0200 | [diff] [blame] | 75 | ExecutionPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); |
Constantin Ziesche | 687f888 | 2020-10-02 16:17:44 +0200 | [diff] [blame] | 76 | ControllerAssembly = Assembly.Load(CONTROLLER_ASSEMBLY_NAME); |
Constantin Ziesche | 0399d41 | 2020-09-24 14:31:15 +0200 | [diff] [blame] | 77 | |
Constantin Ziesche | 687f888 | 2020-10-02 16:17:44 +0200 | [diff] [blame] | 78 | if (!EmbeddedResource.CheckOrWriteRessourceToFile(typeof(ServerApplication).Assembly, Path.Combine(ExecutionPath, "NLog.config"))) |
Constantin Ziesche | 0399d41 | 2020-09-24 14:31:15 +0200 | [diff] [blame] | 79 | logger.Error("NLog.config cannot be loaded or written"); |
| 80 | |
Constantin Ziesche | 687f888 | 2020-10-02 16:17:44 +0200 | [diff] [blame] | 81 | if (settings == null && !EmbeddedResource.CheckOrWriteRessourceToFile(typeof(ServerApplication).Assembly, Path.Combine(ExecutionPath, "ServerSettings.xml"))) |
Constantin Ziesche | 0399d41 | 2020-09-24 14:31:15 +0200 | [diff] [blame] | 82 | logger.Error("ServerSettings.xml cannot be loaded or written"); |
| 83 | |
| 84 | Settings = settings ?? ServerSettings.LoadSettingsFromFile("ServerSettings.xml") ?? throw new ArgumentNullException(nameof(settings)); |
| 85 | |
Constantin Ziesche | 687f888 | 2020-10-02 16:17:44 +0200 | [diff] [blame] | 86 | WebHostBuilder = DefaultWebHostBuilder.CreateWebHostBuilder(webHostBuilderArgs, Settings); |
| 87 | AppBuilderPipeline = new List<Action<IApplicationBuilder>>(); |
| 88 | ServiceBuilderPipeline = new List<Action<IServiceCollection>>(); |
| 89 | |
Constantin Ziesche | 09dcb6b | 2020-10-07 13:47:39 +0200 | [diff] [blame] | 90 | WebHostBuilder.ConfigureServices( (context, services) => |
Constantin Ziesche | 687f888 | 2020-10-02 16:17:44 +0200 | [diff] [blame] | 91 | { |
Constantin Ziesche | 09dcb6b | 2020-10-07 13:47:39 +0200 | [diff] [blame] | 92 | ConfigureServices(context, services); |
Constantin Ziesche | 687f888 | 2020-10-02 16:17:44 +0200 | [diff] [blame] | 93 | }); |
| 94 | |
| 95 | WebHostBuilder.Configure(app => |
| 96 | { |
| 97 | Configure(app); |
| 98 | }); |
| 99 | |
| 100 | WebHostBuilder.UseNLog(); |
| 101 | ConfigureLogging(logger.GetLogLevel()); |
| 102 | |
Constantin Ziesche | 0399d41 | 2020-09-24 14:31:15 +0200 | [diff] [blame] | 103 | if (string.IsNullOrEmpty(Settings.ServerConfig.Hosting.ContentPath)) |
| 104 | _contentRoot = Path.Join(ExecutionPath, DEFAULT_CONTENT_ROOT); |
| 105 | else if (Path.IsPathRooted(Settings.ServerConfig.Hosting.ContentPath)) |
| 106 | _contentRoot = Settings.ServerConfig.Hosting.ContentPath; |
| 107 | else |
| 108 | _contentRoot = Path.Join(ExecutionPath, Settings.ServerConfig.Hosting.ContentPath); |
| 109 | |
Constantin Ziesche | 0399d41 | 2020-09-24 14:31:15 +0200 | [diff] [blame] | 110 | try |
| 111 | { |
| 112 | if (!Directory.Exists(_contentRoot)) |
| 113 | Directory.CreateDirectory(_contentRoot); |
| 114 | WebHostBuilder.UseContentRoot(_contentRoot); |
| 115 | } |
| 116 | catch (Exception e) |
| 117 | { |
| 118 | logger.Error(e, $"ContentRoot path {_contentRoot} cannot be created "); |
| 119 | } |
| 120 | |
Constantin Ziesche | 687f888 | 2020-10-02 16:17:44 +0200 | [diff] [blame] | 121 | _webRoot = Path.Join(ExecutionPath, DEFAULT_WEB_ROOT); |
Constantin Ziesche | 0399d41 | 2020-09-24 14:31:15 +0200 | [diff] [blame] | 122 | |
| 123 | try |
| 124 | { |
| 125 | if (!Directory.Exists(_webRoot)) |
| 126 | Directory.CreateDirectory(_webRoot); |
| 127 | WebHostBuilder.UseWebRoot(_webRoot); |
Constantin Ziesche | 687f888 | 2020-10-02 16:17:44 +0200 | [diff] [blame] | 128 | logger.Info($"wwwroot-Path: {_webRoot}"); |
Constantin Ziesche | 0399d41 | 2020-09-24 14:31:15 +0200 | [diff] [blame] | 129 | } |
| 130 | catch (Exception e) |
| 131 | { |
| 132 | logger.Error(e, $"WebRoot path {_webRoot} cannot be created "); |
Constantin Ziesche | 687f888 | 2020-10-02 16:17:44 +0200 | [diff] [blame] | 133 | } |
Constantin Ziesche | fa61208 | 2020-04-03 09:54:56 +0200 | [diff] [blame] | 134 | } |
| 135 | |
| 136 | public virtual void Run() |
| 137 | { |
Constantin Ziesche | 687f888 | 2020-10-02 16:17:44 +0200 | [diff] [blame] | 138 | logger.Info("Starting Server..."); |
Constantin Ziesche | fa61208 | 2020-04-03 09:54:56 +0200 | [diff] [blame] | 139 | |
Constantin Ziesche | 0399d41 | 2020-09-24 14:31:15 +0200 | [diff] [blame] | 140 | WebHostBuilder.Build().Run(); |
Constantin Ziesche | fa61208 | 2020-04-03 09:54:56 +0200 | [diff] [blame] | 141 | } |
| 142 | |
| 143 | public virtual async Task RunAsync(CancellationToken cancellationToken = default) |
| 144 | { |
Constantin Ziesche | 687f888 | 2020-10-02 16:17:44 +0200 | [diff] [blame] | 145 | logger.Info("Starting Server asynchronously..."); |
Constantin Ziesche | fa61208 | 2020-04-03 09:54:56 +0200 | [diff] [blame] | 146 | |
| 147 | await WebHostBuilder.Build().RunAsync(cancellationToken); |
| 148 | } |
| 149 | |
| 150 | public virtual void ConfigureLogging(Microsoft.Extensions.Logging.LogLevel logLevel) |
| 151 | { |
| 152 | WebHostBuilder.ConfigureLogging(logging => |
Constantin Ziesche | 0399d41 | 2020-09-24 14:31:15 +0200 | [diff] [blame] | 153 | { |
| 154 | logging.ClearProviders(); |
| 155 | logging.SetMinimumLevel(logLevel); |
| 156 | }); |
Constantin Ziesche | fa61208 | 2020-04-03 09:54:56 +0200 | [diff] [blame] | 157 | } |
| 158 | |
Constantin Ziesche | 687f888 | 2020-10-02 16:17:44 +0200 | [diff] [blame] | 159 | public virtual void Configure(Action<IApplicationBuilder> app) => AppBuilderPipeline.Add(app); |
| 160 | public virtual void ConfigureServices(Action<IServiceCollection> services) => ServiceBuilderPipeline.Add(services); |
Constantin Ziesche | 0399d41 | 2020-09-24 14:31:15 +0200 | [diff] [blame] | 161 | public virtual void UseContentRoot(string contentRoot) |
| 162 | { |
| 163 | _contentRoot = contentRoot; |
| 164 | WebHostBuilder.UseContentRoot(contentRoot); |
| 165 | } |
| 166 | public virtual void UseWebRoot(string webRoot) |
| 167 | { |
| 168 | _webRoot = webRoot; |
| 169 | WebHostBuilder.UseWebRoot(webRoot); |
| 170 | } |
Constantin Ziesche | fa61208 | 2020-04-03 09:54:56 +0200 | [diff] [blame] | 171 | public virtual void UseUrls(params string[] urls) |
| 172 | { |
| 173 | WebHostBuilder.UseUrls(urls); |
| 174 | if (Settings?.ServerConfig?.Hosting != null) |
| 175 | Settings.ServerConfig.Hosting.Urls = urls?.ToList(); |
| 176 | } |
| 177 | |
| 178 | public virtual void ProvideContent(Uri relativeUri, Stream content) |
| 179 | { |
| 180 | try |
| 181 | { |
| 182 | using (Stream stream = content) |
| 183 | { |
| 184 | string fileName = Path.GetFileName(relativeUri.ToString()); |
Constantin Ziesche | e837f99 | 2020-08-19 12:04:32 +0200 | [diff] [blame] | 185 | logger.Info("FileName: " + fileName); |
| 186 | string directory = Path.GetDirectoryName(relativeUri.ToString()).TrimStart('\\'); |
| 187 | logger.Info("Directory: " + directory); |
| 188 | |
Constantin Ziesche | 0399d41 | 2020-09-24 14:31:15 +0200 | [diff] [blame] | 189 | string hostingDirectory = Path.Join(_contentRoot, directory); |
Constantin Ziesche | e837f99 | 2020-08-19 12:04:32 +0200 | [diff] [blame] | 190 | |
| 191 | logger.Info($"Try creating hosting directory if not existing: {hostingDirectory}"); |
Constantin Ziesche | fa61208 | 2020-04-03 09:54:56 +0200 | [diff] [blame] | 192 | Directory.CreateDirectory(hostingDirectory); |
| 193 | |
Constantin Ziesche | e837f99 | 2020-08-19 12:04:32 +0200 | [diff] [blame] | 194 | string filePath = Path.Join(hostingDirectory, fileName); |
| 195 | logger.Info($"Try writing file: {filePath}"); |
Constantin Ziesche | fa61208 | 2020-04-03 09:54:56 +0200 | [diff] [blame] | 196 | |
| 197 | using (FileStream fileStream = File.OpenWrite(filePath)) |
| 198 | { |
| 199 | stream.CopyTo(fileStream); |
| 200 | } |
| 201 | } |
| 202 | } |
| 203 | catch (Exception e) |
| 204 | { |
| 205 | logger.Error(e, $"Error providing content {relativeUri}"); |
| 206 | } |
| 207 | } |
Constantin Ziesche | 02817f1 | 2020-08-04 21:40:43 +0200 | [diff] [blame] | 208 | |
| 209 | public virtual void MapControllers(ControllerConfiguration controllerConfig) |
| 210 | { |
| 211 | this.ConfigureServices(services => |
| 212 | { |
| 213 | if (controllerConfig?.Controllers?.Count > 0) |
| 214 | { |
| 215 | var mvcBuilder = services.AddMvc(); |
Constantin Ziesche | 0399d41 | 2020-09-24 14:31:15 +0200 | [diff] [blame] | 216 | foreach (var controllerAssemblyString in controllerConfig.Controllers) |
Constantin Ziesche | 02817f1 | 2020-08-04 21:40:43 +0200 | [diff] [blame] | 217 | { |
Constantin Ziesche | 181770b | 2020-08-20 20:32:39 +0200 | [diff] [blame] | 218 | Assembly controllerAssembly = null; |
| 219 | try |
| 220 | { |
Constantin Ziesche | 0399d41 | 2020-09-24 14:31:15 +0200 | [diff] [blame] | 221 | controllerAssembly = Assembly.Load(controllerAssemblyString); |
Constantin Ziesche | 181770b | 2020-08-20 20:32:39 +0200 | [diff] [blame] | 222 | } |
| 223 | catch (Exception e) |
| 224 | { |
Constantin Ziesche | 0399d41 | 2020-09-24 14:31:15 +0200 | [diff] [blame] | 225 | logger.Warn(e, $"Assembly {controllerAssemblyString} cannot be loaded - maybe it is not referenced. Try reading from file..."); |
Constantin Ziesche | 181770b | 2020-08-20 20:32:39 +0200 | [diff] [blame] | 226 | try |
| 227 | { |
Constantin Ziesche | 0399d41 | 2020-09-24 14:31:15 +0200 | [diff] [blame] | 228 | if (File.Exists(controllerAssemblyString)) |
| 229 | controllerAssembly = Assembly.LoadFile(controllerAssemblyString); |
| 230 | else if (File.Exists(controllerAssemblyString + ".dll")) |
| 231 | controllerAssembly = Assembly.LoadFile(controllerAssemblyString + ".dll"); |
Constantin Ziesche | 181770b | 2020-08-20 20:32:39 +0200 | [diff] [blame] | 232 | else |
Constantin Ziesche | 0399d41 | 2020-09-24 14:31:15 +0200 | [diff] [blame] | 233 | controllerAssembly = Assembly.LoadFrom(controllerAssemblyString); |
Constantin Ziesche | 181770b | 2020-08-20 20:32:39 +0200 | [diff] [blame] | 234 | } |
| 235 | catch (Exception exp) |
| 236 | { |
Constantin Ziesche | 0399d41 | 2020-09-24 14:31:15 +0200 | [diff] [blame] | 237 | logger.Warn(exp, $"Assembly {controllerAssemblyString} can finally not be loaded"); |
| 238 | } |
Constantin Ziesche | 181770b | 2020-08-20 20:32:39 +0200 | [diff] [blame] | 239 | } |
Constantin Ziesche | 0821550 | 2020-09-21 19:08:32 +0200 | [diff] [blame] | 240 | if (controllerAssembly != null) |
| 241 | { |
Constantin Ziesche | 181770b | 2020-08-20 20:32:39 +0200 | [diff] [blame] | 242 | mvcBuilder.AddApplicationPart(controllerAssembly); |
Constantin Ziesche | 0399d41 | 2020-09-24 14:31:15 +0200 | [diff] [blame] | 243 | string controllerAssemblyName = controllerAssembly.GetName().Name; |
| 244 | string xmlDocFile = $"{controllerAssemblyName}.xml"; |
| 245 | string xmlDocFilePath = Path.Combine(ExecutionPath, xmlDocFile); |
| 246 | |
| 247 | if (File.Exists(xmlDocFilePath)) |
| 248 | continue; |
| 249 | |
| 250 | try |
| 251 | { |
| 252 | ManifestEmbeddedFileProvider embeddedFileProvider = new ManifestEmbeddedFileProvider(controllerAssembly); |
| 253 | IFileInfo fileInfo = embeddedFileProvider.GetFileInfo(xmlDocFile); |
| 254 | if (fileInfo == null) |
| 255 | { |
| 256 | logger.Warn($"{xmlDocFile} of Assembly {controllerAssemblyName} not found"); |
| 257 | continue; |
| 258 | } |
| 259 | using (Stream stream = fileInfo.CreateReadStream()) |
| 260 | { |
| 261 | using (FileStream fileStream = File.OpenWrite(xmlDocFilePath)) |
| 262 | { |
| 263 | stream.CopyTo(fileStream); |
| 264 | } |
| 265 | } |
| 266 | logger.Info($"{xmlDocFile} of Assembly {controllerAssemblyName} has been created successfully"); |
| 267 | } |
| 268 | catch (Exception e) |
| 269 | { |
| 270 | logger.Warn(e, $"{xmlDocFile} of Assembly {controllerAssemblyName} cannot be read"); |
| 271 | } |
Constantin Ziesche | 0821550 | 2020-09-21 19:08:32 +0200 | [diff] [blame] | 272 | } |
Constantin Ziesche | 02817f1 | 2020-08-04 21:40:43 +0200 | [diff] [blame] | 273 | } |
| 274 | mvcBuilder.AddControllersAsServices(); |
| 275 | } |
| 276 | }); |
| 277 | } |
Constantin Ziesche | 687f888 | 2020-10-02 16:17:44 +0200 | [diff] [blame] | 278 | |
Constantin Ziesche | 09dcb6b | 2020-10-07 13:47:39 +0200 | [diff] [blame] | 279 | protected virtual void ConfigureServices(WebHostBuilderContext context, IServiceCollection services) |
Constantin Ziesche | 687f888 | 2020-10-02 16:17:44 +0200 | [diff] [blame] | 280 | { |
| 281 | services.AddSingleton(typeof(ServerSettings), Settings); |
| 282 | services.AddSingleton<IServerApplicationLifetime>(this); |
| 283 | |
Constantin Ziesche | 09dcb6b | 2020-10-07 13:47:39 +0200 | [diff] [blame] | 284 | |
Constantin Ziesche | 687f888 | 2020-10-02 16:17:44 +0200 | [diff] [blame] | 285 | var urls = Settings.ServerConfig.Hosting.Urls; |
| 286 | var secureUrl = urls.Find(s => s.StartsWith("https")); |
Constantin Ziesche | 09dcb6b | 2020-10-07 13:47:39 +0200 | [diff] [blame] | 287 | if (!string.IsNullOrEmpty(secureUrl) && !context.HostingEnvironment.IsDevelopment()) |
Constantin Ziesche | 687f888 | 2020-10-02 16:17:44 +0200 | [diff] [blame] | 288 | { |
| 289 | secureUrl = secureUrl.Replace("+", "0.0.0.0"); |
| 290 | Uri secureUri = new Uri(secureUrl); |
| 291 | _secure = true; |
| 292 | services.AddHttpsRedirection(opts => |
| 293 | { |
| 294 | opts.HttpsPort = secureUri.Port; |
| 295 | }); |
| 296 | } |
| 297 | |
| 298 | services.AddStandardImplementation(); |
| 299 | |
| 300 | services.AddCors(); |
| 301 | services.AddMvc() |
| 302 | .AddApplicationPart(ControllerAssembly) |
| 303 | .AddControllersAsServices() |
| 304 | .AddNewtonsoftJson(options => options.GetDefaultMvcJsonOptions(services)); |
| 305 | |
| 306 | services.AddRazorPages(opts => |
| 307 | { |
| 308 | logger.Info("Pages-RootDirectory: " + opts.RootDirectory); |
| 309 | }); |
| 310 | |
| 311 | services.AddDirectoryBrowser(); |
| 312 | |
| 313 | foreach (var serviceBuider in ServiceBuilderPipeline) |
| 314 | { |
| 315 | serviceBuider.Invoke(services); |
| 316 | } |
| 317 | } |
| 318 | |
| 319 | protected virtual void Configure(IApplicationBuilder app) |
| 320 | { |
| 321 | var env = app.ApplicationServices.GetRequiredService<IWebHostEnvironment>(); |
| 322 | var applicationLifetime = app.ApplicationServices.GetRequiredService<IHostApplicationLifetime>(); |
| 323 | |
| 324 | if (env.IsDevelopment() || Debugger.IsAttached) |
| 325 | { |
| 326 | app.UseDeveloperExceptionPage(); |
| 327 | } |
| 328 | else |
| 329 | { |
| 330 | app.UseExceptionHandler("/Error"); |
| 331 | app.UseHsts(); |
| 332 | } |
| 333 | |
Constantin Ziesche | 09dcb6b | 2020-10-07 13:47:39 +0200 | [diff] [blame] | 334 | if(_secure && !env.IsDevelopment()) |
Constantin Ziesche | 687f888 | 2020-10-02 16:17:44 +0200 | [diff] [blame] | 335 | app.UseHttpsRedirection(); |
| 336 | |
| 337 | app.UseStaticFiles(); |
| 338 | |
| 339 | string path = env.ContentRootPath; |
| 340 | if (Directory.Exists(path)) |
| 341 | { |
| 342 | app.UseStaticFiles(new StaticFileOptions() |
| 343 | { |
| 344 | FileProvider = new PhysicalFileProvider(@path), |
| 345 | RequestPath = new PathString("") |
| 346 | }); |
| 347 | |
| 348 | app.UseDirectoryBrowser(new DirectoryBrowserOptions |
| 349 | { |
| 350 | FileProvider = new PhysicalFileProvider(@path), |
| 351 | RequestPath = new PathString("/browse") |
| 352 | }); |
| 353 | } |
| 354 | |
| 355 | app.Use((context, next) => |
| 356 | { |
| 357 | string requestPath = context.Request.Path.ToUriComponent(); |
| 358 | |
| 359 | if (requestPath.Contains("submodelElements/")) |
| 360 | { |
| 361 | Match valueMatch = Regex.Match(requestPath, "(?<=submodelElements/)(.*)(?=/value|/invoke|/invocationList)"); |
Constantin Ziesche | eb74d64 | 2020-11-04 17:57:12 +0100 | [diff] [blame] | 362 | if(valueMatch.Success && !string.IsNullOrEmpty(valueMatch.Value)) |
Constantin Ziesche | 687f888 | 2020-10-02 16:17:44 +0200 | [diff] [blame] | 363 | { |
| 364 | string elementPath = HttpUtility.UrlEncode(valueMatch.Value); |
| 365 | requestPath = requestPath.Replace(valueMatch.Value, elementPath); |
| 366 | context.Request.Path = new PathString(requestPath); |
| 367 | } |
| 368 | else |
| 369 | { |
| 370 | Match baseMatch = Regex.Match(requestPath, "(?<=submodelElements/)(.*)"); |
Constantin Ziesche | eb74d64 | 2020-11-04 17:57:12 +0100 | [diff] [blame] | 371 | if(baseMatch.Success && !string.IsNullOrEmpty(baseMatch.Value)) |
Constantin Ziesche | 687f888 | 2020-10-02 16:17:44 +0200 | [diff] [blame] | 372 | { |
| 373 | string elementPath = HttpUtility.UrlEncode(baseMatch.Value); |
| 374 | requestPath = requestPath.Replace(baseMatch.Value, elementPath); |
| 375 | context.Request.Path = new PathString(requestPath); |
| 376 | } |
| 377 | } |
| 378 | } |
| 379 | return next(); |
| 380 | }); |
| 381 | |
| 382 | app.UseRouting(); |
| 383 | |
| 384 | app.UseCors( |
| 385 | options => options |
| 386 | .AllowAnyHeader() |
| 387 | .AllowAnyMethod() |
| 388 | .AllowAnyOrigin() |
| 389 | ); |
| 390 | app.UseAuthorization(); |
| 391 | |
| 392 | app.UseEndpoints(endpoints => |
| 393 | { |
| 394 | endpoints.MapRazorPages(); |
| 395 | endpoints.MapControllers(); |
| 396 | }); |
| 397 | |
| 398 | var options = new RewriteOptions().AddRedirect("^$", UI_RELATIVE_PATH); |
| 399 | app.UseRewriter(options); |
| 400 | |
| 401 | if (ApplicationStarted != null) |
| 402 | applicationLifetime.ApplicationStarted.Register(ApplicationStarted); |
| 403 | if (ApplicationStopping != null) |
| 404 | applicationLifetime.ApplicationStopping.Register(ApplicationStopping); |
| 405 | if (ApplicationStopped != null) |
| 406 | applicationLifetime.ApplicationStopped.Register(ApplicationStopped); |
| 407 | |
| 408 | foreach (var appBuilder in AppBuilderPipeline) |
| 409 | { |
| 410 | appBuilder.Invoke(app); |
| 411 | } |
| 412 | } |
Constantin Ziesche | fa61208 | 2020-04-03 09:54:56 +0200 | [diff] [blame] | 413 | } |
| 414 | } |