/// <summary>
 /// Create a new abstract remote charging station operator attached via a computer network (HTTPS/TCP/IP).
 /// </summary>
 /// <param name="Hostname">The remote hostname.</param>
 /// <param name="VirtualHostname">An optional remote virtual hostname.</param>
 /// <param name="RemotePort">An optional remote HTTPS port.</param>
 /// <param name="RemoteCertificateValidator">An optional remote SSL/TLS certificate validator.</param>
 /// <param name="RoamingNetworkId">An optional roaming network identification.</param>
 /// <param name="RequestTimeout">An optional request timeout.</param>
 /// <param name="DNSClient">An optional DNS client to use.</param>
 public ANetworkChargingStationOperator(HTTPHostname Hostname,
                                        HTTPHostname?VirtualHostname = null,
                                        IPPort?RemotePort            = null,
                                        RemoteCertificateValidationCallback RemoteCertificateValidator = null,
                                        RoamingNetwork_Id?RoamingNetworkId = null,
                                        TimeSpan?RequestTimeout            = null,
                                        DNSClient DNSClient = null)
 {
     this.Hostname                   = Hostname;
     this.VirtualHostname            = VirtualHostname ?? this.Hostname;
     this.RemotePort                 = RemotePort ?? DefaultRemotePort;
     this.RemoteCertificateValidator = RemoteCertificateValidator ?? ((sender, certificate, chain, policyErrors) => true);
     this.RoamingNetworkId           = RoamingNetworkId ?? DefaultRoamingNetworkId;
     this.RequestTimeout             = RequestTimeout ?? DefaultRequestTimeout;
     this.DNSClient                  = DNSClient;
 }
Example #2
0
        /// <summary>
        /// Register a EventStream handler.
        /// </summary>
        public static void RegisterEventStreamHandler(this HTTPServer  HTTPServer,
                                                      HTTPHostname     Hostname,
                                                      String           URITemplate,
                                                      String           EventSource)
        {
            HTTPServer.AddMethodCallback(Hostname,
                                         HTTPMethod.GET,
                                         URITemplate,
                                         HTTPDelegate: async Request => {

                                             var _LastEventId        = 0UL;
                                             var _Client_LastEventId = 0UL;
                                             var _EventSource        = HTTPServer.GetEventSource(EventSource);

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

                                             //_LastEventId = 0;

                                             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);

                                             _ResourceContent += Environment.NewLine + "retry: " + _EventSource.RetryIntervall.TotalMilliseconds + Environment.NewLine + Environment.NewLine;

                                             return new HTTPResponseBuilder(Request) {
                                                 HTTPStatusCode  = HTTPStatusCode.OK,
                                                 Server          = HTTPServer.DefaultServerName,
                                                 Date            = DateTime.Now,
                                                 ContentType     = HTTPContentType.EVENTSTREAM,
                                                 CacheControl    = "no-cache",
                                                 Connection      = "keep-alive",
                                                 Content         = _ResourceContent.ToUTF8Bytes()
                                             };

                                         });
        }
        /// <summary>
        /// Create a new OICP Mobile client.
        /// </summary>
        /// <param name="ClientId">A unqiue identification of this client.</param>
        /// <param name="Hostname">The OICP hostname to connect to.</param>
        /// <param name="RemotePort">An optional OICP TCP port to connect to.</param>
        /// <param name="RemoteCertificateValidator">A delegate to verify the remote TLS certificate.</param>
        /// <param name="ClientCertificateSelector">A delegate to select a TLS client certificate.</param>
        /// <param name="HTTPVirtualHost">An optional HTTP virtual host name to use.</param>
        /// <param name="HTTPUserAgent">An optional HTTP user agent to use.</param>
        /// <param name="RequestTimeout">An optional timeout for upstream queries.</param>
        /// <param name="MaxNumberOfRetries">The default number of maximum transmission retries.</param>
        /// <param name="DNSClient">An optional DNS client.</param>
        /// <param name="LoggingContext">An optional context for logging client methods.</param>
        /// <param name="LogfileCreator">A delegate to create a log file from the given context and log file name.</param>
        public MobileClient(String ClientId,
                            HTTPHostname Hostname,
                            IPPort?RemotePort = null,
                            RemoteCertificateValidationCallback RemoteCertificateValidator = null,
                            LocalCertificateSelectionCallback ClientCertificateSelector    = null,
                            HTTPHostname?HTTPVirtualHost          = null,
                            HTTPPath?URLPrefix                    = null,
                            String MobileAuthorizationURL         = DefaultMobileAuthorizationURL,
                            String HTTPUserAgent                  = DefaultHTTPUserAgent,
                            TimeSpan?RequestTimeout               = null,
                            Byte?MaxNumberOfRetries               = DefaultMaxNumberOfRetries,
                            DNSClient DNSClient                   = null,
                            String LoggingContext                 = MobileClientLogger.DefaultContext,
                            LogfileCreatorDelegate LogfileCreator = null)

            : base(ClientId,
                   Hostname,
                   RemotePort ?? DefaultRemotePort,
                   RemoteCertificateValidator,
                   ClientCertificateSelector,
                   HTTPVirtualHost,
                   URLPrefix ?? DefaultURLPrefix,
                   null,
                   HTTPUserAgent,
                   RequestTimeout,
                   null,
                   MaxNumberOfRetries,
                   DNSClient)

        {
            #region Initial checks

            if (ClientId.IsNullOrEmpty())
            {
                throw new ArgumentNullException(nameof(ClientId), "The given client identification must not be null or empty!");
            }

            #endregion

            this.MobileAuthorizationURL = MobileAuthorizationURL ?? DefaultMobileAuthorizationURL;

            this.Logger = new MobileClientLogger(this,
                                                 LoggingContext,
                                                 LogfileCreator);
        }
Example #4
0
        /// <summary>
        /// Register a SOAP delegate.
        /// </summary>
        /// <param name="Hostname">The HTTP hostname.</param>
        /// <param name="URITemplate">The URI template.</param>
        /// <param name="Description">A description of this SOAP delegate.</param>
        /// <param name="SOAPMatch">A delegate to check whether this dispatcher matches the given XML.</param>
        /// <param name="SOAPHeaderAndBodyDelegate">A delegate to process a matching SOAP request.</param>
        public void RegisterSOAPDelegate(HTTPHostname Hostname,
                                         String URITemplate,
                                         String Description,
                                         SOAPMatch SOAPMatch,
                                         SOAPHeaderAndBodyDelegate SOAPHeaderAndBodyDelegate)
        {
            SOAPDispatcher _SOAPDispatcher = null;

            // Check if there are other SOAP dispatchers at the given URI template.
            var _Handler = GetHandler(HTTPHostname.Any,
                                      URITemplate,
                                      HTTPMethod.POST,
                                      ContentTypes => SOAPContentType);

            if (_Handler == null)
            {
                _SOAPDispatcher = new SOAPDispatcher(URITemplate, SOAPContentType);
                _SOAPDispatchers.Add(URITemplate, _SOAPDispatcher);

                // Register a new SOAP dispatcher
                AddMethodCallback(Hostname,
                                  HTTPMethod.POST,
                                  URITemplate,
                                  SOAPContentType,
                                  HTTPDelegate: _SOAPDispatcher.Invoke);

                // Register some information text for people using HTTP GET
                AddMethodCallback(Hostname,
                                  HTTPMethod.GET,
                                  URITemplate,
                                  SOAPContentType,
                                  HTTPDelegate: _SOAPDispatcher.EndpointTextInfo);
            }

            else
            {
                _SOAPDispatcher = _Handler.Target as SOAPDispatcher;
            }


            _SOAPDispatcher.RegisterSOAPDelegate(Description,
                                                 SOAPMatch,
                                                 SOAPHeaderAndBodyDelegate);
        }
        public HTTPNotificationSender(UsersAPI UsersAPI,
                                      HTTPHostname Hostname,
                                      IPPort?HTTPPort = null,
                                      TimeSpan?SendNotificationsEvery  = null,
                                      Boolean DisableSendNotifications = false,
                                      PgpPublicKeyRing PublicKeyRing   = null,
                                      PgpSecretKeyRing SecretKeyRing   = null,
                                      DNSClient DNSClient = null)

            : base(UsersAPI,
                   SendNotificationsEvery,
                   DisableSendNotifications,
                   PublicKeyRing,
                   SecretKeyRing,
                   DNSClient)

        {
            this.Hostname = Hostname;
            this.HTTPPort = HTTPPort ?? DefaultHTTPPort;
        }
Example #6
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>();
        }
Example #7
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="ResourceAssembly">The assembly where the resources are located.</param>
        /// <param name="ResourceFilename">The path to the file within the assembly.</param>
        /// <param name="ResponseContentType">Set the HTTP MIME content-type of the file. If null try to autodetect the content type based on the filename extention.</param>
        /// <param name="CacheControl">Set the HTTP cache control response header.</param>
        public static void RegisterResourcesFile(this HTTPServer  HTTPServer,
                                                 HTTPHostname     Hostname,
                                                 String           URITemplate,
                                                 Assembly         ResourceAssembly,
                                                 String           ResourceFilename,
                                                 HTTPContentType  ResponseContentType  = null,
                                                 String           CacheControl         = "no-cache")
        {
            #region Get the appropriate content type based on the suffix of the requested resource

            if (ResponseContentType == null)
                switch (ResourceFilename.Remove(0, ResourceFilename.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

            HTTPServer.AddMethodCallback(Hostname,
                                         HTTPMethod.GET,
                                         URITemplate,
                                         HTTPContentType: ResponseContentType,
                                         HTTPDelegate: async Request => {

                                             var FileStream = ResourceAssembly.GetManifestResourceStream(ResourceFilename);

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

                                             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(ResourceFilename.Substring(0, ResourceFilename.LastIndexOf(".")) + ".ErrorPages." + "404.html");
                                                 }

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

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

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

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

                                                 if (ErrorStream != null)
                                                     return new HTTPResponseBuilder(Request) {
                                                         HTTPStatusCode = HTTPStatusCode.NotFound,
                                                         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

                                             }

                                         }, AllowReplacement: URIReplacement.Fail);

            return;
        }
Example #8
0
        /// <summary>
        /// Return the RAW request header.
        /// </summary>
        public static void RegisterRAWRequestHandler(this HTTPServer  HTTPServer,
                                                     HTTPHostname     Hostname,
                                                     String           URITemplate,
                                                     HTTPMethod       HTTPMethod = null)
        {
            HTTPServer.AddMethodCallback(Hostname,
                                         HTTPMethod:    HTTPMethod ?? HTTPMethod.GET,
                                         URITemplate:   URITemplate,
                                         HTTPDelegate:  async Request => {

                                             return new HTTPResponseBuilder(Request) {

                                                 HTTPStatusCode  = HTTPStatusCode.OK,
                                                 Server          = HTTPServer.DefaultServerName,
                                                 Date            = DateTime.Now,
                                                 CacheControl    = "no-cache",
                                                 Connection      = "close",
                                                 ContentType     = HTTPContentType.TEXT_UTF8,
                                                 Content         = ("Incoming http connection from '" + Request.RemoteSocket + "'" +
                                                                     Environment.NewLine + Environment.NewLine +
                                                                     Request.RawHTTPHeader +
                                                                     Environment.NewLine + Environment.NewLine +
                                                                     "Method => "         + Request.HTTPMethod      + Environment.NewLine +
                                                                     "URL => "            + Request.URI         + Environment.NewLine +
                                                                     "QueryString => "    + Request.QueryString     + Environment.NewLine +
                                                                     "Protocol => "       + Request.ProtocolName    + Environment.NewLine +
                                                                     "Version => "        + Request.ProtocolVersion + Environment.NewLine).ToUTF8Bytes()

                                             };

            });
        }
Example #9
0
 /// <summary>
 /// Register a MovedTemporarily handler.
 /// </summary>
 public static void RegisterMovedTemporarilyHandler(this HTTPServer  HTTPServer,
                                                    HTTPHostname     Hostname,
                                                    String           URITemplate,
                                                    String           URITarget)
 {
     HTTPServer.AddMethodCallback(Hostname,
                                  HTTPMethod.GET,
                                  URITemplate,
                                  HTTPDelegate: async Request => HTTPTools.MovedTemporarily(Request, URITarget));
 }
Example #10
0
        /// <summary>
        /// Returns resources from the given file system location.
        /// </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="DefaultFilename">The default file to load.</param>
        public static void RegisterFilesystemFolder(this HTTPServer         HTTPServer,
                                                    HTTPHostname            Hostname,
                                                    String                  URITemplate,
                                                    Func<String[], String>  ResourcePath,
                                                    String                  DefaultFilename  = "index.html")
        {
            HTTPServer.AddMethodCallback(Hostname,
                                         HTTPMethod.GET,
                                         URITemplate + (URITemplate.EndsWith("/", StringComparison.InvariantCulture) ? "{ResourceName}" : "/{ResourceName}"),
                                         HTTPContentType: HTTPContentType.PNG,
                                         HTTPDelegate: async Request => {

                                             HTTPContentType ResponseContentType = null;

                                             var NumberOfTemplateParameters = URITemplate.Count(c => c == '{');

                                             var FilePath = (Request.ParsedURIParameters != null && Request.ParsedURIParameters.Length > NumberOfTemplateParameters)
                                                                ? Request.ParsedURIParameters.Last().Replace('/', Path.DirectorySeparatorChar)
                                                                : DefaultFilename.Replace('/', Path.DirectorySeparatorChar);

                                             var FileStream = File.OpenRead(ResourcePath(Request.ParsedURIParameters) + Path.DirectorySeparatorChar + 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;
                                                     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
                                                 return new HTTPResponseBuilder(Request) {
                                                     HTTPStatusCode = HTTPStatusCode.NotFound,
                                                     Server          = HTTPServer.DefaultServerName,
                                                     Date            = DateTime.Now,
                                                     CacheControl   = "no-cache",
                                                     Connection     = "close",
                                                 };

                                         }, AllowReplacement: URIReplacement.Fail);

            return;
        }
Example #11
0
        /// <summary>
        /// Returns resources from the given file system location.
        /// </summary>
        /// <param name="HTTPServer">A HTTP server.</param>
        /// <param name="URITemplate">An URI template.</param>
        /// <param name="DefaultFilename">The default file to load.</param>
        public static void RegisterWatchedFileSystemFolder(this HTTPServer         HTTPServer,
                                                           HTTPHostname            Hostname,
                                                           String                  URITemplate,
                                                           String                  FileSystemLocation,
                                                           String                  HTTPSSE_EventIdentification,
                                                           String                  HTTPSSE_URITemplate,
                                                 //          Func<String[], String>  ResourcePath,
                                                           String                  DefaultFilename  = "index.html")
        {
            #region Setup file system watcher

            var watcher = new FileSystemWatcher() {
                              Path                   = FileSystemLocation,
                              NotifyFilter           = NotifyFilters.FileName |
                                                       NotifyFilters.DirectoryName |
                                                       NotifyFilters.LastWrite,
                              //Filter                 = "*.html",//|*.css|*.js|*.json",
                              IncludeSubdirectories  = true,
                              InternalBufferSize     = 4 * 4096
                          };

            watcher.Created += (s, e) => FileWasChanged(HTTPServer, HTTPSSE_EventIdentification, e.ChangeType.ToString(), e.FullPath.Remove(0, FileSystemLocation.Length).Replace(Path.DirectorySeparatorChar, '/'));
            watcher.Changed += (s, e) => FileWasChanged(HTTPServer, HTTPSSE_EventIdentification, e.ChangeType.ToString(), e.FullPath.Remove(0, FileSystemLocation.Length).Replace(Path.DirectorySeparatorChar, '/'));
            watcher.Renamed += FileWasRenamed;
            watcher.Deleted += (s, e) => FileWasChanged(HTTPServer, HTTPSSE_EventIdentification, e.ChangeType.ToString(), e.FullPath.Remove(0, FileSystemLocation.Length).Replace(Path.DirectorySeparatorChar, '/'));
            watcher.Error   += FileWatcherError;

            #endregion

            HTTPServer.AddEventSource(HTTPSSE_EventIdentification, URITemplate: HTTPSSE_URITemplate);

            HTTPServer.AddMethodCallback(Hostname,
                                         HTTPMethod.GET,
                                         URITemplate + (URITemplate.EndsWith("/", StringComparison.InvariantCulture) ? "{ResourceName}" : "/{ResourceName}"),
                                         HTTPContentType.PNG,
                                         HTTPDelegate: async Request => {

                                             HTTPContentType ResponseContentType = null;

                                             var NumberOfTemplateParameters = URITemplate.Count(c => c == '{');

                                             var FilePath    = (Request.ParsedURIParameters != null && Request.ParsedURIParameters.Length > NumberOfTemplateParameters)
                                                                   ? Request.ParsedURIParameters.Last().Replace('/', Path.DirectorySeparatorChar)
                                                                   : DefaultFilename.Replace('/', Path.DirectorySeparatorChar);

                                             try
                                             {

                                                 var FileStream = File.OpenRead(FileSystemLocation + Path.DirectorySeparatorChar + FilePath);

                                                 if (FileStream != null)
                                                 {

                                                     #region Choose HTTP Content Type based on the file name extention...

                                                     ResponseContentType = HTTPContentType.ForFileExtention(FilePath.Remove(0, FilePath.LastIndexOf(".", StringComparison.InvariantCulture) + 1),
                                                                                                            () => HTTPContentType.OCTETSTREAM).FirstOrDefault();

                                                     #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

                                                 }

                                             }
                                             catch (FileNotFoundException e)
                                             {
                                             }

                                             return new HTTPResponseBuilder(Request) {
                                                 HTTPStatusCode  = HTTPStatusCode.NotFound,
                                                 Server          = HTTPServer.DefaultServerName,
                                                 Date            = DateTime.Now,
                                                 ContentType     = HTTPContentType.TEXT_UTF8,
                                                 Content         = "Error 404 - Not found!".ToUTF8Bytes(),
                                                 CacheControl    = "no-cache",
                                                 Connection      = "close",
                                             };

                                         }, AllowReplacement: URIReplacement.Fail);

            // And now my watch begins...
            watcher.EnableRaisingEvents = true;
        }
Example #12
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);

            }

        }
Example #13
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;

            }

        }
Example #14
0
        /// <summary>
        /// Return the best matching method handler for the given parameters.
        /// </summary>
        internal HTTPDelegate GetHandler(HTTPHostname                              Host,
                                         String                                    URI,
                                         HTTPMethod                                HTTPMethod                   = null,
                                         Func<HTTPContentType[], HTTPContentType>  HTTPContentTypeSelector      = null,
                                         Action<IEnumerable<String>>               ParsedURIParametersDelegate  = null)
        {

            Host                     = Host                    ?? HTTPHostname.Any;
            URI                      = URI.IsNullOrEmpty()      ? "/" : URI;
            HTTPMethod               = HTTPMethod              ?? HTTPMethod.GET;
            HTTPContentTypeSelector  = HTTPContentTypeSelector ?? (v => HTTPContentType.HTML_UTF8);

            lock (Lock)
            {

                #region Get HostNode or "*" or fail

                HostnameNode _HostNode = null;
                if (!_HostnameNodes.TryGetValue(Host, out _HostNode))
                    if (!_HostnameNodes.TryGetValue(HTTPHostname.Any, out _HostNode))
                        return null;
                        //return GetErrorHandler(Host, URL, HTTPMethod, HTTPContentType, HTTPStatusCode.BadRequest);

                #endregion

                #region Try to find the best matching URLNode...

                var _RegexList    = from   __URLNode
                                    in     _HostNode.URINodes.Values
                                    select new {
                                        URLNode = __URLNode,
                                        Regex   = __URLNode.URIRegex
                                    };

                var _AllTemplates = from   _RegexTupel
                                    in     _RegexList
                                    select new {
                                        URLNode = _RegexTupel.URLNode,
                                        Match   = _RegexTupel.Regex.Match(URI)
                                    };

                var _Matches      = from    _Match
                                    in      _AllTemplates
                                    where   _Match.Match.Success
                                    orderby 100*_Match.URLNode.SortLength +
                                                _Match.URLNode.ParameterCount
                                            descending
                                    select  new {
                                        URLNode = _Match.URLNode,
                                        Match   = _Match.Match
                                    };

                #endregion

                #region ...or return HostNode

                if (!_Matches.Any())
                {

                    //if (_HostNode.RequestHandler != null)
                    //    return _HostNode.RequestHandler;

                    return null;

                }

                #endregion


                HTTPMethodNode  _HTTPMethodNode       = null;
                ContentTypeNode _HTTPContentTypeNode  = null;

                // Caused e.g. by the naming of the variables within the
                // URI templates, there could be multiple matches!
                //foreach (var _Match in _Matches)
                //{

                // Use best matching URL Handler!
                var _Match2 = _Matches.First();

                    #region Copy MethodHandler Parameters

                    var _Parameters = new List<String>();
                    for (var i = 1; i < _Match2.Match.Groups.Count; i++)
                        _Parameters.Add(_Match2.Match.Groups[i].Value.RemoveLastSlash());

                    var ParsedURIParametersDelegateLocal = ParsedURIParametersDelegate;
                    if (ParsedURIParametersDelegateLocal != null)
                        ParsedURIParametersDelegate(_Parameters);

                    #endregion

                    // If HTTPMethod was found...
                    if (_Match2.URLNode.HTTPMethods.TryGetValue(HTTPMethod, out _HTTPMethodNode))
                    {

                        var BestMatchingContentType = HTTPContentTypeSelector(_HTTPMethodNode.HTTPContentTypes.Keys.ToArray());

                        // Get HTTPContentTypeNode
                        if (!_HTTPMethodNode.HTTPContentTypes.TryGetValue(BestMatchingContentType, out _HTTPContentTypeNode))
                            return _HTTPMethodNode.RequestHandler;

                        return _HTTPContentTypeNode.RequestHandler;

                    }

                //}

                // No HTTPMethod was found => return best matching URL Handler
                return _Match2.URLNode.RequestHandler;

                //return GetErrorHandler(Host, URL, HTTPMethod, HTTPContentType, HTTPStatusCode.BadRequest);

            }

        }
Example #15
0
        /// <summary>
        /// Register a SOAP delegate.
        /// </summary>
        /// <param name="Hostname">The HTTP hostname.</param>
        /// <param name="URITemplate">The URI template.</param>
        /// <param name="Description">A description of this SOAP delegate.</param>
        /// <param name="SOAPMatch">A delegate to check whether this dispatcher matches the given XML.</param>
        /// <param name="SOAPHeaderAndBodyDelegate">A delegate to process a matching SOAP request.</param>
        public void RegisterSOAPDelegate(HTTPHostname               Hostname,
                                         String                     URITemplate,
                                         String                     Description,
                                         SOAPMatch                  SOAPMatch,
                                         SOAPHeaderAndBodyDelegate  SOAPHeaderAndBodyDelegate)
        {
            SOAPDispatcher _SOAPDispatcher = null;

            // Check if there are other SOAP dispatchers at the given URI template.
            var _Handler = GetHandler(HTTPHostname.Any,
                                      URITemplate,
                                      HTTPMethod.POST,
                                      ContentTypes => SOAPContentType);

            if (_Handler == null)
            {

                _SOAPDispatcher = new SOAPDispatcher(URITemplate, SOAPContentType);
                _SOAPDispatchers.Add(URITemplate, _SOAPDispatcher);

                // Register a new SOAP dispatcher
                AddMethodCallback(Hostname,
                                  HTTPMethod.POST,
                                  URITemplate,
                                  SOAPContentType,
                                  HTTPDelegate: _SOAPDispatcher.Invoke);

                // Register some information text for people using HTTP GET
                AddMethodCallback(Hostname,
                                  HTTPMethod.GET,
                                  URITemplate,
                                  SOAPContentType,
                                  HTTPDelegate: _SOAPDispatcher.EndpointTextInfo);

            }

            else
                _SOAPDispatcher = _Handler.Target as SOAPDispatcher;

            _SOAPDispatcher.RegisterSOAPDelegate(Description,
                                                 SOAPMatch,
                                                 SOAPHeaderAndBodyDelegate);
        }
Example #16
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 HTTPServer  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);
        }
Example #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);
        }
Example #18
0
        /// <summary>
        /// Returns a resource from the given file system location.
        /// </summary>
        /// <param name="HTTPServer">A HTTP server.</param>
        /// <param name="Hostname">The HTTP hostname.</param>
        /// <param name="URITemplate">An URI template.</param>
        /// <param name="ResourceFilenameBuilder">The path to the file within the assembly.</param>
        /// <param name="DefaultFile">If an error occures, return this file.</param>
        /// <param name="ResponseContentType">Set the HTTP MIME content-type of the file. If null try to autodetect the content type based on the filename extention.</param>
        /// <param name="CacheControl">Set the HTTP cache control response header.</param>
        public static void RegisterFilesystemFile(this HTTPServer         HTTPServer,
                                                  HTTPHostname            Hostname,
                                                  String                  URITemplate,
                                                  Func<String[], String>  ResourceFilenameBuilder,
                                                  String                  DefaultFile          = null,
                                                  HTTPContentType         ResponseContentType  = null,
                                                  String                  CacheControl         = "no-cache")
        {
            #region Get the appropriate content type based on the suffix returned by the ResourceFilenameBuilder

                                                                                  // NumberOfTemplateParameters
            var _ResourceFilename = ResourceFilenameBuilder(Enumerable.Repeat("", URITemplate.Count(c => c == '{')).ToArray());

            if (ResponseContentType == null)
                switch (_ResourceFilename.Remove(0, _ResourceFilename.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;
                    default:     ResponseContentType = HTTPContentType.OCTETSTREAM;     break;
                }

            #endregion

            HTTPServer.AddMethodCallback(Hostname,
                                         HTTPMethod.GET,
                                         URITemplate,
                                         HTTPContentType: ResponseContentType,
                                         HTTPDelegate: async Request => {

                                             var ResourceFilename = ResourceFilenameBuilder(Request.ParsedURIParameters);

                                             if (!File.Exists(ResourceFilename) && DefaultFile != null)
                                                 ResourceFilename = DefaultFile;

                                             if (File.Exists(ResourceFilename))
                                             {

                                                 var FileStream = File.OpenRead(ResourceFilename);
                                                 if (FileStream != null)
                                                 {

                                                     return new HTTPResponseBuilder(Request)
                                                     {
                                                         HTTPStatusCode  = HTTPStatusCode.OK,
                                                         Server          = HTTPServer.DefaultServerName,
                                                         Date            = DateTime.Now,
                                                         ContentType     = ResponseContentType,
                                                         ContentStream   = FileStream,
                                                         CacheControl    = CacheControl,
                                                         Connection      = "close",
                                                     };

                                                 }

                                             }

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

                                         }, AllowReplacement: URIReplacement.Fail);

            return;
        }
Example #19
0
        /// <summary>
        /// Create a new OICP roaming client for CPOs.
        /// </summary>
        /// <param name="ClientId">A unqiue identification of this client.</param>
        /// <param name="RemoteHostname">The hostname of the remote OICP service.</param>
        /// <param name="RemoteTCPPort">An optional TCP port of the remote OICP service.</param>
        /// <param name="RemoteCertificateValidator">A delegate to verify the remote TLS certificate.</param>
        /// <param name="ClientCertificateSelector">A delegate to select a TLS client certificate.</param>
        /// <param name="RemoteHTTPVirtualHost">An optional HTTP virtual hostname of the remote OICP service.</param>
        /// <param name="HTTPUserAgent">An optional HTTP user agent identification string for this HTTP client.</param>
        /// <param name="RequestTimeout">An optional timeout for upstream queries.</param>
        /// <param name="MaxNumberOfRetries">The default number of maximum transmission retries.</param>
        ///
        /// <param name="ServerName">An optional identification string for the HTTP server.</param>
        /// <param name="ServiceName">An optional identification for this SOAP service.</param>
        /// <param name="ServerTCPPort">An optional TCP port for the HTTP server.</param>
        /// <param name="ServerURLPrefix">An optional prefix for the HTTP URLs.</param>
        /// <param name="ServerContentType">An optional HTTP content type to use.</param>
        /// <param name="ServerRegisterHTTPRootService">Register HTTP root services for sending a notice to clients connecting via HTML or plain text.</param>
        /// <param name="ServerAutoStart">Whether to start the server immediately or not.</param>
        ///
        /// <param name="ClientLoggingContext">An optional context for logging client methods.</param>
        /// <param name="ServerLoggingContext">An optional context for logging server methods.</param>
        /// <param name="LogfileCreator">A delegate to create a log file from the given context and log file name.</param>
        ///
        /// <param name="DNSClient">An optional DNS client to use.</param>
        public CPORoaming(String ClientId,
                          HTTPHostname RemoteHostname,
                          IPPort?RemoteTCPPort = null,
                          RemoteCertificateValidationCallback RemoteCertificateValidator = null,
                          LocalCertificateSelectionCallback ClientCertificateSelector    = null,
                          HTTPHostname?RemoteHTTPVirtualHost = null,
                          HTTPPath?URLPrefix           = null,
                          String EVSEDataURL           = CPOClient.DefaultEVSEDataURL,
                          String EVSEStatusURL         = CPOClient.DefaultEVSEStatusURL,
                          String AuthorizationURL      = CPOClient.DefaultAuthorizationURL,
                          String AuthenticationDataURL = CPOClient.DefaultAuthenticationDataURL,
                          String HTTPUserAgent         = CPOClient.DefaultHTTPUserAgent,
                          TimeSpan?RequestTimeout      = null,
                          Byte?MaxNumberOfRetries      = CPOClient.DefaultMaxNumberOfRetries,

                          String ServerName                     = CPOSOAPServer.DefaultHTTPServerName,
                          IPPort?ServerTCPPort                  = null,
                          String ServiceName                    = null,
                          HTTPPath?ServerURLPrefix              = null,
                          String ServerAuthorizationURL         = CPOSOAPServer.DefaultAuthorizationURL,
                          String ServerReservationURL           = CPOSOAPServer.DefaultReservationURL,
                          HTTPContentType ServerContentType     = null,
                          Boolean ServerRegisterHTTPRootService = true,
                          Boolean ServerAutoStart               = false,

                          String ClientLoggingContext           = CPOClient.CPOClientLogger.DefaultContext,
                          String ServerLoggingContext           = CPOServerLogger.DefaultContext,
                          LogfileCreatorDelegate LogfileCreator = null,

                          DNSClient DNSClient = null)

            : this(new CPOClient(ClientId,
                                 RemoteHostname,
                                 RemoteTCPPort,
                                 RemoteCertificateValidator,
                                 ClientCertificateSelector,
                                 RemoteHTTPVirtualHost,
                                 URLPrefix ?? CPOClient.DefaultURLPrefix,
                                 EVSEDataURL,
                                 EVSEStatusURL,
                                 AuthorizationURL,
                                 AuthenticationDataURL,
                                 HTTPUserAgent,
                                 RequestTimeout,
                                 MaxNumberOfRetries,
                                 DNSClient,
                                 ClientLoggingContext,
                                 LogfileCreator),

                   new CPOSOAPServer(ServerName,
                                     ServerTCPPort,
                                     ServiceName,
                                     ServerURLPrefix ?? CPOSOAPServer.DefaultURLPathPrefix,
                                     ServerAuthorizationURL,
                                     ServerReservationURL,
                                     ServerContentType,
                                     ServerRegisterHTTPRootService,
                                     DNSClient,
                                     false),

                   ServerLoggingContext,
                   LogfileCreator)

        {
            if (ServerAutoStart)
            {
                Start();
            }
        }