3

I have an HTTP Module that I installed on our server. What's weird is that it works but every once in awhile it's not being executed. I have logging and during the times that it doesn't work it doesn't reach the code that logs. I don't see anything in the IIS logs or the event viewer either.

    namespace RedirectModule
    {
        public class RedirectModule : System.Web.IHttpModule
        {
            private const string MobileUserAgent = "MobileUserAgentCacheKey";

            private const string 

STRING_TO_FIND = "info/lps";
        private const string STRING_TO_ADD = "/mobile";


        public void Dispose()
        {
            //clean-up code here.
        }

        public void Init(HttpApplication context)
        {          
            context.BeginRequest += context_BeginRequest;
        }
        private static object sync = new object();
        private void context_BeginRequest(object sender, EventArgs e)
        {

            try
            {


                HttpContext context = HttpContext.Current;


                string url = context.Request.Url.ToString().ToLower();

                if (!url.Contains(STRING_TO_FIND) || url.Contains(STRING_TO_FIND + STRING_TO_ADD))
                    return;
                Logger.Current.Log("Starting Redirect Phase");

                if (XmlToValues.IsMobile(context.Request.ServerVariables["HTTP_USER_AGENT"],
                                       GetCachedFile(context, "Settings.xml")))
                {
                    var mobileRedirect = GetRedirectUrl(url, STRING_TO_FIND, STRING_TO_ADD);
                    if (mobileRedirect != null)
                    {
                        Logger.Current.Log("Redirect to Mobile page");
                        context.Response.Redirect(mobileRedirect);

                    }
                }
                Logger.Current.Log("Web Page");
                Logger.Current.Log("End Begin Request");
            }
            catch (Exception ex)
            {
                if (ex is ThreadAbortException)
                    return;

                Logger.Current.LogError(ex);

            }
        }


        public static string GetRedirectUrl(string url, string strToFind, string strToAdd)
        {
            try
            {
                Logger.Current.Log("Get Redirect Url ");
                int idx = url.IndexOf(strToFind) + strToFind.Length;
                return url.Substring(0, idx) + strToAdd + url.Substring(idx);
            }
            catch (Exception ex)
            {

                Logger.Current.LogError(ex);


                return null;
            }
        }



        private XmlNodeList GetCachedFile(HttpContext context, string filePath)
        {
            try
            {
                Logger.Current.Log("GetCachedFile START");
                if (context.Cache[MobileUserAgent] == null)
                {
                    context.Cache[MobileUserAgent] = XmlToValues.GetMobileUserAgents(filePath);
                    Logger.Current.Log("Add Mobile File to Cache");
                }
                return (XmlNodeList)context.Cache[MobileUserAgent];
            }
            catch (Exception ex)
            {
                Logger.Current.LogError(ex);

                return null;
            }
        }

    }
}

and my Web.Config:

<?xml version="1.0" encoding="UTF-8"?>
<!--
  For more information on how to configure your ASP.NET application, please visit
  http://go.microsoft.com/fwlink/?LinkId=169433
  -->
<configuration>


  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
      <remove name="RedirectModule" />
      <add name="RedirectModule" type="RedirectModule.RedirectModule, RedirectModule" />


    </modules>
    <handlers>
      <remove name="Redirect" />
    </handlers>
    <validation validateIntegratedModeConfiguration="false"/>
  </system.webServer>
  <system.web>
    <httpModules>
      <add name="RedirectModule" type="RedirectModule.RedirectModule, RedirectModule" />
    </httpModules>
    <compilation debug="true">    
    </compilation>
  </system.web>
</configuration>

p.s. I took out the log4net in the web.config as it's cumbersome.

Here's the link to the project: http://www.sendspace.com/file/w42me5

This is the markup of the page being requested, it's in a file called index.htmnl:

<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<!-- no cache headers -->
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="no-cache">
<meta http-equiv="Expires" content="-1">
<meta http-equiv="Cache-Control" content="no-cache">
<!-- end no cache headers -->
</head>
<body>
MOBILE
</body>
</html>
Eitan
  • 1,434
  • 6
  • 21
  • 53
  • Have you logged the URL at the start of the BeginRequest handler to confirm that it is correct and you are not returning early because the URL does not contain the expected strings? – Chris Taylor Aug 05 '12 at 06:52
  • Yes I have logging in the Begin_Request and when it works it logs the request. When it doesn't it doesn't log the request. I've added try and catch around the logging so it shouldn't throw an error. There is nothing in the event log to indicate an error. I've added No Cache tags to the html page I'm trying to reach – Eitan Aug 05 '12 at 08:46
  • In the cases that your HttpModule BeginRequest event is not being hit, is BeginRequest in Global.asax being hit? Are you always requesting an ASPX? Can you share the mark-up for the page that is being requested? – Chris Taylor Aug 05 '12 at 12:29
  • I added the markup being requested at the bottom of the question. It's in a file called index.html in a mobile folder. – Eitan Aug 05 '12 at 14:22

2 Answers2

0

I had a similar prblem... Try to turn of caching in your webbrowser and try again. In order to turn off caching for this requests youll need to modify response header. Example on modifying caching option

CodeDemen
  • 1,841
  • 3
  • 17
  • 30
  • Thanks for the input! I thought the same thing, I've been working in Chrome's incognito mode and clearing the cache in Safari when I'm checking it on mobile. I added the headers but still every once in awhile it's not working. – Eitan Aug 01 '12 at 13:04
0

It sounds like you're probably hitting a cache somewhere between the browser and the server. There's a lot of potential places for the cache to be, here's some general steps to try and find it:

  • Browser - The browser does not have to request what it has cached. This question lists tools for different browsers to confirm what requests are being sent.
  • Client Computer - If a request is being sent from the browser, you may have a proxy (like Squid) returning cached data. You can use Fiddler to check if a HTTP request ever leaves the client computer.
  • Network Proxy - Same idea as the client computer, just the proxy is located on a server somewhere on your network. You would have to analyze outgoing HTTP traffic at the proxy server to determine if a request is being sent or not.
  • Web Server - Your redirect module can serve cached content instead of rendering it new. In this case, it should show up in your logs. Add a log call to the very beginning of your BeginRequest handler to confirm if the request actually makes it to your server.

To prevent caching, you can add add no-cache headers to the request (article here):

        private void Application_EndRequest(Object source, EventArgs e) 
        {
            HttpApplication application = (HttpApplication)source;
            HttpContext context = application.Context;
            context.Response.ExpiresAbsolute = DateTime.Now.AddDays( -100 );
            context.Response.AddHeader( “pragma”, “no-cache” );
            context.Response.AddHeader( “cache-control”, “private” );
            context.Response.CacheControl = “no-cache”;
        }

EDIT

Debugging what request get to the server

HTTP 200 in the response suggests that it's very likely you do not have a cache issue. To confirm every request is actually getting to the server, try adding a log to your Application_BeginRequest handler (in Global.asax) to log every request and compare it to the log generated by your context_BeginRequest in your HttpModule.

//In Global.asax
private void Application_BeginRequest(Object source, EventArgs e) {
    Logger.Current.Log("Request made to Application_BeginRequest")
}

//In your HttpModule
    private void context_BeginRequest(object sender, EventArgs e)
    {
        //Log before any of your other code
        Logger.Current.Log("Request made to context_BeginRequest")

        try
        {
              // your code
        }
        catch (Exception ex)
        {
            // log the exception first in case this is the problem
            Logger.Current.LogError(ex);

            if (ex is ThreadAbortException)
                return;

        }
    }

Interpreting the results

Check your log after a request that is not getting to your module.

  • If it shows nothing, the request never made it to your server. See above about caches
  • If your log end at Request made to Application_BeginRequest, your module is not being called.
  • If it ends at Request made to context_BeginRequest, there's an error in the module code before your logger which is causing a crash on some requests. This could be a null reference HttpContext.Current, or Request, or a problem with overflows, or any number of other things. This should be logged by your finally statement.
Community
  • 1
  • 1
just.another.programmer
  • 8,579
  • 8
  • 51
  • 90
  • I added the code you posted from the previous answer. I used my iPhone from a wireless connection to test the URL and it's not redirecting to the mobile (at first it does but after awhile it stops working). I added logging but it doesn't reach the log that is on the Begin_request. I also added the mobile redirect code to a global.asax fil;e just to be sure and it's still not even reaching the logging code in the Begin_request function. – Eitan Aug 05 '12 at 08:18
  • You can look at at this site: http://blogs.esri.com/esri/supportcenter/2011/12/06/configuring-fiddler-to-capture-web-traffic-from-an-iphone-ipad-device/ for instructions on using Fiddler with an iPhone. Confirm that a request is being generated by your iPhone. If it's not, than this is really more of a question of why an iPhone is not following cache directives. (You should also confirm that the original response you receive has the cache headers set properly). – just.another.programmer Aug 05 '12 at 08:25
  • The cache headers are there. What I'm doing is requesting a simple .html file. So fiddler won't show me that I'm calling the HTTP module. It DOES show me that I'm requesting the page. I can post the link to the project, it's: http://www.sendspace.com/file/w42me5 – Eitan Aug 05 '12 at 08:34
  • I also used Safari Developer tools and fiddler on my development computer, the requests get there. I hard coded thse http headers into the html page: – Eitan Aug 05 '12 at 08:41
  • What do you mean "the requests get there"? You see a request leaving your computer (via Developer tools and Fiddler) and it never arrives at your server? If so, do you have a proxy configured on your network which may be intercepting / caching the page? What are the response headers on these mystery requests? – just.another.programmer Aug 05 '12 at 20:41
  • I see the requests reaching the server i.e. I receive a 200 on the page but the HTTP Module isn't called, there isn't any logging. I would think that the HTTP Module doesn't work but it works for the first few requests constantly and then suddenly stops working and there isn't any logging when it doesn't work. I use log4Net and it logs when I hit the Begin_Request function. – Eitan Aug 06 '12 at 07:04
  • See my edits, lets see if we can track down exactly where how far the request is getting. – just.another.programmer Aug 06 '12 at 07:28
  • ok I put the logging in the global.asax and in the begin_request of the http handler. It logs for a few times but then it stops logging. When I opened up the event viewer it doesn't show any errors. When it stops logging it also stops redirecting. The system is on two servers with a load balancer, could that be the cause of the problem somehow? – Eitan Aug 06 '12 at 12:28
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/14952/discussion-between-just-another-programmer-and-eitan) – just.another.programmer Aug 06 '12 at 13:31