예제 #1
0
        /// <summary>
        /// Behandelt einen eingehenden Anforderung
        /// Wird nebenläufig ausgeführt
        /// </summary>
        /// <param name="client">Der Client</param>
        private void HandleClient(TcpClient client)
        {
            //lock (Context)
            {
                var stopwatch = Stopwatch.StartNew();

                Response response = new ResponseNotFound();
                var      request  = null as Request;
                var      ip       = client.Client.RemoteEndPoint;
                using var stream = client.GetStream();
                var reader        = new BinaryReader(stream);
                var writer        = new StreamWriter(stream);
                var moduleContext = null as IModuleContext;
                var uri           = null as IUri;

                if (!stream.DataAvailable)
                {
                    //Context.Log.Debug(message: this.I18N("httpserver.rejected"), args: ip);
                    //return;
                }

                Context.Log.Info(message: this.I18N("httpserver.connected"), args: ip);


                try
                {
                    request = Request.Create(reader, ip.ToString());
                }
                catch (Exception ex)
                {
                    Context.Log.Exception(ex);
                }

                if (request == null)
                {
                    response = new ResponseBadRequest();
                    var statusPage = CreateStatusPage(response.Status, request, moduleContext, uri);
                    if (statusPage != null)
                    {
                        statusPage.StatusMessage = "";
                        response.Content         = statusPage;
                    }
                    else
                    {
                        response.Content = $"<h4>{response.Status}</h4>Bad Request";
                    }

                    response.HeaderFields.ContentLength = response.Content != null?response.Content.ToString().Length : 0;
                }

                try
                {
                    Context.Log.Debug(message: this.I18N("httpserver.request"), args: new object[] { ip, $"{request?.Method} {request?.URL} {request?.Version}" });

                    var resource = ResourceManager.Find(request?.URL.TrimEnd('/'));
                    if (resource != null && resource.Type != null)
                    {
                        var type    = resource.Type;
                        var culture = Culture;
                        moduleContext = resource.ModuleContext;
                        uri           = new UriResource(resource.ModuleContext, request.URL, resource, culture);

                        try
                        {
                            culture = new CultureInfo(request.HeaderFields?.AcceptLanguage?.TrimStart().Substring(0, 2).ToLower());
                        }
                        catch
                        {
                        }

                        if (type?.Assembly.CreateInstance(type?.FullName) is IResource instance)
                        {
                            if (instance is II18N i18n)
                            {
                                i18n.Culture = culture;
                            }

                            if (instance is Resource res)
                            {
                                res.Request         = request;
                                res.Uri             = uri;
                                res.Context         = resource.ModuleContext;
                                res.ResourceContext = resource.ResourceContext;

                                foreach (var p in request.Param)
                                {
                                    res.AddParam(p.Value);
                                }

                                foreach (var v in resource.Variables)
                                {
                                    res.AddParam(v.Key, v.Value, ParameterScope.Url);
                                }
                            }

                            if (instance is IPage page)
                            {
                                page.Title = resource.Title;
                            }

                            instance.Initialization();
                            instance.PreProcess(request);
                            response = instance.Process(request);
                            response = instance.PostProcess(request, response);

                            if (instance is IPage)
                            {
                                response.Content += $"<!--{ stopwatch.ElapsedMilliseconds } ms -->";
                            }
                        }
                    }

                    if (response is ResponseNotFound)
                    {
                        var statusPage = CreateStatusPage(response.Status, request, moduleContext, uri);
                        if (statusPage != null)
                        {
                            response.Content = statusPage;
                        }
                        else
                        {
                            response.Content = $"<h4>{ response.Status }</h4>";
                        }

                        response.HeaderFields.ContentLength = response.Content != null?response.Content.ToString().Length : 0;
                    }
                }
                catch (RedirectException ex)
                {
                    if (ex.Permanet)
                    {
                        response = new ResponseRedirectPermanentlyMoved(ex.Url);
                    }
                    else
                    {
                        response = new ResponseRedirectTemporarilyMoved(ex.Url);
                    }
                }
                catch (Exception ex)
                {
                    Context.Log.Exception(ex);

                    response = new ResponseInternalServerError();
                    var statusPage = CreateStatusPage(response.Status, request, moduleContext, uri);
                    if (statusPage != null)
                    {
                        statusPage.StatusMessage = $"<h4>Message</h4>{ ex.Message }<br/><br/>" +
                                                   $"<h5>Source</h5>{ ex.Source }<br/><br/>" +
                                                   $"<h5>StackTrace</h5>{ ex.StackTrace.Replace("\n", "<br/>\n") }<br/><br/>" +
                                                   $"<h5>InnerException</h5>{ ex.InnerException?.ToString().Replace("\n", "<br/>\n") }";

                        response.Content = statusPage;
                    }
                    else
                    {
                        response.Content = $"<h4>{ response.Status }</h4> { ex }";
                    }

                    response.HeaderFields.ContentLength = response.Content != null?response.Content.ToString().Length : 0;
                }

                // Response an Client schicken
                try
                {
                    writer.Write(response.GetHeader());
                    writer.Flush();

                    if (response.Content is byte[] content)
                    {
                        using var bw = new BinaryWriter(writer.BaseStream);
                        bw.Write(content);
                    }
                    else
                    {
                        writer.Write(response.Content ?? "");
                    }

                    writer.Flush();
                }
                catch (Exception ex)
                {
                    Context.Log.Error(ip + ": " + ex.Message);
                }

                stopwatch.Stop();

                Context.Log.Info(message: this.I18N("httpserver.request.done"), args: new object[] { ip, stopwatch.ElapsedMilliseconds, response.Status });
            }
        }
예제 #2
0
        /// <summary>
        /// Behandelt einen eingehenden Anforderung
        /// Wird nebenläufig ausgeführt
        /// </summary>
        /// <param name="client"></param>
        private void HandleClient(TcpClient client)
        {
            var ip = client.Client.RemoteEndPoint;

            //if (Context != null && Context.Log != null)
            //{
            //    Context.Log.Info(MethodInfo.GetCurrentMethod(), ip + ": Client wurde verbunden");
            //}

            var reader     = new StreamReader(client.GetStream());
            var requestStr = "";

            try
            {
                while (!reader.EndOfStream && reader.Peek() != 13)
                {
                    requestStr += reader.ReadLine() + "\n";
                }
            }
            catch (Exception)
            {
                //Context.Log.Error(MethodBase.GetCurrentMethod(), ip + ": " + ex.Message);
            }

            Request  request  = null;
            Response response = new ResponseNotFound();

            try
            {
                //Context.Log.Debug(MethodBase.GetCurrentMethod(), ip + ": Anfrage '" + requestStr + "'");

                if (!string.IsNullOrWhiteSpace(requestStr))
                {
                    request = Request.Parse(requestStr, ip.ToString());
                    if (request.HeaderFields.ContentLength > 0 && request.Method == RequestMethod.POST)
                    {
                        var buf = new char[request.HeaderFields.ContentLength];

                        reader.ReadLine();
                        reader.Read(buf, 0, buf.Count());

                        var param = new string(buf).Replace('+', ' ');

                        foreach (var v in param.Split('&'))
                        {
                            var s = v.Split('=');
                            request.AddParam(s[0], !string.IsNullOrWhiteSpace(s[1]) ? s[1] : string.Empty);
                        }
                    }

                    foreach (var p in Plugins)
                    {
                        response = p.PreProcess(request);
                        if (response == null)
                        {
                            response = p.Process(request);
                            response = p.PostProcess(request, response);
                        }

                        if (request != null && response != null && !(response is ResponseNotFound))
                        {
                            break;
                        }
                    }
                }
                else
                {
                    //Context.Log.Debug(MethodBase.GetCurrentMethod(), ip + ": Unerwartete Anfrage '" + requestStr + "'");
                    response = new ResponseInternalServerError();
                }
            }
            catch (Exception ex)
            {
                //if (Context != null && Context.Log != null)
                //{
                //    Context.Log.Exception(MethodInfo.GetCurrentMethod(), ex);
                //}
                response = new ResponseInternalServerError();
            }

            try
            {
                var writer = new StreamWriter(client.GetStream());
                writer.Write(response.GetHeader());
                writer.Flush();

                if (response.Content is byte[])
                {
                    BinaryWriter bw = new BinaryWriter(writer.BaseStream);

                    bw.Write((byte[])response.Content);
                }
                else
                {
                    writer.Write(response.Content ?? "");
                }

                writer.Flush();
            }
            catch (Exception)
            {
                //Context.Log.Error(MethodBase.GetCurrentMethod(), ip + ": " + ex.Message);
            }

            client.Close();

            //Context.Log.Info(MethodInfo.GetCurrentMethod(), ip + ": Anfrage wurde bearbeitet. Status=" + response.Status);
        }