Example #1
0
 public ExtensionLoader(ScriptHostConfiguration config, TraceWriter traceWriter, ILogger startupLogger)
 {
     _config        = config;
     _traceWriter   = traceWriter;
     _startupLogger = startupLogger;
     _dynamicExtensionLoadingEnabled = FeatureFlags.IsEnabled(ScriptConstants.FeatureFlagsEnableDynamicExtensionLoading);
 }
        public HostAzureBlobStorageProvider(IScriptHostManager scriptHostManager, IConfiguration configuration, IOptionsMonitor <JobHostInternalStorageOptions> options, ILogger <HostAzureBlobStorageProvider> logger, AzureComponentFactory componentFactory, AzureEventSourceLogForwarder logForwarder)
        {
            if (configuration == null)
            {
                throw new ArgumentNullException(nameof(configuration));
            }

            _storageOptions = options ?? throw new ArgumentNullException(nameof(options));
            _logger         = logger ?? throw new ArgumentNullException(nameof(logger));

            _blobServiceClientProvider = new BlobServiceClientProvider(componentFactory, logForwarder);

            if (FeatureFlags.IsEnabled(ScriptConstants.FeatureFlagDisableMergedWebHostScriptHostConfiguration))
            {
                Configuration = configuration;
            }
            else
            {
                if (scriptHostManager == null)
                {
                    throw new ArgumentNullException(nameof(scriptHostManager));
                }

                Configuration = new ConfigurationBuilder()
                                .Add(new ActiveHostConfigurationSource(scriptHostManager))
                                .AddConfiguration(configuration)
                                .Build();
            }
        }
        internal ServiceScope CreateChildScope(IServiceScopeFactory rootScopeFactory)
        {
            var       scopedRoot           = rootScopeFactory.CreateScope();
            var       preferInterpretation = (Container as Container).PreferInterpretation;
            Container scopedContext        = Container.OpenScope(preferInterpretation: preferInterpretation) as Container;

            Rules rules = scopedContext.Rules;

            foreach (var unknownServiceResolver in scopedContext.Rules.UnknownServiceResolvers)
            {
                rules = rules.WithoutUnknownServiceResolver(unknownServiceResolver);
            }

            var resolver = scopedContext.With(r => rules.WithUnknownServiceResolvers(request =>
            {
                return(new DelegateFactory(_ => scopedRoot.ServiceProvider.GetService(request.ServiceType), setup: _rootScopeFactorySetup));
            }));

            var scope = new ServiceScope(resolver, scopedRoot);

            if (FeatureFlags.IsEnabled(ScriptConstants.FeatureFlagEnableEnhancedScopes))
            {
                scopedContext.UseInstance <IServiceProvider>(scope.ServiceProvider);
            }

            ChildScopes.TryAdd(scope, null);

            scope.DisposalTask.ContinueWith(t => ChildScopes.TryRemove(scope, out object _));

            return(scope);
        }
Example #4
0
        public async Task <ActionResult> Upload(IFormFile file)
        {
            if (!FeatureFlags.IsEnabled(FeatureFlags.ImageUpload, _hostingEnv))
            {
                return(NotFound());
            }

            if (!ImagesController.IsImage(file))
            {
                return(ErrorResult("The file should be an image"));
            }
            else
            {
                string fileName = Path.GetRandomFileName();
                string filePath = await SaveImageAsync(
                    file,
                    fileName,
                    _hostingEnv);

                if (filePath == null)
                {
                    return(ErrorResult("Image is null"));
                }

                return(Json(filePath));
            }
        }
Example #5
0
        private static void VerifyAndEnableShadowCopy(WebHostSettings webHostSettings)
        {
            if (!FeatureFlags.IsEnabled(ScriptConstants.FeatureFlagDisableShadowCopy))
            {
                string currentShadowCopyDirectories = AppDomain.CurrentDomain.SetupInformation.ShadowCopyDirectories;
                string shadowCopyPath = GetShadowCopyPath(currentShadowCopyDirectories, webHostSettings.ScriptPath);

#pragma warning disable CS0618
                AppDomain.CurrentDomain.SetShadowCopyPath(shadowCopyPath);
#pragma warning restore CS0618
            }
        }
Example #6
0
        private static bool IsEncryptionSupported()
        {
            if (WebScriptHostManager.IsAzureEnvironment)
            {
                // We're temporarily placing encryption behind a feature toggle until
                // other consumers (e.g. portal) are updated to work with it.
                // TODO: Remove this
                return(FeatureFlags.IsEnabled("SecretEncryption"));
            }

            return(Environment.GetEnvironmentVariable(AzureWebsiteLocalEncryptionKey) != null);
        }
        private Dictionary <string, ScriptRuntimeAssembly> GetRuntimeAssemblies()
        {
            lock (_loadSyncRoot)
            {
                _relaxedUnification = FeatureFlags.IsEnabled(ScriptConstants.FeatureFlagRelaxedAssemblyUnification, _environment);

                string manifestName = _relaxedUnification.Value
                    ? "runtimeassemblies-relaxed.json"
                    : "runtimeassemblies.json";

                return(DependencyHelper.GetRuntimeAssemblies(manifestName));
            }
        }
Example #8
0
        public bool ResetIfStale()
        {
            lock (_loadSyncRoot)
            {
                if (_relaxedUnification != null && _relaxedUnification.Value != FeatureFlags.IsEnabled(ScriptConstants.FeatureFlagRelaxedAssemblyUnification, _environment))
                {
                    _runtimeAssemblies = new Lazy <Dictionary <string, ScriptRuntimeAssembly> >(GetRuntimeAssemblies);

                    return(true);
                }
            }

            return(false);
        }
Example #9
0
        public static bool CanWorkerIndex(IEnumerable <RpcWorkerConfig> workerConfigs, IEnvironment environment)
        {
            if (!FeatureFlags.IsEnabled(ScriptConstants.FeatureFlagEnableWorkerIndexing, environment))
            {
                return(false);
            }

            var workerRuntime = environment.GetEnvironmentVariable(EnvironmentSettingNames.FunctionWorkerRuntime);

            if (workerConfigs != null)
            {
                var workerConfig = workerConfigs.Where(c => c.Description != null && c.Description.Language != null && c.Description.Language.Equals(workerRuntime, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();

                // if feature flag is enabled and workerConfig.WorkerIndexing == true, then return true
                if (workerConfig != null &&
                    workerConfig.Description != null &&
                    workerConfig.Description.WorkerIndexing != null &&
                    workerConfig.Description.WorkerIndexing.Equals("true", StringComparison.OrdinalIgnoreCase))
                {
                    return(true);
                }
            }
            return(false);
        }
Example #10
0
        public static IHostBuilder AddWebScriptHost(this IHostBuilder builder, IServiceProvider rootServiceProvider,
                                                    IServiceScopeFactory rootScopeFactory, ScriptApplicationHostOptions webHostOptions, Action <IWebJobsBuilder> configureWebJobs = null)
        {
            ILoggerFactory       configLoggerFactory = rootServiceProvider.GetService <ILoggerFactory>();
            IDependencyValidator validator           = rootServiceProvider.GetService <IDependencyValidator>();
            IMetricsLogger       metricsLogger       = rootServiceProvider.GetService <IMetricsLogger>();
            IEnvironment         environment         = rootServiceProvider.GetService <IEnvironment>();

            builder.UseServiceProviderFactory(new JobHostScopedServiceProviderFactory(rootServiceProvider, rootScopeFactory, validator))
            .ConfigureServices(services =>
            {
                // register default configuration
                // must happen before the script host is added below
                services.ConfigureOptions <HttpOptionsSetup>();
                services.ConfigureOptions <CustomHttpHeadersOptionsSetup>();
                services.ConfigureOptions <HostHstsOptionsSetup>();
                services.ConfigureOptions <HostCorsOptionsSetup>();
                services.ConfigureOptions <CorsOptionsSetup>();
                services.ConfigureOptions <AppServiceOptionsSetup>();
                services.ConfigureOptions <HostEasyAuthOptionsSetup>();
                services.ConfigureOptions <PrimaryHostCoordinatorOptionsSetup>();
            })
            .AddScriptHost(webHostOptions, configLoggerFactory, metricsLogger, webJobsBuilder =>
            {
                // Adds necessary Azure-based services to the ScriptHost, which will use the host-provided IAzureBlobStorageProvider registered below.
                webJobsBuilder.AddAzureStorageCoreServices();

                // This overrides the IAzureBlobStorageProvider registered by the above call to AddAzureStorageCoreServices().
                // This forwards the Host provided implementation to the inner ScriptHost and MUST be called AFTER the AddAzureStorageCoreServices() call to avoid layering mishaps later.
                // The Host provided IAzureBlobStorageProvider is designed to react to specialization and limited ScriptHost lifetimes, so it can be safely forwarded to the ScriptHost.
                webJobsBuilder.Services.AddSingleton <IAzureBlobStorageProvider>(rootServiceProvider.GetService <IAzureBlobStorageProvider>());

                configureWebJobs?.Invoke(webJobsBuilder);

                webJobsBuilder.Services.TryAddSingleton <HttpClient>(f =>
                {
                    var loggerFactory = f.GetService <ILoggerFactory>();
                    loggerFactory.CreateLogger(LogCategories.Startup).LogWarning("Using HttpClient as an injected dependency will not be supported in future versions of Azure Functions. Use IHttpClientFactory instead. See http://aka.ms/functions-httpclient-di for more information.");
                    return(rootServiceProvider.GetService <HttpClient>());
                });

                ConfigureRegisteredBuilders(webJobsBuilder, rootServiceProvider);

                webJobsBuilder.Services.AddSingleton <IHttpRoutesManager, WebScriptHostHttpRoutesManager>();
            })
            .ConfigureAppConfiguration(configurationBuilder =>
            {
                ConfigureRegisteredBuilders(configurationBuilder, rootServiceProvider);
            })
            .ConfigureLogging(loggingBuilder =>
            {
                loggingBuilder.Services.AddSingleton <ILoggerFactory, ScriptLoggerFactory>();

                loggingBuilder.AddWebJobsSystem <SystemLoggerProvider>();
                if (environment.IsAzureMonitorEnabled())
                {
                    loggingBuilder.Services.AddSingleton <ILoggerProvider, AzureMonitorDiagnosticLoggerProvider>();
                }

                if (!FeatureFlags.IsEnabled(ScriptConstants.FeatureFlagDisableDiagnosticEventLogging))
                {
                    loggingBuilder.Services.AddSingleton <ILoggerProvider, DiagnosticEventLoggerProvider>();
                    loggingBuilder.Services.TryAddSingleton <IDiagnosticEventRepository, DiagnosticEventTableStorageRepository>();
                    loggingBuilder.Services.TryAddSingleton <IDiagnosticEventRepositoryFactory, DiagnosticEventRepositoryFactory>();
                }

                ConfigureRegisteredBuilders(loggingBuilder, rootServiceProvider);
            })
            .ConfigureServices(services =>
            {
                var webHostEnvironment = rootServiceProvider.GetService <IScriptWebHostEnvironment>();

                if (FunctionsSyncManager.IsSyncTriggersEnvironment(webHostEnvironment, environment))
                {
                    services.AddSingleton <IHostedService, FunctionsSyncService>();
                }

                if (!environment.IsV2CompatibilityMode())
                {
                    new FunctionsMvcBuilder(services).AddNewtonsoftJson();
                }

                services.AddSingleton <HttpRequestQueue>();
                services.AddSingleton <IHostLifetime, JobHostHostLifetime>();
                services.AddSingleton <IWebJobsExceptionHandler, WebScriptHostExceptionHandler>();

                services.AddSingleton <DefaultScriptWebHookProvider>();
                services.TryAddSingleton <IScriptWebHookProvider>(p => p.GetService <DefaultScriptWebHookProvider>());
                services.TryAddSingleton <IWebHookProvider>(p => p.GetService <DefaultScriptWebHookProvider>());
                services.TryAddSingleton <IJobHostMiddlewarePipeline, DefaultMiddlewarePipeline>();
                services.TryAddEnumerable(ServiceDescriptor.Singleton <IJobHostHttpMiddleware, CustomHttpHeadersMiddleware>());
                services.TryAddEnumerable(ServiceDescriptor.Singleton <IJobHostHttpMiddleware, HstsConfigurationMiddleware>());
                if (environment.IsLinuxConsumption())
                {
                    services.AddSingleton <ICorsMiddlewareFactory, CorsMiddlewareFactory>();
                    services.TryAddEnumerable(ServiceDescriptor.Singleton <IJobHostHttpMiddleware, JobHostCorsMiddleware>());

                    // EasyAuth must go after CORS, as CORS preflight requests can happen before authentication
                    services.TryAddEnumerable(ServiceDescriptor.Singleton <IJobHostHttpMiddleware, JobHostEasyAuthMiddleware>());
                }
                services.TryAddSingleton <IScaleMetricsRepository, TableStorageScaleMetricsRepository>();

                services.TryAddEnumerable(ServiceDescriptor.Singleton <IConcurrencyThrottleProvider, WorkerChannelThrottleProvider>());

                // Make sure the registered IHostIdProvider is used
                IHostIdProvider provider = rootServiceProvider.GetService <IHostIdProvider>();
                if (provider != null)
                {
                    services.AddSingleton <IHostIdProvider>(provider);
                }

                services.AddSingleton <IDelegatingHandlerProvider, DefaultDelegatingHandlerProvider>();

                // Logging and diagnostics
                services.AddSingleton <IMetricsLogger>(a => new NonDisposableMetricsLogger(metricsLogger));
                services.AddSingleton <IEventCollectorProvider, FunctionInstanceLogCollectorProvider>();

                // Hosted services
                services.AddSingleton <IFileMonitoringService, FileMonitoringService>();
                services.TryAddEnumerable(ServiceDescriptor.Singleton <IHostedService, IFileMonitoringService>(p => p.GetService <IFileMonitoringService>()));

                ConfigureRegisteredBuilders(services, rootServiceProvider);
            });

            return(builder);
        }
Example #11
0
        public static IHostBuilder AddWebScriptHost(this IHostBuilder builder, IServiceProvider rootServiceProvider,
                                                    IServiceScopeFactory rootScopeFactory, ScriptApplicationHostOptions webHostOptions, Action <IWebJobsBuilder> configureWebJobs = null)
        {
            ILoggerFactory       configLoggerFactory = rootServiceProvider.GetService <ILoggerFactory>();
            IDependencyValidator validator           = rootServiceProvider.GetService <IDependencyValidator>();
            IMetricsLogger       metricsLogger       = rootServiceProvider.GetService <IMetricsLogger>();
            IEnvironment         environment         = rootServiceProvider.GetService <IEnvironment>();

            builder.UseServiceProviderFactory(new JobHostScopedServiceProviderFactory(rootServiceProvider, rootScopeFactory, validator))
            .ConfigureServices(services =>
            {
                // register default configuration
                // must happen before the script host is added below
                services.ConfigureOptions <HttpOptionsSetup>();
                services.ConfigureOptions <CustomHttpHeadersOptionsSetup>();
                services.ConfigureOptions <HostHstsOptionsSetup>();
                services.ConfigureOptions <HostCorsOptionsSetup>();
                services.ConfigureOptions <CorsOptionsSetup>();
                services.ConfigureOptions <AppServiceOptionsSetup>();
                services.ConfigureOptions <HostEasyAuthOptionsSetup>();
            })
            .AddScriptHost(webHostOptions, configLoggerFactory, metricsLogger, webJobsBuilder =>
            {
                webJobsBuilder.AddAzureStorageCoreServices();

                configureWebJobs?.Invoke(webJobsBuilder);

                ConfigureRegisteredBuilders(webJobsBuilder, rootServiceProvider);

                webJobsBuilder.Services.AddSingleton <IHttpRoutesManager, WebScriptHostHttpRoutesManager>();
            })
            .ConfigureAppConfiguration(configurationBuilder =>
            {
                ConfigureRegisteredBuilders(configurationBuilder, rootServiceProvider);
            })
            .ConfigureLogging(loggingBuilder =>
            {
                loggingBuilder.Services.AddSingleton <ILoggerFactory, ScriptLoggerFactory>();

                loggingBuilder.AddWebJobsSystem <SystemLoggerProvider>();
                if (environment.IsAzureMonitorEnabled())
                {
                    loggingBuilder.Services.AddSingleton <ILoggerProvider, AzureMonitorDiagnosticLoggerProvider>();
                }

                ConfigureRegisteredBuilders(loggingBuilder, rootServiceProvider);
            })
            .ConfigureServices(services =>
            {
                var webHostEnvironment = rootServiceProvider.GetService <IScriptWebHostEnvironment>();

                if (FunctionsSyncManager.IsSyncTriggersEnvironment(webHostEnvironment, environment))
                {
                    services.AddSingleton <IHostedService, FunctionsSyncService>();
                }

                if (!environment.IsV2CompatibilityMode())
                {
                    new FunctionsMvcBuilder(services).AddNewtonsoftJson();
                }

                services.AddSingleton <HttpRequestQueue>();
                services.AddSingleton <IHostLifetime, JobHostHostLifetime>();
                services.AddSingleton <IWebJobsExceptionHandler, WebScriptHostExceptionHandler>();

                services.AddSingleton <DefaultScriptWebHookProvider>();
                services.TryAddSingleton <IScriptWebHookProvider>(p => p.GetService <DefaultScriptWebHookProvider>());
                services.TryAddSingleton <IWebHookProvider>(p => p.GetService <DefaultScriptWebHookProvider>());
                services.TryAddSingleton <IJobHostMiddlewarePipeline, DefaultMiddlewarePipeline>();
                services.TryAddEnumerable(ServiceDescriptor.Singleton <IJobHostHttpMiddleware, CustomHttpHeadersMiddleware>());
                services.TryAddEnumerable(ServiceDescriptor.Singleton <IJobHostHttpMiddleware, HstsConfigurationMiddleware>());
                if (environment.IsLinuxConsumption())
                {
                    services.AddSingleton <ICorsMiddlewareFactory, CorsMiddlewareFactory>();
                    services.TryAddEnumerable(ServiceDescriptor.Singleton <IJobHostHttpMiddleware, JobHostCorsMiddleware>());

                    // EasyAuth must go after CORS, as CORS preflight requests can happen before authentication
                    services.TryAddEnumerable(ServiceDescriptor.Singleton <IJobHostHttpMiddleware, JobHostEasyAuthMiddleware>());
                }
                services.TryAddSingleton <IScaleMetricsRepository, TableStorageScaleMetricsRepository>();

                if (environment.IsWindowsAzureManagedHosting() || environment.IsLinuxAzureManagedHosting())
                {
                    // Enable breaking change analysis only when hosted in Azure
                    services.AddSingleton <IChangeAnalysisStateProvider, BlobChangeAnalysisStateProvider>();
                    services.AddSingleton <IHostedService, ChangeAnalysisService>();
                }

                // Make sure the registered IHostIdProvider is used
                IHostIdProvider provider = rootServiceProvider.GetService <IHostIdProvider>();
                if (provider != null)
                {
                    services.AddSingleton <IHostIdProvider>(provider);
                }

                services.AddSingleton <IDelegatingHandlerProvider, DefaultDelegatingHandlerProvider>();

                // Logging and diagnostics
                services.AddSingleton <IMetricsLogger>(a => new NonDisposableMetricsLogger(metricsLogger));
                services.AddSingleton <IEventCollectorProvider, FunctionInstanceLogCollectorProvider>();

                // Hosted services
                services.AddSingleton <IFileMonitoringService, FileMonitoringService>();
                services.TryAddEnumerable(ServiceDescriptor.Singleton <IHostedService, IFileMonitoringService>(p => p.GetService <IFileMonitoringService>()));

                ConfigureRegisteredBuilders(services, rootServiceProvider);
            });

            var debugStateProvider = rootServiceProvider.GetService <IDebugStateProvider>();

            if (!FeatureFlags.IsEnabled(ScriptConstants.FeatureFlagDisableDevInDebug, environment) && debugStateProvider.InDebugMode)
            {
                builder.UseEnvironment(EnvironmentName.Development);
            }

            return(builder);
        }
Example #12
0
 public void IsEnabled_ReturnsExpectedValue(string name, bool expected)
 {
     Assert.Equal(FeatureFlags.IsEnabled(name), expected);
 }
Example #13
0
 public void Configure(HttpBodyControlOptions options)
 {
     options.AllowSynchronousIO = _environment.IsV2CompatibilityMode() ||
                                  FeatureFlags.IsEnabled(ScriptConstants.FeatureFlagAllowSynchronousIO, _environment);
 }