IIS WarmUp Part II

Home / Blog / IIS WarmUp Part II

IIS WarmUp Part II

Posted:  April 18, 2012

IIS WarmUp Part II

I explained in my earlier post the importance of “warming up” your sites in IIS, especially using the latest .Net frameworks.

Here is a major update to the code posted in that post.

This one will allow you to “warm up” every site in IIS on your server. All you have to do is set the version of IIS to 7 or 6 depending on your install, and then run the program. You could also set the allApplications flag to false and put in the selected sites to “warm up”. Please understand, because of the access needed to warm up all of your sites, this program needs to run under an Administrator account. (it accesses IIS’s metabase files)

So, without too much blab, and without any further ado… here’s the code.

Settings.xml

<Settings>
 <Config>
 <!-- Set your IIS version, and whether or no you want to "warm up" all sites -->
 <IIS version="7" allApplications="True">
 <!-- This is a list of sites to warm up, only comes into play if you have the allApplications flag set to false -->
 <Site url="http://www.o7thwebdesign.com" page="/" />
 <Site url="http://www.facchinifacchinipa.com" page="/" />
 <Site url="http://skor.in" page="/" />
 <Site url="http://o7t.in" page="/" />
 </IIS>
 </Config>
</Settings>

AuditManager.vb

Public Class AuditManager

 'The type of audit to write out
 Public Enum AuditType
 Exception
 General
 End Enum

 'Write the audit to the log file
 Public Shared Sub Write(ByVal _Type As AuditType?, ByVal _Description As String, Optional ByVal _Location As String = Nothing, Optional ByVal _Except As Exception = Nothing)
 Dim _Stack As System.Diagnostics.StackTrace
 If _Except IsNot Nothing Then
 _Stack = New System.Diagnostics.StackTrace(_Except, True)
 Else
 _Stack = Nothing
 End If
 Using _F As New IO.StreamWriter(Common.GetPath() & FormatDateTime(Date.Now, DateFormat.ShortDate).Replace("/", String.Empty) & ".LOG", True)
 Dim tmpString As New Text.StringBuilder
 tmpString.Append("-------------------------------------------------" & vbCrLf)
 tmpString.Append("WHEN:" & vbCrLf)
 tmpString.Append(Date.Now & vbCrLf)
 If _Type.HasValue Then
 tmpString.Append("-------------------------------------------------" & vbCrLf)
 tmpString.Append("TYPE:" & vbCrLf)
 tmpString.Append([Enum].GetName(GetType(AuditType), _Type) & vbCrLf)
 End If
 If _Location IsNot Nothing Then
 tmpString.Append("-------------------------------------------------" & vbCrLf)
 tmpString.Append("LOCATION:" & vbCrLf)
 tmpString.Append(_Location & vbCrLf)
 End If
 tmpString.Append("-------------------------------------------------" & vbCrLf)
 If _Stack IsNot Nothing Then
 tmpString.Append("STACKTRACE:" & vbCrLf)
 tmpString.Append(_Stack.ToString() & vbCrLf)
 tmpString.Append("-------------------------------------------------" & vbCrLf)
 tmpString.Append("STACK FRAMES:" & vbCrLf)
 For Each frame In _Stack.GetFrames()
 tmpString.Append(" - FILE:" & frame.GetFileName() & vbCrLf)
 tmpString.Append(" - METHOD:" & frame.GetMethod().Name & vbCrLf)
 tmpString.Append(" - LINE:" & frame.GetFileLineNumber() & vbCrLf)
 tmpString.Append(" - COLUMN:" & frame.GetFileColumnNumber() & vbCrLf)
 Next
 End If
 If _Except IsNot Nothing Then
 tmpString.Append("-------------------------------------------------" & vbCrLf)
 tmpString.Append("SOURCE:" & vbCrLf)
 tmpString.Append(_Except.Source & vbCrLf)
 tmpString.Append("-------------------------------------------------" & vbCrLf)
 tmpString.Append("MESSAGE:" & vbCrLf)
 tmpString.Append(_Except.Message & vbCrLf)
 tmpString.Append("-------------------------------------------------" & vbCrLf)
 tmpString.Append("DATA:" & vbCrLf)
 tmpString.Append(_Except.Data.ToString() & vbCrLf)
 End If
 tmpString.Append("-------------------------------------------------" & vbCrLf)
 tmpString.Append("NOTES:" & vbCrLf)
 tmpString.Append(_Description & vbCrLf)
 tmpString.Append("-------------------------------------------------" & vbCrLf)
 _F.Write(tmpString.ToString())
 _F.Close()
 End Using
 End Sub

End Class

Common.vb

Public Class Common

 'The applications path
 Public Shared Function GetPath() As String
 Return System.AppDomain.CurrentDomain.BaseDirectory()
 End Function

 'Check to see if a value is Null, if so, set it to equal a default value
 Public Shared Function IsNull(Of T)(ByVal Value As T, ByVal _Default As T) As T
 If Not (IsDBNull(Value)) OrElse Value IsNot Nothing OrElse Not (Value.ToString.Length > 0) Then
 Return DirectCast(Value, T)
 Else
 Return DirectCast(_Default, T)
 End If
 End Function

End Class

CustomCache.vb

Imports System.Runtime.Caching

''' <summary>
''' Our Provider
''' </summary>
''' <remarks></remarks>
Public Interface ICacheProvider
 Function GetItem(Of T)(ByVal key As String) As T
 Sub SetItem(ByVal data As Object, ByVal key As String)
 Sub Remove(ByVal key As String)
 Sub Clear()
End Interface

''' <summary>
''' Our Custom Caching Object
''' </summary>
''' <remarks></remarks>
Public Class CustomCache
 Implements ICacheProvider

 ''' <summary>
 ''' The Cache Object
 ''' </summary>
 ''' <value></value>
 ''' <returns></returns>
 ''' <remarks></remarks>
 Private ReadOnly Property Cache() As ObjectCache
 Get
 Return MemoryCache.Default
 End Get
 End Property

 ''' <summary>
 ''' Set the cache Item
 ''' </summary>
 ''' <param name="key"></param>
 ''' <param name="data"></param>
 ''' <remarks></remarks>
 Public Sub SetCacheItem(ByVal data As Object, ByVal key As String) Implements ICacheProvider.SetItem
 Dim policy As New CacheItemPolicy()
 policy.AbsoluteExpiration = DateTime.Now.AddHours(24)
 Cache.Add(New CacheItem(key, data), policy)
 End Sub

 ''' <summary>
 ''' Get the Cache Item
 ''' </summary>
 ''' <typeparam name="T"></typeparam>
 ''' <param name="key"></param>
 ''' <returns></returns>
 ''' <remarks></remarks>
 Public Function GetCacheItem(Of T)(ByVal key As String) As T Implements ICacheProvider.GetItem
 Return DirectCast(Cache(key), T)
 End Function

 ''' <summary>
 ''' Remove the Item from Cache
 ''' </summary>
 ''' <param name="key"></param>
 ''' <remarks></remarks>
 Public Sub RemoveItem(ByVal key As String) Implements ICacheProvider.Remove
 Cache.Remove(key)
 End Sub

 ''' <summary>
 ''' Remove All items from Cache
 ''' </summary>
 ''' <remarks></remarks>
 Public Sub ClearCache() Implements ICacheProvider.Clear
 For Each item In Cache
 Cache.Remove(item.Key)
 Next
 End Sub

End Class

Settings.vb

Public Class Settings

 Private Shared Cache As New CustomCache

 'Grab our settings file
 Private Shared ReadOnly Property SettingDoc As XDocument
 Get
 Dim _C As XDocument = Cache.GetCacheItem(Of XDocument)("Settings")
 If _C IsNot Nothing Then
 Return _C
 Else
 Return XDocument.Load(Common.GetPath() & "Settings.xml")
 End If
 End Get
 End Property

 'Get and set all our settings
 Public Shared Function GetSettings() As List(Of Typing.Settings.Settings)
 Dim _Qry As New List(Of Typing.Settings.Settings)
 _Qry = (From n In SettingDoc...<IIS>.AsParallel()
 Select New Typing.Settings.Settings() With {
 .IisVersion = Common.IsNull(Of Integer)(n.@version, 0),
 .PrimeAll = Common.IsNull(Of Boolean)(n.@allApplications, True),
 .Sites = Common.IsNull(Of List(Of Typing.Settings.Sites))((From s In n.<Site>.AsParallel()
 Select New Typing.Settings.Sites() With {
 .Url = s.@url,
 .Page = s.@page
 }).ToList(), Nothing)
 }).ToList()
 If _Qry IsNot Nothing Then
 Return _Qry
 Else
 Return Nothing
 End If
 _Qry.Clear()
 End Function

End Class

Typing.vb

'Strongly Type all our values
Public Class Typing

 Partial Public Class Settings

 Partial Public Class Settings
 Public Property IisVersion As Integer
 Public Property PrimeAll As Boolean
 Public Property Sites As List(Of Sites)
 End Class

 Partial Public Class Sites
 Public Property Url As String
 Public Property Page As String
 End Class

 End Class

 Partial Public Class MetaBase
 Public Property Protocol As String
 Public Property Binding As String
 End Class

End Class

WarmUpService.vb

Imports System.Threading.Tasks
Imports System.Security.Principal

Module WarmUpService

 'Check and make sure we have Admin Privelages
 Private ReadOnly Property HasAdminPrivelages()
 Get
 Dim _Id = WindowsIdentity.GetCurrent()
 Dim _Prin = New WindowsPrincipal(_Id)
 Return _Prin.IsInRole(WindowsBuiltInRole.Administrator)
 End Get
 End Property

 'Fire It Up!
 Public Sub Main()
 If HasAdminPrivelages() Then
 AuditManager.Write(AuditManager.AuditType.General, "Fireing Up...")
 DoTheWarmUp()
 AuditManager.Write(AuditManager.AuditType.General, "All Set...")
 Else
 MsgBox("You need to be an administrator in order to run this.")
 End If
 End Sub

 Private Sub DoTheWarmUp()
 Try
 Dim _Set As List(Of Typing.Settings.Settings) = Settings.GetSettings()
 If _Set IsNot Nothing Then
 If _Set(0).PrimeAll Then
 Select Case _Set(0).IisVersion
 Case 6 ' IIS 6
 Dim _PT As New Iis6Primer()
 _PT.PrimeThem()
 Case 7 ' IIS 7 & IIS 7.5
 Dim _PT As New Iis7Primer()
 _PT.PrimeThem()
 Case Else
 AuditManager.Write(AuditManager.AuditType.Exception, "There was an issue! Unsupported IIS version.", "DoTheWarmUp")
 End Select
 Else
 Dim _Sites As List(Of Typing.Settings.Sites) = _Set.Item(0).Sites
 If _Sites IsNot Nothing Then
 Parallel.ForEach(_Sites, Sub(Item)
 Primer.GrabEm(Item.Url & Item.Page)
 End Sub)
 _Sites.Clear()
 End If
 _Set.Clear()
 End If
 Else
 AuditManager.Write(AuditManager.AuditType.Exception, "There was an issue! There are no settings.", "DoTheWarmUp")
 End If
 Catch ex As Exception
 AuditManager.Write(AuditManager.AuditType.Exception, "There was an issue!", "DoTheWarmUp", ex)
 End Try
 End Sub

End Module

Primer.vb

Imports System.Net
Imports System.Reflection

Public Class Primer

 Public Shared Sub GrabEm(ByVal _SitePath As String)
 Try
 SetAllowUnsafeHeaderParsing20()
 Using _WC As New WebClient()
 _WC.Headers.Add("user-agent", "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13")
 _WC.DownloadData(_SitePath)
 End Using
 AuditManager.Write(AuditManager.AuditType.General, "Site: " & _SitePath & " Is Now Primed!")
 Catch ex As Exception
 AuditManager.Write(AuditManager.AuditType.Exception, "Issue with the site: " & _SitePath & ".", "GrabEm", ex)
 End Try
 End Sub

 Private Shared Sub SetAllowUnsafeHeaderParsing20()
 Dim a As New System.Net.Configuration.SettingsSection
 Dim aNetAssembly As System.Reflection.Assembly = Assembly.GetAssembly(a.GetType)
 Dim aSettingsType As Type = aNetAssembly.GetType("System.Net.Configuration.SettingsSectionInternal")
 Dim args As Object() = Nothing
 Dim anInstance As Object = aSettingsType.InvokeMember("Section", BindingFlags.Static Or BindingFlags.GetProperty Or BindingFlags.NonPublic, Nothing, Nothing, args)
 Dim aUseUnsafeHeaderParsing As FieldInfo = aSettingsType.GetField("useUnsafeHeaderParsing", BindingFlags.NonPublic Or BindingFlags.Instance)
 aUseUnsafeHeaderParsing.SetValue(anInstance, True)
 End Sub

End Class

Iis6Primer.vb

Imports <xmlns="urn:microsoft-catalog:XML_Metabase_V64_0">
Imports System.Threading.Tasks

Public Class Iis6Primer

 Private _Xml As XDocument
 Dim _Qry As New List(Of Typing.MetaBase)

 Public Sub New()
 Dim _MetaBasePath As String = Environment.GetFolderPath(Environment.SpecialFolder.System) & "inetsrv"
 _MetaBasePath += "metabase.xml"
 _Xml = XDocument.Load(_MetaBasePath, LoadOptions.PreserveWhitespace)
 _Qry = (From n In _Xml...<IIsWebServer>
 Where (n.@ServerBindings IsNot Nothing)
 Select New Typing.MetaBase() With {
 .Binding = Common.IsNull(Of String)(n.@ServerBindings, String.Empty)
 }).ToList()
 End Sub

 Public Sub PrimeThem()
 Dim _Binding, _Url, _T
 Parallel.ForEach(_Qry, Sub(Item)
 _Binding = Item.Binding
 If _Binding.Contains(" ") Then
 _Binding = _Binding.Replace(" ", "|")
 _T = _Binding.Split("|")
 For Each i In _T
 _Url = i.Split(":")
 If _Url(1).Contains("80") Then
 Primer.GrabEm("http://" & _Url(_Url.GetUpperBound(0)))
 End If
 Next
 Else
 _Url = _Binding.Split(":")
 If _Url(1).Contains("80") Then
 Primer.GrabEm("http://" & _Url(_Url.GetUpperBound(0)))
 End If
 End If
 End Sub)
 _Qry.Clear()
 End Sub

End Class

Iis7Primer.vb

Imports System.Threading.Tasks

Public Class Iis7Primer

 Private _Xml As XDocument
 Dim _Qry As New List(Of Typing.MetaBase)

 Public Sub New()
 Dim _MetaBasePath As String = Environment.GetFolderPath(Environment.SpecialFolder.System) & "inetsrv"
 _MetaBasePath += "configapplicationHost.config"
 _Xml = XDocument.Load(_MetaBasePath, LoadOptions.PreserveWhitespace)
 _Qry = (From n In _Xml...<binding>.AsParallel()
 Select New Typing.MetaBase() With {
 .Binding = Common.IsNull(Of String)(n.@bindingInformation, String.Empty),
 .Protocol = Common.IsNull(Of String)(n.@protocol, String.Empty)
 }).ToList()
 End Sub

 Public Sub PrimeThem()
 Dim _Prot, _Binding, _Url
 Parallel.ForEach(_Qry, Sub(i)
 _Prot = i.Protocol
 If _Prot = "http" Then
 _Binding = i.Binding
 _Url = _Binding.Split(":")
 Primer.GrabEm("http://" & _Url(_Url.GetUpperBound(0)))
 End If
 End Sub)
 _Qry.Clear()
 End Sub

End Class

 

Kevin Pirnie

20+ Years of PC and server maintenance & over 15+ years of web development/design experience; you can rest assured that I take every measure possible to ensure your computers are running to their peak potentials. I treat them as if they were mine, and I am quite a stickler about keeping my machines up to date and optimized to run as well as they can.

Cookie Notice

This site utilizes cookies to improve your browsing experience, analyze the type of traffic we receive, and serve up proper content for you. If you wish to continue browsing, you must agree to allow us to set these cookies. If not, please visit another website.

IIS WarmUp Part II

I explained in my earlier post the importance of “warming up” your sites in IIS, especially using the latest .Net frameworks.

Here is a major update to the code posted in that post.

This one will allow you to “warm up” every site in IIS on your server. All you have to do is set the version of IIS to 7 or 6 depending on your install, and then run the program. You could also set the allApplications flag to false and put in the selected sites to “warm up”. Please understand, because of the access needed to warm up all of your sites, this program needs to run under an Administrator account. (it accesses IIS’s metabase files)

So, without too much blab, and without any further ado… here’s the code.

Settings.xml

<Settings>
 <Config>
 <!-- Set your IIS version, and whether or no you want to "warm up" all sites -->
 <IIS version="7" allApplications="True">
 <!-- This is a list of sites to warm up, only comes into play if you have the allApplications flag set to false -->
 <Site url="http://www.o7thwebdesign.com" page="/" />
 <Site url="http://www.facchinifacchinipa.com" page="/" />
 <Site url="http://skor.in" page="/" />
 <Site url="http://o7t.in" page="/" />
 </IIS>
 </Config>
</Settings>

AuditManager.vb

Public Class AuditManager

 'The type of audit to write out
 Public Enum AuditType
 Exception
 General
 End Enum

 'Write the audit to the log file
 Public Shared Sub Write(ByVal _Type As AuditType?, ByVal _Description As String, Optional ByVal _Location As String = Nothing, Optional ByVal _Except As Exception = Nothing)
 Dim _Stack As System.Diagnostics.StackTrace
 If _Except IsNot Nothing Then
 _Stack = New System.Diagnostics.StackTrace(_Except, True)
 Else
 _Stack = Nothing
 End If
 Using _F As New IO.StreamWriter(Common.GetPath() & FormatDateTime(Date.Now, DateFormat.ShortDate).Replace("/", String.Empty) & ".LOG", True)
 Dim tmpString As New Text.StringBuilder
 tmpString.Append("-------------------------------------------------" & vbCrLf)
 tmpString.Append("WHEN:" & vbCrLf)
 tmpString.Append(Date.Now & vbCrLf)
 If _Type.HasValue Then
 tmpString.Append("-------------------------------------------------" & vbCrLf)
 tmpString.Append("TYPE:" & vbCrLf)
 tmpString.Append([Enum].GetName(GetType(AuditType), _Type) & vbCrLf)
 End If
 If _Location IsNot Nothing Then
 tmpString.Append("-------------------------------------------------" & vbCrLf)
 tmpString.Append("LOCATION:" & vbCrLf)
 tmpString.Append(_Location & vbCrLf)
 End If
 tmpString.Append("-------------------------------------------------" & vbCrLf)
 If _Stack IsNot Nothing Then
 tmpString.Append("STACKTRACE:" & vbCrLf)
 tmpString.Append(_Stack.ToString() & vbCrLf)
 tmpString.Append("-------------------------------------------------" & vbCrLf)
 tmpString.Append("STACK FRAMES:" & vbCrLf)
 For Each frame In _Stack.GetFrames()
 tmpString.Append(" - FILE:" & frame.GetFileName() & vbCrLf)
 tmpString.Append(" - METHOD:" & frame.GetMethod().Name & vbCrLf)
 tmpString.Append(" - LINE:" & frame.GetFileLineNumber() & vbCrLf)
 tmpString.Append(" - COLUMN:" & frame.GetFileColumnNumber() & vbCrLf)
 Next
 End If
 If _Except IsNot Nothing Then
 tmpString.Append("-------------------------------------------------" & vbCrLf)
 tmpString.Append("SOURCE:" & vbCrLf)
 tmpString.Append(_Except.Source & vbCrLf)
 tmpString.Append("-------------------------------------------------" & vbCrLf)
 tmpString.Append("MESSAGE:" & vbCrLf)
 tmpString.Append(_Except.Message & vbCrLf)
 tmpString.Append("-------------------------------------------------" & vbCrLf)
 tmpString.Append("DATA:" & vbCrLf)
 tmpString.Append(_Except.Data.ToString() & vbCrLf)
 End If
 tmpString.Append("-------------------------------------------------" & vbCrLf)
 tmpString.Append("NOTES:" & vbCrLf)
 tmpString.Append(_Description & vbCrLf)
 tmpString.Append("-------------------------------------------------" & vbCrLf)
 _F.Write(tmpString.ToString())
 _F.Close()
 End Using
 End Sub

End Class

Common.vb

Public Class Common

 'The applications path
 Public Shared Function GetPath() As String
 Return System.AppDomain.CurrentDomain.BaseDirectory()
 End Function

 'Check to see if a value is Null, if so, set it to equal a default value
 Public Shared Function IsNull(Of T)(ByVal Value As T, ByVal _Default As T) As T
 If Not (IsDBNull(Value)) OrElse Value IsNot Nothing OrElse Not (Value.ToString.Length > 0) Then
 Return DirectCast(Value, T)
 Else
 Return DirectCast(_Default, T)
 End If
 End Function

End Class

CustomCache.vb

Imports System.Runtime.Caching

''' <summary>
''' Our Provider
''' </summary>
''' <remarks></remarks>
Public Interface ICacheProvider
 Function GetItem(Of T)(ByVal key As String) As T
 Sub SetItem(ByVal data As Object, ByVal key As String)
 Sub Remove(ByVal key As String)
 Sub Clear()
End Interface

''' <summary>
''' Our Custom Caching Object
''' </summary>
''' <remarks></remarks>
Public Class CustomCache
 Implements ICacheProvider

 ''' <summary>
 ''' The Cache Object
 ''' </summary>
 ''' <value></value>
 ''' <returns></returns>
 ''' <remarks></remarks>
 Private ReadOnly Property Cache() As ObjectCache
 Get
 Return MemoryCache.Default
 End Get
 End Property

 ''' <summary>
 ''' Set the cache Item
 ''' </summary>
 ''' <param name="key"></param>
 ''' <param name="data"></param>
 ''' <remarks></remarks>
 Public Sub SetCacheItem(ByVal data As Object, ByVal key As String) Implements ICacheProvider.SetItem
 Dim policy As New CacheItemPolicy()
 policy.AbsoluteExpiration = DateTime.Now.AddHours(24)
 Cache.Add(New CacheItem(key, data), policy)
 End Sub

 ''' <summary>
 ''' Get the Cache Item
 ''' </summary>
 ''' <typeparam name="T"></typeparam>
 ''' <param name="key"></param>
 ''' <returns></returns>
 ''' <remarks></remarks>
 Public Function GetCacheItem(Of T)(ByVal key As String) As T Implements ICacheProvider.GetItem
 Return DirectCast(Cache(key), T)
 End Function

 ''' <summary>
 ''' Remove the Item from Cache
 ''' </summary>
 ''' <param name="key"></param>
 ''' <remarks></remarks>
 Public Sub RemoveItem(ByVal key As String) Implements ICacheProvider.Remove
 Cache.Remove(key)
 End Sub

 ''' <summary>
 ''' Remove All items from Cache
 ''' </summary>
 ''' <remarks></remarks>
 Public Sub ClearCache() Implements ICacheProvider.Clear
 For Each item In Cache
 Cache.Remove(item.Key)
 Next
 End Sub

End Class

Settings.vb

Public Class Settings

 Private Shared Cache As New CustomCache

 'Grab our settings file
 Private Shared ReadOnly Property SettingDoc As XDocument
 Get
 Dim _C As XDocument = Cache.GetCacheItem(Of XDocument)("Settings")
 If _C IsNot Nothing Then
 Return _C
 Else
 Return XDocument.Load(Common.GetPath() & "Settings.xml")
 End If
 End Get
 End Property

 'Get and set all our settings
 Public Shared Function GetSettings() As List(Of Typing.Settings.Settings)
 Dim _Qry As New List(Of Typing.Settings.Settings)
 _Qry = (From n In SettingDoc...<IIS>.AsParallel()
 Select New Typing.Settings.Settings() With {
 .IisVersion = Common.IsNull(Of Integer)(n.@version, 0),
 .PrimeAll = Common.IsNull(Of Boolean)(n.@allApplications, True),
 .Sites = Common.IsNull(Of List(Of Typing.Settings.Sites))((From s In n.<Site>.AsParallel()
 Select New Typing.Settings.Sites() With {
 .Url = s.@url,
 .Page = s.@page
 }).ToList(), Nothing)
 }).ToList()
 If _Qry IsNot Nothing Then
 Return _Qry
 Else
 Return Nothing
 End If
 _Qry.Clear()
 End Function

End Class

Typing.vb

'Strongly Type all our values
Public Class Typing

 Partial Public Class Settings

 Partial Public Class Settings
 Public Property IisVersion As Integer
 Public Property PrimeAll As Boolean
 Public Property Sites As List(Of Sites)
 End Class

 Partial Public Class Sites
 Public Property Url As String
 Public Property Page As String
 End Class

 End Class

 Partial Public Class MetaBase
 Public Property Protocol As String
 Public Property Binding As String
 End Class

End Class

WarmUpService.vb

Imports System.Threading.Tasks
Imports System.Security.Principal

Module WarmUpService

 'Check and make sure we have Admin Privelages
 Private ReadOnly Property HasAdminPrivelages()
 Get
 Dim _Id = WindowsIdentity.GetCurrent()
 Dim _Prin = New WindowsPrincipal(_Id)
 Return _Prin.IsInRole(WindowsBuiltInRole.Administrator)
 End Get
 End Property

 'Fire It Up!
 Public Sub Main()
 If HasAdminPrivelages() Then
 AuditManager.Write(AuditManager.AuditType.General, "Fireing Up...")
 DoTheWarmUp()
 AuditManager.Write(AuditManager.AuditType.General, "All Set...")
 Else
 MsgBox("You need to be an administrator in order to run this.")
 End If
 End Sub

 Private Sub DoTheWarmUp()
 Try
 Dim _Set As List(Of Typing.Settings.Settings) = Settings.GetSettings()
 If _Set IsNot Nothing Then
 If _Set(0).PrimeAll Then
 Select Case _Set(0).IisVersion
 Case 6 ' IIS 6
 Dim _PT As New Iis6Primer()
 _PT.PrimeThem()
 Case 7 ' IIS 7 & IIS 7.5
 Dim _PT As New Iis7Primer()
 _PT.PrimeThem()
 Case Else
 AuditManager.Write(AuditManager.AuditType.Exception, "There was an issue! Unsupported IIS version.", "DoTheWarmUp")
 End Select
 Else
 Dim _Sites As List(Of Typing.Settings.Sites) = _Set.Item(0).Sites
 If _Sites IsNot Nothing Then
 Parallel.ForEach(_Sites, Sub(Item)
 Primer.GrabEm(Item.Url & Item.Page)
 End Sub)
 _Sites.Clear()
 End If
 _Set.Clear()
 End If
 Else
 AuditManager.Write(AuditManager.AuditType.Exception, "There was an issue! There are no settings.", "DoTheWarmUp")
 End If
 Catch ex As Exception
 AuditManager.Write(AuditManager.AuditType.Exception, "There was an issue!", "DoTheWarmUp", ex)
 End Try
 End Sub

End Module

Primer.vb

Imports System.Net
Imports System.Reflection

Public Class Primer

 Public Shared Sub GrabEm(ByVal _SitePath As String)
 Try
 SetAllowUnsafeHeaderParsing20()
 Using _WC As New WebClient()
 _WC.Headers.Add("user-agent", "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13")
 _WC.DownloadData(_SitePath)
 End Using
 AuditManager.Write(AuditManager.AuditType.General, "Site: " & _SitePath & " Is Now Primed!")
 Catch ex As Exception
 AuditManager.Write(AuditManager.AuditType.Exception, "Issue with the site: " & _SitePath & ".", "GrabEm", ex)
 End Try
 End Sub

 Private Shared Sub SetAllowUnsafeHeaderParsing20()
 Dim a As New System.Net.Configuration.SettingsSection
 Dim aNetAssembly As System.Reflection.Assembly = Assembly.GetAssembly(a.GetType)
 Dim aSettingsType As Type = aNetAssembly.GetType("System.Net.Configuration.SettingsSectionInternal")
 Dim args As Object() = Nothing
 Dim anInstance As Object = aSettingsType.InvokeMember("Section", BindingFlags.Static Or BindingFlags.GetProperty Or BindingFlags.NonPublic, Nothing, Nothing, args)
 Dim aUseUnsafeHeaderParsing As FieldInfo = aSettingsType.GetField("useUnsafeHeaderParsing", BindingFlags.NonPublic Or BindingFlags.Instance)
 aUseUnsafeHeaderParsing.SetValue(anInstance, True)
 End Sub

End Class

Iis6Primer.vb

Imports <xmlns="urn:microsoft-catalog:XML_Metabase_V64_0">
Imports System.Threading.Tasks

Public Class Iis6Primer

 Private _Xml As XDocument
 Dim _Qry As New List(Of Typing.MetaBase)

 Public Sub New()
 Dim _MetaBasePath As String = Environment.GetFolderPath(Environment.SpecialFolder.System) & "inetsrv"
 _MetaBasePath += "metabase.xml"
 _Xml = XDocument.Load(_MetaBasePath, LoadOptions.PreserveWhitespace)
 _Qry = (From n In _Xml...<IIsWebServer>
 Where (n.@ServerBindings IsNot Nothing)
 Select New Typing.MetaBase() With {
 .Binding = Common.IsNull(Of String)(n.@ServerBindings, String.Empty)
 }).ToList()
 End Sub

 Public Sub PrimeThem()
 Dim _Binding, _Url, _T
 Parallel.ForEach(_Qry, Sub(Item)
 _Binding = Item.Binding
 If _Binding.Contains(" ") Then
 _Binding = _Binding.Replace(" ", "|")
 _T = _Binding.Split("|")
 For Each i In _T
 _Url = i.Split(":")
 If _Url(1).Contains("80") Then
 Primer.GrabEm("http://" & _Url(_Url.GetUpperBound(0)))
 End If
 Next
 Else
 _Url = _Binding.Split(":")
 If _Url(1).Contains("80") Then
 Primer.GrabEm("http://" & _Url(_Url.GetUpperBound(0)))
 End If
 End If
 End Sub)
 _Qry.Clear()
 End Sub

End Class

Iis7Primer.vb

Imports System.Threading.Tasks

Public Class Iis7Primer

 Private _Xml As XDocument
 Dim _Qry As New List(Of Typing.MetaBase)

 Public Sub New()
 Dim _MetaBasePath As String = Environment.GetFolderPath(Environment.SpecialFolder.System) & "inetsrv"
 _MetaBasePath += "configapplicationHost.config"
 _Xml = XDocument.Load(_MetaBasePath, LoadOptions.PreserveWhitespace)
 _Qry = (From n In _Xml...<binding>.AsParallel()
 Select New Typing.MetaBase() With {
 .Binding = Common.IsNull(Of String)(n.@bindingInformation, String.Empty),
 .Protocol = Common.IsNull(Of String)(n.@protocol, String.Empty)
 }).ToList()
 End Sub

 Public Sub PrimeThem()
 Dim _Prot, _Binding, _Url
 Parallel.ForEach(_Qry, Sub(i)
 _Prot = i.Protocol
 If _Prot = "http" Then
 _Binding = i.Binding
 _Url = _Binding.Split(":")
 Primer.GrabEm("http://" & _Url(_Url.GetUpperBound(0)))
 End If
 End Sub)
 _Qry.Clear()
 End Sub

End Class

 

Our Privacy Policy

Last Updated: June 18th, 2025

Introduction

Western Mass Hosting (“we,” “our,” or “us”) respects the privacy of all individuals and organizations that interact with our services. This Privacy Policy establishes our practices regarding the collection, use, disclosure, and protection of personal information for visitors to our website and clients utilizing our managed hosting and WordPress services. By accessing our website or engaging our services, you acknowledge that you have read and understood this policy in its entirety.

Scope and Applicability

This Privacy Policy governs our handling of information collected through our corporate website and in the course of providing managed hosting, WordPress maintenance, and development services. In accordance with global privacy regulations, we serve as a Data Controller for information related to our business operations and client relationships. When processing data on behalf of our clients through hosted services, we act as a Data Processor under applicable data protection laws.

Information We Collect

We collect various categories of information necessary to provide and improve our services. This includes personal contact and payment details provided during account registration, technical information such as IP addresses and device characteristics for security purposes, and records of communications through support channels. For clients utilizing our hosting services, we may process end-user data stored within client websites, though we do not control or monitor the collection practices of such data.

Purpose and Legal Basis for Processing

We process personal information only when we have proper justification under applicable laws. The primary legal bases for our processing activities include the necessity to fulfill contractual obligations to our clients, our legitimate business interests in maintaining and improving our services, and in limited cases, explicit consent for specific marketing communications. We maintain detailed records of processing activities to demonstrate compliance with legal requirements.

Use of Collected Information

The information we collect serves multiple business purposes. Primarily, we use this data to deliver and maintain reliable hosting services, including server provisioning, performance monitoring, and technical support. We also utilize information for business operations such as billing, customer relationship management, and service improvement initiatives. Security represents another critical use case, where we analyze data to detect and prevent fraudulent activity or unauthorized access to our systems.

Data Sharing and Third-Party Disclosures

We engage with carefully selected third-party service providers to support our operations, including cloud infrastructure providers, payment processors, and customer support platforms. These relationships are governed by strict contractual agreements that mandate appropriate data protection measures. We may disclose information when legally required to comply with court orders, government requests, or to protect our legal rights and the security of our services.

International Data Transfers

As a global service provider, we may transfer and process data in various locations worldwide. When transferring personal data originating from the European Economic Area or other regulated jurisdictions, we implement appropriate safeguards such as Standard Contractual Clauses and rely on adequacy decisions where applicable. Our subprocessors, including AWS Lightsail, maintain robust compliance certifications to ensure the protection of transferred data.

Data Retention Practices

We retain personal information only for as long as necessary to fulfill the purposes outlined in this policy. Client account information is typically maintained for five years following service termination to comply with legal and financial reporting obligations. Backup data associated with hosting services is automatically purged after thirty days, as specified in our Terms of Service. For data processed on behalf of clients, retention periods are determined by the respective client’s policies and instructions.

Security Measures

We implement comprehensive technical and organizational security measures to protect personal information against unauthorized access, alteration, or destruction. Our security program includes network encryption protocols, regular vulnerability assessments, strict access controls, and employee training on data protection best practices. We maintain incident response procedures to address potential security breaches and will notify affected parties where required by law.

Individual Rights

Individuals whose personal data we process may exercise certain rights under applicable privacy laws. These rights may include requesting access to their information, seeking correction of inaccurate data, requesting deletion under specific circumstances, and objecting to particular processing activities. We have established procedures to handle such requests in accordance with legal requirements, typically responding within thirty days of receipt. Requests should be submitted to our designated Data Protection Officer through the contact information provided in this policy.

Cookies and Tracking Technologies

Our website employs various technologies to enhance user experience and analyze site performance. Essential cookies are used for basic functionality and security purposes, while analytics cookies help us understand how visitors interact with our site. Marketing cookies are only deployed with explicit user consent. Visitors can manage cookie preferences through their browser settings or our cookie consent tool.

Policy Updates and Notifications

We periodically review and update this Privacy Policy to reflect changes in our practices or legal obligations. Material changes will be communicated to affected clients through email notifications at least thirty days prior to implementation. Continued use of our services following such notifications constitutes acceptance of the revised policy.

Contact Information

For questions or concerns regarding this Privacy Policy or our privacy practices, please contact our Data Protection Officer at info@westernmasshosting.com or by mail at:

Western Mass Hosting
22 Orlando. St.,
Feeding Hills, MA 01030.

We take all privacy-related inquiries seriously and will respond promptly to legitimate requests. For clients with specific data processing agreements, please reference your contract for any additional terms that may apply to our handling of your data.