Beispiel #1
0
        public void AddHandler(HTTPDelegate HTTPDelegate,

                               HTTPMethod HTTPMethod           = null,
                               HTTPContentType HTTPContentType = null,

                               HTTPAuthentication HTTPMethodAuthentication  = null,
                               HTTPAuthentication ContentTypeAuthentication = null,

                               HTTPDelegate DefaultErrorHandler = null,
                               URIReplacement AllowReplacement  = URIReplacement.Fail)

        {
            HTTPMethodNode _HTTPMethodNode = null;

            if (!_HTTPMethods.TryGetValue(HTTPMethod, out _HTTPMethodNode))
            {
                _HTTPMethodNode = new HTTPMethodNode(HTTPMethod, HTTPMethodAuthentication, HTTPDelegate, DefaultErrorHandler);
                _HTTPMethods.Add(HTTPMethod, _HTTPMethodNode);
            }

            _HTTPMethodNode.AddHandler(HTTPDelegate,

                                       HTTPContentType,

                                       ContentTypeAuthentication,

                                       DefaultErrorHandler,
                                       AllowReplacement);
        }
Beispiel #2
0
        /// <summary>
        /// Creates a new URLNode.
        /// </summary>
        /// <param name="URITemplate">The URI template for this service.</param>
        /// <param name="URIAuthentication">This and all subordinated nodes demand an explicit URI authentication.</param>
        /// <param name="RequestHandler">The default delegate to call for any request to this URI template.</param>
        /// <param name="DefaultErrorHandler">The default error handling delegate.</param>
        internal URINode(String URITemplate,
                         HTTPAuthentication URIAuthentication = null,
                         HTTPDelegate RequestHandler          = null,
                         HTTPDelegate DefaultErrorHandler     = null)

        {
            URITemplate.FailIfNullOrEmpty();

            this._URITemplate         = URITemplate;
            this._URIAuthentication   = URIAuthentication;
            this._RequestHandler      = RequestHandler;
            this._DefaultErrorHandler = DefaultErrorHandler;
            this._ErrorHandlers       = new Dictionary <HTTPStatusCode, HTTPDelegate>();
            this._HTTPMethods         = new Dictionary <HTTPMethod, HTTPMethodNode>();

            var _ReplaceLastParameter = new Regex(@"\{[^/]+\}$");

            this._ParameterCount = (UInt16)_ReplaceLastParameter.Matches(URITemplate).Count;
            var URLTemplate2           = _ReplaceLastParameter.Replace(URITemplate, "([^\n]+)");
            var URLTemplateWithoutVars = _ReplaceLastParameter.Replace(URITemplate, "");

            var _ReplaceAllParameters = new Regex(@"\{[^/]+\}");

            this._ParameterCount += (UInt16)_ReplaceAllParameters.Matches(URLTemplate2).Count;
            this._URIRegex        = new Regex("^" + _ReplaceAllParameters.Replace(URLTemplate2, "([^/]+)") + "$");
            this._SortLength      = (UInt16)_ReplaceAllParameters.Replace(URLTemplateWithoutVars, "").Length;
        }
Beispiel #3
0
        public void AddHandler(HTTPDelegate HTTPDelegate,

                               String URITemplate              = "/",
                               HTTPMethod HTTPMethod           = null,
                               HTTPContentType HTTPContentType = null,

                               HTTPAuthentication URIAuthentication         = null,
                               HTTPAuthentication HTTPMethodAuthentication  = null,
                               HTTPAuthentication ContentTypeAuthentication = null,

                               HTTPDelegate DefaultErrorHandler = null,
                               URIReplacement AllowReplacement  = URIReplacement.Fail)

        {
            URINode _URINode = null;

            if (!_URINodes.TryGetValue(URITemplate, out _URINode))
            {
                _URINode = new URINode(URITemplate, URIAuthentication, HTTPDelegate, DefaultErrorHandler);
                _URINodes.Add(URITemplate, _URINode);
            }

            _URINode.AddHandler(HTTPDelegate,

                                HTTPMethod,
                                HTTPContentType,

                                HTTPMethodAuthentication,
                                ContentTypeAuthentication,

                                DefaultErrorHandler,
                                AllowReplacement);
        }
Beispiel #4
0
        /// <summary>
        /// Creates a new hostname node.
        /// </summary>
        /// <param name="Hostname">The hostname(s) for this (virtual) http service.</param>
        /// <param name="RequestHandler">The default delegate to call for any request to this hostname.</param>
        /// <param name="HostAuthentication">This and all subordinated nodes demand an explicit host authentication.</param>
        /// <param name="DefaultErrorHandler">The default error handling delegate.</param>
        internal HostnameNode(HTTPHostname Hostname,
                              HTTPAuthentication HostAuthentication = null,
                              HTTPDelegate RequestHandler           = null,
                              HTTPDelegate DefaultErrorHandler      = null)

        {
            #region Check Hostname

            if (Hostname == null)
            {
                throw new ArgumentNullException("Hostname", "The given HTTP hostname must not be null!");
            }

            var HostHeader = Hostname.ToString().Split(new Char[1] {
                ':'
            }, StringSplitOptions.None).Select(v => v.Trim()).ToArray();
            UInt16 HostPort = 80;

            // 1.2.3.4          => 1.2.3.4:80
            // 1.2.3.4:80       => ok
            // 1.2.3.4 : 80     => ok
            // 1.2.3.4:*        => ok
            // 1.2.3.4:a        => invalid
            // 1.2.3.4:80:      => ok
            // 1.2.3.4:80:0     => invalid

            // rfc 2616 - 3.2.2
            // If the port is empty or not given, port 80 is assumed.
            if (HostHeader.Length == 1)
            {
                this._Hostname = HTTPHostname.Parse(Hostname + ":" + HostPort);
            }

            else if ((HostHeader.Length == 2 && (!UInt16.TryParse(HostHeader[1], out HostPort) && HostHeader[1] != "*")) ||
                     HostHeader.Length > 2)
            {
                throw new ArgumentException("Invalid Hostname!", "Hostname");
            }

            else
            {
                this._Hostname = HTTPHostname.Parse(HostHeader[0] + ":" + HostHeader[1]);
            }

            #endregion

            this._HostAuthentication  = (HostAuthentication != null) ? HostAuthentication : _ => true;
            this._RequestHandler      = RequestHandler;
            this._DefaultErrorHandler = DefaultErrorHandler;
            this._URINodes            = new Dictionary <String, URINode>();
            this._ErrorHandlers       = new Dictionary <HTTPStatusCode, HTTPDelegate>();
        }
Beispiel #5
0
        /// <summary>
        /// Creates a new HTTPMethodNode.
        /// </summary>
        /// <param name="HTTPMethod">The http method for this service.</param>
        /// <param name="HTTPMethodAuthentication">This and all subordinated nodes demand an explicit HTTP method authentication.</param>
        /// <param name="RequestHandler">The default delegate to call for any request to this URI template.</param>
        /// <param name="DefaultErrorHandler">The default error handling delegate.</param>
        internal HTTPMethodNode(HTTPMethod          HTTPMethod,
                                HTTPAuthentication  HTTPMethodAuthentication    = null,
                                HTTPDelegate        RequestHandler              = null,
                                HTTPDelegate        DefaultErrorHandler         = null)
        {
            if (HTTPMethod == null)
                throw new ArgumentException("HTTPMethod == null!");

            this.HTTPMethod                = HTTPMethod;
            this.HTTPMethodAuthentication  = HTTPMethodAuthentication;
            this.RequestHandler            = RequestHandler;
            this.DefaultErrorHandler       = DefaultErrorHandler;

            this._ErrorHandlers             = new Dictionary<HTTPStatusCode,  HTTPDelegate>();
            this._HTTPContentTypes          = new Dictionary<HTTPContentType, ContentTypeNode>();
        }
Beispiel #6
0
        /// <summary>
        /// Creates a new HTTPMethodNode.
        /// </summary>
        /// <param name="HTTPMethod">The http method for this service.</param>
        /// <param name="HTTPMethodAuthentication">This and all subordinated nodes demand an explicit HTTP method authentication.</param>
        /// <param name="RequestHandler">The default delegate to call for any request to this URI template.</param>
        /// <param name="DefaultErrorHandler">The default error handling delegate.</param>
        internal HTTPMethodNode(HTTPMethod HTTPMethod,
                                HTTPAuthentication HTTPMethodAuthentication = null,
                                HTTPDelegate RequestHandler      = null,
                                HTTPDelegate DefaultErrorHandler = null)

        {
            if (HTTPMethod == null)
            {
                throw new ArgumentException("HTTPMethod == null!");
            }

            this.HTTPMethod = HTTPMethod;
            this.HTTPMethodAuthentication = HTTPMethodAuthentication;
            this.RequestHandler           = RequestHandler;
            this.DefaultErrorHandler      = DefaultErrorHandler;

            this._ErrorHandlers    = new Dictionary <HTTPStatusCode, HTTPDelegate>();
            this._HTTPContentTypes = new Dictionary <HTTPContentType, ContentTypeNode>();
        }
Beispiel #7
0
        /// <summary>
        /// Creates a new hostname node.
        /// </summary>
        /// <param name="Hostname">The hostname(s) for this (virtual) http service.</param>
        /// <param name="RequestHandler">The default delegate to call for any request to this hostname.</param>
        /// <param name="HostAuthentication">This and all subordinated nodes demand an explicit host authentication.</param>
        /// <param name="DefaultErrorHandler">The default error handling delegate.</param>
        internal HostnameNode(HTTPHostname        Hostname,
                              HTTPAuthentication  HostAuthentication   = null,
                              HTTPDelegate        RequestHandler       = null,
                              HTTPDelegate        DefaultErrorHandler  = null)
        {
            #region Check Hostname

            if (Hostname == null)
                throw new ArgumentNullException("Hostname", "The given HTTP hostname must not be null!");

            var    HostHeader  = Hostname.ToString().Split(new Char[1] { ':' }, StringSplitOptions.None).Select(v => v.Trim()).ToArray();
            UInt16 HostPort    = 80;

            // 1.2.3.4          => 1.2.3.4:80
            // 1.2.3.4:80       => ok
            // 1.2.3.4 : 80     => ok
            // 1.2.3.4:*        => ok
            // 1.2.3.4:a        => invalid
            // 1.2.3.4:80:      => ok
            // 1.2.3.4:80:0     => invalid

            // rfc 2616 - 3.2.2
            // If the port is empty or not given, port 80 is assumed.
            if (HostHeader.Length == 1)
                this._Hostname = HTTPHostname.Parse(Hostname + ":" + HostPort);

            else if ((HostHeader.Length == 2 && (!UInt16.TryParse(HostHeader[1], out HostPort) && HostHeader[1] != "*")) ||
                      HostHeader.Length  > 2)
                      throw new ArgumentException("Invalid Hostname!", "Hostname");

            else
                this._Hostname = HTTPHostname.Parse(HostHeader[0] + ":" + HostHeader[1]);

            #endregion

            this._HostAuthentication   = (HostAuthentication != null) ? HostAuthentication : _ => true;
            this._RequestHandler       = RequestHandler;
            this._DefaultErrorHandler  = DefaultErrorHandler;
            this._URINodes             = new Dictionary<String,         URINode>();
            this._ErrorHandlers        = new Dictionary<HTTPStatusCode, HTTPDelegate>();
        }
Beispiel #8
0
        /// <summary>
        /// Creates a new HTTP ContentTypeNode.
        /// </summary>
        /// <param name="HTTPContentType">The http content type for this service.</param>
        /// <param name="HTTPContentTypeAuthentication">This and all subordinated nodes demand an explicit HTTP content type authentication.</param>
        /// <param name="RequestHandler">The default delegate to call for any request to this URI template.</param>
        /// <param name="DefaultErrorHandler">The default error handling delegate.</param>
        /// <param name="AllowReplacement">How to handle duplicate URI handlers.</param>
        internal ContentTypeNode(HTTPContentType     HTTPContentType,
                                 HTTPAuthentication  HTTPContentTypeAuthentication   = null,
                                 HTTPDelegate        RequestHandler                  = null,
                                 HTTPDelegate        DefaultErrorHandler             = null,
                                 URIReplacement      AllowReplacement                = URIReplacement.Fail)
        {
            #region Initial checks

            if (HTTPContentType == null)
                throw new ArgumentNullException(nameof(HTTPContentType),  "The given HTTP content type must not be null!");

            #endregion

            this.HTTPContentType                = HTTPContentType;
            this.HTTPContentTypeAuthentication  = HTTPContentTypeAuthentication;
            this.RequestHandler                 = RequestHandler;
            this.DefaultErrorHandler            = DefaultErrorHandler;
            this.AllowReplacement               = AllowReplacement;

            this.ErrorHandlers                  = new Dictionary<HTTPStatusCode, HTTPDelegate>();
        }
Beispiel #9
0
        public void AddHandler(HTTPDelegate HTTPDelegate,
                               HTTPContentType HTTPContentType = null,
                               HTTPAuthentication ContentTypeAuthentication = null,
                               HTTPDelegate DefaultErrorHandler             = null,
                               URIReplacement AllowReplacement = URIReplacement.Fail)

        {
            ContentTypeNode _ContentTypeNode = null;

            if (HTTPContentType == null)
            {
                //RequestHandler       = HTTPDelegate;
                //DefaultErrorHandler  = DefaultErrorHandler;
            }

            else if (!_HTTPContentTypes.TryGetValue(HTTPContentType, out _ContentTypeNode))
            {
                _ContentTypeNode = new ContentTypeNode(HTTPContentType, ContentTypeAuthentication, HTTPDelegate, DefaultErrorHandler, AllowReplacement);
                _HTTPContentTypes.Add(HTTPContentType, _ContentTypeNode);
            }

            else
            {
                if (_ContentTypeNode.AllowReplacement == URIReplacement.Allow)
                {
                    _ContentTypeNode = new ContentTypeNode(HTTPContentType, ContentTypeAuthentication, HTTPDelegate, DefaultErrorHandler, AllowReplacement);
                    _HTTPContentTypes[HTTPContentType] = _ContentTypeNode;
                }

                else if (_ContentTypeNode.AllowReplacement == URIReplacement.Ignore)
                {
                }

                else
                {
                    throw new ArgumentException("Duplicate HTTP API definition!");
                }
            }
        }
Beispiel #10
0
        /// <summary>
        /// Creates a new HTTP ContentTypeNode.
        /// </summary>
        /// <param name="HTTPContentType">The http content type for this service.</param>
        /// <param name="HTTPContentTypeAuthentication">This and all subordinated nodes demand an explicit HTTP content type authentication.</param>
        /// <param name="RequestHandler">The default delegate to call for any request to this URI template.</param>
        /// <param name="DefaultErrorHandler">The default error handling delegate.</param>
        /// <param name="AllowReplacement">How to handle duplicate URI handlers.</param>
        internal ContentTypeNode(HTTPContentType HTTPContentType,
                                 HTTPAuthentication HTTPContentTypeAuthentication = null,
                                 HTTPDelegate RequestHandler      = null,
                                 HTTPDelegate DefaultErrorHandler = null,
                                 URIReplacement AllowReplacement  = URIReplacement.Fail)
        {
            #region Initial checks

            if (HTTPContentType == null)
            {
                throw new ArgumentNullException(nameof(HTTPContentType), "The given HTTP content type must not be null!");
            }

            #endregion

            this.HTTPContentType = HTTPContentType;
            this.HTTPContentTypeAuthentication = HTTPContentTypeAuthentication;
            this.RequestHandler      = RequestHandler;
            this.DefaultErrorHandler = DefaultErrorHandler;
            this.AllowReplacement    = AllowReplacement;

            this.ErrorHandlers = new Dictionary <HTTPStatusCode, HTTPDelegate>();
        }
Beispiel #11
0
        /// <summary>
        /// Creates a new URLNode.
        /// </summary>
        /// <param name="URITemplate">The URI template for this service.</param>
        /// <param name="URIAuthentication">This and all subordinated nodes demand an explicit URI authentication.</param>
        /// <param name="RequestHandler">The default delegate to call for any request to this URI template.</param>
        /// <param name="DefaultErrorHandler">The default error handling delegate.</param>
        internal URINode(String              URITemplate,
                         HTTPAuthentication  URIAuthentication    = null,
                         HTTPDelegate        RequestHandler       = null,
                         HTTPDelegate        DefaultErrorHandler  = null)
        {
            URITemplate.FailIfNullOrEmpty();

            this._URITemplate           = URITemplate;
            this._URIAuthentication     = URIAuthentication;
            this._RequestHandler        = RequestHandler;
            this._DefaultErrorHandler   = DefaultErrorHandler;
            this._ErrorHandlers         = new Dictionary<HTTPStatusCode, HTTPDelegate>();
            this._HTTPMethods           = new Dictionary<HTTPMethod, HTTPMethodNode>();

            var _ReplaceLastParameter   = new Regex(@"\{[^/]+\}$");
            this._ParameterCount        = (UInt16) _ReplaceLastParameter.Matches(URITemplate).Count;
            var URLTemplate2            = _ReplaceLastParameter.Replace(URITemplate, "([^\n]+)");
            var URLTemplateWithoutVars  = _ReplaceLastParameter.Replace(URITemplate, "");

            var _ReplaceAllParameters   = new Regex(@"\{[^/]+\}");
            this._ParameterCount       += (UInt16) _ReplaceAllParameters.Matches(URLTemplate2).Count;
            this._URIRegex              = new Regex("^" + _ReplaceAllParameters.Replace(URLTemplate2, "([^/]+)") + "$");
            this._SortLength            = (UInt16) _ReplaceAllParameters.Replace(URLTemplateWithoutVars, "").Length;
        }
Beispiel #12
0
        public void AddHandler(HTTPDelegate        HTTPDelegate,

                               HTTPMethod          HTTPMethod                  = null,
                               HTTPContentType     HTTPContentType             = null,

                               HTTPAuthentication  HTTPMethodAuthentication    = null,
                               HTTPAuthentication  ContentTypeAuthentication   = null,

                               HTTPDelegate        DefaultErrorHandler         = null,
                               URIReplacement      AllowReplacement            = URIReplacement.Fail)
        {
            HTTPMethodNode _HTTPMethodNode = null;

            if (!_HTTPMethods.TryGetValue(HTTPMethod, out _HTTPMethodNode))
            {
                _HTTPMethodNode = new HTTPMethodNode(HTTPMethod, HTTPMethodAuthentication, HTTPDelegate, DefaultErrorHandler);
                _HTTPMethods.Add(HTTPMethod, _HTTPMethodNode);
            }

            _HTTPMethodNode.AddHandler(HTTPDelegate,

                                       HTTPContentType,

                                       ContentTypeAuthentication,

                                       DefaultErrorHandler,
                                       AllowReplacement);
        }
Beispiel #13
0
        public void AddHandler(HTTPDelegate        HTTPDelegate,
                               HTTPContentType     HTTPContentType            = null,
                               HTTPAuthentication  ContentTypeAuthentication  = null,
                               HTTPDelegate        DefaultErrorHandler        = null,
                               URIReplacement      AllowReplacement           = URIReplacement.Fail)
        {
            ContentTypeNode _ContentTypeNode = null;

            if (HTTPContentType == null)
            {
                //RequestHandler       = HTTPDelegate;
                //DefaultErrorHandler  = DefaultErrorHandler;
            }

            else if (!_HTTPContentTypes.TryGetValue(HTTPContentType, out _ContentTypeNode))
            {
                _ContentTypeNode = new ContentTypeNode(HTTPContentType, ContentTypeAuthentication, HTTPDelegate, DefaultErrorHandler, AllowReplacement);
                _HTTPContentTypes.Add(HTTPContentType, _ContentTypeNode);
            }

            else
            {

                if (_ContentTypeNode.AllowReplacement == URIReplacement.Allow)
                {
                    _ContentTypeNode = new ContentTypeNode(HTTPContentType, ContentTypeAuthentication, HTTPDelegate, DefaultErrorHandler, AllowReplacement);
                    _HTTPContentTypes[HTTPContentType] = _ContentTypeNode;
                }

                else if (_ContentTypeNode.AllowReplacement == URIReplacement.Ignore)
                {
                }

                else
                    throw new ArgumentException("Duplicate HTTP API definition!");

            }
        }
Beispiel #14
0
        public void AddHandler(HTTPDelegate        HTTPDelegate,

                               String              URITemplate                 = "/",
                               HTTPMethod          HTTPMethod                  = null,
                               HTTPContentType     HTTPContentType             = null,

                               HTTPAuthentication  URIAuthentication           = null,
                               HTTPAuthentication  HTTPMethodAuthentication    = null,
                               HTTPAuthentication  ContentTypeAuthentication   = null,

                               HTTPDelegate        DefaultErrorHandler         = null,
                               URIReplacement      AllowReplacement            = URIReplacement.Fail)
        {
            URINode _URINode = null;

            if (!_URINodes.TryGetValue(URITemplate, out _URINode))
            {
                _URINode = new URINode(URITemplate, URIAuthentication, HTTPDelegate, DefaultErrorHandler);
                _URINodes.Add(URITemplate, _URINode);
            }

            _URINode.AddHandler(HTTPDelegate,

                                HTTPMethod,
                                HTTPContentType,

                                HTTPMethodAuthentication,
                                ContentTypeAuthentication,

                                DefaultErrorHandler,
                                AllowReplacement);
        }
Beispiel #15
0
        /// <summary>
        /// Returns internal resources embedded within the given assembly.
        /// </summary>
        /// <param name="HTTPServer">A HTTP server.</param>
        /// <param name="Hostname">The HTTP hostname.</param>
        /// <param name="URITemplate">An URI template.</param>
        /// <param name="ResourcePath">The path to the file within the assembly.</param>
        /// <param name="ResourceAssembly">Optionally the assembly where the resources are located (default: the calling assembly).</param>
        /// <param name="DefaultFilename">The default file to load.</param>
        /// <param name="HTTPRealm">An optional realm for HTTP basic authentication.</param>
        /// <param name="HTTPLogin">An optional login for HTTP basic authentication.</param>
        /// <param name="HTTPPassword">An optional password for HTTP basic authentication.</param>
        public static void RegisterResourcesFolder(this IHTTPServer HTTPServer,
                                                   HTTPHostname Hostname,
                                                   String URITemplate,
                                                   String ResourcePath,
                                                   Assembly ResourceAssembly = null,
                                                   String DefaultFilename    = "index.html",
                                                   String HTTPRealm          = null,
                                                   String HTTPLogin          = null,
                                                   String HTTPPassword       = null)
        {
            if (ResourceAssembly == null)
            {
                ResourceAssembly = Assembly.GetCallingAssembly();
            }


            HTTPDelegate GetEmbeddedResources = async Request => {
                #region Check HTTP Basic Authentication

                if (HTTPLogin.IsNotNullOrEmpty() && HTTPPassword.IsNotNullOrEmpty())
                {
                    if (Request.Authorization == null ||
                        Request.Authorization.Username != HTTPLogin ||
                        Request.Authorization.Password != HTTPPassword)
                    {
                        return new HTTPResponseBuilder(Request)
                               {
                                   HTTPStatusCode  = HTTPStatusCode.Unauthorized,
                                   Server          = HTTPServer.DefaultServerName,
                                   Date            = DateTime.Now,
                                   WWWAuthenticate = @"Basic realm=""" + HTTPRealm + @"""",
                                   ContentType     = HTTPContentType.TEXT_UTF8,
                                   Content         = "Unauthorized Access!".ToUTF8Bytes(),
                                   Connection      = "close"
                               }
                    }
                    ;
                }

                #endregion


                HTTPContentType ResponseContentType = null;

                var FilePath = (Request.ParsedURIParameters != null && Request.ParsedURIParameters.Length > 0)
                                      ? Request.ParsedURIParameters.Last().Replace("/", ".")
                                      : DefaultFilename.Replace("/", ".");

                var FileStream = ResourceAssembly.GetManifestResourceStream(ResourcePath + "." + FilePath);

                if (FileStream != null)
                {
                    #region Choose HTTP Content Type based on the file name extention...

                    var FileName = FilePath.Substring(FilePath.LastIndexOf("/") + 1);

                    // Get the appropriate content type based on the suffix of the requested resource
                    switch (FileName.Remove(0, FileName.LastIndexOf(".") + 1))
                    {
                    case "htm": ResponseContentType = HTTPContentType.HTML_UTF8;       break;

                    case "html": ResponseContentType = HTTPContentType.HTML_UTF8;       break;

                    case "css": ResponseContentType = HTTPContentType.CSS_UTF8;        break;

                    case "gif": ResponseContentType = HTTPContentType.GIF;             break;

                    case "jpg": ResponseContentType = HTTPContentType.JPEG;            break;

                    case "jpeg": ResponseContentType = HTTPContentType.JPEG;            break;

                    case "svg": ResponseContentType = HTTPContentType.SVG;             break;

                    case "png": ResponseContentType = HTTPContentType.PNG;             break;

                    case "ico": ResponseContentType = HTTPContentType.ICO;             break;

                    case "swf": ResponseContentType = HTTPContentType.SWF;             break;

                    case "js": ResponseContentType = HTTPContentType.JAVASCRIPT_UTF8; break;

                    case "txt": ResponseContentType = HTTPContentType.TEXT_UTF8;       break;

                    case "xml":  ResponseContentType = HTTPContentType.XML_UTF8;        break;

                    default:     ResponseContentType = HTTPContentType.OCTETSTREAM;     break;
                    }

                    #endregion

                    #region Create HTTP Response

                    return(new HTTPResponseBuilder(Request)
                    {
                        HTTPStatusCode = HTTPStatusCode.OK,
                        Server = HTTPServer.DefaultServerName,
                        Date = DateTime.Now,
                        ContentType = ResponseContentType,
                        ContentStream = FileStream,
                        CacheControl = "public, max-age=300",
                        //Expires          = "Mon, 25 Jun 2015 21:31:12 GMT",
                        KeepAlive = new KeepAliveType(TimeSpan.FromMinutes(5), 500),
                        Connection = "Keep-Alive",
                    });

                    #endregion
                }

                else
                {
                    #region Try to find a appropriate customized errorpage...

                    Stream ErrorStream = null;

                    Request.BestMatchingAcceptType = Request.Accept.BestMatchingContentType(new HTTPContentType[] { HTTPContentType.HTML_UTF8, HTTPContentType.TEXT_UTF8 });

                    if (Request.BestMatchingAcceptType == HTTPContentType.HTML_UTF8)
                    {
                        ResponseContentType = HTTPContentType.HTML_UTF8;
                        ErrorStream         = ResourceAssembly.GetManifestResourceStream(ResourcePath.Substring(0, ResourcePath.LastIndexOf(".")) + ".ErrorPages." + "404.html");
                    }

                    else if (Request.BestMatchingAcceptType == HTTPContentType.TEXT_UTF8)
                    {
                        ResponseContentType = HTTPContentType.TEXT_UTF8;
                        ErrorStream         = ResourceAssembly.GetManifestResourceStream(ResourcePath.Substring(0, ResourcePath.LastIndexOf(".")) + ".ErrorPages." + "404.txt");
                    }

                    else if (Request.BestMatchingAcceptType == HTTPContentType.JSON_UTF8)
                    {
                        ResponseContentType = HTTPContentType.JSON_UTF8;
                        ErrorStream         = ResourceAssembly.GetManifestResourceStream(ResourcePath.Substring(0, ResourcePath.LastIndexOf(".")) + ".ErrorPages." + "404.js");
                    }

                    else if (Request.BestMatchingAcceptType == HTTPContentType.XML_UTF8)
                    {
                        ResponseContentType = HTTPContentType.XML_UTF8;
                        ErrorStream         = ResourceAssembly.GetManifestResourceStream(ResourcePath.Substring(0, ResourcePath.LastIndexOf(".")) + ".ErrorPages." + "404.xml");
                    }

                    else if (Request.BestMatchingAcceptType == HTTPContentType.ALL)
                    {
                        ResponseContentType = HTTPContentType.HTML_UTF8;
                        ErrorStream         = ResourceAssembly.GetManifestResourceStream(ResourcePath.Substring(0, ResourcePath.LastIndexOf(".")) + ".ErrorPages." + "404.html");
                    }

                    if (ErrorStream != null)
                    {
                        return new HTTPResponseBuilder(Request)
                               {
                                   HTTPStatusCode = HTTPStatusCode.NotFound,
                                   Server         = HTTPServer.DefaultServerName,
                                   Date           = DateTime.Now,
                                   ContentType    = ResponseContentType,
                                   ContentStream  = ErrorStream,
                                   CacheControl   = "no-cache",
                                   Connection     = "close",
                               }
                    }
                    ;

                    #endregion

                    #region ...or send a default error page!

                    else
                    {
                        return new HTTPResponseBuilder(Request)
                               {
                                   HTTPStatusCode = HTTPStatusCode.NotFound,
                                   Server         = HTTPServer.DefaultServerName,
                                   Date           = DateTime.Now,
                                   CacheControl   = "no-cache",
                                   Connection     = "close",
                               }
                    };

                    #endregion
                }
            };


            // ~/map
            HTTPServer.AddMethodCallback(Hostname,
                                         HTTPMethod.GET,
                                         URITemplate.EndsWith("/", StringComparison.InvariantCulture) ? URITemplate.Substring(0, URITemplate.Length) : URITemplate,
                                         HTTPDelegate: GetEmbeddedResources);

            // ~/map/
            HTTPServer.AddMethodCallback(Hostname,
                                         HTTPMethod.GET,
                                         URITemplate + (URITemplate.EndsWith("/", StringComparison.InvariantCulture) ? "" : "/"),
                                         HTTPDelegate: GetEmbeddedResources);

            // ~/map/file.name
            HTTPServer.AddMethodCallback(Hostname,
                                         HTTPMethod.GET,
                                         URITemplate + (URITemplate.EndsWith("/", StringComparison.InvariantCulture) ? "{ResourceName}" : "/{ResourceName}"),
                                         HTTPDelegate: GetEmbeddedResources);
        }
Beispiel #16
0
        /// <summary>
        /// Add a method call back for the given URI template and
        /// add a HTTP Sever Sent Events source.
        /// </summary>
        /// <param name="EventIdentification">The unique identification of the event source.</param>
        /// <param name="MaxNumberOfCachedEvents">Maximum number of cached events.</param>
        /// <param name="RetryIntervall">The retry intervall.</param>
        /// 
        /// <param name="Hostname">The HTTP host.</param>
        /// <param name="URITemplate">The URI template.</param>
        /// <param name="HTTPMethod">The HTTP method.</param>
        /// <param name="HTTPContentType">The HTTP content type.</param>
        /// 
        /// <param name="HostAuthentication">Whether this method needs explicit host authentication or not.</param>
        /// <param name="URIAuthentication">Whether this method needs explicit uri authentication or not.</param>
        /// <param name="HTTPMethodAuthentication">Whether this method needs explicit HTTP method authentication or not.</param>
        /// 
        /// <param name="DefaultErrorHandler">The default error handler.</param>
        internal HTTPEventSource AddEventSource(String              EventIdentification,
                                                UInt32              MaxNumberOfCachedEvents     = 500,
                                                TimeSpan?           RetryIntervall              = null,

                                                HTTPHostname        Hostname                    = null,
                                                String              URITemplate                 = "/",
                                                HTTPMethod          HTTPMethod                  = null,
                                                HTTPContentType     HTTPContentType             = null,

                                                HTTPAuthentication  HostAuthentication          = null,
                                                HTTPAuthentication  URIAuthentication           = null,
                                                HTTPAuthentication  HTTPMethodAuthentication    = null,

                                                HTTPDelegate        DefaultErrorHandler         = null)

        {

            lock (Lock)
            {

                #region Get or Create Event Source

                HTTPEventSource _HTTPEventSource;

                if (!_EventSources.TryGetValue(EventIdentification, out _HTTPEventSource))
                    _HTTPEventSource = _EventSources.AddAndReturnValue(EventIdentification,
                                                                       new HTTPEventSource(EventIdentification, MaxNumberOfCachedEvents, RetryIntervall));

                #endregion

                #region Define HTTP Delegate

                HTTPDelegate _HTTPDelegate = Request => {

                    var _LastEventId        = 0UL;
                    var _Client_LastEventId = 0UL;
                    var _EventSource        = GetEventSource(EventIdentification);

                    if (Request.TryGet<UInt64>("Last-Event-ID", out _Client_LastEventId))
                        _LastEventId = _Client_LastEventId;

                    var _HTTPEvents      = (from   _HTTPEvent
                                            in     _EventSource.GetAllEventsGreater(_LastEventId)
                                            where  _HTTPEvent != null
                                            select _HTTPEvent.ToString())
                                           .ToArray(); // For thread safety!

                    // Transform HTTP events into an UTF8 string
                    var _ResourceContent = String.Empty;

                    if (_HTTPEvents.Length > 0)
                        _ResourceContent = Environment.NewLine + _HTTPEvents.Aggregate((a, b) => a + Environment.NewLine + b) + Environment.NewLine;

                    else
                        _ResourceContent += Environment.NewLine + "retry: " + ((UInt32) _EventSource.RetryIntervall.TotalMilliseconds) + Environment.NewLine + Environment.NewLine;


                    return Task.FromResult<HTTPResponse>(
                        new HTTPResponseBuilder(Request) {
                            HTTPStatusCode  = HTTPStatusCode.OK,
                            ContentType     = HTTPContentType.EVENTSTREAM,
                            CacheControl    = "no-cache",
                            Connection      = "keep-alive",
                            KeepAlive       = new KeepAliveType(TimeSpan.FromSeconds(2*_EventSource.RetryIntervall.TotalSeconds)),
                            Content         = _ResourceContent.ToUTF8Bytes()
                        });

                };

                #endregion

                AddHandler(_HTTPDelegate,
                           Hostname,
                           URITemplate,
                           HTTPMethod ?? HTTPMethod.GET,
                           HTTPContentType.EVENTSTREAM,

                           HostAuthentication,
                           URIAuthentication,
                           HTTPMethodAuthentication,
                           null,

                           DefaultErrorHandler);

                return _HTTPEventSource;

            }

        }
Beispiel #17
0
        /// <summary>
        /// Add a method callback for the given URL template.
        /// </summary>
        /// <param name="CommonAPI">The OCPI Common API.</param>
        /// <param name="Hostname">The HTTP hostname.</param>
        /// <param name="HTTPMethod">The HTTP method.</param>
        /// <param name="URLTemplate">The URL template.</param>
        /// <param name="HTTPContentType">The HTTP content type.</param>
        /// <param name="URLAuthentication">Whether this method needs explicit uri authentication or not.</param>
        /// <param name="HTTPMethodAuthentication">Whether this method needs explicit HTTP method authentication or not.</param>
        /// <param name="ContentTypeAuthentication">Whether this method needs explicit HTTP content type authentication or not.</param>
        /// <param name="OCPIRequestLogger">A OCPI request logger.</param>
        /// <param name="OCPIResponseLogger">A OCPI response logger.</param>
        /// <param name="DefaultErrorHandler">The default error handler.</param>
        /// <param name="OCPIRequestHandler">The method to call.</param>
        public static void AddOCPIMethod(this CommonAPI CommonAPI,
                                         HTTPHostname Hostname,
                                         HTTPMethod HTTPMethod,
                                         HTTPPath URLTemplate,
                                         HTTPContentType HTTPContentType              = null,
                                         HTTPAuthentication URLAuthentication         = null,
                                         HTTPAuthentication HTTPMethodAuthentication  = null,
                                         HTTPAuthentication ContentTypeAuthentication = null,
                                         OCPIRequestLogHandler OCPIRequestLogger      = null,
                                         OCPIResponseLogHandler OCPIResponseLogger    = null,
                                         HTTPDelegate DefaultErrorHandler             = null,
                                         OCPIRequestDelegate OCPIRequestHandler       = null,
                                         URLReplacement AllowReplacement              = URLReplacement.Fail)

        {
            CommonAPI.HTTPServer.
            AddMethodCallback(Hostname,
                              HTTPMethod,
                              URLTemplate,
                              HTTPContentType,
                              URLAuthentication,
                              HTTPMethodAuthentication,
                              ContentTypeAuthentication,
                              (timestamp, httpAPI, httpRequest) => OCPIRequestLogger?.Invoke(timestamp, null, HTTP.OCPIRequest.Parse(httpRequest, CommonAPI)),
                              (timestamp, httpAPI, httpRequest, httpResponse) => OCPIResponseLogger?.Invoke(timestamp, null, httpRequest.SubprotocolRequest  as OCPIRequest,
                                                                                                            (httpResponse.SubprotocolResponse as OCPIResponse)
                                                                                                            ?? new OCPIResponse(httpRequest.SubprotocolRequest as OCPIRequest,
                                                                                                                                2000,
                                                                                                                                "OCPIResponse is null!",
                                                                                                                                httpResponse.HTTPBodyAsUTF8String,
                                                                                                                                httpResponse.Timestamp,
                                                                                                                                httpResponse)),
                              DefaultErrorHandler,
                              async httpRequest => {
                try
                {
                    // When no OCPIRequestLogger was used!
                    if (httpRequest.SubprotocolRequest is null)
                    {
                        httpRequest.SubprotocolRequest = OCPIRequest.Parse(httpRequest, CommonAPI);
                    }

                    var OCPIResponseBuilder = await OCPIRequestHandler(httpRequest.SubprotocolRequest as OCPIRequest);
                    var httpResponseBuilder = OCPIResponseBuilder.ToHTTPResponseBuilder();

                    httpResponseBuilder.SubprotocolResponse = new OCPIResponse(OCPIResponseBuilder.Request,
                                                                               OCPIResponseBuilder.StatusCode ?? 3000,
                                                                               OCPIResponseBuilder.StatusMessage,
                                                                               OCPIResponseBuilder.AdditionalInformation,
                                                                               OCPIResponseBuilder.Timestamp ?? DateTime.UtcNow,
                                                                               httpResponseBuilder.AsImmutable);

                    return(httpResponseBuilder);
                }
                catch (Exception e)
                {
                    return(new HTTPResponse.Builder(HTTPStatusCode.InternalServerError)
                    {
                        ContentType = HTTPContentType.JSON_UTF8,
                        Content = new OCPIResponse <JObject>(
                            JSONObject.Create(
                                new JProperty("description", e.Message),
                                new JProperty("stacktrace", e.StackTrace.Split(new String[] { Environment.NewLine }, StringSplitOptions.None).ToArray()),
                                new JProperty("source", e.TargetSite.Module.Name),
                                new JProperty("type", e.TargetSite.ReflectedType.Name)
                                ),
                            2000,
                            e.Message,
                            null,
                            DateTime.UtcNow,
                            null,
                            (httpRequest.SubprotocolRequest as OCPIRequest)?.RequestId,
                            (httpRequest.SubprotocolRequest as OCPIRequest)?.CorrelationId
                            ).ToJSON(json => json).ToUTF8Bytes(),
                        Connection = "close"
                    });
                }
            },
                              AllowReplacement);
        }
Beispiel #18
0
        // Method Callbacks

        #region (internal) AddHandler(HTTPDelegate, Hostname = "*", URITemplate = "/", HTTPMethod = null, HTTPContentType = null, HostAuthentication = null, URIAuthentication = null, HTTPMethodAuthentication = null, ContentTypeAuthentication = null, DefaultErrorHandler = null)

        /// <summary>
        /// Add a method callback for the given URI template.
        /// </summary>
        /// <param name="HTTPDelegate">A delegate called for each incoming HTTP request.</param>
        /// <param name="Hostname">The HTTP hostname.</param>
        /// <param name="URITemplate">The URI template.</param>
        /// <param name="HTTPMethod">The HTTP method.</param>
        /// <param name="HTTPContentType">The HTTP content type.</param>
        /// <param name="HostAuthentication">Whether this method needs explicit host authentication or not.</param>
        /// <param name="URIAuthentication">Whether this method needs explicit uri authentication or not.</param>
        /// <param name="HTTPMethodAuthentication">Whether this method needs explicit HTTP method authentication or not.</param>
        /// <param name="ContentTypeAuthentication">Whether this method needs explicit HTTP content type authentication or not.</param>
        /// <param name="DefaultErrorHandler">The default error handler.</param>
        internal void AddHandler(HTTPDelegate HTTPDelegate,

                                 HTTPHostname Hostname           = null,
                                 String URITemplate              = "/",
                                 HTTPMethod HTTPMethod           = null,
                                 HTTPContentType HTTPContentType = null,

                                 HTTPAuthentication HostAuthentication        = null,
                                 HTTPAuthentication URIAuthentication         = null,
                                 HTTPAuthentication HTTPMethodAuthentication  = null,
                                 HTTPAuthentication ContentTypeAuthentication = null,

                                 HTTPDelegate DefaultErrorHandler = null,
                                 URIReplacement AllowReplacement  = URIReplacement.Fail)

        {
            lock (Lock)
            {
                #region Initial Checks

                if (HTTPDelegate == null)
                {
                    throw new ArgumentNullException("HTTPDelegate", "The given parameter must not be null!");
                }

                if (Hostname == null)
                {
                    Hostname = HTTPHostname.Any;
                }

                if (URITemplate.IsNullOrEmpty())
                {
                    URITemplate = "/";
                }

                if (HTTPMethod == null && HTTPContentType != null)
                {
                    throw new ArgumentNullException("If HTTPMethod is null the HTTPContentType must also be null!");
                }

                #endregion

                #region AddOrUpdate HostNode

                HostnameNode _HostnameNode = null;
                if (!_HostnameNodes.TryGetValue(Hostname, out _HostnameNode))
                {
                    _HostnameNode = new HostnameNode(Hostname, HostAuthentication, HTTPDelegate, DefaultErrorHandler);
                    _HostnameNodes.Add(Hostname, _HostnameNode);
                }

                #endregion

                _HostnameNode.AddHandler(HTTPDelegate,

                                         URITemplate,
                                         HTTPMethod,
                                         HTTPContentType,

                                         URIAuthentication,
                                         HTTPMethodAuthentication,
                                         ContentTypeAuthentication,

                                         DefaultErrorHandler,
                                         AllowReplacement);
            }
        }
Beispiel #19
0
        /// <summary>
        /// Add a method call back for the given URI template and
        /// add a HTTP Sever Sent Events source.
        /// </summary>
        /// <param name="EventIdentification">The unique identification of the event source.</param>
        /// <param name="URITemplate">The URI template.</param>
        ///
        /// <param name="MaxNumberOfCachedEvents">Maximum number of cached events.</param>
        /// <param name="RetryIntervall">The retry intervall.</param>
        /// <param name="LogfileName">A delegate to create a filename for storing and reloading events.</param>
        ///
        /// <param name="Hostname">The HTTP host.</param>
        /// <param name="HTTPMethod">The HTTP method.</param>
        /// <param name="HTTPContentType">The HTTP content type.</param>
        ///
        /// <param name="HostAuthentication">Whether this method needs explicit host authentication or not.</param>
        /// <param name="URIAuthentication">Whether this method needs explicit uri authentication or not.</param>
        /// <param name="HTTPMethodAuthentication">Whether this method needs explicit HTTP method authentication or not.</param>
        ///
        /// <param name="DefaultErrorHandler">The default error handler.</param>
        internal HTTPEventSource AddEventSource(String EventIdentification,
                                                String URITemplate,

                                                UInt32 MaxNumberOfCachedEvents = 500,
                                                TimeSpan?RetryIntervall        = null,
                                                Func <String, DateTime, String> LogfileName = null,

                                                HTTPHostname Hostname           = null,
                                                HTTPMethod HTTPMethod           = null,
                                                HTTPContentType HTTPContentType = null,

                                                HTTPAuthentication HostAuthentication       = null,
                                                HTTPAuthentication URIAuthentication        = null,
                                                HTTPAuthentication HTTPMethodAuthentication = null,

                                                HTTPDelegate DefaultErrorHandler = null)

        {
            lock (Lock)
            {
                #region Get or Create Event Source

                HTTPEventSource _HTTPEventSource;

                if (!_EventSources.TryGetValue(EventIdentification, out _HTTPEventSource))
                {
                    _HTTPEventSource = _EventSources.AddAndReturnValue(EventIdentification,
                                                                       new HTTPEventSource(EventIdentification,
                                                                                           MaxNumberOfCachedEvents,
                                                                                           RetryIntervall,
                                                                                           LogfileName));
                }

                #endregion

                #region Define HTTP Delegate

                HTTPDelegate _HTTPDelegate = Request => {
                    var _LastEventId        = 0UL;
                    var _Client_LastEventId = 0UL;
                    var _EventSource        = GetEventSource(EventIdentification);

                    if (Request.TryGet <UInt64>("Last-Event-ID", out _Client_LastEventId))
                    {
                        _LastEventId = _Client_LastEventId;
                    }

                    var _HTTPEvents = (from _HTTPEvent
                                       in     _EventSource.GetAllEventsGreater(_LastEventId)
                                       where  _HTTPEvent != null
                                       select _HTTPEvent.ToString())
                                      .ToArray();      // For thread safety!

                    // Transform HTTP events into an UTF8 string
                    var _ResourceContent = String.Empty;

                    if (_HTTPEvents.Length > 0)
                    {
                        _ResourceContent = Environment.NewLine + _HTTPEvents.Aggregate((a, b) => a + Environment.NewLine + b) + Environment.NewLine;
                    }

                    else
                    {
                        _ResourceContent += Environment.NewLine + "retry: " + ((UInt32)_EventSource.RetryIntervall.TotalMilliseconds) + Environment.NewLine + Environment.NewLine;
                    }


                    return(Task.FromResult <HTTPResponse>(
                               new HTTPResponseBuilder(Request)
                    {
                        HTTPStatusCode = HTTPStatusCode.OK,
                        ContentType = HTTPContentType.EVENTSTREAM,
                        CacheControl = "no-cache",
                        Connection = "keep-alive",
                        KeepAlive = new KeepAliveType(TimeSpan.FromSeconds(2 * _EventSource.RetryIntervall.TotalSeconds)),
                        Content = _ResourceContent.ToUTF8Bytes()
                    }));
                };

                #endregion

                AddHandler(_HTTPDelegate,
                           Hostname,
                           URITemplate,
                           HTTPMethod ?? HTTPMethod.GET,
                           HTTPContentType.EVENTSTREAM,

                           HostAuthentication,
                           URIAuthentication,
                           HTTPMethodAuthentication,
                           null,

                           DefaultErrorHandler);

                return(_HTTPEventSource);
            }
        }
Beispiel #20
0
        // Method Callbacks

        #region (internal) AddHandler(HTTPDelegate, Hostname = "*", URITemplate = "/", HTTPMethod = null, HTTPContentType = null, HostAuthentication = null, URIAuthentication = null, HTTPMethodAuthentication = null, ContentTypeAuthentication = null, DefaultErrorHandler = null)

        /// <summary>
        /// Add a method callback for the given URI template.
        /// </summary>
        /// <param name="HTTPDelegate">A delegate called for each incoming HTTP request.</param>
        /// <param name="Hostname">The HTTP hostname.</param>
        /// <param name="URITemplate">The URI template.</param>
        /// <param name="HTTPMethod">The HTTP method.</param>
        /// <param name="HTTPContentType">The HTTP content type.</param>
        /// <param name="HostAuthentication">Whether this method needs explicit host authentication or not.</param>
        /// <param name="URIAuthentication">Whether this method needs explicit uri authentication or not.</param>
        /// <param name="HTTPMethodAuthentication">Whether this method needs explicit HTTP method authentication or not.</param>
        /// <param name="ContentTypeAuthentication">Whether this method needs explicit HTTP content type authentication or not.</param>
        /// <param name="DefaultErrorHandler">The default error handler.</param>
        internal void AddHandler(HTTPDelegate        HTTPDelegate,

                                 HTTPHostname        Hostname                    = null,
                                 String              URITemplate                 = "/",
                                 HTTPMethod          HTTPMethod                  = null,
                                 HTTPContentType     HTTPContentType             = null,

                                 HTTPAuthentication  HostAuthentication          = null,
                                 HTTPAuthentication  URIAuthentication           = null,
                                 HTTPAuthentication  HTTPMethodAuthentication    = null,
                                 HTTPAuthentication  ContentTypeAuthentication   = null,

                                 HTTPDelegate        DefaultErrorHandler         = null,
                                 URIReplacement      AllowReplacement            = URIReplacement.Fail)

        {

            lock (Lock)
            {

                #region Initial Checks

                if (HTTPDelegate == null)
                    throw new ArgumentNullException("HTTPDelegate", "The given parameter must not be null!");

                if (Hostname == null)
                    Hostname = HTTPHostname.Any;

                if (URITemplate.IsNullOrEmpty())
                    URITemplate = "/";

                if (HTTPMethod == null && HTTPContentType != null)
                    throw new ArgumentNullException("If HTTPMethod is null the HTTPContentType must also be null!");

                #endregion

                #region AddOrUpdate HostNode

                HostnameNode _HostnameNode = null;
                if (!_HostnameNodes.TryGetValue(Hostname, out _HostnameNode))
                {
                    _HostnameNode = new HostnameNode(Hostname, HostAuthentication, HTTPDelegate, DefaultErrorHandler);
                    _HostnameNodes.Add(Hostname, _HostnameNode);
                }

                #endregion

                _HostnameNode.AddHandler(HTTPDelegate,

                                         URITemplate,
                                         HTTPMethod,
                                         HTTPContentType,

                                         URIAuthentication,
                                         HTTPMethodAuthentication,
                                         ContentTypeAuthentication,

                                         DefaultErrorHandler,
                                         AllowReplacement);

            }

        }