public Task <EditorHttpResonseData> WebAPIProccessor(string apiParams, HttpListenerResponse response)
        {
            string filePath = IPath.Combine(BApplication.DevOpsPublishAssetsPath, PublishPipelineTools.UPLOAD_FOLDER_SUFFIX, apiParams);

            if (!File.Exists(filePath))
            {
                response.ContentLength64 = 0;
                response.StatusCode      = 400;
                response.Abort();
            }
            else
            {
                response.StatusCode  = 200;
                response.ContentType = "application/octet-stream";
                FileStream fileStream = new System.IO.FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read, FileShare.ReadWrite);
                int        byteLength = (int)fileStream.Length;
                byte[]     fileBytes  = new byte[byteLength];
                fileStream.Read(fileBytes, 0, byteLength);
                fileStream.Close();
                fileStream.Dispose();
                response.ContentLength64 = byteLength;
                response.OutputStream.Write(fileBytes, 0, byteLength);
                response.OutputStream.Close();
            }

            //自行处理
            return(null);
        }
Esempio n. 2
0
        public static void WaitForConnections()
        {
            listener.Prefixes.Add("http://*:" + Port + "/");
            listener.Start();
            Thread iconthread = new Thread(() => createIcon(true));

            iconthread.Name = "IconThread";
            iconthread.Start();
            while (true)
            {
                while (true)
                {
                    HttpListenerContext  s        = listener.GetContext();
                    HttpListenerResponse response = s.Response;
                    if (BanList.Contains(s.Request.RemoteEndPoint.Address.ToString()))
                    {
                        response.Abort();
                        continue;
                    }
                    response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, user, password");
                    response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
                    response.AppendHeader("Access-Control-Allow-Origin", "*");
                    response.AppendHeader("Content-Type", "text/plain;charset=UTF-8");
                    response.ContentEncoding = Encoding.UTF8;
                    totalconnections++;
                    SpawnNewClient = new Thread(() => NewClient(s));
                    SpawnNewClient.Start();
                }
            }
        }
Esempio n. 3
0
 public bool Abort()
 {
     try
     {
         response.Abort();
         return(true);
     }
     catch (Exception)
     {
         return(false);
     }
 }
Esempio n. 4
0
        public static void WriteFileChunked(this HttpListenerResponse response, string path)
        {
            if (!File.Exists(path))
            {
                response.StatusCode = (int)HttpStatusCode.NotFound;
                response.WriteText($"The file '{path}' could not be found. Are you sure this is the correct url?");
                return;
            }

            //Get exetension
            var ext = Path.GetExtension(path);

            response.ContentType     = ContentType.FromFileExtension(ext);
            response.ContentEncoding = Encoding.UTF8;

            //Send in chunks
            response.SendChunked = true;

            //Prepare read values
            int bytesRead;

            byte[] chunk = new byte[CHUNK_SIZE];

            //Do the reading
            try
            {
                using (FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                {
                    using (BinaryReader reader = new BinaryReader(stream))
                    {
                        using (Stream outputStream = response.OutputStream)
                        {
                            while ((bytesRead = reader.Read(chunk, 0, chunk.Length)) > 0)
                            {
                                outputStream.Write(chunk, 0, bytesRead);
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                throw e;
            }
            finally
            {
                response.Abort();
            }
        }
Esempio n. 5
0
        [ConditionalFact(nameof(Helpers) + "." + nameof(Helpers.IsWindowsImplementation))] // [ActiveIssue(19975, TestPlatforms.AnyUnix)]
        public async Task Abort_Invoke_ForciblyTerminatesConnection()
        {
            Client.Send(Factory.GetContent("1.1", "POST", null, "Give me a context, please", null, headerOnly: false));
            HttpListenerContext context = await Factory.GetListener().GetContextAsync();

            HttpListenerResponse response = context.Response;
            Stream ouputStream            = response.OutputStream;

            response.Abort();

            // Aborting the response should dispose the response.
            Assert.Throws <ObjectDisposedException>(() => response.ContentType = null);

            // The output stream should be not be disposed.
            // NOTE: using Assert.Throws<ObjectDisposedException>(() => ...) doesn't work here as XUnit internally
            // throws an ObjectDisposedException after we have caught the ObjectDisposedException.
            bool threwObjectDisposedException = false;

            try
            {
                ouputStream.Write(SimpleMessage, 0, SimpleMessage.Length);
            }
            catch (ObjectDisposedException)
            {
                threwObjectDisposedException = true;
            }
            Assert.True(threwObjectDisposedException);

            // The connection should be forcibly terminated.
            Assert.Throws <SocketException>(() => GetClientResponse(120));

            // Extra calls to Abort, Close or Dispose are nops.
            response.Abort();
            response.Close();
            ((IDisposable)response).Dispose();
        }
Esempio n. 6
0
 static void ReturnInternalError(HttpListenerResponse response, Exception cause)
 {
     Console.Error.WriteLine(cause);
     response.StatusCode  = (int)HttpStatusCode.InternalServerError;
     response.ContentType = "text/plain";
     try
     {
         using (var writer = new StreamWriter(response.OutputStream, Encoding.UTF8))
             writer.Write(cause.ToString());
         response.Close();
     }
     catch (Exception e)
     {
         Console.Error.WriteLine(e);
         response.Abort();
     }
 }
Esempio n. 7
0
        public async Task Dispose_Invoke_ClosesConnection()
        {
            using (HttpListenerResponse response = await GetResponse())
            {
                Stream ouputStream = response.OutputStream;
                ((IDisposable)response).Dispose();

                // Aborting the response should dispose the response.
                Assert.Throws <ObjectDisposedException>(() => response.ContentType = null);

                // The output stream should be disposed.
                ouputStream.Write(SimpleMessage, 0, SimpleMessage.Length);

                // The connection should not be forcibly terminated.
                string clientResponse = GetClientResponse(120);
                Assert.NotEmpty(clientResponse);

                // Extra calls to Abort, Close or Dispose are nops.
                response.Abort();
                response.Close();
                ((IDisposable)response).Dispose();
            }
        }
Esempio n. 8
0
 public void Abort()
 {
     _response.Abort();
 }
Esempio n. 9
0
 public void Abort() => inner.Abort();
Esempio n. 10
0
 public override void Abort()
 {
     res.Abort();
 }
Esempio n. 11
0
    //处理客户端请求
    private void HandleRequest(object ctx)
    {
        HttpListenerContext  context  = ctx as HttpListenerContext;
        HttpListenerResponse response = context.Response;
        HttpListenerRequest  request  = context.Request;

        try
        {
            string rawUrl          = request.RawUrl;
            int    paramStartIndex = rawUrl.IndexOf('?');
            if (paramStartIndex > 0)
            {
                rawUrl = rawUrl.Substring(0, paramStartIndex);
            }
            else if (paramStartIndex == 0)
            {
                rawUrl = "";
            }


            #region 网页请求
            //string InputStream = "";
            using (var streamReader = new StreamReader(request.InputStream))
            {
                //InputStream = streamReader.ReadToEnd();
            }
            string filePath = "";
            if (string.IsNullOrEmpty(rawUrl) || rawUrl.Length == 0 || rawUrl == "/")
            {
                filePath = WebHomeDir + "/index.html";                // + directorySeparatorChar + "Index.html";
            }
            else
            {
                filePath = WebHomeDir + rawUrl;                //.Replace("/", directorySeparatorChar);
            }
            if (!File.Exists(filePath))
            {
                HttpPacket packet = HttpPacketFactory.createPacket(rawUrl);
                if (null != packet)
                {
                    packet.handlePacket(ref response, ref request);
                }
                else
                {
                    response.ContentLength64 = 0;
                    response.StatusCode      = 404;
                    response.Abort();
                }
            }
            else
            {
                response.StatusCode = 200;
                string exeName = Path.GetExtension(filePath);
                response.ContentType = GetContentType(exeName);
                FileStream fileStream = new System.IO.FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read, FileShare.ReadWrite);
                int        byteLength = (int)fileStream.Length;
                byte[]     fileBytes  = new byte[byteLength];
                fileStream.Read(fileBytes, 0, byteLength);
                fileStream.Flush();
                fileStream.Dispose();
                response.ContentLength64 = byteLength;
                response.OutputStream.Write(fileBytes, 0, byteLength);
                response.OutputStream.Flush();
            }
            #endregion
        }
        catch (Exception ex)
        {
            UnityUtility.logInfo(typeof(HttpServerManager) + ex.Message);
            response.StatusCode  = 200;
            response.ContentType = "text/plain";
            using (StreamWriter writer = new StreamWriter(response.OutputStream, Encoding.UTF8))
            {
                writer.WriteLine("接收完成!");
            }
        }
        try
        {
            response.Close();
        }
        catch (Exception ex)
        {
            UnityUtility.logInfo(typeof(HttpServerManager) + ex.Message);
        }
    }
Esempio n. 12
0
        async void GetContent_Callback(IAsyncResult ar)
        {
            listener.BeginGetContext(GetContent, listener);

            HttpListenerContext context = listener.EndGetContext(ar);
            HttpListenerRequest req     = context.Request;

            using (HttpListenerResponse res = context.Response)
            {
                string filePath;
                //重定向
                if (redirect_rules(req.Url.AbsolutePath))
                {
                    Console.WriteLine("ressrv: redir {0}", req.Url.AbsolutePath);
                    filePath = conf["res_redirect_dir"].ToString() + req.Url.AbsolutePath;
                }
                else
                {
                    filePath = conf["res_dir"].ToString() + req.Url.AbsolutePath;
                }

                //本地缓存
                if (System.IO.File.Exists(filePath))
                {
                    //命中本地缓存
                    Console.WriteLine("ressrv: HitCache {0} ", req.RawUrl);
                    try
                    {
                        await SendFileAsync(res, filePath);

                        res.Close();
                        return;
                    }
                    catch (IOException e)
                    {
                        Console.WriteLine("ressrv: Cache IOException {0}\r\n{1}", req.RawUrl, e.Message);
                    }
                }

                #region 请求官方
                //请求官方
                Console.WriteLine("ressrv: proxy {0} ", conf["official_address"] + req.RawUrl);
                HttpWebRequest  c_req = HttpWebRequest.CreateHttp(conf["official_address"] + req.RawUrl);
                HttpWebResponse c_res = null;

                //尝试连接官方获取c_res对象
                try
                {
                    c_res = (HttpWebResponse)await c_req.GetResponseAsync();
                }
                catch (WebException e)
                {
                    if (e.Response != null)
                    {
                        HttpWebResponse e_res = (HttpWebResponse)e.Response;
                        Console.WriteLine("ressrv: {0} {1} ", (int)e_res.StatusCode, e_res.ResponseUri);
                        res.StatusCode = (int)e_res.StatusCode;
                        e_res.Dispose();
                    }
                    else
                    {
                        Console.WriteLine("ressrv: 502 {0}", e.Message);
                        res.StatusCode = 502;
                    }
                    res.Close();
                    return;
                }
                using (c_res)
                {
                    res.ContentLength64 = c_res.ContentLength;
                    res.ContentType     = c_res.ContentType;

                    //尝试获取文件流
                    FileStream f_stream = null;
                    try
                    {
                        string dirName = Path.GetDirectoryName(filePath);
                        if (!Directory.Exists(dirName))
                        {
                            Directory.CreateDirectory(dirName);
                        }
                        f_stream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None);
                    }
                    catch (IOException)
                    {
                        //throw;
                    }

                    //start copy
                    using (Stream c_stream = c_res.GetResponseStream(), s_stream = res.OutputStream)
                    {
                        try
                        {
                            await CopyStreamAsync(c_stream, s_stream, f_stream);

                            //dispose f_stream
                            if (f_stream != null)
                            {
                                f_stream.Close();
                                f_stream.Dispose();
                                Console.WriteLine("ressrv: Cached {0}", req.Url.AbsolutePath);
                            }
                        }
                        catch (Exception e)
                        {
                            if (f_stream != null)
                            {
                                lock (FileDelete_lock)
                                {
                                    f_stream.Close();
                                    File.Delete(filePath);
                                }
                                f_stream.Dispose();
                            }
                            Console.WriteLine("ressrv: Error {0}", e.Message);
                            res.Abort();
                        }
                        finally
                        {
                            s_stream.Close();
                            c_stream.Close();
                        }
                    }
                    c_res.Close();
                }
                res.Close();
            }

            #endregion
        }
Esempio n. 13
0
        //处理客户端请求
        private async void HandleRequest(object ctx)
        {
            HttpListenerContext  context  = ctx as HttpListenerContext;
            HttpListenerResponse response = context.Response;
            HttpListenerRequest  request  = context.Request;

            try
            {
                string rawUrl          = System.Web.HttpUtility.UrlDecode(request.RawUrl);
                int    paramStartIndex = rawUrl.IndexOf('?');
                if (paramStartIndex > 0)
                {
                    rawUrl = rawUrl.Substring(0, paramStartIndex);
                }
                else if (paramStartIndex == 0)
                {
                    rawUrl = "";
                }
                if (string.Compare(rawUrl, "/ImageUpload", true) == 0)
                {
                    var result = new ResoponseResult()
                    {
                        Count = 0
                    };
                    var count = 0;
                    #region   图片
                    using (var stream = request.InputStream)
                    {
                        using (System.IO.StreamReader reader = new System.IO.StreamReader(stream, request.ContentEncoding))
                        {
                            var content = await reader.ReadToEndAsync();

                            var param = JsonConvert.DeserializeObject <RequestParam>(content);
                            if (param != null)
                            {
                                param.Images.ForEach(x => {
                                    var base64Pic   = x.pic;
                                    var fileName    = Guid.NewGuid().ToString("N") + "." + x.Type;
                                    string filePath = FormConfigUtil.WifiPath + "\\" + fileName;
                                    byte[] bt       = Convert.FromBase64String(base64Pic.Substring(base64Pic.IndexOf(',') + 1));
                                    var picStream   = new System.IO.MemoryStream(bt);
                                    var bitmap      = new Bitmap(picStream);
                                    bitmap.Save(filePath);
                                    picStream.Close();
                                    form.PushImages(bitmap, filePath, x.Type, result);
                                });
                            }
                        }
                    }
                    response.ContentType = "text/html;charset=utf-8";

                    using (StreamWriter writer = new StreamWriter(response.OutputStream, Encoding.UTF8))
                    {
                        writer.Write(JsonConvert.SerializeObject(result));
                    }

                    #endregion
                }
                else
                {
                    #region 网页请求
                    string InputStream = "";
                    using (var streamReader = new StreamReader(request.InputStream))
                    {
                        InputStream = streamReader.ReadToEnd();
                    }
                    string filePath = "";
                    if (string.IsNullOrEmpty(rawUrl) || rawUrl.Length == 0 || rawUrl == "/")
                    {
                        filePath = WebHomeDir + directorySeparatorChar + "Index.html";
                    }
                    else
                    {
                        filePath = WebHomeDir + rawUrl.Replace("/", directorySeparatorChar);
                    }
                    if (!File.Exists(filePath))
                    {
                        response.ContentLength64 = 0;
                        response.StatusCode      = 404;
                        response.Abort();
                    }
                    else
                    {
                        response.StatusCode = 200;
                        string exeName = Path.GetExtension(filePath);
                        response.ContentType = GetContentType(exeName);
                        FileStream fileStream = new System.IO.FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read, FileShare.ReadWrite);
                        int        byteLength = (int)fileStream.Length;
                        byte[]     fileBytes  = new byte[byteLength];
                        fileStream.Read(fileBytes, 0, byteLength);
                        fileStream.Close();
                        fileStream.Dispose();
                        response.ContentLength64 = byteLength;
                        response.OutputStream.Write(fileBytes, 0, byteLength);
                        response.OutputStream.Close();
                    }
                    #endregion
                }
            }
            catch (Exception ex)
            {
                response.StatusCode  = 200;
                response.ContentType = "text/plain";
                using (StreamWriter writer = new StreamWriter(response.OutputStream, Encoding.UTF8))
                {
                    writer.WriteLine("500");
                }
            }
            try
            {
                response.Close();
            }
            catch (Exception ex)
            {
                throw;
                //LogHelper.WriteLog(typeof(HttpServerBLL), ex);
            }
        }
Esempio n. 14
0
 //
 // Summary:
 //     Closes the connection to the client without sending a response.
 public void Abort()
 {
     response.Abort();
     context.Close();
 }
Esempio n. 15
0
        /// <summary>
        ///     This methods is the start of incoming HTTP request handling.
        /// </summary>
        /// <param name="context"></param>
        public virtual void HandleRequest(HttpListenerContext context)
        {
            HttpListenerRequest request = context.Request;

            using (HttpListenerResponse response = context.Response)
            {
                OSHttpRequest  req  = new OSHttpRequest(context);
                OSHttpResponse resp = new OSHttpResponse(context);
                if (request.HttpMethod == String.Empty) // Can't handle empty requests, not wasting a thread
                {
                    byte[] buffer = GetHTML500(response);
                    response.ContentLength64 = buffer.LongLength;
                    response.Close(buffer, true);
                    return;
                }

                response.KeepAlive = false;
                string requestMethod    = request.HttpMethod;
                string uriString        = request.RawUrl;
                int    requestStartTick = Environment.TickCount;

                // Will be adjusted later on.
                int requestEndTick = requestStartTick;

                IStreamedRequestHandler requestHandler = null;

                try
                {
                    System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US",
                                                                                                                true);

                    string path       = request.RawUrl;
                    string handlerKey = GetHandlerKey(request.HttpMethod, path);
                    byte[] buffer     = null;

                    if ((request.ContentType == "application/xml" || request.ContentType == "text/xml") && GetXmlRPCHandler(request.RawUrl) != null)
                    {
                        buffer = HandleXmlRpcRequests(req, resp);
                    }
                    else if (TryGetStreamHandler(handlerKey, out requestHandler))
                    {
                        response.ContentType = requestHandler.ContentType;
                        // Lets do this defaulting before in case handler has varying content type.

                        buffer = requestHandler.Handle(path, request.InputStream, req, resp);
                    }

                    request.InputStream.Close();
                    try
                    {
                        if (buffer != null)
                        {
                            if (request.ProtocolVersion.Minor == 0)
                            {
                                //HTTP 1.0... no chunking
                                response.ContentLength64 = buffer.Length;
                                using (Stream stream = response.OutputStream)
                                {
                                    HttpServerHandlerHelpers.WriteNonChunked(stream, buffer);
                                }
                            }
                            else
                            {
                                response.SendChunked = true;
                                using (Stream stream = response.OutputStream)
                                {
                                    HttpServerHandlerHelpers.WriteChunked(stream, buffer);
                                }
                            }
                            //response.ContentLength64 = buffer.LongLength;
                            response.Close();
                        }
                        else
                        {
                            response.Close(new byte[0], true);
                        }
                    }
                    catch (Exception ex)
                    {
                        if (!(ex is HttpListenerException) ||
                            !HttpListenerManager.IGNORE_ERROR_CODES.Contains(((HttpListenerException)ex).ErrorCode))
                        {
                            MainConsole.Instance.WarnFormat(
                                "[BASE HTTP SERVER]: HandleRequest failed to write all data to the stream: {0}", ex.ToString());
                        }
                        response.Abort();
                    }

                    requestEndTick = Environment.TickCount;
                }
                catch (Exception e)
                {
                    MainConsole.Instance.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw {0} ", e.ToString());
                    response.Abort();
                }
                finally
                {
                    // Every month or so this will wrap and give bad numbers, not really a problem
                    // since its just for reporting
                    int tickdiff = requestEndTick - requestStartTick;
                    if (tickdiff > 3000 && requestHandler != null)
                    {
                        MainConsole.Instance.InfoFormat(
                            "[BASE HTTP SERVER]: Slow handling of {0} {1} took {2}ms",
                            requestMethod,
                            uriString,
                            tickdiff);
                    }
                    else if (MainConsole.Instance.IsTraceEnabled)
                    {
                        MainConsole.Instance.TraceFormat(
                            "[BASE HTTP SERVER]: Handling {0} {1} took {2}ms",
                            requestMethod,
                            uriString,
                            tickdiff);
                    }
                }
            }
        }
Esempio n. 16
0
 public void Abort()
 {
     Response.Abort();
 }
Esempio n. 17
0
        //处理客户端请求
        private void HandleRequest(object ctx)
        {
            HttpListenerContext  context  = ctx as HttpListenerContext;
            HttpListenerResponse response = context.Response;
            HttpListenerRequest  request  = context.Request;

            try
            {
                string rawUrl          = Uri.UnescapeDataString(request.RawUrl);
                int    paramStartIndex = rawUrl.IndexOf('?');
                if (paramStartIndex > 0)
                {
                    rawUrl = rawUrl.Substring(0, paramStartIndex);
                }
                else if (paramStartIndex == 0)
                {
                    rawUrl = "";
                }

                #region 文件请求

                {
                    string filePath = WebHomeDir + rawUrl;
                    //替换
                    // var platforms = BDApplication.GetSupportPlatform();
                    // foreach (var platform in platforms)
                    // {
                    //     var platformStr = BDApplication.GetPlatformPath(platform);
                    //     filePath = filePath.Replace(platformStr, platformStr + PublishPipelineTools.UPLOAD_FOLDER_SUFFIX);
                    // }

                    if (!File.Exists(filePath))
                    {
                        response.ContentLength64 = 0;
                        response.StatusCode      = 404;
                        response.Abort();
                    }
                    else
                    {
                        response.StatusCode = 200;
                        string exeName = Path.GetExtension(filePath);
                        response.ContentType = GetContentType(exeName);
                        FileStream fileStream = new System.IO.FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read, FileShare.ReadWrite);
                        int        byteLength = (int)fileStream.Length;
                        byte[]     fileBytes  = new byte[byteLength];
                        fileStream.Read(fileBytes, 0, byteLength);
                        fileStream.Close();
                        fileStream.Dispose();
                        response.ContentLength64 = byteLength;
                        response.OutputStream.Write(fileBytes, 0, byteLength);
                        response.OutputStream.Close();
                    }

                    #endregion
                }
            }
            catch (Exception ex)
            {
                response.StatusCode  = 200;
                response.ContentType = "text/plain";
                using (StreamWriter writer = new StreamWriter(response.OutputStream, Encoding.UTF8))
                {
                    writer.WriteLine("接收完成!");
                }
            }

            try
            {
                response.Close();
            }
            catch (Exception ex)
            {
                Debug.LogError(ex);
            }
        }
Esempio n. 18
0
 /// <summary>
 /// Aborts the request
 /// </summary>
 /// <returns>
 /// itself
 /// </returns>
 public IServerResponse Abort()
 {
     _res.Abort();
     return(this);
 }
        private void Worker(object state)
        {
            HttpListenerRequest  request  = null;
            HttpListenerResponse response = null;

            try
            {
                var context = state as HttpListenerContext;
                //
                request  = context.Request;
                response = context.Response;
                //
                if (request.UserLanguages != null && request.UserLanguages.Length > 0)
                {
                    try
                    {
                        CultureInfo culture = CultureInfo.CreateSpecificCulture(request.UserLanguages[0].ToLowerInvariant().Trim());
                        Thread.CurrentThread.CurrentCulture   = culture;
                        Thread.CurrentThread.CurrentUICulture = culture;
                    }
                    catch
                    {
                    }
                }
                //
                if (request.IsSecureConnection)
                {
                    var       clientCertificate = request.GetClientCertificate();
                    X509Chain chain             = new X509Chain();
                    chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
                    chain.Build(clientCertificate);
                    if (chain.ChainStatus.Length != 0)
                    {
                        // Invalid certificate
                        response.StatusCode = (int)HttpStatusCode.Unauthorized;
                        response.OutputStream.Close();
                        return;
                    }
                }
                //
                response.Headers.Set(HttpResponseHeader.Server, "MIG WebService Gateway");
                response.KeepAlive = false;
                //
                bool   isAuthenticated = (request.Headers["Authorization"] != null);
                string remoteAddress   = request.RemoteEndPoint.Address.ToString();
                string logExtras       = "";
                //
                if (servicePassword == "" || isAuthenticated) //request.IsAuthenticated)
                {
                    bool verified = false;
                    //
                    string authUser = "";
                    string authPass = "";
                    //
                    //NOTE: context.User.Identity and request.IsAuthenticated
                    //aren't working under MONO with this code =/
                    //so we proceed by manually parsing Authorization header
                    //
                    //HttpListenerBasicIdentity identity = null;
                    //
                    if (isAuthenticated)
                    {
                        //identity = (HttpListenerBasicIdentity)context.User.Identity;
                        // authuser = identity.Name;
                        // authpass = identity.Password;
                        byte[] encodedDataAsBytes = System.Convert.FromBase64String(request.Headers["Authorization"].Split(' ')[1]);
                        string authtoken          = System.Text.Encoding.UTF8.GetString(encodedDataAsBytes);
                        authUser = authtoken.Split(':')[0];
                        authPass = authtoken.Split(':')[1];
                    }
                    //
                    //TODO: complete authorization (for now with one fixed user 'admin', add multiuser support)
                    //
                    if (servicePassword == "" || (authUser == serviceUsername && Utility.Encryption.SHA1.GenerateHashString(authPass) == servicePassword))
                    {
                        verified = true;
                    }
                    //
                    if (verified)
                    {
                        string url = request.RawUrl.TrimStart('/').TrimStart('\\').TrimStart('.');
                        if (url.IndexOf("?") > 0)
                        {
                            url = url.Substring(0, url.IndexOf("?"));
                        }
                        // Check if this url is an alias
                        url = UrlAliasCheck(url.TrimEnd('/'));
                        //
                        // url aliasing check
                        if (url == "" || url.TrimEnd('/') == baseUrl.TrimEnd('/'))
                        {
                            // default home redirect
                            response.Redirect("/" + baseUrl.TrimEnd('/') + "/index.html");
                            //TODO: find a solution for HG homepage redirect ---> ?" + new TimeSpan(DateTime.UtcNow.Ticks).TotalMilliseconds + "#page_control");
                            response.Close();
                        }
                        else
                        {
                            var connectionWatch = Stopwatch.StartNew();
                            MigService.Log.Info(new MigEvent(this.GetName(), remoteAddress, "HTTP", request.HttpMethod.ToString(), String.Format("{0} {1} [OPEN]", response.StatusCode, request.RawUrl)));
                            // this url is reserved for Server Sent Event stream
                            if (url.TrimEnd('/').Equals("events"))
                            {
                                // TODO: move all of this to a separate function
                                // Server sent events
                                // NOTE: no PreProcess or PostProcess events are fired in this case
                                //response.KeepAlive = true;
                                response.ContentEncoding = Encoding.UTF8;
                                response.ContentType     = "text/event-stream";
                                response.Headers.Set(HttpResponseHeader.CacheControl, "no-cache, no-store, must-revalidate");
                                response.Headers.Set(HttpResponseHeader.Pragma, "no-cache");
                                response.Headers.Set("Access-Control-Allow-Origin", "*");

                                // 2K padding for IE
                                var    padding     = ":" + new String(' ', 2048) + "\n";
                                byte[] paddingData = System.Text.Encoding.UTF8.GetBytes(padding);
                                response.OutputStream.Write(paddingData, 0, paddingData.Length);
                                byte[] retryData = System.Text.Encoding.UTF8.GetBytes("retry: 1000\n");
                                response.OutputStream.Write(retryData, 0, retryData.Length);

                                DateTime lastTimeStamp = DateTime.UtcNow;
                                var      lastId        = context.Request.Headers.Get("Last-Event-ID");
                                if (lastId == null || lastId == "")
                                {
                                    var queryValues = HttpUtility.ParseQueryString(context.Request.Url.Query);
                                    lastId = queryValues.Get("lastEventId");
                                }

                                if (lastId != null && lastId != "")
                                {
                                    double unixTimestamp = 0;
                                    double.TryParse(lastId, NumberStyles.Float | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out unixTimestamp);
                                    if (unixTimestamp != 0)
                                    {
                                        lastTimeStamp = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc);
                                        lastTimeStamp.AddSeconds(Math.Round(unixTimestamp / 1000d));
                                    }
                                }

                                bool connected    = true;
                                var  timeoutWatch = Stopwatch.StartNew();
                                while (connected)
                                {
                                    // dirty work around for signaling new event and
                                    // avoiding locks on long socket timetout
                                    lock (sseEventToken)
                                        Monitor.Wait(sseEventToken, 1000);
                                    // safely dequeue events
                                    List <SseEvent> bufferedData;
                                    do
                                    {
                                        bufferedData = sseEventBuffer.FindAll(le => le != null && le.Timestamp.Ticks > lastTimeStamp.Ticks);
                                        if (bufferedData.Count > 0)
                                        {
                                            foreach (SseEvent entry in bufferedData)
                                            {
                                                // send events
                                                try
                                                {
                                                    // The following throws an error on some mono-arm (Input string was not in the correct format)
                                                    // entry.Event.UnixTimestamp.ToString("R", CultureInfo.InvariantCulture)
                                                    byte[] data = System.Text.Encoding.UTF8.GetBytes("id: " + entry.Event.UnixTimestamp.ToString().Replace(",", ".") + "\ndata: " + MigService.JsonSerialize(entry.Event) + "\n\n");
                                                    response.OutputStream.Write(data, 0, data.Length);
                                                    //response.OutputStream.Flush();
                                                    lastTimeStamp = entry.Timestamp;
                                                }
                                                catch (Exception e)
                                                {
                                                    MigService.Log.Info(new MigEvent(this.GetName(), remoteAddress, "HTTP", request.HttpMethod.ToString(), String.Format("{0} {1} [ERROR: {2}]", response.StatusCode, request.RawUrl, e.Message)));
                                                    connected = false;
                                                    break;
                                                }
                                            }
                                            Thread.Sleep(100);
                                        }
                                        // there might be new data after sending
                                    } while (connected && bufferedData.Count > 0);
                                    // check if the remote end point is still alive every 15 seconds or so
                                    if (timeoutWatch.Elapsed.TotalSeconds > 15)
                                    {
                                        connected = connected && IsRemoteEndPointConnected(request.RemoteEndPoint);
                                        timeoutWatch.Stop();
                                        timeoutWatch = Stopwatch.StartNew();
                                    }
                                }
                            }
                            else
                            {
                                try
                                {
                                    MigClientRequest migRequest = null;
                                    if (url.StartsWith("api/"))
                                    {
                                        string message    = url.Substring(url.IndexOf('/', 1) + 1);
                                        var    migContext = new MigContext(ContextSource.WebServiceGateway, context);
                                        migRequest = new MigClientRequest(migContext, new MigInterfaceCommand(message));
                                        // Disable HTTP caching
                                        response.Headers.Set(HttpResponseHeader.CacheControl, "no-cache, no-store, must-revalidate");
                                        response.Headers.Set(HttpResponseHeader.Pragma, "no-cache");
                                        response.Headers.Set(HttpResponseHeader.Expires, "0");
                                        // Store POST data (if any) in the migRequest.RequestData field
                                        migRequest.RequestData = WebServiceUtility.ReadToEnd(request.InputStream);
                                        migRequest.RequestText = request.ContentEncoding.GetString(migRequest.RequestData);
                                    }

                                    OnPreProcessRequest(migRequest);

                                    bool requestHandled = (migRequest != null && migRequest.Handled);
                                    if (requestHandled)
                                    {
                                        SendResponseObject(context, migRequest.ResponseData);
                                    }
                                    else if (url.StartsWith(baseUrl) || baseUrl.Equals("/"))
                                    {
                                        // If request begins <base_url>, process as standard Web request
                                        string requestedFile = GetWebFilePath(url);
                                        if (!System.IO.File.Exists(requestedFile))
                                        {
                                            response.StatusCode = (int)HttpStatusCode.NotFound;
                                            WebServiceUtility.WriteStringToContext(context, "<h1>404 - Not Found</h1>");
                                        }
                                        else
                                        {
                                            bool isText = false;
                                            if (url.ToLower().EndsWith(".js")) // || requestedurl.EndsWith(".json"))
                                            {
                                                response.ContentType = "text/javascript";
                                                isText = true;
                                            }
                                            else if (url.ToLower().EndsWith(".css"))
                                            {
                                                response.ContentType = "text/css";
                                                isText = true;
                                            }
                                            else if (url.ToLower().EndsWith(".zip"))
                                            {
                                                response.ContentType = "application/zip";
                                            }
                                            else if (url.ToLower().EndsWith(".png"))
                                            {
                                                response.ContentType = "image/png";
                                            }
                                            else if (url.ToLower().EndsWith(".jpg"))
                                            {
                                                response.ContentType = "image/jpeg";
                                            }
                                            else if (url.ToLower().EndsWith(".gif"))
                                            {
                                                response.ContentType = "image/gif";
                                            }
                                            else if (url.ToLower().EndsWith(".svg"))
                                            {
                                                response.ContentType = "image/svg+xml";
                                            }
                                            else if (url.ToLower().EndsWith(".mp3"))
                                            {
                                                response.ContentType = "audio/mp3";
                                            }
                                            else if (url.ToLower().EndsWith(".wav"))
                                            {
                                                response.ContentType = "audio/x-wav";
                                            }
                                            else if (url.ToLower().EndsWith(".appcache"))
                                            {
                                                response.ContentType = "text/cache-manifest";
                                            }
                                            else if (url.ToLower().EndsWith(".otf") || url.ToLower().EndsWith(".ttf") || url.ToLower().EndsWith(".woff") || url.ToLower().EndsWith(".woff2"))
                                            {
                                                response.ContentType = "application/octet-stream";
                                            }
                                            else if (url.ToLower().EndsWith(".xml"))
                                            {
                                                response.ContentType = "text/xml";
                                                isText = true;
                                            }
                                            else
                                            {
                                                response.ContentType = "text/html";
                                                isText = true;
                                            }

                                            var file = new System.IO.FileInfo(requestedFile);
                                            response.ContentLength64 = file.Length;

                                            bool modified = true;
                                            if (request.Headers.AllKeys.Contains("If-Modified-Since"))
                                            {
                                                var modifiedSince = DateTime.MinValue;
                                                DateTime.TryParse(request.Headers["If-Modified-Since"], out modifiedSince);
                                                if (file.LastWriteTime.ToUniversalTime().Equals(modifiedSince))
                                                {
                                                    modified = false;
                                                }
                                            }
                                            bool disableCacheControl = HttpCacheIgnoreCheck(url);
                                            if (!modified && !disableCacheControl)
                                            {
                                                // TODO: !IMPORTANT! exclude from caching files that contains SSI tags!
                                                response.StatusCode = (int)HttpStatusCode.NotModified;
                                                //!!DISABLED!! - The following line was preventing browser to load file from cache
                                                //response.Headers.Set(HttpResponseHeader.Date, file.LastWriteTimeUtc.ToString().Replace(",", "."));
                                            }
                                            else
                                            {
                                                response.Headers.Set(HttpResponseHeader.LastModified, file.LastWriteTimeUtc.ToString().Replace(",", "."));
                                                if (disableCacheControl)
                                                {
                                                    response.Headers.Set(HttpResponseHeader.CacheControl, "no-cache, no-store, must-revalidate");
                                                    response.Headers.Set(HttpResponseHeader.Pragma, "no-cache");
                                                    response.Headers.Set(HttpResponseHeader.Expires, "0");
                                                }
                                                else
                                                {
                                                    response.Headers.Set(HttpResponseHeader.CacheControl, "max-age=86400");
                                                }

                                                // PRE PROCESS text output
                                                if (isText)
                                                {
                                                    try
                                                    {
                                                        WebFile webFile = GetWebFile(requestedFile);
                                                        response.ContentEncoding = webFile.Encoding;
                                                        response.ContentType    += "; charset=" + webFile.Encoding.BodyName;
                                                        // We don't need to parse the content again if it's coming from the cache
                                                        if (!webFile.IsCached)
                                                        {
                                                            string body = webFile.Content;
                                                            if (requestedFile.EndsWith(".md"))
                                                            {
                                                                // Built-in Markdown files support
                                                                body = CommonMark.CommonMarkConverter.Convert(body);
                                                                // TODO: add a way to include HTML header and footer template to be appended to the
                                                                // TODO: translated markdown text
                                                            }
                                                            else
                                                            {
                                                                // HTML file
                                                                // replace prepocessor directives with values
                                                                bool tagFound;
                                                                do
                                                                {
                                                                    tagFound = false;
                                                                    int ts = body.IndexOf("{include ");
                                                                    if (ts >= 0)
                                                                    {
                                                                        int te = body.IndexOf("}", ts);
                                                                        if (te > ts)
                                                                        {
                                                                            string rs = body.Substring(ts + (te - ts) + 1);
                                                                            string cs = body.Substring(ts, te - ts + 1);
                                                                            string ls = body.Substring(0, ts);
                                                                            //
                                                                            try
                                                                            {
                                                                                if (cs.StartsWith("{include "))
                                                                                {
                                                                                    string fileName = cs.Substring(9).TrimEnd('}').Trim();
                                                                                    fileName = GetWebFilePath(fileName);
                                                                                    //
                                                                                    Encoding fileEncoding = DetectWebFileEncoding(fileName);
                                                                                    if (fileEncoding == null)
                                                                                    {
                                                                                        fileEncoding = defaultWebFileEncoding;
                                                                                    }
                                                                                    var incFile = System.IO.File.ReadAllText(fileName, fileEncoding) + rs;
                                                                                    body = ls + incFile;
                                                                                }
                                                                            }
                                                                            catch
                                                                            {
                                                                                body = ls + "<h5 style=\"color:red\">Error processing '" + cs.Replace("{", "[").Replace("}", "]") + "'</h5>" + rs;
                                                                            }
                                                                            tagFound = true;
                                                                        }
                                                                    }
                                                                } while (tagFound); // continue if a pre processor tag was found
                                                                // {hostos}
                                                                body = body.Replace("{hostos}", Environment.OSVersion.Platform.ToString());
                                                                // {filebase}
                                                                body = body.Replace("{filebase}", Path.GetFileNameWithoutExtension(requestedFile));
                                                            }
                                                            // update the cache content with parsing results
                                                            webFile.Content = body;
                                                        }
                                                        // Store the cache item if the file cache is enabled
                                                        if (enableFileCache)
                                                        {
                                                            UpdateWebFileCache(requestedFile, webFile.Content, response.ContentEncoding);
                                                        }
                                                        //
                                                        WebServiceUtility.WriteStringToContext(context, webFile.Content);
                                                    }
                                                    catch (Exception ex)
                                                    {
                                                        // TODO: report internal mig interface  error
                                                        response.StatusCode = (int)HttpStatusCode.InternalServerError;
                                                        WebServiceUtility.WriteStringToContext(context, ex.Message + "\n" + ex.StackTrace);
                                                        MigService.Log.Error(ex);
                                                    }
                                                }
                                                else
                                                {
                                                    WebServiceUtility.WriteBytesToContext(context, System.IO.File.ReadAllBytes(requestedFile));
                                                }
                                            }
                                        }
                                        requestHandled = true;
                                    }

                                    OnPostProcessRequest(migRequest);

                                    if (!requestHandled && migRequest != null && migRequest.Handled)
                                    {
                                        SendResponseObject(context, migRequest.ResponseData);
                                    }
                                    else if (!requestHandled)
                                    {
                                        response.StatusCode = (int)HttpStatusCode.NotFound;
                                        WebServiceUtility.WriteStringToContext(context, "<h1>404 - Not Found</h1>");
                                    }
                                }
                                catch (Exception eh)
                                {
                                    // TODO: add error logging
                                    Console.Error.WriteLine(eh);
                                }
                            }
                            connectionWatch.Stop();
                            logExtras = " [CLOSED AFTER " + Math.Round(connectionWatch.Elapsed.TotalSeconds, 3) + " seconds]";
                        }
                    }
                    else
                    {
                        response.StatusCode = (int)HttpStatusCode.Unauthorized;
                        // this will only work in Linux (mono)
                        //response.Headers.Set(HttpResponseHeader.WwwAuthenticate, "Basic");
                        // this works both on Linux and Windows
                        //response.AddHeader("WWW-Authenticate", "Basic");
                    }
                }
                else
                {
                    response.StatusCode = (int)HttpStatusCode.Unauthorized;
                    // this will only work in Linux (mono)
                    //response.Headers.Set(HttpResponseHeader.WwwAuthenticate, "Basic");
                    // this works both on Linux and Windows
                    //response.AddHeader("WWW-Authenticate", "Basic");
                }
                MigService.Log.Info(new MigEvent(this.GetName(), remoteAddress, "HTTP", request.HttpMethod.ToString(), String.Format("{0} {1}{2}", response.StatusCode, request.RawUrl, logExtras)));
            }
            catch (Exception ex)
            {
                MigService.Log.Error(ex);
            }
            finally
            {
                //
                // CleanUp/Dispose allocated resources
                //
                try { request.InputStream.Close(); } catch {
                    // TODO: add logging
                }
                try { response.OutputStream.Close(); } catch {
                    // TODO: add logging
                }
                try { response.Close(); } catch {
                    // TODO: add logging
                }
                try { response.Abort(); } catch {
                    // TODO: add logging
                }
            }
        }
Esempio n. 20
0
        private void Worker(object state)
        {
            HttpListenerRequest  request  = null;
            HttpListenerResponse response = null;

            try
            {
                var context = state as HttpListenerContext;
                //
                request  = context.Request;
                response = context.Response;
                //
                if (request.UserLanguages != null && request.UserLanguages.Length > 0)
                {
                    try
                    {
                        CultureInfo culture = CultureInfo.CreateSpecificCulture(request.UserLanguages[0].ToLowerInvariant().Trim());
                        Thread.CurrentThread.CurrentCulture   = culture;
                        Thread.CurrentThread.CurrentUICulture = culture;
                    }
                    catch
                    {
                    }
                }
                //
                if (request.IsSecureConnection)
                {
                    var clientCertificate = request.GetClientCertificate();
                    var chain             = new X509Chain
                    {
                        ChainPolicy = { RevocationMode = X509RevocationMode.NoCheck }
                    };
                    chain.Build(clientCertificate);
                    if (chain.ChainStatus.Length != 0)
                    {
                        // Invalid certificate
                        response.StatusCode = (int)HttpStatusCode.Unauthorized;
                        response.OutputStream.Close();
                        return;
                    }
                }
                //
                response.Headers.Set(HttpResponseHeader.Server, "MIG WebService Gateway");
                response.KeepAlive = false;
                //
                bool   requestHasAuthorizationHeader = request.Headers["Authorization"] != null;
                string remoteAddress = request.RemoteEndPoint.Address.ToString();
                string logExtras     = "";
                //
                if (servicePassword == "" || requestHasAuthorizationHeader) //request.IsAuthenticated)
                {
                    bool verified = false;
                    //
                    string authUser = "";
                    string authPass = "";
                    //
                    //NOTE: context.User.Identity and request.IsAuthenticated
                    //aren't working under MONO with this code =/
                    //so we proceed by manually parsing Authorization header
                    //
                    //HttpListenerBasicIdentity identity = null;
                    //
                    if (requestHasAuthorizationHeader)
                    {
                        //identity = (HttpListenerBasicIdentity)context.User.Identity;
                        // authuser = identity.Name;
                        // authpass = identity.Password;
                        byte[] encodedDataAsBytes = Convert.FromBase64String(request.Headers["Authorization"].Split(' ')[1]);
                        string authtoken          = Encoding.UTF8.GetString(encodedDataAsBytes);
                        authUser = authtoken.Split(':')[0];
                        authPass = authtoken.Split(':')[1];
                    }
                    //
                    //TODO: complete authorization (for now with one fixed user 'admin', add multiuser support)
                    //
                    if (servicePassword == "" || authUser == serviceUsername && Utility.Encryption.SHA1.GenerateHashString(authPass) == servicePassword)
                    {
                        verified = true;
                    }
                    //
                    if (verified)
                    {
                        string url = request.RawUrl.TrimStart('/').TrimStart('\\').TrimStart('.');
                        if (url.IndexOf("?") > 0)
                        {
                            url = url.Substring(0, url.IndexOf("?"));
                        }
                        // Check if this url is an alias
                        url = UrlAliasCheck(url.TrimEnd('/'));
                        //
                        // url aliasing check
                        if (url == "" || url.TrimEnd('/') == baseUrl.TrimEnd('/'))
                        {
                            // default home redirect
                            response.Redirect("/" + baseUrl.TrimEnd('/') + "/index.html");
                            //TODO: find a solution for HG homepage redirect ---> ?" + new TimeSpan(DateTime.UtcNow.Ticks).TotalMilliseconds + "#page_control");
                            response.Close();
                        }
                        else
                        {
                            var connectionWatch = Stopwatch.StartNew();
                            MigService.Log.Info(new MigEvent(this.GetName(), remoteAddress, "HTTP", request.HttpMethod,
                                                             $"{response.StatusCode} {request.RawUrl} [OPEN]"));
                            // this url is reserved for Server Sent Event stream
                            if (url.TrimEnd('/').Equals("events"))
                            {
                                HandleEventsRoute(request, response, context, remoteAddress);
                            }
                            else
                            {
                                try
                                {
                                    MigClientRequest migRequest = null;
                                    if (url.StartsWith("api/"))
                                    {
                                        string message    = url.Substring(url.IndexOf('/', 1) + 1);
                                        var    migContext = new MigContext(ContextSource.WebServiceGateway, context);
                                        migRequest = new MigClientRequest(migContext, new MigInterfaceCommand(message));
                                        // Disable HTTP caching
                                        response.Headers.Set(HttpResponseHeader.CacheControl, "no-cache, no-store, must-revalidate");
                                        response.Headers.Set(HttpResponseHeader.Pragma, "no-cache");
                                        response.Headers.Set(HttpResponseHeader.Expires, "0");
                                        // Store POST data (if any) in the migRequest.RequestData field
                                        migRequest.RequestData = WebServiceUtility.ReadToEnd(request.InputStream);
                                        migRequest.RequestText = request.ContentEncoding.GetString(migRequest.RequestData);
                                    }

                                    OnPreProcessRequest(migRequest);

                                    bool requestHandled = migRequest != null && migRequest.Handled;
                                    if (requestHandled)
                                    {
                                        SendResponseObject(context, migRequest.ResponseData);
                                    }
                                    else if (url.StartsWith(baseUrl) || baseUrl.Equals("/"))
                                    {
                                        // If request begins <base_url>, process as standard Web request
                                        string requestedFile = GetWebFilePath(url);
                                        if (!File.Exists(requestedFile))
                                        {
                                            response.StatusCode = (int)HttpStatusCode.NotFound;
                                            WebServiceUtility.WriteStringToContext(context, $"<h1>404 - Not Found</h1><br/>{requestedFile}");
                                        }
                                        else
                                        {
                                            bool isText = false;
                                            if (url.ToLower().EndsWith(".js")) // || requestedurl.EndsWith(".json"))
                                            {
                                                response.ContentType = "text/javascript";
                                                isText = true;
                                            }
                                            else if (url.ToLower().EndsWith(".css"))
                                            {
                                                response.ContentType = "text/css";
                                                isText = true;
                                            }
                                            else if (url.ToLower().EndsWith(".zip"))
                                            {
                                                response.ContentType = "application/zip";
                                            }
                                            else if (url.ToLower().EndsWith(".png"))
                                            {
                                                response.ContentType = "image/png";
                                            }
                                            else if (url.ToLower().EndsWith(".jpg"))
                                            {
                                                response.ContentType = "image/jpeg";
                                            }
                                            else if (url.ToLower().EndsWith(".gif"))
                                            {
                                                response.ContentType = "image/gif";
                                            }
                                            else if (url.ToLower().EndsWith(".svg"))
                                            {
                                                response.ContentType = "image/svg+xml";
                                            }
                                            else if (url.ToLower().EndsWith(".mp3"))
                                            {
                                                response.ContentType = "audio/mp3";
                                            }
                                            else if (url.ToLower().EndsWith(".wav"))
                                            {
                                                response.ContentType = "audio/x-wav";
                                            }
                                            else if (url.ToLower().EndsWith(".appcache"))
                                            {
                                                response.ContentType = "text/cache-manifest";
                                            }
                                            else if (url.ToLower().EndsWith(".otf") || url.ToLower().EndsWith(".ttf") || url.ToLower().EndsWith(".woff") || url.ToLower().EndsWith(".woff2"))
                                            {
                                                response.ContentType = "application/octet-stream";
                                            }
                                            else if (url.ToLower().EndsWith(".xml"))
                                            {
                                                response.ContentType = "text/xml";
                                                isText = true;
                                            }
                                            else
                                            {
                                                response.ContentType = "text/html";
                                                isText = true;
                                            }

                                            var file = new FileInfo(requestedFile);
                                            response.ContentLength64 = file.Length;

                                            bool modified = true;
                                            if (request.Headers.AllKeys.Contains("If-Modified-Since"))
                                            {
                                                var modifiedSince = DateTime.MinValue;
                                                DateTime.TryParse(request.Headers["If-Modified-Since"], out modifiedSince);
                                                if (file.LastWriteTime.ToUniversalTime().Equals(modifiedSince))
                                                {
                                                    modified = false;
                                                }
                                            }
                                            bool disableCacheControl = HttpCacheIgnoreCheck(url);
                                            if (!modified && !disableCacheControl)
                                            {
                                                // TODO: !IMPORTANT! exclude from caching files that contains SSI tags!
                                                response.StatusCode = (int)HttpStatusCode.NotModified;
                                                //!!DISABLED!! - The following line was preventing browser to load file from cache
                                                //response.Headers.Set(HttpResponseHeader.Date, file.LastWriteTimeUtc.ToString().Replace(",", "."));
                                            }
                                            else
                                            {
                                                response.Headers.Set(HttpResponseHeader.LastModified, file.LastWriteTimeUtc.ToString().Replace(",", "."));
                                                if (disableCacheControl)
                                                {
                                                    response.Headers.Set(HttpResponseHeader.CacheControl, "no-cache, no-store, must-revalidate");
                                                    response.Headers.Set(HttpResponseHeader.Pragma, "no-cache");
                                                    response.Headers.Set(HttpResponseHeader.Expires, "0");
                                                }
                                                else
                                                {
                                                    response.Headers.Set(HttpResponseHeader.CacheControl, "max-age=86400");
                                                }

                                                // PRE PROCESS text output
                                                if (isText)
                                                {
                                                    try
                                                    {
                                                        WebFile webFile = GetWebFile(requestedFile);
                                                        response.ContentEncoding = webFile.Encoding;
                                                        response.ContentType    += "; charset=" + webFile.Encoding.BodyName;
                                                        // We don't need to parse the content again if it's coming from the cache
                                                        if (!webFile.IsCached)
                                                        {
                                                            string body = webFile.Content;
                                                            if (requestedFile.EndsWith(".md"))
                                                            {
                                                                // Built-in Markdown files support
                                                                body = CommonMarkConverter.Convert(body);
                                                                // TODO: add a way to include HTML header and footer template to be appended to the
                                                                // TODO: translated markdown text
                                                            }
                                                            else
                                                            {
                                                                // HTML file
                                                                // replace prepocessor directives with values
                                                                bool tagFound;
                                                                do
                                                                {
                                                                    tagFound = false;
                                                                    var ts = body.IndexOf("{include ");
                                                                    if (ts >= 0)
                                                                    {
                                                                        var te = body.IndexOf("}", ts);
                                                                        if (te > ts)
                                                                        {
                                                                            var rs = body.Substring(ts + (te - ts) + 1);
                                                                            var cs = body.Substring(ts, te - ts + 1);
                                                                            var ls = body.Substring(0, ts);
                                                                            //
                                                                            try
                                                                            {
                                                                                if (cs.StartsWith("{include "))
                                                                                {
                                                                                    var fileName = cs.Substring(9).TrimEnd('}').Trim();
                                                                                    fileName = GetWebFilePath(fileName);

                                                                                    var fileEncoding = DetectWebFileEncoding(fileName) ??
                                                                                                       defaultWebFileEncoding;
                                                                                    var incFile = File.ReadAllText(fileName, fileEncoding) + rs;
                                                                                    body = ls + incFile;
                                                                                }
                                                                            }
                                                                            catch
                                                                            {
                                                                                body = ls + "<h5 style=\"color:red\">Error processing '" + cs.Replace("{", "[").Replace("}", "]") + "'</h5>" + rs;
                                                                            }
                                                                            tagFound = true;
                                                                        }
                                                                    }
                                                                } while (tagFound); // continue if a pre processor tag was found
                                                                // {hostos}
                                                                body = body.Replace("{hostos}", Environment.OSVersion.Platform.ToString());
                                                                // {filebase}
                                                                body = body.Replace("{filebase}", Path.GetFileNameWithoutExtension(requestedFile));
                                                            }
                                                            // update the cache content with parsing results
                                                            webFile.Content = body;
                                                        }
                                                        // Store the cache item if the file cache is enabled
                                                        if (enableFileCache)
                                                        {
                                                            UpdateWebFileCache(requestedFile, webFile.Content, response.ContentEncoding);
                                                        }
                                                        //
                                                        WebServiceUtility.WriteStringToContext(context, webFile.Content);
                                                    }
                                                    catch (Exception ex)
                                                    {
                                                        // TODO: report internal mig interface  error
                                                        response.StatusCode = (int)HttpStatusCode.InternalServerError;
                                                        WebServiceUtility.WriteStringToContext(context, ex.Message + "\n" + ex.StackTrace);
                                                        MigService.Log.Error(ex);
                                                    }
                                                }
                                                else
                                                {
                                                    WebServiceUtility.WriteBytesToContext(context, File.ReadAllBytes(requestedFile));
                                                }
                                            }
                                        }
                                        requestHandled = true;
                                    }

                                    OnPostProcessRequest(migRequest);

                                    if (!requestHandled && migRequest != null && migRequest.Handled)
                                    {
                                        SendResponseObject(context, migRequest.ResponseData);
                                    }
                                    else if (!requestHandled)
                                    {
                                        response.StatusCode = (int)HttpStatusCode.NotFound;
                                        WebServiceUtility.WriteStringToContext(context, "<h1>404 - Not Found</h1>");
                                    }
                                }
                                catch (Exception eh)
                                {
                                    // TODO: add error logging
                                    Console.Error.WriteLine(eh);
                                }
                            }
                            connectionWatch.Stop();
                            logExtras = " [CLOSED AFTER " + Math.Round(connectionWatch.Elapsed.TotalSeconds, 3) + " seconds]";
                        }
                    }
                    else
                    {
                        response.StatusCode = (int)HttpStatusCode.Unauthorized;
                        // this will only work in Linux (mono)
                        //response.Headers.Set(HttpResponseHeader.WwwAuthenticate, "Basic");
                        // this works both on Linux and Windows
                        response.AddHeader("WWW-Authenticate", "Basic realm=\"User Visible Realm\"");
                    }
                }
                else
                {
                    response.StatusCode = (int)HttpStatusCode.Unauthorized;
                    // this will only work in Linux (mono)
                    //response.Headers.Set(HttpResponseHeader.WwwAuthenticate, "Basic");
                    // this works both on Linux and Windows
                    response.AddHeader("WWW-Authenticate", "Basic realm=\"User Visible Realm\"");
                }
                MigService.Log.Info(new MigEvent(this.GetName(), remoteAddress, "HTTP", request.HttpMethod,
                                                 $"{response.StatusCode} {request.RawUrl}{logExtras}"));
            }
            catch (Exception ex)
            {
                MigService.Log.Error(ex);
            }
            finally
            {
                //
                // CleanUp/Dispose allocated resources
                //
                try { request.InputStream.Close(); } catch {
                    // TODO: add logging
                }
                try { response.OutputStream.Close(); } catch {
                    // TODO: add logging
                }
                try { response.Close(); } catch {
                    // TODO: add logging
                }
                try { response.Abort(); } catch {
                    // TODO: add logging
                }
            }
        }
 /// <summary>
 /// Closes the connection without sending a response
 /// </summary>
 internal protected void Abort()
 {
     _httpListenerResponse.Abort();
 }