AW: slow servlet filter for ByteArrayOutputStream response Wrapper

2010-06-04 Thread Steffen Heil
Hi

I just read that reply and noticed that I have the same fault in my code.
How can I measure the length of the utf8-Encoding?

The only way I can think of is to convert the String to byte[] and the take
its length. However at that point it does not make any sense to use a
writer, it would be more suitable to use the OutputStream and send that
byte[], right?

Is there another way to get the correct content-length?

Regards,
  Steffen


 -Ursprüngliche Nachricht-
 Von: Konstantin Kolinko [mailto:knst.koli...@gmail.com]
 Gesendet: Dienstag, 1. Juni 2010 11:41
 An: Tomcat Users List
 Betreff: Re: slow servlet filter for ByteArrayOutputStream response
Wrapper
 
 2010/6/1 Manny Mondeo manny...@yahoo.com:
   httpRes.setContentLength(content.toString().length());
 
 Also, the above, or simplier content.length(), will give you the length
 measured in characters,  but Content-Length must be the length measured
 in bytes.  For a multi-byte charset such as UTF-8 those are certainly not
the
 same. (Unless all your characters are 7-bit).
 
   httpRes.setContentType( text/html; charset=UTF-8 ) ;
   out.write(content);
   out.flush();
   out.close();
 
   }
 
 
 Best regards,
 Konstantin Kolinko
 
 -
 To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
 For additional commands, e-mail: users-h...@tomcat.apache.org


smime.p7s
Description: S/MIME cryptographic signature


Re: slow servlet filter for ByteArrayOutputStream response Wrapper

2010-06-01 Thread Mark Thomas
On 01/06/2010 03:53, Manny Mondeo wrote:
 Hi ,
 I have written a filter that strips the response of some html tags.
 The filter is working and executing around 30milliseconds.
 
 The problem is that the request takes around 30 seconds to load this in a 
 browser. The filter gets executed fast but the status bar in the browser does 
 not complete and the page gets struck to about 25 seconds before the response 
 comes and gets rendered.

That usually means the content length header isn't set correctly.

Mark



-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org



Re: slow servlet filter for ByteArrayOutputStream response Wrapper

2010-06-01 Thread Konstantin Kolinko
2010/6/1 Manny Mondeo manny...@yahoo.com:
  httpRes.setContentLength(content.toString().length());

Also, the above, or simplier content.length(), will give you the
length measured in characters,  but Content-Length must be the length
measured in bytes.  For a multi-byte charset such as UTF-8 those are
certainly not the same. (Unless all your characters are 7-bit).

  httpRes.setContentType( text/html; charset=UTF-8 ) ;
  out.write(content);
  out.flush();
  out.close();

  }


Best regards,
Konstantin Kolinko

-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org



Re: slow servlet filter for ByteArrayOutputStream response Wrapper

2010-06-01 Thread Christopher Schultz
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Konstantin,

On 6/1/2010 5:41 AM, Konstantin Kolinko wrote:
 2010/6/1 Manny Mondeo manny...@yahoo.com:
  httpRes.setContentLength(content.toString().length());
 
 Also, the above, or simplier content.length(), will give you the
 length measured in characters,  but Content-Length must be the length
 measured in bytes.  For a multi-byte charset such as UTF-8 those are
 certainly not the same. (Unless all your characters are 7-bit).

I would think that this would be the problem, except that
charCount(utf8str) = byteCount(utf8Str), so the worst thing that could
happen is that the Content-Length was too /short/, and the browser would
either read everything anyway, or ignore the extra bytes. A too-long
Content-Type can definitely cause a browser to stall.

I like this error better as the cause:

   //PrintWriter out = httpRes.getWriter();
   PrintWriter out = wrapp.getWriter();
 Why wrapp.getWriter(); ??

Certainly writing to the buffered response and never to the actual
response will not send any data to the browser. :(

- -chris
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.10 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkwFE/UACgkQ9CaO5/Lv0PDnYACgwCosffsg66HpD7f443xYhscx
of4An00pZmi8lbb8Ef3PJO+9Kr+k7n87
=q0Fl
-END PGP SIGNATURE-

-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org



Re: slow servlet filter for ByteArrayOutputStream response Wrapper

2010-06-01 Thread Konstantin Kolinko
2010/6/1 Christopher Schultz ch...@christopherschultz.net:
 On 6/1/2010 5:41 AM, Konstantin Kolinko wrote:
 2010/6/1 Manny Mondeo manny...@yahoo.com:
          httpRes.setContentLength(content.toString().length());

 Also, the above, or simplier content.length(), will give you the
 length measured in characters,  but Content-Length must be the length
 measured in bytes.  For a multi-byte charset such as UTF-8 those are
 certainly not the same. (Unless all your characters are 7-bit).

 I would think that this would be the problem, except that
 charCount(utf8str) = byteCount(utf8Str), so the worst thing that could
 happen is that the Content-Length was too /short/, and the browser would
 either read everything anyway, or ignore the extra bytes. A too-long
 Content-Type can definitely cause a browser to stall.


There is such thing as o.a.coyote.http11.filters.IdentityOutputFilter.
If contentLength is set it will prevent sending more than the stated
number of bytes (discarding the rest of them). Thus, the data will be
trimmed at any HTML construct, or even between bytes comprising a
single multibyte character.
That is how I read the code: someone should do a test run to be sure.

 I like this error better as the cause:

           //PrintWriter out = httpRes.getWriter();
           PrintWriter out = wrapp.getWriter();
 Why wrapp.getWriter(); ??

 Certainly writing to the buffered response and never to the actual
 response will not send any data to the browser. :(

Certainly. Or the code that was posted in not the one that was run.


Best regards,
Konstantin Kolinko

-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org



slow servlet filter for ByteArrayOutputStream response Wrapper

2010-05-31 Thread Manny Mondeo
Hi ,
I have written a filter that strips the response of some html tags.
The filter is working and executing around 30milliseconds.

The problem is that the request takes around 30 seconds to load this in a 
browser. The filter gets executed fast but the status bar in the browser does 
not complete and the page gets struck to about 25 seconds before the response 
comes and gets rendered.

Apache 6.0.26, windows 7 OS, jdk 1.5

here is the filter code

 
public class InterimFilter implements Filter 
{
    public final static String NAV_START = !--START Nav--;
        public final static String NAV_END = !--END Nav--;
    public final static String NAV_START_HIDE = !--hide;
    public final static String NAV_END_HIDE = hide--;
    public final static double millsToSecConvertFactor = 0.001;
    private FilterConfig filterConfig;
    
public void init( FilterConfig config ) throws ServletException
{
    System.out.println( ((- Initialised Interim Filter -)) );
}
public void destroy()
{    
filterConfig = null;
}
    
 public void doFilter( ServletRequest request, ServletResponse response, 
FilterChain chain )                     throws IOException, ServletException
{ 
      HttpServletResponse    httpRes   = (HttpServletResponse)response;
     //PrintWriter out = httpRes.getWriter();
     GenericResponseWrapper wrapp    = new GenericResponseWrapper( httpRes);
     long startTime = System.currentTimeMillis();
     chain.doFilter(request, wrapp);
     long endTime = System.currentTimeMillis();
     byte[] c  = wrapp.getResponseBytes();
     String content = new String(c);
    
    //actual filter work
 //from start to end of contents.
 int i = content.indexOf( NAV_START );
 int j = content.indexOf( NAV_END );
 if( ( i =0 )  ( j  i ) )
 {
 String nav = content.substring( i, j + NAV_END.length() );
 StringBuffer buffer = new StringBuffer();
 for( int k = nav.indexOf( NAV_START_HIDE ), l = nav.indexOf( 
NAV_END_HIDE ) + NAV_END_HIDE.length(), m = 0; ( k =0 )  ( l  k ); )
 {
 buffer.append( nav.substring( m, k ) );
 m = l;
 k = nav.indexOf(  NAV_START_HIDE, l );
 //new
 if (k == -1)
 {
 buffer.append( nav.substring(l, 
nav.indexOf(NAV_END)));
 break;
 }
 //end new
 l = nav.indexOf(  NAV_END_HIDE, k ) + 
NAV_END_HIDE.length();
 }
    nav= buffer.toString();
    buffer = new StringBuffer();
 buffer.append( content.substring( 0, i ) );
 buffer.append( nav );
 buffer.append( content.substring( j ) );
    
 content = buffer.toString();
 buffer = null;
 nav = null;
 }
 //PrintWriter out = httpRes.getWriter();
 PrintWriter out = wrapp.getWriter();
 httpRes.setContentLength(content.toString().length());
 httpRes.setContentType( text/html; charset=UTF-8 ) ;
 out.write(content);
 out.flush();
 out.close();         
         
 }
     
 public FilterConfig getFilterConfig()
  {
    return this.filterConfig;
  }
  public void setFilterConfig (FilterConfig filterConfig)
  {
    this.filterConfig = filterConfig;
  }
      
  public class GenericResponseWrapper extends HttpServletResponseWrapper    
{
     private PrintWriter writer;  
     private ServletOutputStream outputStream;
     private ByteArrayOutputStream buffer;    
             
     public GenericResponseWrapper(HttpServletResponse response)    
      {    
                super(response);    
                buffer = new ByteArrayOutputStream();
                 
            }
            
            public byte[] getResponseBytes()
            {
                flushBuffer();
                return buffer.toByteArray();
            }
            
            public void flushBuffer()
            {
                if (outputStream != null) 
                {
                    try
                    {
                        outputStream.flush();
                    }
                    catch (IOException e)
                    {
                        e.printStackTrace();
                    }
                }
                if (writer != null)
                {
                    writer.flush();
                }
            }

            public ServletOutputStream getOutputStream()    
            {  
                if (outputStream == null)
                {
                     outputStream = new FilterServletOutputStream(buffer);
                                      
                }
                return 

Re: slow servlet filter for ByteArrayOutputStream response Wrapper

2010-05-31 Thread Konstantin Kolinko
2010/6/1 Manny Mondeo manny...@yahoo.com:
 Hi ,
 I have written a filter that strips the response of some html tags.
 The filter is working and executing around 30milliseconds.

How do you measure the time?

 The problem is that the request takes around 30 seconds to load this in a 
 browser. The filter gets executed fast but the status bar in the browser does 
 not complete and the page gets struck to about 25 seconds before the response 
 comes and gets rendered.

Maybe it loads images, loads and executes javascript, or maybe your
HTML is invalid. Maybe you have a firewall that scans your traffic for
malware. Have you tried it with a different browser?

      String content = new String(c);

The above line is wrong. Use some explicit encoding.

  StringBuffer buffer = new StringBuffer();

java.lang.StringBuilder may be a bit faster (though it is unlikely
that you will notice).

  //PrintWriter out = httpRes.getWriter();
  PrintWriter out = wrapp.getWriter();

Why wrapp.getWriter(); ??

  httpRes.setContentLength(content.toString().length());
  httpRes.setContentType( text/html; charset=UTF-8 ) ;

You cannot set charset when you already called getWriter(). Move the
above line higher in the code.

             public PrintWriter getWriter()
             {
                 if (writer == null)
                 {
                     try
                     {
                         writer = new PrintWriter(new 
 OutputStreamWriter(outputStream, this.getCharacterEncoding()));

The above will throw an exception if outputStream is null.

Best regards,
Konstantin Kolinko

-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org