// Rewrites before displaying HTML code private static void RewritePipeHtmlRewriteUrl(object sender, HtmlRewriteEventArgs e) { try { IEnumerable<ProviderSettings> providerSettings = Helpers.AmazonS3VirtualPathHelper.GetAllSettings(); if (!providerSettings.Any()) { return; } foreach (ProviderSettings providerSetting in providerSettings) { string virtualPath = Helpers.AmazonS3VirtualPathHelper.GetVirtualPath(providerSetting); if (e.Value.StartsWith(virtualPath)) { string url = Helpers.AmazonS3VirtualPathHelper.GetBaseUrl(providerSetting); e.ValueBuilder.Replace(virtualPath, string.Empty); e.ValueBuilder.Insert(0, url); } } } catch (Exception ex) { Log.Error(ex.Message); // Important to never throw an exception in the friendly URL handling. } }
/// <summary> /// Init the HtmlRewrite-engines event handlers. This is called every time a HtmlRewritePipe object /// is instantiated by the UrlRewriteModule /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="EPiServer.Web.HtmlRewriteEventArgs"/> instance containing the event data.</param> static private void HtmlRewriteToExternal_HtmlRewriteInit(object sender, HtmlRewriteEventArgs e) { // We need an instance of ourselves, to keep track of our state ViewStateMover viewStateMover = new ViewStateMover(); // There are two major events from the HtmlRewrite-engine, which allow us to rewrite // names and values of the content. The exact definition depends on the XmlNodeType // that is being processed. e.RewritePipe.HtmlRewriteName += viewStateMover.HtmlRewriteNameEventHandler; e.RewritePipe.HtmlRewriteValue += viewStateMover.HtmlRewriteValueEventHandler; }
/// <summary> /// Handle rewrite name /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="EPiServer.Web.HtmlRewriteEventArgs"/> instance containing the event data.</param> /// <remarks> /// The name event is raised before an associated value event. Check the e.NodeType and other properties to determine /// course of action. /// </remarks> private void HtmlRewriteNameEventHandler(object sender, HtmlRewriteEventArgs e) { switch (_state) { case State.WaitingForForm: if (e.NodeType == XmlNodeType.Element && String.Compare(e.Name, "form", StringComparison.OrdinalIgnoreCase) == 0) { _state = State.InFormElement; } break; case State.InFormElement: if (e.NodeType != XmlNodeType.Element) { break; } if (String.Compare(e.Name, "input", StringComparison.OrdinalIgnoreCase) == 0) { _inputAttributes.Clear(); e.IsHoldingOutput = true; _state = State.BufferingInput; break; } // If we've seen ViewState, we either buffer script, or emit previously buffered script because // we're not at the end of the form element yet. if (_viewState.Count > 0) { if (String.Compare(e.Name, "script", StringComparison.OrdinalIgnoreCase) == 0) { _scripts.Append("<script"); e.IsHoldingOutput = true; _state = State.BufferingScript; break; } // If we find an element inside the form element and we have scripts buffered, we change our // mind and output it anyway, since we want to ensure that only the last scripts are output // after the ViewState (which should be the ones registred as startup script). if (_scripts.Length > 0) { e.ValueBuilder.Length = 0; e.ValueBuilder.Append(_scripts); _scripts.Length = 0; e.ValueBuilder.Append("<").Append(e.Name); } } break; } }
/// <summary> /// Handle rewrite value /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="EPiServer.Web.HtmlRewriteEventArgs"/> instance containing the event data.</param> /// <remarks> /// The value event is raised after an associated name event. Check the e.NodeType and other properties to determine /// course of action. /// </remarks> private void HtmlRewriteValueEventHandler(object sender, HtmlRewriteEventArgs e) { // Remove all insignificant whitespace if (_enableWhitespaceRemoval && e.NodeType == XmlNodeType.Whitespace) { e.ValueBuilder.Length = 0; e.ValueBuilder.Append(" "); return; } switch (_state) { // We're buffering the contents of input element attributes, while checking for if it is a ViewState field case State.BufferingInput: switch (e.NodeType) { // Another attribute, add it to the collection and check if it's a ViewState case XmlNodeType.Attribute: _inputAttributes.Add(e.Name, new AttributeValue(e.Value, e.QuoteChar)); _viewStateFound |= String.Compare(e.Name, "name", StringComparison.OrdinalIgnoreCase) == 0 && e.Value.StartsWith("__VIEWSTATE"); e.IsHoldingOutput = true; break; // End of the input element start tag. Determine if we're to output and continue waiting, or if it's the ViewState, // in which case we switch state, and output nothing here. case XmlNodeType.Element: if (_viewStateFound && e.IsEmptyElement) { e.IsHoldingOutput = true; _viewState.Add(_inputAttributes); _inputAttributes = new Dictionary <string, AttributeValue>(); _state = State.InFormElement; } else { e.ValueBuilder.Length = 0; AppendInputElement(e.ValueBuilder, _inputAttributes, e.IsEmptyElement); _inputAttributes.Clear(); _state = State.InFormElement; } _viewStateFound = false; break; } break; case State.BufferingScript: bool isHoldingOutput = true; switch (e.NodeType) { case XmlNodeType.Attribute: _scripts.AppendFormat(" {0}={2}{1}{2}", e.Name, HttpUtility.HtmlAttributeEncode(e.Value), e.QuoteChar); break; case XmlNodeType.Comment: case XmlNodeType.SignificantWhitespace: case XmlNodeType.Text: case XmlNodeType.CDATA: _scripts.Append(e.Value); break; case XmlNodeType.Element: _scripts.Append(e.Value); if (e.IsEmptyElement) { _state = State.InFormElement; } break; case XmlNodeType.EndElement: _scripts.Append(e.Value); _state = State.InFormElement; break; default: isHoldingOutput = false; break; } if (isHoldingOutput) { e.IsHoldingOutput = true; } break; case State.InFormElement: string value; switch (e.NodeType) { case XmlNodeType.EndElement: if (String.Compare(e.Name, "form", StringComparison.OrdinalIgnoreCase) == 0) { value = e.Value; e.ValueBuilder.Length = 0; if (_viewState.Count > 0) { // Setting display:none because the div will under some circumstances // take up place in IE6 even though it shouldn't. e.ValueBuilder.Append("<div style=\"display:none\">"); foreach (Dictionary <string, AttributeValue> viewState in _viewState) { AppendInputElement(e.ValueBuilder, viewState, e.IsEmptyElement); } e.ValueBuilder.Append("</div>"); } _inputAttributes.Clear(); _viewState.Clear(); e.ValueBuilder.Append(_scripts); _scripts.Length = 0; e.ValueBuilder.Append(value); _state = State.SkipToEnd; } break; } break; case State.SkipToEnd: break; } }
/// <summary> /// Handle rewrite value /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="EPiServer.Web.HtmlRewriteEventArgs"/> instance containing the event data.</param> /// <remarks> /// The value event is raised after an associated name event. Check the e.NodeType and other properties to determine /// course of action. /// </remarks> private void HtmlRewriteValueEventHandler(object sender, HtmlRewriteEventArgs e) { // Remove all insignificant whitespace if (_enableWhitespaceRemoval && e.NodeType == XmlNodeType.Whitespace) { e.ValueBuilder.Length = 0; e.ValueBuilder.Append(" "); return; } switch (_state) { // We're buffering the contents of input element attributes, while checking for if it is a ViewState field case State.BufferingInput: switch (e.NodeType) { // Another attribute, add it to the collection and check if it's a ViewState case XmlNodeType.Attribute: _inputAttributes.Add(e.Name, new AttributeValue(e.Value, e.QuoteChar)); _viewStateFound |= String.Compare(e.Name, "name", StringComparison.OrdinalIgnoreCase) == 0 && e.Value.StartsWith("__VIEWSTATE"); e.IsHoldingOutput = true; break; // End of the input element start tag. Determine if we're to output and continue waiting, or if it's the ViewState, // in which case we switch state, and output nothing here. case XmlNodeType.Element: if (_viewStateFound && e.IsEmptyElement) { e.IsHoldingOutput = true; _viewState.Add(_inputAttributes); _inputAttributes = new Dictionary<string, AttributeValue>(); _state = State.InFormElement; } else { e.ValueBuilder.Length = 0; AppendInputElement(e.ValueBuilder, _inputAttributes, e.IsEmptyElement); _inputAttributes.Clear(); _state = State.InFormElement; } _viewStateFound = false; break; } break; case State.BufferingScript: bool isHoldingOutput = true; switch (e.NodeType) { case XmlNodeType.Attribute: _scripts.AppendFormat(" {0}={2}{1}{2}", e.Name, HttpUtility.HtmlAttributeEncode(e.Value), e.QuoteChar); break; case XmlNodeType.Comment: case XmlNodeType.SignificantWhitespace: case XmlNodeType.Text: case XmlNodeType.CDATA: _scripts.Append(e.Value); break; case XmlNodeType.Element: _scripts.Append(e.Value); if (e.IsEmptyElement) { _state = State.InFormElement; } break; case XmlNodeType.EndElement: _scripts.Append(e.Value); _state = State.InFormElement; break; default: isHoldingOutput = false; break; } if (isHoldingOutput) { e.IsHoldingOutput = true; } break; case State.InFormElement: string value; switch (e.NodeType) { case XmlNodeType.EndElement: if (String.Compare(e.Name, "form", StringComparison.OrdinalIgnoreCase) == 0) { value = e.Value; e.ValueBuilder.Length = 0; if (_viewState.Count > 0) { // Setting display:none because the div will under some circumstances // take up place in IE6 even though it shouldn't. e.ValueBuilder.Append("<div style=\"display:none\">"); foreach (Dictionary<string, AttributeValue> viewState in _viewState) { AppendInputElement(e.ValueBuilder, viewState, e.IsEmptyElement); } e.ValueBuilder.Append("</div>"); } _inputAttributes.Clear(); _viewState.Clear(); e.ValueBuilder.Append(_scripts); _scripts.Length = 0; e.ValueBuilder.Append(value); _state = State.SkipToEnd; } break; } break; case State.SkipToEnd: break; } }
/// <summary> /// Init the HtmlRewrite-engines event handlers. This is called every time a HtmlRewritePipe object /// is instantiated by the UrlRewriteModule /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="EPiServer.Web.HtmlRewriteEventArgs"/> instance containing the event data.</param> private static void HtmlRewriteToExternal_HtmlRewriteInit(object sender, HtmlRewriteEventArgs e) { // We need an instance of ourselves, to keep track of our state ViewStateMover viewStateMover = new ViewStateMover(); // There are two major events from the HtmlRewrite-engine, which allow us to rewrite // names and values of the content. The exact definition depends on the XmlNodeType // that is being processed. e.RewritePipe.HtmlRewriteName += viewStateMover.HtmlRewriteNameEventHandler; e.RewritePipe.HtmlRewriteValue += viewStateMover.HtmlRewriteValueEventHandler; }
private static void HtmlRewriteToExternalHtmlRewriteInit(object sender, HtmlRewriteEventArgs e) { e.RewritePipe.HtmlRewriteUrl += RewritePipeHtmlRewriteUrl; }