Remove query strings from static resources - asp.net

My website is running on ASP.NET platform and recently i test my website on pingdom and i found the below error.
Resources with a "?" in the URL are not cached by some proxy caching
servers. Remove the query string and encode the parameters into the
URL for the following resources:
https://projectsdeal.co.uk/ScriptResource.axd?d ...
63Nawdr4rAt1lvT7c_zyBEkV9INg0&t=ffffffffe3663df5
https://projectsdeal.co.uk/ScriptResource.axd?d ...
JGTlZFM0WRegQM9wdaZV3fQWMKwg2&t=ffffffffe3663df5

Simple leave it as it is (its not an error !) - you can not remove this query string from resource because this is the id on how to load that resource from asp.net
The message that you get is actually talk for a proxy caching servers - what is a proxy caching server ? a middle computer that cache pages of your site, not the actually client computer - that can hold in cache that page and not bring slower your site in general.
So your client can hold that resource on cache if you set them correctly, and from what I see asp.net take care correctly and you resource are cached just fine - see this screen shot.
Now if you wish to add even more aggressive cache you can use the global.asax and do something like
protected void Application_BeginRequest(Object sender, EventArgs e)
{
string cTheFile = HttpContext.Current.Request.Path;
if (cTheFile.EndsWith("WebResource.axd", StringComparison.InvariantCultureIgnoreCase))
{
JustSetSomeCache(app);
}
}
private static void JustSetSomeCache(HttpApplication app)
{
app.Response.Cache.AppendCacheExtension("post-check=900, pre-check=3600");
app.Response.Cache.SetExpires(DateTime.UtcNow.AddHours(32));
app.Response.Cache.SetMaxAge(new TimeSpan(32, 0, 0));
app.Response.Cache.SetCacheability(HttpCacheability.Public);
app.Response.AppendHeader("Vary", "Accept-Encoding");
}
What is the different ? The second cache is not check the server at all for file change as the asp.net do, you can gain one webserver call.

Related

Setting cache control to private for ALL items

I'm about to include this into our build:
void Application_PreSendRequestHeaders(Object sender, EventArgs e)
{
// Cache only on the server and the client (if SSL is disabled)
// This doesn't determine what should be cached, only where
// cacheable items are allowed to be stored.
Response.Cache.SetCacheability(HttpCacheability.Private);
}
First off, are my comments in the code correct?
Second, is this an OK action to take? Is it fine to set a cache-control header for all requests? Most my reading, people set cache headers per directory.
I assume this should probably be done in IIS, but we are running in azure so its a little trickier making IIS changes (have to automate it).

How can I generate a 404 response from an IHttpModule configured in the global web.config?

I'm trying to generate a 404 response for certain requests on all sites on a server based on the HttpRequest.UserAgent.
I've configured an IHttpModule in the server's global web.config containing the code below:
private void Application_BeginRequest(Object source, EventArgs e)
{
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
if (isBot(context.Request.UserAgent))
{
System.Diagnostics.EventLog.WriteEntry(
"Application",
"\nBotRequestChecker -- request 404d\n" + "Url: " +
context.Request.Url + "\nUserAgent: " + context.Request.UserAgent,
EventLogEntryType.Information);
context.Response.StatusCode = 404;
context.Response.StatusDescription = "Not Found";
context.ApplicationInstance.CompleteRequest();
}
}
Setting the User-Agent in a browser and visiting a page results in an entry in the event log, but the page is also returned, without a 404 status.
Any thoughts on what I'm missing?
Update:
The IHttpModule does seem to work if I add it to a single site (in the site's web.config), just not for all sites.
Update 2:
The IHttpModule only works on a single site on an IIS7 server, not on IIS6.
Make sure that you've subscribed to the the BeginRequest event in your module's IHttpModule.Init() implementation. The events don't get auto-wired in IHttpModule implementations the way same they do in Global.asax.
I also missed the bit about the global web.config at first.
On a 64-bit server, you'll need to make sure you make the changes in both the 32- and 64-bit configurations (depending on the bitness that your sites are running in) in all ASP.NET versions you need to support:
%windows%\Microsoft.NET\Framework\v2.0.50727\CONFIG\web.config
%windows%\Microsoft.NET\Framework64\v2.0.50727\CONFIG\web.config
%windows%\Microsoft.NET\Framework\v4.0.30319\CONFIG\web.config
%windows%\Microsoft.NET\Framework64\v4.0.30319\CONFIG\web.config
If you're targeting both IIS6 and IIS7, you'll need to make sure the module is referenced in both the <system.web>/<httpModules> element for IIS6 and the <system.webServer>/<modules> element for IIS7.

Track each request to the website using HttpModule

I want to save each request to the website. In general I want to include the following information:
User IP, The web site url, user-if-exist, date-time.
Response time, response success-failed status.
Is it reasonable to collect the 1 and 2 in the same action? (like same HttpModule)?
Do you know about any existing structure that I can follow that track every request/response-status to the website?
The data need to be logged to sql server.
Look in your web server logs.
How about IIS logs? they already have all the data items you listed so far
In BeginRequest Method you need to write the following code.
protected void Application_BeginRequest(object sender, EventArgs e)
{
//String s = HttpContext.Current.Request.Path;
//HttpContext.Current.RewritePath("Login.aspx");
String referrer = HttpContext.Current.Request.UrlReferrer;
String sourceIP = HttpContext.Current.Request.UserHostAddress;
String browser = HttpContext.Current.Request.UserAgent;
}

Cookies. Case Sensitive Paths. How to rewrite URLs

We have a sizable collection of applications (>50) all running under a single domain but with different virtual directories. Pretty standard stuff. We store cookies using paths to segregate cookies by application. Paths are set the the Application Path.
This seems to work fine as long as the casing of the URL is the same as the application path. If it is different, the browser fails to retrieve the collection of cookies.
Is there any very basic way (ISAPI? Global ASAX?) to rewrite all URLs so that they match the Application Path? Ideally this is something that can be configured at the application level.
Currently stuck on IIS6.
thanks
Wondering if this is a possible (even a good) solution:
In Global.asax:
void Application_BeginRequest(object sender, EventArgs e)
{
string url = HttpContext.Current.Request.Url.PathAndQuery;
string application = HttpContext.Current.Request.ApplicationPath;
if (!url.StartsWith(application))
{
HttpContext.Current.Response.Redirect(application + url.Substring(application.Length));
}
}
Use relative URLs in conjunction with a BASE tag might work?

How to have http module on fire events only for specific page types [duplicate]

This question already has answers here:
Exclude certain pages from using a HTTPModule
(3 answers)
Closed 7 years ago.
I have an http module on a sharepoint site and this module instantiates a custom class and add it to the session and does other initial things for my site.
However, I'm noticing that the http module is being called for all request types (.aspx, .js, .png, .jpg).
Is there any way to have an http module only be called for .net specific page types?
In IIS you will set up the handler to be associated with your specific extension so the handler will only be applied to that extension. JavaScript files should not be processed.
I would also have a look at this article is you are looking at integrating your module/handler with SharePoint in any way.
While I do like the ease of deployment of this type of http handler (and the fact that you do not have to deploy a web.config entry for the handler), in cases where you may not want to use the _layouts directory OR you want to have a custom file extension, here is an alternative method that works as well (although it does take one manual configuration step in IIS so it may not be suitable for a "No Touch Deployment")
1) Create your http handler as you normally would for an asp.net application. You can add references to the SharePoint DLLs and interact with the object model since you are in the App Pool.
2) Add and entry into your web.config to register your handler and define the extension you are going to use. IE:
3) Define your custom extension in IIS through the IIS > Web SIte Properties > Home Directory > Configuration > Mappings
In this case, we defined a .proxy extension that the handler will pick up. Our handler is a .NET assembly so we need to add the mapping to route .proxy requests to the .net isapi dll (C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll).. also, make sure you UNcheck the "
From comments on http://msdn.microsoft.com/en-us/library/bb457204.aspx
I've done a bit more research and it seems there is no way to do what I'm intending.
I will have to check the request type and cancel from there.
Thanks everyone for their answers.
D
You can do this in a very lightweight manner using a HttpModule (before making any calls to the expensive SharePoint object model) by checking the extension in the content of the last Uri.Segments
void context_BeginRequest(object sender, EventArgs e)
{
HttpApplication app = (HttpApplication)sender;
Uri uri = app.Request.Url;
string lastSegment = uri.Segments[uri.Segments.Length-1];
.. check your extension here an do nothing if it doesn't match.
..
}
We use this in our 'TinyURL' implementation for SharePoint to ensure the performance impact for regular URLs is almost 0.
Here is some simple example how to filter requests by extension... the example below exclude from the processing files with the specific extensions.
public class AuthenticationModule : IHttpModule
{
private static readonly List<string> extensionsToSkip = AuthenticationConfig.ExtensionsToSkip.Split('|').ToList();
// In the Init function, register for HttpApplication
// events by adding your handlers.
public void Init(HttpApplication application)
{
application.BeginRequest += new EventHandler(this.Application_BeginRequest);
application.EndRequest += new EventHandler(this.Application_EndRequest);
}
private void Application_BeginRequest(Object source, EventArgs e)
{
// we don't have to process all requests...
if (extensionsToSkip.Contains(Path.GetExtension(HttpContext.Current.Request.Url.LocalPath)))
return;
Trace.WriteLine("Application_BeginRequest: " + HttpContext.Current.Request.Url.AbsoluteUri);
}
private void Application_EndRequest(Object source, EventArgs e)
{
// we don't have to process all requests...
if (extensionsToSkip.Contains(Path.GetExtension(HttpContext.Current.Request.Url.LocalPath)))
return;
Trace.WriteLine("Application_BeginRequest: " + HttpContext.Current.Request.Url.AbsoluteUri);
}
}
In config file specify what extensions should be excluded and initiate the list of extensions in the module.

Resources