} // proc WriteText /// <summary>Writes the stream to the output.</summary> /// <param name="context"></param> /// <param name="stream"></param> /// <param name="contentType"></param> public static void WriteStream(this IDEContext context, Stream stream, string contentType = MimeTypes.Application.OctetStream) { var length = stream.CanSeek ? stream.Length : -1L; using (var dst = context.GetOutputStream(contentType, length)) stream.CopyTo(dst); } // proc WriteStream
private void HttpDumpLoadAction(IDEContext r, int id = -1) { // get the dump file DumpFileInfo di = null; using (dumpFiles.EnterReadLock()) { var index = dumpFiles.FindIndex(c => c.Id == id); if (index >= 0) { di = dumpFiles[index]; } } // send the file if (di == null) { throw new ArgumentException("dump id is wrong."); } var fi = new FileInfo(di.FileName); if (!fi.Exists) { throw new ArgumentException("dump id is invalid."); } r.SetAttachment(fi.Name) .WriteFile(fi.FullName, MimeTypes.Application.OctetStream + ";gzip"); } // HttpDumpLoadAction
} // proc OnEndReadConfiguration public override bool Request(IDEContext r) { // create the full file name var fileName = Path.GetFullPath(Path.Combine(directoryBase, ProcsDE.GetLocalPath(r.RelativeSubPath))); // Check for a directory escape if (!fileName.StartsWith(directoryBase, StringComparison.OrdinalIgnoreCase)) { return(false); } // is the filename a directory, add index.html if (Directory.Exists(fileName)) { fileName = Path.Combine(fileName, "Index.html"); } if (File.Exists(fileName)) { // security DemandFile(r, fileName); // Send the file r.WriteFile(fileName, GetFileContentType(fileName)); return(true); } else { return(false); } } // func Request
} // proc WriteXml public static void WriteObject(this IDEContext context, object value, string contentType = null) { if (value == null) { throw new ArgumentNullException("value"); } else if (value is XElement) { WriteXml(context, (XElement)value, contentType ?? MimeTypes.Text.Xml); } else if (value is XDocument) { WriteXml(context, (XDocument)value, contentType ?? MimeTypes.Text.Xml); } else if (value is string) { WriteText(context, (string)value, contentType ?? MimeTypes.Text.Plain); } else if (value is Stream) { WriteStream(context, (Stream)value, contentType ?? MimeTypes.Application.OctetStream); } else if (value is byte[]) { WriteBytes(context, (byte[])value, contentType ?? MimeTypes.Application.OctetStream); } else if (value is LuaTable) { WriteXml(context, new XDocument(Procs.ToXml((LuaTable)value))); } else { throw new HttpResponseException(HttpStatusCode.BadRequest, String.Format("Can not send return value of type '{0}'.", value.GetType().FullName)); } } // proc WriteObject
protected override bool OnProcessRequest(IDEContext r) { if (base.OnProcessRequest(r)) { return(true); } return(Request(r)); } // func OnProcessRequest
} // proc WriteTextAsHtml public static void WriteXml(this IDEContext context, XElement value, string contentType = MimeTypes.Text.Xml) { WriteXml(context, new XDocument( new XDeclaration("1.0", context.Server.Encoding.WebName, "yes"), value ), contentType); } // proc WriteXml
} // proc SetAttachment #endregion #region -- WriteText, WriteBytes, WriteStream ------------------------------------- /// <summary>Writes the text to the output.</summary> /// <param name="context"></param> /// <param name="value"></param> /// <param name="contentType"></param> public static void WriteText(this IDEContext context, string value, string contentType = MimeTypes.Text.Plain, Encoding encoding = null) { if (encoding == null) { encoding = context.InputEncoding ?? context.Server.Encoding; } WriteBytes(context, encoding.GetBytes(value), contentType); } // proc WriteText
} // func WriteFile /// <summary></summary> /// <param name="context"></param> /// <param name="type"></param> /// <param name="resourceName"></param> /// <param name="contentType"></param> public static void WriteResource(this IDEContext context, Type type, string resourceName, string contentType = null) { if (String.IsNullOrEmpty(resourceName)) { throw new ArgumentNullException("resourceName"); } // Öffne die Resource WriteResource(context, type.Assembly, type.Namespace + '.' + resourceName, contentType); } // proc WriteResource
} // proc WriteResource private static object CreateScript(IDEContext context, string cacheId, Func <TextReader> createSource) { var p = cacheId.LastIndexOf('\\'); var luaEngine = context.Server.GetService <IDELuaEngine>(true); return(luaEngine.CreateScript( createSource, p >= 0 ? cacheId.Substring(p + 1) : "content.lua" )); } // func CreateScript
} // proc GenerateHtmlBlock #endregion #region -- SetLastModified, SetXXXXFileName --------------------------------------- /// <summary>Sets the output last modified date</summary> /// <param name="context"></param> /// <param name="lastModified"></param> /// <returns></returns> public static IDEContext SetLastModified(this IDEContext context, DateTime lastModified) { if (lastModified.Kind != DateTimeKind.Utc) { lastModified = lastModified.ToUniversalTime(); } context.OutputHeaders[HttpResponseHeader.LastModified] = lastModified.ToString("R", CultureInfo.InvariantCulture); return(context); } // proc SetLastModified
} // proc WriteObject #endregion #region -- WriteSafeCall ---------------------------------------------------------- public static void WriteSafeCall(this IDEContext r, XElement x, string successMessage = null) { if (x == null) { x = new XElement("return"); } DEConfigItem.SetStatusAttributes(x, true, successMessage); WriteXml(r, x); } // proc WriteSafeCall
} // HttpDumpLoadAction #endregion #endregion #region -- OnProcessRequest ------------------------------------------------------- protected override bool OnProcessRequest(IDEContext r) { if (String.Compare(r.RelativeSubPath, "favicon.ico", true) == 0) { r.WriteResource(typeof(DEServer), "des.ico"); return(true); } else { return(base.OnProcessRequest(r)); } } // proc OnProcessRequest
private void HttpListGetAction(IDEContext r, string id, int start = 0, int count = Int32.MaxValue) { // Suche den passenden Controller var controller = FindController(id); if (controller == null) { throw new HttpResponseException(HttpStatusCode.BadRequest, String.Format("Liste '{0}' nicht gefunden.", id)); } // check security token r.DemandToken(controller.SecurityToken); // write list ((IDEListService)Server).WriteList(r, controller, start, count); } // func HttpListGetAction
} // func GetContent #endregion #region -- WriteXXXX -------------------------------------------------------------- /// <summary>Writes the text as an html page.</summary> /// <param name="context"></param> /// <param name="value"></param> public static void WriteTextAsHtml(this IDEContext context, string value, string title = "page") { WriteText(context, String.Join(Environment.NewLine, "<!DOCTYPE html>", "<html>", "<head>", " <meta charset=\"utf-8\"/>", $" <title>{title}</title>", "</head>", "<body>", $" <pre>{value}</pre>", "</body>"), MimeTypes.Text.Html, Encoding.UTF8 ); } // proc WriteTextAsHtml
} // ctor public object Invoke(DEConfigItem item, IDEContext context) { if (action != null) { if (isNativeCall) { action(item, context); return(DBNull.Value); } else { return(action(item, context)); } } else { return(null); } } // proc Invoke
/// <summary>Writes the file to the output.</summary> /// <param name="context"></param> /// <param name="fi"></param> /// <param name="contentType"></param> public static void WriteFile(this IDEContext context, FileInfo fi, string contentType = null) { // set last modified SetLastModified(context, fi.LastWriteTimeUtc); // set the filename SetInlineFileName(context, fi.Name); // fint the correct content type if (contentType == null) { contentType = context.Server.GetContentType(fi.Extension); } // write the content WriteContent(context, () => new FileStream(fi.FullName, FileMode.Open, FileAccess.Read), fi.DirectoryName + "\\[" + fi.Length + "," + fi.LastWriteTimeUtc.ToString("R") + "]\\" + fi.Name, contentType); } // func WriteFile
} // proc CollectActions /// <summary>Führt eine Aktion aus.</summary> /// <param name="actionName">Name der Aktion</param> /// <param name="context">Parameter, die übergeben werden sollen.</param> /// <returns>Rückgabe</returns> public object InvokeAction(string actionName, IDEContext context) { // Suche die Action im Cache DEConfigAction a; lock (actions) { a = actions[actionName]; if (a == null) // Beziehungsweise erzeuge sie { a = CompileAction(actionName); if (a == null) { a = DEConfigAction.Empty; } actions[actionName] = a; } } // Führe die Aktion aus try { if (a == DEConfigAction.Empty) { throw new HttpResponseException(HttpStatusCode.BadRequest, String.Format("Action {0} not found", actionName)); } context.DemandToken(a.SecurityToken); return(a.Invoke(this, context)); } catch (Exception e) { if (!a.IsSafeCall || context.IsOutputStarted || (e is HttpResponseException)) // Antwort kann nicht mehr gesendet werden { throw; } // Meldung protokollieren Log.LogMsg(LogMsgType.Error, e.GetMessageString()); return(CreateDefaultXmlReturn(false, e.Message)); } } // func InvokeAction
} // proc WriteResource /// <summary></summary> /// <param name="context"></param> /// <param name="assembly"></param> /// <param name="resourceName"></param> /// <param name="contentType"></param> public static void WriteResource(this IDEContext context, Assembly assembly, string resourceName, string contentType = null) { // Ermittle den ContentType if (contentType == null) { contentType = context.Server.GetContentType(Path.GetExtension(resourceName)); } WriteContent(context, () => { var src = assembly.GetManifestResourceStream(resourceName); if (src == null) { throw new ArgumentException(String.Format("Resource '{0}' not found.", resourceName)); } return(src); }, assembly.FullName.Replace(" ", "") + "\\" + resourceName, contentType); } // proc WriteResource
protected void DemandFile(IDEContext r, string subPath) { var tokens = Config.Elements(xnSecurityDef).Where(x => TestFilter(x, subPath)).Select(x => x.Value?.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)).FirstOrDefault(); if (tokens == null || tokens.Length == 0) { return; } var a = false; foreach (var c in tokens) { if (a |= r.TryDemandToken(c)) { break; } } if (!a) { throw r.CreateAuthorizationException(subPath); } } // func DemandFile
} // proc WriteSafeCall public static void WriteSafeCall(this IDEContext r, string errorMessage) { WriteXml(r, DEConfigItem.CreateDefaultXmlReturn(false, errorMessage) ); } // proc WriteSafeCall
} // proc WriteXml public static void WriteXml(this IDEContext context, XDocument value, string contentType = MimeTypes.Text.Xml) { using (var tw = context.GetOutputTextWriter(contentType, context.Server.Encoding, -1)) value.Save(tw); } // proc WriteXml
} // proc OnBeginReadConfiguration public override bool Request(IDEContext r) { if (assembly == null || namespaceRoot == null) { return(false); } // create the resource name var resourceName = namespaceRoot + r.RelativeSubPath.Replace('/', '.'); var src = (Stream)null; try { DateTime stamp; // try to open the resource stream var forceAlternativeCheck = nonePresentAlternativeExtensions != null && nonePresentAlternativeExtensions.FirstOrDefault(c => resourceName.EndsWith(c, StringComparison.OrdinalIgnoreCase)) != null; src = assembly.GetManifestResourceStream(resourceName); if (src == null && !forceAlternativeCheck) // nothing... { return(false); } // check if there is a newer file if (alternativeRoots != null) { var relativeFileName = ProcsDE.GetLocalPath(r.RelativeSubPath); var alternativeFile = (from c in alternativeRoots let fi = new FileInfo(Path.Combine(c, relativeFileName)) where fi.Exists && (forceAlternativeCheck || fi.LastWriteTimeUtc > assemblyStamp) orderby fi.LastWriteTimeUtc descending select fi).FirstOrDefault(); if (alternativeFile != null) { src?.Close(); src = alternativeFile.OpenRead(); stamp = alternativeFile.LastWriteTimeUtc; } else { stamp = assemblyStamp; if (forceAlternativeCheck && src == null) { return(false); } } } else { stamp = assemblyStamp; if (forceAlternativeCheck && src == null) { return(false); } } // security DemandFile(r, resourceName); // send the file r.SetLastModified(stamp) .WriteStream(src, GetFileContentType(resourceName) ?? r.Server.GetContentType(Path.GetExtension(resourceName))); return(true); } finally { Procs.FreeAndNil(ref src); } } // func Request
} // func CreateScript public static void WriteContent(this IDEContext context, Func <Stream> createSource, string cacheId, string contentType) { if (cacheId == null) { throw new ArgumentNullException("cacheId"); } if (contentType == null) { throw new ArgumentNullException("contentType"); } var http = context.Server as IDEHttpServer; var o = http?.GetWebCache(cacheId); // create the item if (o == null) { using (var src = createSource()) { var isLua = contentType == MimeTypes.Text.Lua; var isHtml = contentType == MimeTypes.Text.Html; var cacheItem = isLua || isHtml || (src.CanSeek && src.Length < CacheSize); if (cacheItem) { var isText = contentType.StartsWith("text/"); if (isLua) { o = CreateScript(context, cacheId, () => Procs.OpenStreamReader(src, Encoding.Default)); } else if (isHtml) { bool isPlainText; var content = "otext('text/html');" + ParseHtml(Procs.OpenStreamReader(src, Encoding.Default), src.CanSeek ? src.Length : 1024, out isPlainText); o = isPlainText ? content : CreateScript(context, cacheId, () => new StringReader(content)); } else if (isText) { using (var tr = Procs.OpenStreamReader(src, Encoding.Default)) o = tr.ReadToEnd(); } else { o = src.ReadInArray(); } // write the cache item http?.UpdateWebCache(cacheId, o); } else // write data without cache { WriteStream(context, src, contentType); return; } } } // write the item to the output if (o == null) { throw new ArgumentNullException("output", "No valid output."); } else if (o is ILuaScript) { var c = (ILuaScript)o; LuaResult r; using (var g = new LuaHttpTable(context, contentType)) r = c.Run(g, true); if (!context.IsOutputStarted && r.Count > 0) { WriteObject(context, r[0], r.GetValueOrDefault(1, MimeTypes.Text.Html)); } } else if (o is byte[]) { WriteBytes(context, (byte[])o, contentType); } else if (o is string) { WriteText(context, (string)o, contentType, context.Server.Encoding); } else { throw new ArgumentException($"Invalid cache item. Type '{o.GetType()}' is not supported."); } } // func GetContent
} // func DemandFile /// <summary>Does the specific address.</summary> /// <param name="r">Request context.</param> /// <returns><c>true</c>, if the request is processed.</returns> public abstract bool Request(IDEContext r);
} // proc WriteStream #endregion #region -- WriteFile, WriteResource, WriteContent --------------------------------- /// <summary>Writes the file to the output.</summary> /// <param name="context"></param> /// <param name="fileName"></param> /// <param name="contentType"></param> public static void WriteFile(this IDEContext context, string fileName, string contentType = null) => WriteFile(context, new FileInfo(fileName), contentType);
public LuaHttpTable(IDEContext context, string contentType) { this.context = context; this.contentType = contentType; } // ctor
} // proc WriteSafeCall public static void WriteSafeCall(this IDEContext r, Exception e) { WriteSafeCall(r, e.Message); } // proc WriteSafeCall
} // proc SetAttachment /// <summary>Sets the content disposition to the given filename.</summary> /// <param name="context"></param> /// <param name="fileName"></param> /// <returns></returns> public static IDEContext SetAttachment(this IDEContext context, string fileName) { context.OutputHeaders["Content-Disposition"] = $"attachment; filename = \"{fileName}\""; return(context); } // proc SetAttachment
} // proc WriteListFetchList #endregion void IDEListService.WriteList(IDEContext r, IDEListController controller, int startAt, int count) { var sendTypeDefinition = String.Compare(r.GetProperty("desc", Boolean.FalseString), Boolean.TrueString, StringComparison.OrdinalIgnoreCase) == 0; // Suche den passenden Descriptor var descriptor = controller.Descriptor; if (descriptor == null) { throw new HttpResponseException(HttpStatusCode.BadRequest, String.Format("Liste '{0}' besitzt kein Format.", controller.Id)); } controller.OnBeforeList(); // Rückgabe using (var tw = r.GetOutputTextWriter(MimeTypes.Text.Xml)) using (var xml = XmlWriter.Create(tw, GetSettings(tw))) { xml.WriteStartDocument(); xml.WriteStartElement("list"); // Sollen die Strukturinformationen übertragen werdem if (sendTypeDefinition) { xml.WriteStartElement("typedef"); descriptor.WriteType(new DEListTypeWriter(xml)); xml.WriteEndElement(); } // Gib die Daten aus using (controller.EnterReadLock()) { var list = controller.List; // Prüfe auf Indexierte Listen var useInterface = ListEnumeratorType.Enumerable; Type useInterfaceType = null; foreach (var ii in list.GetType().GetTypeInfo().ImplementedInterfaces) { if (ii.IsGenericType) { Type genericType = ii.GetGenericTypeDefinition(); if (genericType == typeof(IList <>)) { if (useInterface < ListEnumeratorType.ListTyped) { useInterface = ListEnumeratorType.ListTyped; useInterfaceType = ii; } } else if (genericType == typeof(IReadOnlyList <>)) { if (useInterface < ListEnumeratorType.ReadOnlyList) { useInterface = ListEnumeratorType.ReadOnlyList; useInterfaceType = ii; } } else if (genericType == typeof(IDERangeEnumerable2 <>)) { if (useInterface < ListEnumeratorType.RangeEnumerator) { useInterface = ListEnumeratorType.RangeEnumerator; useInterfaceType = ii; } } } else if (ii == typeof(System.Collections.IList)) { if (useInterface < ListEnumeratorType.ListUntyped) { useInterface = ListEnumeratorType.ListUntyped; } } } // Gib die entsprechende Liste aus xml.WriteStartElement("items"); switch (useInterface) { case ListEnumeratorType.Enumerable: var enumerator = list.GetEnumerator(); try { WriteListFetchEnum(xml, descriptor, enumerator, startAt, count); } finally { var tmp = enumerator as IDisposable; if (tmp != null) { tmp.Dispose(); } } break; case ListEnumeratorType.ReadOnlyList: case ListEnumeratorType.ListTyped: case ListEnumeratorType.RangeEnumerator: WriteListFetchTyped(useInterfaceType, r, xml, descriptor, list, startAt, count); break; case ListEnumeratorType.ListUntyped: WriteListFetchList(xml, descriptor, (IList)list, startAt, count); break; default: throw new HttpResponseException(System.Net.HttpStatusCode.InternalServerError, String.Format("Liste '{0}' nicht aufzählbar.", controller.Id)); } xml.WriteEndElement(); } xml.WriteEndElement(); xml.WriteEndDocument(); } } // proc IDEListService.WriteList
} // proc WriteText /// <summary>Writes the bytes to the output.</summary> /// <param name="context"></param> /// <param name="value"></param> /// <param name="contentType"></param> public static void WriteBytes(this IDEContext context, byte[] value, string contentType = MimeTypes.Application.OctetStream) { using (var dst = context.GetOutputStream(contentType, value.Length)) dst?.Write(value, 0, value.Length); } // proc WriteText