using System; using System.Web; using System.Threading; using System.Globalization; using System.IO; /* * @page: Global.asax.cs * @copy: ConceptDevelopment.NET * @created: Jun-04 * @desc: HttpFilter that processes outbound Html responses to * search and replace 'language identifiers' in English * web pages so that the images & links point to French * pages (why? it's a DEMO, remember!) * Majority of the code is from this page * http://authors.aspalliance.com/aspxtreme/sys/Web/HttpResponseClassFilter.aspx * which has an HttpFilter example that converts all text * on the page to UPPERCASE */ namespace HttpFilterDemo { /// <remarks>[static] Global</remarks> public class Global : System.Web.HttpApplication { /// <summary>Constructor</summary> public Global() { InitializeComponent(); } /// <summary>App Request start</summary> protected void Application_BeginRequest(Object sender, EventArgs e) { // attach the Filter to each response object HttpResponse response = HttpContext.Current.Response; // In reality, you would want to decide here whether // or not you _wanted_ the Filter enabled (for example, // English pages don't need it, French pages do) if (response.ContentType == "text/html") { response.Filter = new LinkPathFilter(response.Filter); } } #region Web Form Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() {} #endregion } /// <summary> /// The purpose of this Filter is to 'find and replace' /// language-identifiers in URLs/Links and in Image filenames. /// Urls are in the form http://server/lang/page.html /// eg. change http://server/en/page.html to http://server/fr/page.html /// Image names are in the form header_lang_1.gif /// eg. change header_e_1.gif to header_f_1.gif /// </summary> /// <remarks> /// Code for this 'demo' couresty of: /// http://www.aspalliance.com/aspxtreme/sys/Web/HttpResponseClassFilter.aspx /// http://authors.aspalliance.com/aspxtreme/sys/Web/HttpResponseClassFilter.aspx /// with ideas from /// http://www.aspnetresources.com/articles/HttpFilters.aspx /// </remarks> public class LinkPathFilter : Stream { private Stream _sink; private long _position; public LinkPathFilter ( Stream sink ) { _sink = sink; } // The following members of Stream must be overriden. public override bool CanRead { get { return true; } } public override bool CanSeek { get { return true; } } public override bool CanWrite { get { return true; } } public override long Length { get { return 0; } } public override long Position { get { return _position; } set { _position = value; } } public override long Seek ( long offset, System.IO.SeekOrigin direction ) { return _sink.Seek ( offset, direction ); } public override void SetLength ( long length ) { _sink.SetLength ( length ); } public override void Close ( ) { _sink.Close ( ); } public override void Flush ( ) { _sink.Flush ( ); } public override int Read ( byte [ ] buffer, int offset, int count ) { return _sink.Read ( buffer, offset, count ); } // The Write method actually does the filtering. public override void Write ( byte [ ] buffer, int offset, int count ) { byte [ ] data = new byte [ count ] ; Buffer.BlockCopy ( buffer, offset, data, 0, count ); // <LinkPath specific changes to sample code> // This may not be pretty, but it works byte data1=data[0],data2=data[0],data3=data[0],data4=data[0]; for ( int i = 0; i < count; i++ ) { if (i > 4){ // once we're far enough in data4 = data3; data3 = data2; data2 = data1; } data1 = data[i]; // test for /en/ pattern if (data1 == Convert.ToByte('/') ) { if ( (data4 == Convert.ToByte('/')) && (data3 == Convert.ToByte('e')) && (data2 == Convert.ToByte('n'))){ // change it to /fr/ data [ i-1 ] = Convert.ToByte('r'); data [ i-2 ] = Convert.ToByte('f'); } } // test for _e_ pattern else if (data1 == Convert.ToByte('_' )) { if ( (data3 == Convert.ToByte('_') ) && (data2 == Convert.ToByte('e') ) ){ // change it to _f_ data [ i-1 ] = Convert.ToByte('k'); } } } // </LinkPath specific changes to sample code> _sink.Write ( data, 0, count ); } } // LinkPathFilter } // namespace