/// <summary> /// Creates a new instance of HttpServer. /// </summary> /// <param name="myIPAddress">The IP address this server will listen for new connections.</param> /// <param name="myPort">The port this server will listen for new connections.</param> /// <param name="myServerLogic">An instance of the server logic. The class of this instance must implement at least one interface that is decorated with a ServiceContractAttribute.</param> /// <param name="mySecurity"></param> /// <param name="mySecureConnection">If true, this server will listen for request with HTTPS protocol, otherwise HTTP.</param> /// <param name="myAutoStart">If true, the method Start is called implicitly, otherwise not.</param> /// <exception cref="ArgumentNullException">If myIPAddress is <c>NULL</c>.</exception> /// <exception cref="ArgumentNullException">If myServerLogic is <c>NULL</c>.</exception> public HttpServer(IPAddress myIPAddress, ushort myPort, object myServerLogic, IServerSecurity mySecurity = null, bool mySecureConnection = false, bool myAutoStart = false) { #region argument checks if (myIPAddress == null) { throw new ArgumentNullException("myIPAddress"); } if (myServerLogic == null) { throw new ArgumentNullException("myServerLogic"); } #endregion #region set data ListeningAddress = myIPAddress; ListeningPort = myPort; IsSecureConnection = mySecureConnection; IsRunning = false; _logic = myServerLogic; _security = mySecurity; _parser = ParseInterface(); #endregion CreateListener(); //create listener as late as possible _disposalService = new DisposalService(GetType().Name); //add close method to desposal service, //this service will provide that the dispose method won't be called multiple times _disposalService.AddManagedResourceDisposal(Close); if (myAutoStart) { Start(); } }
/// <summary> /// Parses the class of _logic for interesting attributes. /// </summary> /// <remarks> /// Searches for interesting attributes in the inheritance hierarchy of the class of the _logic. /// After that it parses the attributes and builds a connection from the url pattern to the implementation method. /// </remarks> private UrlParser ParseInterface() { var result = new UrlParser(new[] { '/' }); #region Find the correct interfaces var allInterfaces = from interfaceInst in _logic.GetType().GetInterfaces() where interfaceInst.GetCustomAttributes(typeof (ServiceContractAttribute), false).Count() > 0 select interfaceInst; if (allInterfaces.Count() == 0) throw new ArgumentException("Could not find any valid interface having the ServiceContract attribute!"); #endregion foreach (var currentInterfaces in allInterfaces) { #region Check global Force-/NoAuthenticationAttribute var globalNeedsExplicitAuthentication = false; if (currentInterfaces.GetCustomAttributes(typeof (ForceAuthenticationAttribute), false).Count() > 0) globalNeedsExplicitAuthentication = true; #endregion foreach (var method in currentInterfaces.GetMethods()) { var needsExplicitAuthentication = globalNeedsExplicitAuthentication; var attributes = method.GetCustomAttributes(false); #region Authentication if (attributes.Any(_ => _.GetType() == typeof(NoAuthenticationAttribute))) needsExplicitAuthentication = false; if (attributes.Any(_ => _.GetType() == typeof(ForceAuthenticationAttribute))) needsExplicitAuthentication = true; #endregion foreach (var attribute in attributes) { String aURIPattern = null; String webMethod = null; #region WebGet var webAttribute = attribute as WebGetAttribute; if (webAttribute != null) { aURIPattern = webAttribute.UriTemplate.ToLower(); webMethod = "GET"; } #endregion #region WebInvoke var webInvokeAttribute = attribute as WebInvokeAttribute; if (webInvokeAttribute != null) { aURIPattern = webInvokeAttribute.UriTemplate.ToLower(); webMethod = webInvokeAttribute.Method; } #endregion if (aURIPattern != null) result.AddUrl(aURIPattern, method, needsExplicitAuthentication, webMethod); } } } return result; }
/// <summary> /// Creates a new instance of HttpServer. /// </summary> /// <param name="myIPAddress">The IP address this server will listen for new connections.</param> /// <param name="myPort">The port this server will listen for new connections.</param> /// <param name="myServerLogic">An instance of the server logic. The class of this instance must implement at least one interface that is decorated with a ServiceContractAttribute.</param> /// <param name="mySecurity"></param> /// <param name="mySecureConnection">If true, this server will listen for request with HTTPS protocol, otherwise HTTP.</param> /// <param name="myAutoStart">If true, the method Start is called implicitly, otherwise not.</param> /// <exception cref="ArgumentNullException">If myIPAddress is <c>NULL</c>.</exception> /// <exception cref="ArgumentNullException">If myServerLogic is <c>NULL</c>.</exception> public HttpServer(IPAddress myIPAddress, ushort myPort, object myServerLogic, IServerSecurity mySecurity = null, bool mySecureConnection = false, bool myAutoStart = false) { #region argument checks if (myIPAddress == null) throw new ArgumentNullException("myIPAddress"); if (myServerLogic == null) throw new ArgumentNullException("myServerLogic"); #endregion #region set data ListeningAddress = myIPAddress; ListeningPort = myPort; IsSecureConnection = mySecureConnection; IsRunning = false; _logic = myServerLogic; _security = mySecurity; _parser = ParseInterface(); #endregion CreateListener(); //create listener as late as possible _disposalService = new DisposalService(GetType().Name); //add close method to desposal service, //this service will provide that the dispose method won't be called multiple times _disposalService.AddManagedResourceDisposal(Close); if (myAutoStart) Start(); }
/// <summary> /// Parses the class of _logic for interesting attributes. /// </summary> /// <remarks> /// Searches for interesting attributes in the inheritance hierarchy of the class of the _logic. /// After that it parses the attributes and builds a connection from the url pattern to the implementation method. /// </remarks> private UrlParser ParseInterface() { var result = new UrlParser(new[] { '/' }); #region Find the correct interfaces var allInterfaces = from interfaceInst in _logic.GetType().GetInterfaces() where interfaceInst.GetCustomAttributes(typeof(ServiceContractAttribute), false).Count() > 0 select interfaceInst; if (allInterfaces.Count() == 0) { throw new ArgumentException("Could not find any valid interface having the ServiceContract attribute!"); } #endregion foreach (var currentInterfaces in allInterfaces) { #region Check global Force-/NoAuthenticationAttribute var globalNeedsExplicitAuthentication = false; if (currentInterfaces.GetCustomAttributes(typeof(ForceAuthenticationAttribute), false).Count() > 0) { globalNeedsExplicitAuthentication = true; } #endregion foreach (var method in currentInterfaces.GetMethods()) { var needsExplicitAuthentication = globalNeedsExplicitAuthentication; var attributes = method.GetCustomAttributes(false); #region Authentication if (attributes.Any(_ => _.GetType() == typeof(NoAuthenticationAttribute))) { needsExplicitAuthentication = false; } if (attributes.Any(_ => _.GetType() == typeof(ForceAuthenticationAttribute))) { needsExplicitAuthentication = true; } #endregion foreach (var attribute in attributes) { String aURIPattern = null; String webMethod = null; #region WebGet var webAttribute = attribute as WebGetAttribute; if (webAttribute != null) { aURIPattern = webAttribute.UriTemplate.ToLower(); webMethod = "GET"; } #endregion #region WebInvoke var webInvokeAttribute = attribute as WebInvokeAttribute; if (webInvokeAttribute != null) { aURIPattern = webInvokeAttribute.UriTemplate.ToLower(); webMethod = webInvokeAttribute.Method; } #endregion if (aURIPattern != null) { result.AddUrl(aURIPattern, method, needsExplicitAuthentication, webMethod); } } } } return(result); }