Reading Response Data

This code snippet illustrates how to read an HTTP response in a Java Extension.

Reading an HTTP response is not as simple as it might appear. Response data may be implicitly empty (for example, 304 Not Modified responses), the content length value may be missing, and the data may be transfer-encoded with chunking.

ZXTM will automatically handle all content length issues for you and it will de-chunk response data automatically so you don't need to worry about transfer encodings. The following code snippet will read the response from the server and place it in a Java String named 'body':

public void doGet( HttpServletRequest req, HttpServletResponse res )
    throws ServletException, IOException
{
    ZXTMHttpServletResponse zres = (ZXTMHttpServletResponse) res;

    // Read the response
    BufferedReader reader = zres.getReader();
			
    StringBuilder data = new StringBuilder();
    char[] buf = new char[4096];
    int len;
    while( ( len = reader.read( buf ) ) >= 0 ) {
        data.append( buf, 0, len );
    }
    String body = data.toString();

    // Now process the body data...
}

Handling Compressed Responses

If the client provides an 'Accept-Encoding' header, it indicates that it can accept responses in various encodings; gzip is commonly used to compress content.

Generally, if you intend to inspect and process response data, you would want to supress this so that the remote server does not return compressed data. Compressing and decompressing the data between the server and ZXTM is wasteful - bandwidth should be plentiful, and the compression adds latency and CPU processing to the response.

You can use TrafficScript™, or a simple RuleBuilder™ rule to supress the Accept-Encoding header from the client:

Note: Even if you delete the Accept-Encoding header, ZXTM will remember that the remote client can accept compressed data. ZXTM will still compress responses (with the correct mime-types, etc) if you enable ZXTM's content compression.

Alternatively, you can decompress the response data in the Java Servlet:

// Read the response
String body;

String contentEncoding = zres.getHeader( "Content-Encoding" ); 
if( contentEncoding != null && contentEncoding.equals( "gzip" ) )

    zres.removeHeader( "Content-Encoding" );
				
    // Currently, ZXTM's implementation of ServletInputStream.read() does not 
    // correctly handle high-bit characters.  This anonymous class provides an 
    // alternative read() implementation until this is resolved.

    InputStream is = new FilterInputStream( zres.getInputStream() ) {
        public int read() throws IOException
        {
            byte[] single = new byte[1];
            int r = read( single );
            return( r > 0 ) ? single[0] < 0 ? 256+single[0] : single[0] : -1;
        }
    };
        
    GZIPInputStream gis = new GZIPInputStream( is ); 
        
    // InputStreams return byte[]; Strings need char[].
    StringBuilder data = new StringBuilder();
    byte[] buf = new byte[4096];
    char[] bufc = new char[4096];
    int len;

    while( ( len = gis.read( buf, 0, 4096 ) ) >= 0 ) {
        for( int i = 0; i < len; i++ ) bufc[i] = (char)buf[i];
        data.append( bufc, 0, len );
    }
    body = data.toString();
        
} else {
    BufferedReader reader = zres.getReader();
    StringBuilder data = new StringBuilder();
    char[] buf = new char[4096];
    int len;
    while( ( len = reader.read( buf ) ) >= 0 ) {
        data.append( buf, 0, len );
    }
    body = data.toString();
}
Owen Garrett [Zeus Dev Team] 01 July 2008  Permalink  
Leave a comment ...
Your email address will not be displayed.
Your URL will be displayed.
This public messageboard is not a forum for technical support. To report technical support problems, please contact our dedicated Support team using the instructions at the bottom of this page.
Options:
 
(Line breaks become <br />)
(Set cookies for name, email & url)
Download Free ZXTM Desktop Edition

Recent Articles

Other Resources



www.zeus.com