webForumDet fria alternativet

XHTMLStrictFilter och Windows 2003 server?

1 svar · 216 visningar · startad av maqe

maqeMedlem sedan dec. 2003824 inlägg
#1

Jag använder mig av en klass jag hittat här på webbforum för att få sidan att validera på w3c. Allt fungerar väldigt bra på min windows xp pro maskin men när jag driftsätter det på en 2003 server så får jag javascript fel samt att allt verkar gå väldigt segt? Det skall väl inte vara någon större prestandaförlust på att köra det filtret? Någon som har koll på skillnaderna mellan xp och 2003 server och vad det kan vara som genererar felen?

	public class XHTMLStrictFilter : Stream {

		private Stream _sink;
		private long _position;

		private static Regex _regForm = new Regex("<form .*name=.* .*>", RegexOptions.Compiled|RegexOptions.IgnoreCase);
		private static Regex _regNameReplace = new Regex("name=[^ ]*", RegexOptions.Compiled|RegexOptions.IgnoreCase);
		private static Regex _regViewState = new Regex("<input type=\"hidden\" name=\"__VIEWSTATE\" value=\".*\" />", RegexOptions.Compiled|RegexOptions.IgnoreCase);
		private static Regex _regEventTarget = new Regex("<input type=\"hidden\" name=\"__EVENTTARGET\" value=\".*\" />", RegexOptions.Compiled|RegexOptions.IgnoreCase);
		private static Regex _regEventArg = new Regex("<input type=\"hidden\" name=\"__EVENTARGUMENT\" value=\".*\" />", RegexOptions.Compiled|RegexOptions.IgnoreCase);
		// Tar bort alla border="0"
		private static Regex _regBorder = new Regex("border=[^ ]*", RegexOptions.Compiled|RegexOptions.IgnoreCase);
		// Byter language="javascript" till type="text/javascript"
		private static Regex _regType = new Regex("language=\"javascript\"", RegexOptions.Compiled|RegexOptions.IgnoreCase);

		private bool _formFix;
		private bool _viewStateFix;
		private bool _eventTargetFix;
		private bool _eventArgFix;
		private bool _borderFix;
		private bool _typeFix;
		
		#region public override bool CanRead
		/// <summary>
		/// 
		/// </summary>
		/// <value></value>
		public override bool CanRead
		{
			get { return true; }
		}
		#endregion
		#region public override bool CanSeek
		/// <summary>
		/// 
		/// </summary>
		/// <value></value>
		public override bool CanSeek
		{
			get { return true; }
		}
		#endregion
		#region public override bool CanWrite
		/// <summary>
		/// 
		/// </summary>
		/// <value></value>
		public override bool CanWrite
		{
			get { return true; }
		}
		#endregion
		#region public override long Length
		/// <summary>
		/// 
		/// </summary>
		/// <value></value>
		public override long Length
		{
			get { return 0; }
		}
		#endregion
		#region public override long Position
		/// <summary>
		/// 
		/// </summary>
		/// <value></value>
		public override long Position
		{
			get { return _position; }
			set { _position = value; }
		}
		#endregion

		#region public XHTMLStrictFilter()
		/// <summary>
		/// Creates an instance of the XHTMLStrictFilter class.
		/// </summary>
		public XHTMLStrictFilter() 
		{
			//
			// TODO: Add constructor logic here
			//
		}
		#endregion
		#region public XHTMLStrictFilter(Stream sink)
		/// <summary>
		/// Initializes a new instance of the <b>XHTMLStrictFilter</b> class.
		/// </summary>
		/// <param name="sink"></param>
		public XHTMLStrictFilter(Stream sink)
		{
			_sink = sink;
		}
		#endregion

		#region public override long Seek(long offset, System.IO.SeekOrigin direction)
		/// <summary>
		/// 
		/// </summary>
		/// <param name="offset"></param>
		/// <param name="direction"></param>
		/// <returns></returns>
		public override long Seek(long offset, System.IO.SeekOrigin direction)
		{
			return _sink.Seek(offset, direction);
		}
		#endregion
		#region public override void SetLength(long length)
		/// <summary>
		/// 
		/// </summary>
		/// <param name="length"></param>
		public override void SetLength(long length)
		{
			_sink.SetLength(length);
		}
		#endregion
		#region public override void Close()
		/// <summary>
		/// 
		/// </summary>
		public override void Close()
		{
			_sink.Close();
		}
		#endregion
		#region public override void Flush()
		/// <summary>
		/// 
		/// </summary>
		public override void Flush()
		{
			_sink.Flush();
		}
		#endregion
		#region public override int Read(byte[] buffer, int offset, int count)
		/// <summary>
		/// 
		/// </summary>
		/// <param name="buffer"></param>
		/// <param name="offset"></param>
		/// <param name="count"></param>
		/// <returns></returns>
		public override int Read(byte[] buffer, int offset, int count)
		{
			return _sink.Read(buffer, offset, count);
		}
		#endregion
		#region public bool IsLoggedOn(IPrincipal user)
		/// <summary>
		/// 
		/// </summary>
		/// <param name="user"></param>
		/// <returns></returns>
		public bool IsLoggedOn(IPrincipal user)
		{
			bool _isLoggedOn;
			_isLoggedOn = user != null && user.Identity.IsAuthenticated;
			return _isLoggedOn;
		}
		#endregion

		// The Write method actually does the filtering.
		#region public override void Write(byte[] buffer, int offset, int count)
		/// <summary>
		/// 
		/// </summary>
		/// <param name="buffer"></param>
		/// <param name="offset"></param>
		/// <param name="count"></param>
		public override void Write(byte[] buffer, int offset, int count)
		{
			byte[] data;

			if((!IsLoggedOn(HttpContext.Current.User)) && (!_formFix || !_viewStateFix || !_eventArgFix || !_eventTargetFix || !_borderFix || !_typeFix))
			{
				//string htmlOutput = System.Text.UTF8Encoding.UTF8.GetString(buffer);
				string htmlOutput = System.Text.Encoding.GetEncoding("iso-8859-1").GetString(buffer);
				int length = htmlOutput.Length;
				if(!_formFix && _regForm.IsMatch(htmlOutput))
				{
					string formMatch=_regForm.Match(htmlOutput).Value;
					htmlOutput=Regex.Replace(htmlOutput, _regNameReplace.Match(formMatch).Value,"", RegexOptions.IgnoreCase);
					_formFix=true;
				}
				if(!_viewStateFix && _regViewState.IsMatch(htmlOutput))
				{
					string viewStateMatch=_regViewState.Match(htmlOutput).Value;
					htmlOutput=Regex.Replace(htmlOutput, "<input type=\"hidden\" name=\"__VIEWSTATE\" value=\".*\" />", "<div>"+viewStateMatch+"</div>", RegexOptions.IgnoreCase); 
					_viewStateFix=true;
				}
				if(!_eventTargetFix && _regEventTarget.IsMatch(htmlOutput))
				{
					string eventTargetMatch=_regEventTarget.Match(htmlOutput).Value;
					htmlOutput=Regex.Replace(htmlOutput, "<input type=\"hidden\" name=\"__EVENTTARGET\" value=\".*\" />", "<div>"+eventTargetMatch+"</div>", RegexOptions.IgnoreCase); 
					_eventTargetFix=true;
				}
				if(!_eventArgFix && _regEventArg.IsMatch(htmlOutput))
				{
					string eventArgMatch=_regEventArg.Match(htmlOutput).Value;
					htmlOutput=Regex.Replace(htmlOutput, "<input type=\"hidden\" name=\"__EVENTARGUMENT\" value=\".*\" />", "<div>"+eventArgMatch+"</div>", RegexOptions.IgnoreCase); 
					_eventArgFix=true;
				}
				if(!this._typeFix && _regType.IsMatch(htmlOutput))
				{
					string formMatch=_regType.Match(htmlOutput).Value;
					htmlOutput=Regex.Replace(htmlOutput, _regType.Match(formMatch).Value,"type=\"text/javascript\"", RegexOptions.IgnoreCase);
					this._typeFix=true;
				}
				// If __doPostBack is registered, replace the whole function
				if (htmlOutput.IndexOf ("__doPostBack") > -1)
				{
					try
					{
						int     pos1 = htmlOutput.IndexOf ("var theform;");
						int     pos2 = htmlOutput.IndexOf ("theform.__EVENTTARGET", pos1);
						string  methodText = htmlOutput.Substring (pos1, pos2-pos1);
						string  formID = Regex.Match (methodText,"document.forms\\[\"(.*?)\"\\];",RegexOptions.IgnoreCase).Groups[1].Value.Replace (":", "_");

						htmlOutput = htmlOutput.Replace (methodText,@"var theform = document.getElementById ('" + formID + "');");
					}
					catch {}
				}

				// Tar bort alla border="0"
				if(!_borderFix && _regBorder.IsMatch(htmlOutput))
				{
					string formMatch=_regBorder.Match(htmlOutput).Value;
					htmlOutput=Regex.Replace(htmlOutput, _regBorder.Match(formMatch).Value,"", RegexOptions.IgnoreCase);
					_borderFix=true;
				}
				data = System.Text.Encoding.GetEncoding("iso-8859-1").GetBytes(htmlOutput);
				count -= length - htmlOutput.Length;
			}
			else
			{
				data = new byte[count];
				Buffer.BlockCopy(buffer, offset, data, 0, count);
			}
			_sink.Write(data, 0, count);
		}
		#endregion
	}
emissionMedlem sedan dec. 19996 721 inlägg
#2

Re: XHTMLStrictFilter och Windows 2003 server?

Det ska inte vara någon skillnad på hur filteret fungerar. Javascript-felet borde du kunna lokalisera (kör Firefox så får du vettigare debug-info). Prestandan blir säkert lidande om man har en högtrafikerad webbplats, men det borde gå att förbättra filtret en smula, eftersom det inte är särskilt välskrivet. Huruvida det blir en märkbar förbättring eller inte återstår att se.

Jag ger ett exempel på vad som är knasigt, så kanske du kan implementera förbättringar.

Originalkod:

if(!this._typeFix && _regType.IsMatch(htmlOutput))
{
   string formMatch=_regType.Match(htmlOutput).Value;
   htmlOutput=Regex.Replace(htmlOutput, _regType.Match(formMatch).Value,"type=\"text/javascript\"", RegexOptions.IgnoreCase);
   this._typeFix=true;
}

Felet med denna kodsnutt (som är närmast genomgående i alla matchningar) är att RegEx:en _regType körs 2 gånger för mycket. En gång för att testa om något ska ersättas, en gång för för att plocka ut vad som ska ersättas (vad som ska ersättas är ju bestämt), och en gång för att göra ersättningen

Följande kod ger exakt samma resultat (förvisso med en potentiellt onödig omtilldelning av htmlOutput, men det kostar sannolikt mindre än att matcha det reguljära uttrycket.


if(!this._typeFix)
{
   htmlOutput=_regType.Replace(htmlOutput,"type=\"text/javascript\"");
   this._typeFix=true;
}
141 ms totalt · 3 externa anrop · v20260731065814-full.30151723
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
138 ms — hämta tråd, inlägg och bilagor (db)