It would seem that WAF currently triggers a 404 only if a route is not found and a node with the current URL address is not found.
If however, a route is found, but not a node with a correct Address is not found, Request.GetContent() defaults to the Site's start node, but does not return a 404.
I understand this behaviour because otherwise there would be no way of reaching routes that do not belong to a node.
Is there some way of detecting if a node with a corresponding Address was not found? Is there a property in place on Request somewhere? :)
I currently have the following "hack" in place:
if (site.StartNode.GetId() != content.NodeId || (localPath = requestContext.HttpContext.Request.Url.LocalPath) == "/" || localPath.Equals(WAFContext.GetUrl(content), StringComparison.OrdinalIgnoreCase)) page exists...
else not found...
And additionally:
static void WriteResponseFromRequest(string url, int errorCode)
{
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
using (MemoryStream memoryStream = new MemoryStream())
{
HttpResponse response = HttpContext.Current.Response; HttpWebResponse webResponse;
response.TrySkipIisCustomErrors = true;
try
{
webResponse = (HttpWebResponse)httpWebRequest.GetResponse();
}
catch (WebException e)
{
webResponse = (HttpWebResponse)e.Response;
}
Stream responseStream = webResponse.GetResponseStream();
byte[] buffer = new byte[8192]; int count;
do
{
count = responseStream.Read(buffer, 0, buffer.Length);
if (count != 0) memoryStream.Write(buffer, 0, count);
} while (count > 0);
response.StatusCode = errorCode;
response.StatusDescription = webResponse.StatusDescription;
response.BinaryWrite(memoryStream.ToArray());
}
}
static void NotFound(Site site)
{
var context = HttpContext.Current;
if (site.ShowUnfriendly404ErrorPage(context.Request)) return;
var application = context.ApplicationInstance;
switch (site.Friendly404ErrorPageUrl.LinkType)
{
case LinkType.InternalContent:
WriteResponseFromRequest(WAFContext.UrlFromRootToHost + site.Friendly404ErrorPageUrl.GetUrl() + "?Url=" + HttpUtility.UrlEncode(WAFContext.GetFullOriginalUrl()) + "&ErrorCode=404", 404);
application.Server.ClearError();
break;
case LinkType.ExternalAddress:
application.Response.Redirect(site.Friendly404ErrorPageUrl.GetUrl() + "?ErrorCode=404&Url=" + HttpUtility.UrlEncode(WAFContext.GetFullOriginalUrl()));
application.Server.ClearError();
break;
case LinkType.Email:
application.Response.Redirect(site.Friendly404ErrorPageUrl.GetUrl() + "?Body=" + HttpUtility.UrlEncode(site.Friendly404ErrorMessage));
application.Server.ClearError();
break;
case LinkType.Empty:
WAFContext.ReturnPage(site.GetFriendly404ErrorTitle(404), site.Friendly404ErrorMessage, false, true, 404);
application.Server.ClearError();
break;
}
application.Response.End();
}