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;
}