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