Пример #1
0
        /// <summary>
        /// Loads an XmlDocument from the filecontainer, replacing GET parameters and verifying permissions
        /// </summary>
        /// <param name="xml"></param>
        /// <param name="xmlParseMode">The kind of text that's being parsed</param>
        /// <param name="fullpath"></param>
        /// <returns></returns>
        public XmlDocument LoadXmlDocument(string xml, XmlParseMode xmlParseMode, string fullpath)
        {
            XmlDocument xmlDocument = new XmlDocument();

            if (XmlParseMode.Html == xmlParseMode)
            {
                // see http://htmlagilitypack.codeplex.com
                // see http://htmlagilitypack.codeplex.com/SourceControl/changeset/view/67079#52182

                xml = "<!DOCTYPE html><html>" + xml.Split(new char[] { '>' }, 2)[1];

                HtmlDocument htmlDocument = new HtmlDocument();

                // Create a stream that's used for reading and writing
                Stream stream = new MemoryStream(xml.Length + (xml.Length / 5));

                // Create the XML writer
                XmlWriterSettings settings = new XmlWriterSettings();
                //settings.ConformanceLevel = ConformanceLevel.Fragment;
                settings.OmitXmlDeclaration = true;
                XmlWriter xmlWriter = XmlWriter.Create(stream, settings);

                try
                {
                    htmlDocument.LoadHtml(xml);

                    // Write the html to XML
                    htmlDocument.OptionOutputAsXml = true;
                    htmlDocument.Save(xmlWriter);
                }
                catch (Exception e)
                {
                    log.Error("An error occured trying to parse html:\n" + xml, e);
                    throw new WebResultsOverrideException(WebResults.From(Status._500_Internal_Server_Error, "An error occured trying to parse HTML, see the logs for more information"));
                }

                stream.Seek(0, SeekOrigin.Begin);

                // Read xml from the stream
                XmlReader xmlReader = XmlReader.Create(stream);
                xmlDocument.Load(xmlReader);

                // Get rid of junk nodes
                while ("html" != xmlDocument.FirstChild.LocalName)
                    xmlDocument.RemoveChild(xmlDocument.FirstChild);

                // Convert the namespace and clean up &nbsp; &lt; &gt that are converted incorrectly
                // TODO:  There really needs to be a better way to do this
                XmlAttribute namespaceAttribute = xmlDocument.CreateAttribute("xmlns");
                namespaceAttribute.Value = TemplateHandlerLocator.TemplatingConstants.HtmlNamespace;
                xmlDocument.DocumentElement.Attributes.Append(namespaceAttribute);

                xml = xmlDocument.OuterXml;
                foreach (KeyValuePair<string, string> toReplace in TemplateHandlerLocator.TemplatingConstants.HTMLReplacementChars)
                    xml = xml.Replace(toReplace.Key, toReplace.Value);
            }

            try
            {
                xmlDocument.LoadXml(xml);
            }
            catch (XmlException xmlException)
            {
                // When the Xml parse mode is to try HTML, then try HTML but if an error occurs swallow it and throw the original
                if (XmlParseMode.XmlThenHtml == xmlParseMode)
                    try
                    {
                        return LoadXmlDocument(xml, XmlParseMode.Html, fullpath);
                    }
                    catch { }

                // Everyone else can see a nice descriptive error
                StringBuilder errorBuilder = new StringBuilder(string.Format("An error occured while loading {0}\n", fullpath));
                errorBuilder.AppendFormat("{0}\n\n\nFrom:\n", xmlException.Message);

                string[] xmlLines = xml.Split('\n', '\r');
                for (int ctr = 0; ctr < xmlLines.Length; ctr++)
                {
                    int lineNumber = ctr + 1;

                    if (ctr < 9)
                        errorBuilder.Append("    ");
                    else if (ctr < 99)
                        errorBuilder.Append("   ");
                    else if (ctr < 999)
                        errorBuilder.Append("  ");
                    else if (ctr < 9999)
                        errorBuilder.Append(" ");

                    errorBuilder.AppendFormat("{0}: {1}\n", lineNumber, xmlLines[ctr]);

                    if (lineNumber == xmlException.LineNumber)
                        errorBuilder.AppendFormat("    -: {0}^\n", "".PadLeft(xmlException.LinePosition));
                }

                throw new WebResultsOverrideException(WebResults.From(Status._500_Internal_Server_Error, errorBuilder.ToString()));
            }

            return xmlDocument;
        }
Пример #2
0
        /// <summary>
        /// Loads an XmlDocument from the filecontainer, replacing GET parameters and verifying permissions
        /// </summary>
        /// <param name="arguments"></param>
        /// <param name="fileContainer"></param>
        /// <param name="xmlParseMode">The kind of text that's being parsed</param>
        /// <returns></returns>
        public XmlDocument LoadXmlDocumentAndReplaceGetParameters(
            IDictionary<string, object> arguments, 
            IFileContainer fileContainer,
            XmlParseMode xmlParseMode)
        {
            XmlDocument xmlDocument = LoadXmlDocument(fileContainer, xmlParseMode);

            // Do the replacements
            HandleArguments(arguments, xmlDocument);

            if (WebConnection.CookiesFromBrowser.ContainsKey(TemplateHandlerLocator.TemplatingConstants.XMLDebugModeCookie))
            {
                StringBuilder commentBuilder = new StringBuilder("\n\nDEBUG INFO\n");

                SortedDictionary<string, object> sortedArguments = new SortedDictionary<string, object>(arguments);

                foreach (KeyValuePair<string, object> getArgument in sortedArguments)
                    if (null != getArgument.Value)
                        commentBuilder.AppendFormat("\t{0}: {1}\n", getArgument.Key, getArgument.Value.ToString());
                    else
                        commentBuilder.AppendFormat("\t{0}: null\n", getArgument.Key);

                commentBuilder.Append("\n\n");

                XmlComment comment = xmlDocument.CreateComment(commentBuilder.ToString());

                XmlNode firstChild = xmlDocument.FirstChild;
                if ((firstChild.LocalName == "componentdef") && (firstChild.NamespaceURI == TemplateHandlerLocator.TemplatingConstants.TemplateNamespace))
                    firstChild.InsertBefore(comment, firstChild.FirstChild);
                else if ("html" != xmlDocument.FirstChild.LocalName)
                    xmlDocument.InsertBefore(comment, firstChild);
                else
                    firstChild.InsertBefore(comment, firstChild.FirstChild);
            }

            return xmlDocument;
        }
Пример #3
0
        /// <summary>
        /// Loads an XmlDocument from the filecontainer, replacing GET parameters and verifying permissions
        /// </summary>
        /// <param name="fileContainer"></param>
        /// <param name="xmlParseMode">The kind of text that's being parsed</param>
        /// <returns></returns>
        public XmlDocument LoadXmlDocument(IFileContainer fileContainer, XmlParseMode xmlParseMode)
        {
            WebConnection.TouchedFiles.Add(fileContainer);

            // Verify permission
            if (null == fileContainer.LoadPermission(WebConnection.Session.User.Id))
                throw new WebResultsOverrideException(WebResults.From(Status._401_Unauthorized, "You do not have permission to read " + fileContainer.FullPath));

            if (!(fileContainer.FileHandler is ITextHandler))
                throw new WebResultsOverrideException(WebResults.From(Status._400_Bad_Request, fileContainer.FullPath + " must be a text file"));

            return LoadXmlDocument(
                fileContainer.CastFileHandler<ITextHandler>().ReadAll(),
                xmlParseMode,
                fileContainer.FullPath);
        }