private static Site SetSite()

in src/Microsoft.IIS.Administration.WebServer.Sites/SiteHelper.cs [375:519]


        private static Site SetSite(Site site, dynamic model, IFileProvider fileProvider)
        {
            Debug.Assert(site != null);
            Debug.Assert((bool)(model != null));

            //
            // Name
            DynamicHelper.If((object)model.name, v => { site.Name = v; });

            //
            // Server Auto Start
            site.ServerAutoStart = DynamicHelper.To<bool>(model.server_auto_start) ?? site.ServerAutoStart;

            //
            // Key
            long? key = DynamicHelper.To<long>(model.key);
            if (key.HasValue) {
                if (ManagementUnit.ServerManager.Sites.Any(s => s.Id == key.Value && site.Id != key.Value)) {
                    throw new AlreadyExistsException("key");
                }
                site.Id = key.Value;
            }

            //
            // Physical Path
            string physicalPath = DynamicHelper.Value(model.physical_path);

            if (physicalPath != null) {

                physicalPath = physicalPath.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
                var expanded = System.Environment.ExpandEnvironmentVariables(physicalPath);

                if (!PathUtil.IsFullPath(expanded)) {
                    throw new ApiArgumentException("physical_path");
                }
                if (!fileProvider.IsAccessAllowed(expanded, FileAccess.Read)) {
                    throw new ForbiddenArgumentException("physical_path", physicalPath);
                }
                if (!Directory.Exists(expanded)) {
                    throw new NotFoundException("physical_path");
                }

                var rootApp = site.Applications["/"];
                if (rootApp != null) {

                    var rootVDir = rootApp.VirtualDirectories["/"];

                    if (rootVDir != null) {

                        rootVDir.PhysicalPath = physicalPath;
                    }
                }
            }

            //
            // Enabled Protocols
            string enabledProtocols = DynamicHelper.Value(model.enabled_protocols);

            if (enabledProtocols != null) {
                var rootApp = site.Applications["/"];

                if (rootApp != null) {
                    rootApp.EnabledProtocols = enabledProtocols;
                }
            }

            //
            // Limits
            if (model.limits != null) {
                dynamic limits = model.limits;

                site.Limits.MaxBandwidth = DynamicHelper.To(limits.max_bandwidth, 0, uint.MaxValue) ?? site.Limits.MaxBandwidth;
                site.Limits.MaxConnections = DynamicHelper.To(limits.max_connections, 0, uint.MaxValue) ?? site.Limits.MaxConnections;

                if (site.Limits.Schema.HasAttribute(MaxUrlSegmentsAttribute)) {
                    site.Limits.MaxUrlSegments = DynamicHelper.To(limits.max_url_segments, 0, 16383) ?? site.Limits.MaxUrlSegments;
                }

                long? connectionTimeout = DynamicHelper.To(limits.connection_timeout, 0, ushort.MaxValue);
                site.Limits.ConnectionTimeout = (connectionTimeout != null) ? TimeSpan.FromSeconds(connectionTimeout.Value) : site.Limits.ConnectionTimeout;
            }

            //
            // Bindings
            if (model.bindings != null) {
                IEnumerable<dynamic> bindings = (IEnumerable<dynamic>)model.bindings;

                // If the user passes an object for the bindings property rather than an array we will hit an exception when we try to access any property in
                // the foreach loop.
                // This means that the bindings collection won't be deleted, so the bindings are safe from harm.

                List<Binding> newBindings = new List<Binding>();

                // Iterate over the bindings to create a new binding list
                foreach (dynamic b in bindings) {
                    Binding binding = site.Bindings.CreateElement();
                    SetBinding(binding, b);

                    foreach (Binding addedBinding in newBindings) {
                        if (addedBinding.Protocol.Equals(binding.Protocol, StringComparison.OrdinalIgnoreCase) &&
                            addedBinding.BindingInformation.Equals(binding.BindingInformation, StringComparison.OrdinalIgnoreCase)) {
                            throw new AlreadyExistsException("binding");
                        }
                    }

                    // Add to bindings list
                    newBindings.Add(binding);
                }

                // All bindings have been verified and added to the list
                // Clear the old list, and add the new
                site.Bindings.Clear();
                newBindings.ForEach(binding => site.Bindings.Add(binding));
            }

            //
            // App Pool
            if (model.application_pool != null) {

                // Extract the uuid from the application_pool object provided in model
                string appPoolUuid = DynamicHelper.Value(model.application_pool.id);

                // It is an error to provide an application pool object without specifying its id property
                if (appPoolUuid == null) {
                    throw new ApiArgumentException("application_pool.id");
                }

                // Create application pool id object from uuid provided, use this to obtain the application pool
                AppPoolId appPoolId = AppPoolId.CreateFromUuid(appPoolUuid);
                ApplicationPool pool = AppPoolHelper.GetAppPool(appPoolId.Name);

                Application rootApp = site.Applications["/"];

                if (rootApp == null) {
                    throw new ApiArgumentException("application_pool", "Root application does not exist.");
                }

                // REVIEW: Should we create the root application if it doesn't exist and they specify an application pool?
                // We decided not to do this for physical_path.
                // Application pool for a site is extracted from the site's root application
                rootApp.ApplicationPoolName = pool.Name;
            }

            return site;
        }