IIS Image Cache Directives Cause 500.19 Error - caching

I wanted to add cache header to browser on IIS. I found this:
IIS 7.5 and images not being cached
<staticContent>
<clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="1.00:00:00" />
</staticContent>
<httpProtocol>
<customHeaders>
<add name="Cache-Control" value="public" />
</customHeaders>
</httpProtocol>
This solves cache problem that Google warned about on PageSpeed test:
https://developers.google.com/speed/pagespeed/insights/
But also this causes 500.19 error, and it says that: "The configuration section 'staticContent' cannot be read because it is missing a section declaration"
My web.config file was look like that:
<?xml version="1.0"?>
<configuration>
<appSettings/>
<connectionStrings/>
<system.web>
<compilation debug="false"></compilation>
<authentication mode="Windows"/>
</system.web>
<system.webServer>
<httpErrors errorMode="Custom">
<remove statusCode="404" subStatusCode="-1"/>
<error statusCode="404" prefixLanguageFilePath="" path="/rewrite.asp" responseMode="ExecuteURL"/>
</httpErrors>
</system.webServer>
</configuration>
How to prevent this error?

Related

Why does the name of my Publish Profile affect the transformation of my Web.config?

I think I have encountered a strange interaction where the name of my Publish Profile is affecting the contents of the published Web.config.
For context, I have 2 solution configurations; Release & Staging, and a folder Publish Profile called 'Release.pubxml'. Below are stripped down versions of the three web configs involved.
Web.config:
<configuration>
<connectionStrings>
<add name="DBEntities" connectionString="{Web.config connection string}" />
</connectionStrings>
<appSettings>
<add key="WEBSITEURL" value="http://website.com" />
<add key="ADMINURL" value="http://admin.website.com" />
</appSettings>
</configuration>
Web.Release.config:
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<connectionStrings>
<add xdt:Transform="SetAttributes" xdt:Locator="Match(name)" name="DBEntities" connectionString="{Web.Release.config connection string}" />
</connectionStrings>
<system.web>
<compilation xdt:Transform="RemoveAttributes(debug)" />
</system.web>
<system.webServer>
<rewrite xdt:Transform="Insert">
<rules>
<rule name="HTTPtoHTTPSredirect" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="off" ignoreCase="true" />
</conditions>
<action type="Redirect" redirectType="Found" url="https://{HTTP_HOST}/{R:1}" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
Web.Staging.config:
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<connectionStrings>
<add xdt:Transform="SetAttributes" xdt:Locator="Match(name)" name="DBEntities" connectionString="{Web.Staging.config connection string}" />
</connectionStrings>
<appSettings>
<add xdt:Transform="SetAttributes" xdt:Locator="Match(key)" key="WEBSITEURL" value="http://stagingwebsite.com" />
<add xdt:Transform="SetAttributes" xdt:Locator="Match(key)" key="ADMINURL" value="http://admin.stagingwebsite.com />
</appSettings>
<system.web>
<compilation xdt:Transform="RemoveAttributes(debug)" />
</system.web>
</configuration>
I had recently adjusted our Staging web config, and tried publishing under the Release.pubxml profile, but with the Configuration set to Staging, rather than Release. The result I expected was the original Web.config file, with all Web.Staging.config xdt transformations applied.
What ended up happening was a Frankenstein mix of the Web.Staging.config and the Web.Release.config transforming into Web.config:
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<connectionStrings>
<add xdt:Transform="SetAttributes" xdt:Locator="Match(name)" name="DBEntities" connectionString="{Web.Release.config connection string}" />
</connectionStrings>
<appSettings>
<add xdt:Transform="SetAttributes" xdt:Locator="Match(key)" key="WEBSITEURL" value="http://stagingwebsite.com" />
<add xdt:Transform="SetAttributes" xdt:Locator="Match(key)" key="ADMINURL" value="http://admin.stagingwebsite.com />
</appSettings>
<system.web>
<compilation xdt:Transform="RemoveAttributes(debug)" />
</system.web>
<system.webServer>
<rewrite xdt:Transform="Insert">
<rules>
<rule name="HTTPtoHTTPSredirect" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="off" ignoreCase="true" />
</conditions>
<action type="Redirect" redirectType="Found" url="https://{HTTP_HOST}/{R:1}" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
You'll notice it has the Release connection string, the Staging WEBSITEURL/ADMINURL, and the Release HTTP rules.
I could not find any trace of the Release configuration anywhere in my settings. I had checked the configuration manager and all projects were set to build as Staging & I had cleaned/rebuilt multiple times. I had also tested it with both VS 2022 & VS 2019, and with multiple, separate solutions; each yielded the same result.
What ended up "fixing" it, was changing the name from 'Release.pubxml' to anything but Release.pubxml or Staging.pubxml. Although you wouldn't usually want to name your publish profile anything outside of what its configured to, why does the name of the publish profile override the configuration build you have set? With some further investigation, it seems that it might be transforming the chosen configured build first (Staging), then it transforms any config with the same name as your publish profile (Release).
This interaction seems extremely dangerous to me, so would anybody be able to explain to me why Visual Studio would do this (or if I have maybe encountered a bug)?

web.config gets modified when published

I have an asp.net web application and everything is working correctly. Now I wanted to upload another app on a subdomain of my server and to run both I have to change hostingModel from "inprocess" to "outofprocess".
So I modified my web.config to
?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\AmsWebApp.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="outofprocess" />
</system.webServer>
</location>
</configuration>
<!--ProjectGuid: XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX-->
I found out that when I publish my application the original web.config file from the bin\Release\net6.0 folder gets deleted and a new and different one is appearing in the obj\Release\net6.0\PubTmp\Out folder looking like that
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\AmsWebApp.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="inprocess" />
</system.webServer>
</location>
</configuration>
Why is this happening and what do I have to do to avoid this?
Many thanks
I got some feedback from my server host telling me to update the .csproj file with following addon
<PropertyGroup>
<AspNetCoreHostingModel>OutOfProcess</AspNetCoreHostingModel>
</PropertyGroup>
and now all is working as supposed.

How to add no-cache header for IIS when request is localhost/site root

I have a website hosted in IIS 10
The .js and .css files are versioned using this pattern ?v=a.b.c (where a.b.c is changed with a new number every time is required) in order to invalidate the cache browser.
This is how the site starts :
user enters www.sitename.com (or "localhost" in my case)
the index.html file is loaded . This files loads a main.js?v=a.b.c file that loads/configures "require.js" . Every other file from this point forward is handled by require (also management of the versioning for the html/css/js)
The problem that I am facing is the following :
How to invalidate the cache browser for index.html ?
I tried to send a no-cache header for the index.html with the following web.config file in IIS that works if I write localhost/index.html in the browser URL...but it does not work if I write only localhost (in this case the old index.html from the cache is loaded)
<configuration>
<system.web>
<urlMappings enabled="true">
<add url="~/" mappedUrl="~/index.html" />
</urlMappings>
</system.web>
<location path="index.html">
<system.webServer>
<staticContent>
<clientCache cacheControlMode="DisableCache" />
</staticContent>
</system.webServer>
</location>
</configuration>
Can I receive some help ?
you can set the no-cache header by using iis URL rewrite rule:
<system.webServer>
<rewrite>
<outboundRules>
<rule name="RewriteCache-Control" preCondition="old url with 301" stopProcessing="true">
<match serverVariable="RESPONSE_Cache-Control" pattern="(.*)" />
<conditions>
</conditions>
<action type="Rewrite" value="no-cache" />
</rule>
<preConditions>
<preCondition name="old url with 301">
<add input="{URL}" pattern="index.html|^$" />
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>>
</preConditions>
</outboundRules>
</rewrite>
<tracing>
<traceFailedRequests>
<add path="*">
<traceAreas>
<add provider="WWW Server" areas="Rewrite" verbosity="Verbose" />
</traceAreas>
<failureDefinitions statusCodes="100-900" />
</add>
</traceFailedRequests>
</tracing>
</system.webServer>
another way:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<location path="index.html">
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Cache-Control" value="no-cache" />
</customHeaders>
</httpProtocol>
</system.webServer>
</location>
</configuration>

WebMatrix WebSecurity: Keeps logging out user randomly

I'm using WebMatrix and applied a login system on my website. I'm running into a strange problem. My website keeps randomly logging out the user. Happens unexpectedly. Not only on my code, but happens in the WebMatrix sample projects as well.
My Web.Config file is:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appSettings>
<add key="loginUrl" value="~/login" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.0" />
<sessionState timeout="20" />
<!-- This is for links with incorrect file extensions -->
<!-- This only handles .NET based errors, not classic web like HTML or ASP based extensions -->
<customErrors mode="Off">
<error statusCode="403" redirect="/Shared/Error404.cshtml" />
<error statusCode="404" redirect="/Shared/Error404.cshtml" />
<error statusCode="500" redirect="/Shared/Error500.cshtml" />
</customErrors>
</system.web>
<system.webServer>
<!-- This handles all other types of link errors -->
<httpErrors errorMode="Custom">
<remove statusCode="404" subStatusCode="-1" />
<error statusCode="404" path="/Shared/Error404.cshtml" responseMode="ExecuteURL" />
</httpErrors>
</system.webServer>
<system.data>
<DbProviderFactories>
<remove invariant="System.Data.SqlServerCe.4.0" />
<add invariant="System.Data.SqlServerCe.4.0" name="Microsoft® SQL Server® Compact 4.0" description=".NET Framework Data Provider for Microsoft SQL Server Compact" type="System.Data.SqlServerCe.SqlCeProviderFactory, System.Data.SqlServerCe, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" />
</DbProviderFactories>
</system.data>
</configuration>
I've defined the session timeout as 20 minutes. I use the same plain way of logging in the user.
if (WebSecurity.Login(email, password, rememberMe)) {
Context.RedirectLocal(returnUrl);
return;
} else {
ModelState.AddFormError("The user name or password provided is incorrect.");
}
And this is how I check whether my user is signed-in or not in secured pages:
if (!WebSecurity.IsAuthenticated) {
Response.Redirect("~/login", true);
}
I've searched a bit on google, there are few people who have also been complaining that WebMatrix WebSecurity randomly logs out user. Sometimes when an activity is performed, like form submission or sometimes a simple url click.
Any ideas or suggestions? Someone even suggested me to dump Razor and move to MVC, it doesn't have this problem. I'm not sure whether thats true.
UPDATE
I have the following code in top of all my secured pages (which require user being logged in). Does anyone think this would be causing the issue?
// Ensure this page is not cached
Response.Expires = -1;
Response.Cache.SetNoServerCaching();
Response.Cache.SetAllowResponseInBrowserHistory(false);
Response.CacheControl = "no-cache";
Response.Cache.SetNoStore();
Thanks
-Faraz Azhar
I will have to check further, i remember some weirdo setting to increase the cookie stay-logged-in time. Here's what's in my config and i don't see anything else that has a time:
<system.web>
<customErrors mode="RemoteOnly" defaultRedirect="~/error/"></customErrors>
<compilation debug="true" targetFramework="4.0" />
<authentication>
<forms timeout="10080" />
</authentication>

Only allow script access to a file iis7.5

I have a file (called 'log.html') on my iis7.5 server that I would like my PHP installation to be able to access and write to, but I do not want anybody to access the file directly, for example typing in 'http://computername/log.html' (I am on a LAN).
How can I prevent users from accessing it but allow php to see it?
When using the web.config file suggested below, I get this error:
You can use IIS URL Rewrite and create a Request Blocking Rule to prevent access over HTTP:
For example:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="BlockLogFile"
patternSyntax="Wildcard"
stopProcessing="true">
<match url="*" />
<conditions>
<add input="{URL}" pattern="/log.html" />
</conditions>
<action type="CustomResponse"
statusCode="403"
statusReason="Forbidden: Access is denied."
statusDescription="This is sekret!" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
I think that I may have answered my own question! I still need to test it a bit more, and perhaps if it does not work completely then someone could correct me:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="cache-control" value="no-store, no-cache, must-revalidate, max-age=0" />
</customHeaders>
</httpProtocol>
<staticContent>
<clientCache cacheControlMode="DisableCache" />
</staticContent>
<security>
<requestFiltering>
<denyUrlSequences>
<add sequence="log.html" />
</denyUrlSequences>
</requestFiltering>
</security>
</system.webServer>
</configuration>
The cache control bit prevents the browser from caching anything that it returned.
Hope this helps somebody else! I am still very new to this, so you might be able to get around this.

Resources