tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jun Inamori <j-off...@osa.att.ne.jp>
Subject Re: Proposal: RequestImpl
Date Thu, 04 May 2000 17:00:11 GMT
Hi Costin, Dmitry and Eugen
Thank you for your reply.

Based on the discussion about my proposal, I've just wrote some sort of
RequestInterceptor.
While I've not completed it yet, I send its source.
I'll write some comment about it later.

-- 
Happy Java programming!

Jun Inamori
E-mail: j-office@osa.att.ne.jp
URL:    http://www.oop-reserch.com

*** source ***
*** for FixCharset ***

package org.apache.tomcat.request;

import org.apache.tomcat.core.*;
import org.apache.tomcat.util.*;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

// Should we use this?
//import sun.io.ByteToCharConverter;

public class FixCharset extends  BaseInterceptor
    implements RequestInterceptor {

    static private int result=0;

    /**
     *  Web masters can override this by 'charSet' property.
     *  Should be overriden by 'charset' attribute
     *  of 'Content-Type' from WWW browser.
     *  But at this time, we don't know such a browser.
     */
    static private String cs="US-ASCII";

    /**
     *  Web masters can override this by 'charSet' property.
     *  Should be overriden by 'charset' attribute
     *  of 'Content-Type' from WWW browser.
     *  But at this time, we don't know such a browser.
     */
    static private String enc=System.getProperty("file.encoding");
    // Or should we use this?
    // static private String
enc=ByteToCharConverter.getDefault().getCharacterEncoding();


    /** an original request */
    static private Request req = null;
    
    /** parameter storage */
    static private Hashtable params = new Hashtable();
    /** file storage */
    
    /** the HTTP GET method signature */
    final static private String METHOD_GET = "GET";
    /** the HTTP POST method signature */
    final static private String METHOD_POST = "POST";
    /** the url-style form parameter encoding */
    final static private String ENCODING_URL =
"application/x-www-form-urlencoded";

    public FixCharset() {
    }

    public void setCharset(String c_set){
	cs=c_set;
	enc=CharsetToJavaEnc.getJavaEncoding(cs);
	if(enc==null){
	    enc=System.getProperty("file.encoding");
	    // Or should we use this?
	    //enc=ByteToCharConverter.getDefault().getCharacterEncoding();
	}
    }

    public String getCharset(){
	return cs;
    }

    public String getJavaEnc(){
	return enc;
    }

    /**
     *  Called at first in ServletWrapper.handleRequest().
     *  In case of POST or GET, parameters must be parsed
     *  and decoded.
     *  For POST, parameters should be read from InputStream.
     */
    public int afterRead( Request request, Response response ) {
	req=request;
	result=0;
	params.clear();
	/**
	 *  Override the initial value
	 *  (which is specified by webmaster)
	 *  by the one from WWW browser.
	 */
        String c_set=req.getCharacterEncoding();
	if(c_set!=null){
	    cs=c_set;
	    String w_enc=CharsetToJavaEnc.getJavaEncoding(c_set);
	    if(w_enc!=null){
		enc=w_enc;
	    }
	}
	// Set the initial value to request
	else{
	    req.setCharEncoding(cs);
	}


if(!req.getMethod().toUpperCase().equals(METHOD_GET)&&!req.getMethod().toUpperCase().equals(METHOD_POST)){
	    return 0;
	}
	else{
	    try{
		processParameters(getByteArray());
		req.setParameters(params);
	    }
	    catch(Exception ex){}
	}
	return result;
    }

    /**
     *  In case of POST, we have to read from InputStream.
     *  Otherwise we can use req.getQueryString.
     */
    private byte[] getByteArray()
	throws Exception{
	byte[] buffer=null;
	if(req.getMethod().toUpperCase().equals(METHOD_POST)){
	    try{
		ServletInputStream sis = req.getInputStream();
		if(sis!=null){
		    int length=req.getContentLength();
		    buffer=new byte[length];
		    int offset=0;
		    for(int readBytes=0; offset<length; offset+=readBytes){
			readBytes=sis.read(buffer,offset,length-offset );
			if(readBytes==-1){
			    break;
			}
		    }
		    sis.close();
		}
	    }
	    catch(Exception ex){
		result=HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
		throw ex;
	    }
        }
	else{
	    String s=req.getQueryString();
	    if(s!=null && s.length() > 0 ){
		buffer=s.getBytes();
	    }
	    else{
		result=HttpServletResponse.SC_BAD_REQUEST;
		throw (new TomcatException("No query string!"));
	    }
	}
	return buffer;
    }

    /**
     *  Parameter processor core. Parses text values,
     *  extracts and saves files.
     */
    private void processParameters(byte[] buffer)
	throws Exception{

	//extract parameters
        byte[] b2 = new byte[buffer.length + 1];
        int n = 0;
        for ( int i = 0; i < buffer.length; i++ ){
	    char some=(char)buffer[i];
	    switch ( some ){
            case '+':
		b2[n++] =(byte) ' ';
		break;
            case '%':
		char[] digit=new char[2];
		digit[0]=(char)buffer[++i];
		digit[1]=(char)buffer[++i];
		int i_v=Integer.parseInt((new String(digit)),16);
		b2[n++]=(byte)i_v;
		break;
            case '&':
		convertParameter( b2, n );
		n = 0;
		break;
            default:
		b2[n++] = buffer[i];
		break;
	    }
        }
        convertParameter( b2, n );
    }

    /**
     * The parameter parser
     * @param bytes a byte array representing the parameter entry
     * @param n entry length (it's expected that the buffer is longer)
     */
    private void convertParameter( byte[] bytes, int n )
	throws Exception{
	int n2 = 0;
	// At first, we have to know the index of '='.
	// Without String.indexOf()!
	while ( bytes[n2++] != '=' && n2 < n );
	
	// Then devide given byte array into key and value.
	int del=(bytes[n2 - 1] == '=') ? n2 - 1 : n2;
	try{
	    String key = new String(bytes, 0, del, enc);
	    String value = "";
	    if( n2 < n ){
		value=new String(bytes, n2, n - n2, enc);
	    }
	    putParameter( key, value );
	}
	catch(Exception ex){
	    result=HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
	    throw ex;
	}
    }

    private void putParameter(String key, String value){
	String values[];
	if (params.containsKey(key)) {
	    String oldValues[] = (String[])params.get(key);
	    values = new String[oldValues.length + 1];
	    for (int i = 0; i < oldValues.length; i++) {
		values[i] = oldValues[i];
	    }
	    values[oldValues.length] = value;
	} else {
	    values = new String[1];
	    values[0] = value;
	}
	params.put(key, values);
    }
    
}

Mime
View raw message