Content are missing when replacing strings

Jun 30, 2009 at 6:25 AM

HI

I am using version 3.0 &  want to customize Reverse proxy before use it.

i want to change content of the response retrived from the original url & then write to output stream,

for that i have changed SendResponseToClient function of the proxyhandler class. it working finely just problem is it drops the end string

from the  original response. it seems this may be problem with the length of the outputstream as string which i am replacing have bigger length then the original one. please help me to get out of this....

below is the changed part of the function.

using (Stream responseStream = response.GetResponseStream(), bufferStream = new BufferedStream(responseStream, Manager.Configuration.Rewriter.Proxy.BufferSize))
            {
                //StreamReader oReader = new StreamReader(responseStream, Encoding.ASCII);
                //string str = oReader.ReadToEnd();

                byte[] buffer = new byte[bufferSize];
                while (true)
                {
                    buffer = new byte[bufferSize];
                    int bytesReturned = bufferStream.Read(buffer, 0, bufferSize);

                    // if not bytes were returned the end of the stream has been reached
                    // and the loop should exit
                    if (bytesReturned == 0)
                        break;

                    //TO DO : change the string over here
                    byte[] tmpbuffer;
                    if (response.ContentType.Contains("text/html"))
                    {
                        System.Text.UTF8Encoding utf8 = new System.Text.UTF8Encoding();

                        System.Text.StringBuilder strBuffer = new System.Text.StringBuilder(utf8.GetString(buffer));
                        string strsourcesite = System.Configuration.ConfigurationManager.AppSettings["SourceSite"];
                        string strdestinationsite = System.Configuration.ConfigurationManager.AppSettings["DestinitionSite"];
            
                        strBuffer.Replace(strsourcesite, strdestinationsite);
                        tmpbuffer = null;
                        tmpbuffer = UTF8Encoding.UTF8.GetBytes(strBuffer.ToString());
                    }
                    else
                        tmpbuffer = buffer;
                    // write bytes to the response
                    context.Response.OutputStream.Write(tmpbuffer, 0, tmpbuffer.Length);
                }
            }

 

Coordinator
Jun 30, 2009 at 10:29 AM
Edited Jun 30, 2009 at 12:48 PM

I would recommend doing this as a filter. In an additional HTTP Module. Because the filter will do the exact same thing you want to do, and it will not require you to maintain your own branch of the URL Rewriter. A filter is basically a post processing the stream before it exits to the web browser. Here is an example of a filter:

http://urlrewriter.codeplex.com/SourceControl/changeset/view/32603#364433

and if you create your own HttpModule

public class DestinationUrlFilter : IHttpModule {

#region IHttpModule Members

public void Dispose() { }

public void Init(HttpApplication context) {

context.PostReleaseRequestState += new EventHandler(context_PostReleaseRequestState);

}

#endregion

private void context_PostReleaseRequestState(object sender, EventArgs e) {

HttpContext context = ((HttpApplication)sender).Context;

if (Manager.Configuration.Rewriter.RewriteFormPostBack && !context.Items.Contains(Manager.ProxyHandlerStorageName) && context.Response.ContentType != null && context.Response.ContentType.IndexOf("text/html", StringComparison.InvariantCultureIgnoreCase) >= 0)

context.Response.Filter = new FormActionFilter(context.Response.Filter);

}

}

Then the last step is to just register it in your Web.config after the URL Rewriter.

<httpModules>

<add name="RewriterModule" type="ManagedFusion.Rewriter.RewriterModule, ManagedFusion.Rewriter"/>

<add name="DestinationUrlFilter" type="MyFilter.DestinationUrlFilter, MyFilter"/>

</httpModules>

Hope this helps you to avoid making a separate branch of my URL Rewriter. Also you don't have to store the Source and Destination information.

Source = HttpContext.Current.Items["X-Rewrite-Url"]

Destination = HttpContext.Request.Url Let me know how it goes.

 

Sorry don't know what happened to the formating.

Jun 30, 2009 at 11:32 AM

Hi

Thanks for the reply

now i have tried with httpmodule as per your suggestion

still i have same problem. i have added this module in my web application instead of using it with rewriter.

below is my write method of the response filter.

public override void Write(byte[] buffer, int offset, int count)
        {
            string textBuffer = Encoding.UTF8.GetString(buffer, offset, count);
            string url = HttpContext.Current.Items["X-Rewrite-Url"] as string;
            string strsourcesite = System.Configuration.ConfigurationManager.AppSettings["SourceSite"];
            string strdestinationsite = System.Configuration.ConfigurationManager.AppSettings["DestinitionSite"];

            if (textBuffer.IndexOf(strsourcesite) > -1)
            {
                try
                {
                    textBuffer = textBuffer.Replace(strsourcesite, strdestinationsite);
                    byte[] response = Encoding.UTF8.GetBytes(textBuffer);
                    _internalStream.Write(response, 0, response.Length);
                    return;
                }
                catch (HttpException) { }
            }

            _internalStream.Write(buffer, offset, count);
        }

i know it is not related to your product but it will be great if u could help me.

1 more thing i have tried apache rul set to redirect from subdomain to domain name but i didnt succeed

i want to write rule like http://mukesh.site.com to rewrite to http://site.com/rep__mukesh/ if u provide an example then it will be really

very helpfull.

regards,

Mukesh Chudasama

Coordinator
Jun 30, 2009 at 12:52 PM

You may have to process the entire contents at once.  Loop through all the text with each write until an end of line is found and then do you modifications.  Because you cannot predict where the buffer will break your content so you may not being getting hte full URL.

Second you need to process the URL seperate from the path.  Like I did with:

RewriteCond %{HTTP_HOST} !^www.coderjournal.com$ [NC]
RewriteRule ^(.*)$ http://www.coderjournal.com$1 [R=301,L]

So for you it would be

RewriteCond %{HTTP_HOST} ^mukesh.site.com$ [NC]
RewriteRule ^(.*)$
http://site.com/rep__mukesh/$1 [L]

Jul 1, 2009 at 6:22 AM

HI

thanks for the help...

i have changed code for processing the response at once.

but the original problems still remains. i got the exact problem why this is happing.

when i use the response.filter in filter i am replacing the string. original string is shorter then the replacing string

now the length of the output stream is not increasing while my replaced string is bigger then the original string.

i have checked and found only problem is output stream is not increasing the length which resulting the loss of ending bytes.

i have tried to setlength but it not allowing to set length of the output stream. can u guid me to get out of this.

and for apache rewriting i want wildcard to map to my site as it is not possible to predifined the no of domains. in apache there is some

% operator is there that can be used to meet the requirements i have tried that but i think it is not working with the rewriter. if it is

not available then i have to maintain the sepreate copy of the rewriter to meet the requirement.

 

thanks & regards,

Mukesh Chudasama

Coordinator
Jul 1, 2009 at 9:52 AM

Hi Mukesh,

The % opperator is present, but the % opperator takes the whole part of a condition, not a specific part like the regex filter in RewriteRule.  If you can find a syntax that works in Apache I will make sure that it is supported, because the rewriter is very close to being 100% complete, and is is 100% complete for the RewriteRule and RewriteCond.  That being said what you want may require a custom RewriteRule module.  

http://www.coderjournal.com/2008/12/creating-extension-module-net-url-rewriter-reverse-proxy/

Also, I don't really know what the issue is with the filter.  I have never had any problems expanding the length.  You many want to try looking at another example of modifying the output stream.

http://aspnetresources.com/articles/HttpFilters.aspx

Hope that helps,

Nick Berardi