diff --git a/Rest.Net/Rest.Net/Extensions/HttpListenerResponseExtensions.cs b/Rest.Net/Rest.Net/Extensions/HttpListenerResponseExtensions.cs
index 694ff4b..aa9dcc8 100644
--- a/Rest.Net/Rest.Net/Extensions/HttpListenerResponseExtensions.cs
+++ b/Rest.Net/Rest.Net/Extensions/HttpListenerResponseExtensions.cs
@@ -173,5 +173,19 @@ namespace MontoyaTech.Rest.Net
return response;
}
+
+ ///
+ /// Sets a header for a given response.
+ ///
+ ///
+ ///
+ ///
+ /// This response.
+ public static HttpListenerResponse WithHeader(this HttpListenerResponse response, string name, string value)
+ {
+ response.AddHeader(name, value);
+
+ return response;
+ }
}
}
diff --git a/Rest.Net/Rest.Net/Rest.Net.csproj b/Rest.Net/Rest.Net/Rest.Net.csproj
index 4ca6c3d..0377318 100644
--- a/Rest.Net/Rest.Net/Rest.Net.csproj
+++ b/Rest.Net/Rest.Net/Rest.Net.csproj
@@ -14,7 +14,7 @@
MontoyaTech.Rest.Net
MontoyaTech.Rest.Net
True
- 1.0.3
+ 1.0.5
diff --git a/Rest.Net/Rest.Net/RouteListener.cs b/Rest.Net/Rest.Net/RouteListener.cs
index 53c9c44..ff022a4 100644
--- a/Rest.Net/Rest.Net/RouteListener.cs
+++ b/Rest.Net/Rest.Net/RouteListener.cs
@@ -29,6 +29,16 @@ namespace MontoyaTech.Rest.Net
///
public ushort Port = 8081;
+ ///
+ /// An event to preprocess routes before the route is executed.
+ ///
+ public event RoutePreprocess PreprocessEvent;
+
+ ///
+ /// An event to postprocess routes before the route response is returned.
+ ///
+ public event RoutePostprocess PostprocessEvent;
+
///
/// Creates a new RouteListener with the default port number.
///
@@ -111,16 +121,34 @@ namespace MontoyaTech.Rest.Net
handled = true;
close = this.Routes[i].CloseResponse;
+ var context = new RouteContext(ctx.Request, ctx.Response);
+
+ //Preprocess the route context, if it returns false, then we have to not invoke the route.
+ try
+ {
+ if (this.PreprocessEvent != null && !this.PreprocessEvent.Invoke(context))
+ break;
+ }
+ catch { }
+
//Make sure if the route fails we don't die here, just set the response to internal server error.
try
{
- this.Routes[i].Invoke(new RouteContext(ctx.Request, ctx.Response), arguments);
+ this.Routes[i].Invoke(context, arguments);
}
catch
{
ctx.Response.WithStatus(HttpStatusCode.InternalServerError);
}
+ //Post process the route context.
+ try
+ {
+ if (this.PostprocessEvent != null)
+ this.PostprocessEvent.Invoke(context);
+ }
+ catch { }
+
break;
}
}
diff --git a/Rest.Net/Rest.Net/RouteMatcher.cs b/Rest.Net/Rest.Net/RouteMatcher.cs
index 5e802b9..4f9052f 100644
--- a/Rest.Net/Rest.Net/RouteMatcher.cs
+++ b/Rest.Net/Rest.Net/RouteMatcher.cs
@@ -41,8 +41,11 @@ namespace MontoyaTech.Rest.Net
var urlSegments = url.Split('/').Where(segment => segment.Length > 0).Select(segment => segment.Trim()).ToArray();
var syntaxSegments = syntax.Split('/').Where(segment => segment.Length > 0).Select(segment => segment.Trim()).ToArray();
+ //If we have no url segments, and we have no syntax segments, this is a root match which is fine.
+ if (urlSegments.Length == 0 && syntaxSegments.Length == 0)
+ return true;
//If we have no syntax segments this is not a match.
- if (syntaxSegments.Length == 0)
+ else if (syntaxSegments.Length == 0)
return false;
//If we have segments and the url does not then this may not be a match.
diff --git a/Rest.Net/Rest.Net/RoutePostprocess.cs b/Rest.Net/Rest.Net/RoutePostprocess.cs
new file mode 100644
index 0000000..25d7b15
--- /dev/null
+++ b/Rest.Net/Rest.Net/RoutePostprocess.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MontoyaTech.Rest.Net
+{
+ ///
+ /// A route post process delegate that can be used to process the response from routes.
+ ///
+ ///
+ public delegate void RoutePostprocess(RouteContext context);
+}
diff --git a/Rest.Net/Rest.Net/RoutePreprocess.cs b/Rest.Net/Rest.Net/RoutePreprocess.cs
new file mode 100644
index 0000000..eeb517f
--- /dev/null
+++ b/Rest.Net/Rest.Net/RoutePreprocess.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MontoyaTech.Rest.Net
+{
+ ///
+ /// A route preprocess delegate that can be used to process requests before they reach a route
+ /// and reject them if needed.
+ ///
+ ///
+ ///
+ public delegate bool RoutePreprocess(RouteContext context);
+}