I have an application that taps into BeginRequest
and EndRequest
to set up and tear down NHibernate sessions like this:
BeginRequest += delegate
{
CurrentSessionContext.Bind(SessionFactory.OpenSession());
};
EndRequest += delegate
{
var session = CurrentSessionContext.Unbind(SessionFactory);
session.Dispose();
Container.Release(session);
};
This works fine when deployed in IIS, until I check the "Require SSL" box. Once I do this, I get a NullReferenceException
at session.Dispose()
.
I haven't debugged this yet and, yes, the fix is trivial, but I'm just curious about how "Require SSL" affects the lifecycle of a request. Is a session not set up on the server in these cases?
EDIT: Just to clarify, I'm referring to the "Require SSL" option in IIS configuration for the application, not the RequireHttps
attribute for controllers.
This one piqued my curiosity so I dug into it a little; sorry for the necromancy.
I created a simple project that wired up notifications for every lifecycle event on the application object, and set breakpoints on each one.
It turns out that when "Require SSL" is set and you access without SSL, most of the events are completely skipped. The first event to fire is
LogRequest
, followed byPostLogRequest
,EndRequest
,PreSendRequestContent
, andPreSendRequestHeaders
(in that order). No other events are fired.So your code was crashing because the
BeginRequest
event was never fired, and theEndRequest
delegate tried toDispose()
something that had never been created.What's interesting to me is figuring out why IIS behaves like this. I suspect the reason is that IIS still needs to log invalid connection attempts, as well as send content and headers, even if the requested resource requires SSL. Something has to generate that friendly "forbidden" page, after all. What I don't know is why
EndRequest
is called at all when they didn't bother callingBeginRequest
; I'm guessing there's some IIS/ASP cleanup code that depends on it.This behavior varies depending on whether the application pool is running in "Integrated" or "Classic" mode. In "Classic" mode, the ASP.NET events all fire "in between" the IIS
PreRequestHandlerExecute
andPostRequestHandlerExecute
events. You didn't say which you were running, but it has to be Integrated; otherwise you'd have seen the behavior you were expecting, i.e. none of your code would have executed at all.Interestingly, if you try to subscribe to the
LogRequest
,PostLogRequest
, orMapRequestHandler
events when in Classic mode, you get a runtime exception; these only "make sense" in the context of the integrated pipeline.