1
votes

Getting Sitecore to respond with a 404 error code, this blog seems to be the most referenced, where a processor is added to the httpRequestBegin pipeline and the StatusCode is set to 404 while the response is written from the results of a separate request. Like so:

// Request the NotFound page
string domain = context.Request.Url.GetComponents(UriComponents.Scheme | UriComponents.Host, UriFormat.Unescaped);
string content = Sitecore.Web.WebUtil.ExecuteWebPage(string.Concat(domain, url));

// Send the NotFound page content to the client with a 404 status code
context.Response.TrySkipIisCustomErrors = true;
context.Response.StatusCode = 404;
context.Response.Write(content);

This solution does not work well for me because cookies/security and IP detection is lost when it's the server makes a second request to get the 404 content.

After some back and forth with Sitecore's support, we came up with this code (just a quick sample):

public class MyHttpBeginRequestProcessor : Sitecore.Pipelines.HttpRequest.HttpRequestProcessor
{
    public override void Process(Sitecore.Pipelines.HttpRequest.HttpRequestArgs args)
    {
        if (Sitecore.Context.Item != null
        || Sitecore.Context.Site == null
        || Sitecore.Context.Database == null)
        {
            return;
        }
        Sitecore.Data.Database master = Sitecore.Configuration.Factory.GetDatabase("master");
        Sitecore.Context.Item = master.GetItem("/sitecore/content/home");
        Sitecore.Context.Items["Set404"] = "true";
    }
}
public class MyHttpEndRequestProcessor : Sitecore.Pipelines.HttpRequest.HttpRequestProcessor
{
    public override void Process(Sitecore.Pipelines.HttpRequest.HttpRequestArgs args)
    {
        if (Sitecore.Context.Items.Contains("Set404"))
        {
            args.Context.Response.StatusCode = 404;
        }
    }
}

And then you put a new processor in the httpRequestEnd pipeline as well as the httpRequestBegin pipeline like so:

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore database="SqlServer">
    <pipelines>
      <httpRequestBegin>
        <processor type="NewInstance3.Pipelines.MyHttpBeginRequestProcessor, NewInstance3" patch:after="processor[@type='Sitecore.Pipelines.HttpRequest.ItemResolver, Sitecore.Kernel']"/>
      </httpRequestBegin>
      <httpRequestEnd>
        <processor type="NewInstance3.Pipelines.MyHttpEndRequestProcessor, NewInstance3"/>
      </httpRequestEnd>
    </pipelines>
  </sitecore>
</configuration>

This works perfectly on my local workstation (Win7 x64); however, when I copy the site to a Win2008 x64 server, the default IIS 404 error page is displayed. Setting the StatusCode to 404 on the httpRequestEnd pipeline is causing IIS to display its 404 error rather than the Sitecore Item that I set in the httpRequestBegin pipeline.

Sitecore support says OS shouldn't matter and it works for them on Win2008 server, but I have tried 4 separate Win2008 machines, I have tried a vanilla installation of Sitecore 7.2 rev. 141226 and every time, the default IIS 404 error is displayed.

Any ideas? Thanks

1

1 Answers

3
votes

Add the following to your code:

context.Response.TrySkipIisCustomErrors = true;