You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by ha...@apache.org on 2005/11/13 23:13:10 UTC
svn commit: r343982 - in
/webservices/axis/trunk/c/tests/utils/monitor/org/apache/test:
ClientReturner.java MockServerThread.java Response.java ResponseSender.java
TestClientListener.java
Author: hawkeye
Date: Sun Nov 13 14:13:01 2005
New Revision: 343982
URL: http://svn.apache.org/viewcvs?rev=343982&view=rev
Log:
Improving Unit test monitor so that it handles responses better. It now does better guesses at chunk sizes. A number of tests were failing because the user had put in bad chunk sizes and these had not been picked up in the past because (don't ask!) we used to send out each response twice. When I fixed that I realised the chunk size problem. this is quite a big change and might mean that unix test break - but I have tried to prevent that.
Added:
webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/Response.java
Modified:
webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/ClientReturner.java
webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/MockServerThread.java
webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/ResponseSender.java
webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/TestClientListener.java
Modified: webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/ClientReturner.java
URL: http://svn.apache.org/viewcvs/webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/ClientReturner.java?rev=343982&r1=343981&r2=343982&view=diff
==============================================================================
--- webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/ClientReturner.java (original)
+++ webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/ClientReturner.java Sun Nov 13 14:13:01 2005
@@ -103,7 +103,6 @@
System.err
.println("IOException when writing server response back to client");
exception.printStackTrace(System.err);
-
}
// System.out.println("ClientReturner#run(): flushed");
TCPMonitor.getInstance( ).writeResponse(readBuffer,
@@ -123,11 +122,11 @@
catch (IOException exception)
{
System.err
- .println("IOException when reading in response from server ");
+ .println("ClientReturner#run(): IOException when reading in response from server ");
exception.printStackTrace(System.err);
}
+ System.out.println( "ClientReturner#run(): exit");
}
- // System.out.println( "ClientReturner#run(): exit");
}
Modified: webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/MockServerThread.java
URL: http://svn.apache.org/viewcvs/webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/MockServerThread.java?rev=343982&r1=343981&r2=343982&view=diff
==============================================================================
--- webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/MockServerThread.java (original)
+++ webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/MockServerThread.java Sun Nov 13 14:13:01 2005
@@ -47,8 +47,9 @@
private static int requests =0;
- // We cache the entire output file in an array of char[]
- private static Object[] responses;
+ private static Response[] responses;
+
+ private boolean closedConnection=false;
public MockServerThread(Socket socket, File responseFile)
throws IOException , StopRequestException
@@ -193,7 +194,14 @@
}
catch (IOException exception)
{
- exception.printStackTrace(System.err);
+ if(!closedConnection)
+ {
+ exception.printStackTrace(System.err);
+ }
+ else
+ {
+ System.out.println( "MockServerThread#run(): Connection Has Been Closed");
+ }
}
System.out.println("MockServerThread#run(): exit");
}
@@ -209,11 +217,13 @@
IOException
{
// Create a seperate thread and return
- char[] responseMessage=getResponseMessage( );
+ Response responseMessage=getResponseMessage( );
+// System.out.println( "responsemessage ======="+responseMessage);
+// System.out.println( "===================================================");
if (responseMessage!=null)
{
ResponseSender responseSender=new ResponseSender(responseMessage,
- outputStream);
+ outputStream, this);
Thread responseSenderThread=new Thread(responseSender);
responseSenderThread.start( );
}
@@ -232,10 +242,10 @@
*
* @return a complete HTTP response
*/
- private char[] getResponseMessage( ) throws IOException,
+ private Response getResponseMessage( ) throws IOException,
ArrayIndexOutOfBoundsException
{
- return (char[]) responses[requests++];
+ return (Response) responses[requests++];
}
static void cacheResponseFile(File responseFile)
@@ -291,7 +301,7 @@
String[] responseStrings=completeFile.split("HTTP");
// now convert these into char[] and store them
- responses=new Object[responseStrings.length];
+ responses=new Response[responseStrings.length];
// the first line always has "HTTP" in it so the first response is null
// so I have to do the wierd loop below
for(int i=1; i<responseStrings.length; i++)
@@ -308,309 +318,323 @@
tmpString=tmpString.substring(0, hash)+len
+tmpString.substring(hash+3);
}
- responses[i-1]=tmpString.toCharArray( );
+ responses[i-1]=new Response(tmpString);
}
-
- setCRLF( );
}
- /**
- * Because the repositories we use accomodate the dos2unix conversion we
- * have a problem. On unix the response files have the crlf converted to
- * just cr. this method returns the crlf !
- *
- * The HTTP header and chunk sizes need to be delimited with CR LF's.
- * The 'server response' expected files used to mimic the response of a
- * server when performing unit tests also need to have the correct
- * delimiting character combinations in the fake response messages
- * (generated by the monitor). Problems arise because the expected
- * response files have been captured on different operating systems (Unix
- * and Windows) and then edited using a variety of editors that interpret
- * the CR character differently. Thus the file may be stored with or
- * without the CR characters. Also, the souce control application can be
- * set to convert a single LF character into a CR LF combination. The
- * outcome of all this character manipulation is that LF's may or may not
- * have the necessary associated CR for it to be recognised by the HTTP
- * transport. It is not just sufficient to look for every LF and to prefix
- * it with a CR because the context of that LF must be taken into
- * consideration. For example, if a LF is found in the HTTP header then it
- * definitely needs a CR prefix. This also applies when the message is
- * chunked and the chunk size must also be delimited by the CR LF sequence.
- * But, when a LF appears inside a chunk of data it should remain unchanged
- * unless the chunk size is different from the actual data size between
- * chunks, in which case the CR has probably been stripped out and needs to
- * be replaced. Below is a low level design of what should work in all
- * instances...
- *
- * Is the message chunked?
- * NO: Convert all single LF sequences to CR+LF.
- * NB: Because the value associated with the 'Content-Length' label is
- * not used correctly, if the size of the file grows larger than the
- * Content-Length value, no action is taken.
- * Exit.
- * YES: Convert all single LF sequences to CR+LF in the HTTP header.
- * Set Index = location of the first 'chunk' value.
- * Read the chunk size.
- * While the chunk size > 0
- * Convert any single LF sequences to CR+LF that surround the chunk
- * value.
- * Is the character at offset Index + chunk size equal to CR or LF?
- * NO: Count up the number of unaccompanied LF's in the chunk.
- * Is the difference between the expected and actual chunk data
- * length double the number of unaccompanied LF's?
- * NO: Error - Irreconcilable differences between expected and
- * actual chunk data sizes.
- * Exit.
- * YES: Convert all single LF sequences to CR+LF in the chunk
- * data.
- * Continue.
- * Index = Index + chunk size.
- * Read the new chunk size.
- * End of while.
- * Exit.
- */
- private static void setCRLF( )
- {
- String sLF = "\n";
- String sCR = "\r";
- String sCRLF = sCR + sLF;
- String sContentLength = "Content-Length:";
-
- for( int i = 0; i < responses.length; i++)
- {
- if( responses[i] != null)
- {
- String sResponse = new String((char[]) responses[i]);
- String sModifiedResponse = "";
- boolean bChunked = sResponse.indexOf( sContentLength) == -1;
-
- if( bChunked)
- {
- System.out.println("Information - Response file is chunked.");
-
- // Process HTTP header block. At the end of each line in
- // the header block, if there is only a LF character,
- // prefix it with a CR. The end of the HTTP header block
- // is denoted by an empty line (i.e. CR LF).
- String sLine;
- int iIndex = 0;
- int iEoL = sResponse.indexOf( sLF, iIndex) + 1;
-
- do
- {
- sLine = getResponseLine( sResponse, sCRLF, iIndex, iEoL);
-
- sModifiedResponse += sLine;
-
- // Get next line.
- iIndex = iEoL;
-
- iEoL = sResponse.indexOf( sLF, iIndex) + 1;
- } while( iEoL > 0 && !sLine.equals( sCRLF));
-
- // Immediately after the HTTP header block should be the
- // first chunk_size. All chunk_sizes are in hex. A chunk
- // size gives the size in bytes of the data that follows
- // the value (i.e. CR LF 2 0 0 0 CR LF <---Data---> CR LF)
- // but any number of CR may be missing and need to be
- // accounted for if the response file is to be processed
- // correctly.
- // Do some 'first time' processing to initialise the loop
- // that will process the HTTP message until the chunk size
- // is zero (signifying the end of the message).
- sLine = getResponseLine(sResponse, sCRLF, iIndex, iEoL);
-
- sModifiedResponse += sLine;
-
- iIndex = iEoL;
-
- // Evaluate chunk_size value.
- int iChunkSize = Integer.parseInt( sLine.trim(), 16);
-
- // On entry to the loop, iChunkSize is the size of the data
- // chunk and iIndex is the current location that is being
- // processed.
- do
- {
- int iChunkDataBlockBegin = iIndex;
- int iChunkDataBlockEnd = iIndex + iChunkSize;
- int iResponseSize = sResponse.length();
-
- // If the chunk data block end is greater than the size
- // of the file, then the size of the chunk is incorrect.
- // If '###' was used, then the size of the chunk is
- // incorrectly calculated to include the chunk size in
- // the chunk length.
- if( iChunkDataBlockEnd > iResponseSize)
- {
- if( iChunkDataBlockEnd - iResponseSize > 1)
- {
- System.out.println( "Warning - The chunk size is greater than the file size by " + (iChunkDataBlockEnd - iResponseSize) + " bytes.");
- }
-
- iChunkDataBlockEnd = sResponse.lastIndexOf( "0") - 1;
- iChunkSize = iChunkDataBlockEnd - iIndex;
- }
-
- String sChunkDataBlock = sResponse.substring( iChunkDataBlockBegin, iChunkDataBlockEnd);
-
- iIndex += iChunkSize;
-
- // Check that offset from current position + chunk_size is
- // another chunk_size.
- iEoL = sResponse.indexOf( sLF, iIndex) + 1;
-
- if( iEoL == 0)
- {
- // There are no more LF's in the file. This is
- // probably because there is no LF at the end of
- // the file. Assume so and make sLine = "0".
- System.out.println( "Warning - The response file chunk sizes appear to be wrong.");
-
- sLine = "";
- }
- else
- {
- // Check if the chunk data size is bigger than
- // expected. If it is, then count up the number
- // of CR LF in the data chunk and iff this number
- // matches the difference is actual and expected
- // chunk size, then remove all CR within the data
- // chunk.
- if( iEoL - iIndex > 2)
- {
- int iLFCount = 0;
- int iLF = 0;
-
- while( (iLF = sChunkDataBlock.indexOf( sLF, iLF) + 1) > 0)
- {
- iLFCount++;
- }
-
- if( iLFCount == (iEoL - iIndex - 2))
- {
- System.out.println( "Warning - chunk data size is larger than expected. Additional CR may have been added to LF within data chunk. Fixed.");
-
- sChunkDataBlock = sChunkDataBlock.replaceAll( sCRLF, sLF);
- }
- else
- {
- System.out.println( "Warning - chunk data size is larger than expected. Additional CR may have been added to LF within data chunk. Unable to fix.");
- }
- }
-
- sLine = getResponseLine( sResponse, sCRLF, iIndex, iEoL);
-
- sChunkDataBlock += sLine;
-
- // Get next line.
- iIndex = iEoL;
-
- iEoL = sResponse.indexOf( sLF, iIndex) + 1;
-
- if( iEoL == 0)
- {
- // There are no more LF's in the file. This is
- // probably because there is no LF at the end of
- // the file. Assume so and make sLine = "0".
- System.out.println( "Warning - The response file does not end with a LF.");
-
- sLine = "0" + sLF;
- }
- else
- {
- sLine = getResponseLine( sResponse, sCRLF, iIndex, iEoL);
- }
-
- if( !isStringAHexNumber( sLine.trim()))
- {
- // Next chunk_size not found at position. Count the
- // number of LF's in the block. Check if when this
- // number * 2 is added to the offset that the pointer
- // now points to the next chunk_size.
- System.out.println( "Error - The next chunk_size was not found in the correct position. Check that the contents of the chunked data between " + iChunkDataBlockBegin + " and " + iChunkDataBlockEnd + " is correct.");
- }
- }
-
- sModifiedResponse += sChunkDataBlock;
- sModifiedResponse += sLine;
-
- iIndex = iEoL;
-
- // Evaluate chunk_size value.
- if( sLine.trim().length() > 0 && isStringAHexNumber( sLine.trim()))
- {
- iChunkSize = Integer.parseInt( sLine.trim(), 16);
- }
- else
- {
- System.out.println( "Warning - The response file does not appear to end with a 0 and LF characters.");
-
- iChunkSize = 0;
- }
- } while( iChunkSize > 0);
-
- // Now put it back into the responses
- responses[i] = sModifiedResponse.toCharArray();
- }
- else
- {
- if (System.getProperty("os.name").toLowerCase( ).startsWith("windows"))
- {
- System.out
- .println("Windows operating system - not converting crlf's");
- }
- else
- {
- String request=new String((char[]) responses[i]);
-
- // check the last two digits for CRLF - if they
- // are LFLF
- // then this is wrong
- // e.g. 0a 0a converts to 0d0a 0d0a
- // I'm doing it using a matcher because this
- // could get
- // complicated !
- Pattern pattern=Pattern.compile("\n");
- Matcher matcher=pattern.matcher(request);
- StringBuffer stringBuffer=new StringBuffer( );
-
- while (matcher.find( ))
- {
- char[] tmpStr=matcher.group( ).toCharArray( );
- matcher.appendReplacement(stringBuffer, "\r\n");
- }
-
- matcher.appendTail(stringBuffer);
-
- // Now put it back into the responses
- responses[i]=stringBuffer.toString( ).toCharArray( );
- }
- }
- }
- }
-
- // Irrespective of platform ensure that all responses end with \r\n\r\n
- for(int i=0; i<responses.length; i++)
- {
- if (responses[i]!=null)
- {
- String request=new String((char[]) responses[i]);
- Pattern pattern=Pattern.compile("([^\r\n])(\r\n)*$");
- Matcher matcher=pattern.matcher(request);
- StringBuffer stringBuffer=new StringBuffer(request);
- while (matcher.find( ))
- {
- char[] tmpStr=matcher.group( ).toCharArray( );
- // and replace them with the proper sentence !
- matcher.appendReplacement(stringBuffer, "$1\r\n\r\n");
- }
- matcher.appendTail(stringBuffer);
- // Now put it back into the responses
- responses[i]=stringBuffer.toString( ).toCharArray( );
- }
- }
- }
+// /**
+// * Because the repositories we use accomodate the dos2unix conversion we
+// * have a problem. On unix the response files have the crlf converted to
+// * just cr. this method returns the crlf !
+// *
+// * The HTTP header and chunk sizes need to be delimited with CR LF's.
+// * The 'server response' expected files used to mimic the response of a
+// * server when performing unit tests also need to have the correct
+// * delimiting character combinations in the fake response messages
+// * (generated by the monitor). Problems arise because the expected
+// * response files have been captured on different operating systems (Unix
+// * and Windows) and then edited using a variety of editors that interpret
+// * the CR character differently. Thus the file may be stored with or
+// * without the CR characters. Also, the souce control application can be
+// * set to convert a single LF character into a CR LF combination. The
+// * outcome of all this character manipulation is that LF's may or may not
+// * have the necessary associated CR for it to be recognised by the HTTP
+// * transport. It is not just sufficient to look for every LF and to prefix
+// * it with a CR because the context of that LF must be taken into
+// * consideration. For example, if a LF is found in the HTTP header then it
+// * definitely needs a CR prefix. This also applies when the message is
+// * chunked and the chunk size must also be delimited by the CR LF sequence.
+// * But, when a LF appears inside a chunk of data it should remain unchanged
+// * unless the chunk size is different from the actual data size between
+// * chunks, in which case the CR has probably been stripped out and needs to
+// * be replaced. Below is a low level design of what should work in all
+// * instances...
+// *
+// * Is the message chunked?
+// * NO: Convert all single LF sequences to CR+LF.
+// * NB: Because the value associated with the 'Content-Length' label is
+// * not used correctly, if the size of the file grows larger than the
+// * Content-Length value, no action is taken.
+// * Exit.
+// * YES: Convert all single LF sequences to CR+LF in the HTTP header.
+// * Set Index = location of the first 'chunk' value.
+// * Read the chunk size.
+// * While the chunk size > 0
+// * Convert any single LF sequences to CR+LF that surround the chunk
+// * value.
+// * Is the character at offset Index + chunk size equal to CR or LF?
+// * NO: Count up the number of unaccompanied LF's in the chunk.
+// * Is the difference between the expected and actual chunk data
+// * length double the number of unaccompanied LF's?
+// * NO: Error - Irreconcilable differences between expected and
+// * actual chunk data sizes.
+// * Exit.
+// * YES: Convert all single LF sequences to CR+LF in the chunk
+// * data.
+// * Continue.
+// * Index = Index + chunk size.
+// * Read the new chunk size.
+// * End of while.
+// * Exit.
+// */
+// private static void setCRLF( )
+// {
+// String sLF = "\n";
+// String sCR = "\r";
+// String sCRLF = sCR + sLF;
+// String sContentLength = "Content-Length:";
+//
+// for( int i = 0; i < responses.length; i++)
+// {
+// if( responses[i] != null)
+// {
+// System.out.println( "WE HAVE "+responses[i].getMessage().length);
+//
+//
+// String sResponse = new String(responses[i].getMessage());
+// String sModifiedResponse = "";
+// boolean bChunked = sResponse.indexOf( sContentLength) == -1;
+//
+// if( bChunked)
+// {
+// System.out.println("Information - Response file is chunked.");
+//
+// // Process HTTP header block. At the end of each line in
+// // the header block, if there is only a LF character,
+// // prefix it with a CR. The end of the HTTP header block
+// // is denoted by an empty line (i.e. CR LF).
+// String sLine;
+// int iIndex = 0;
+// int iEoL = sResponse.indexOf( sLF, iIndex) + 1;
+//
+// do
+// {
+// sLine = getResponseLine( sResponse, sCRLF, iIndex, iEoL);
+//
+// sModifiedResponse += sLine;
+//
+// // Get next line.
+// iIndex = iEoL;
+//
+// iEoL = sResponse.indexOf( sLF, iIndex) + 1;
+// } while( iEoL > 0 && !sLine.equals( sCRLF));
+//
+// // Immediately after the HTTP header block should be the
+// // first chunk_size. All chunk_sizes are in hex. A chunk
+// // size gives the size in bytes of the data that follows
+// // the value (i.e. CR LF 2 0 0 0 CR LF <---Data---> CR LF)
+// // but any number of CR may be missing and need to be
+// // accounted for if the response file is to be processed
+// // correctly.
+// // Do some 'first time' processing to initialise the loop
+// // that will process the HTTP message until the chunk size
+// // is zero (signifying the end of the message).
+// sLine = getResponseLine(sResponse, sCRLF, iIndex, iEoL);
+//
+// sModifiedResponse += sLine;
+//
+// iIndex = iEoL;
+//
+// // Evaluate chunk_size value.
+// int iChunkSize = Integer.parseInt( sLine.trim(), 16);
+//
+// // On entry to the loop, iChunkSize is the size of the data
+// // chunk and iIndex is the current location that is being
+// // processed.
+// do
+// {
+// int iChunkDataBlockBegin = iIndex;
+// int iChunkDataBlockEnd = iIndex + iChunkSize;
+// int iResponseSize = sResponse.length();
+//
+// // If the chunk data block end is greater than the size
+// // of the file, then the size of the chunk is incorrect.
+// // If '###' was used, then the size of the chunk is
+// // incorrectly calculated to include the chunk size in
+// // the chunk length.
+// if( iChunkDataBlockEnd > iResponseSize)
+// {
+// if( iChunkDataBlockEnd - iResponseSize > 1)
+// {
+// System.out.println( "Warning - The chunk size is greater than the file size by " + (iChunkDataBlockEnd - iResponseSize) + " bytes.");
+// }
+//
+// iChunkDataBlockEnd = sResponse.lastIndexOf( "0") - 1;
+// iChunkSize = iChunkDataBlockEnd - iIndex;
+// }
+//
+// String sChunkDataBlock = sResponse.substring( iChunkDataBlockBegin, iChunkDataBlockEnd);
+//
+// iIndex += iChunkSize;
+//
+// // Check that offset from current position + chunk_size is
+// // another chunk_size.
+// iEoL = sResponse.indexOf( sLF, iIndex) + 1;
+//
+// if( iEoL == 0)
+// {
+// // There are no more LF's in the file. This is
+// // probably because there is no LF at the end of
+// // the file. Assume so and make sLine = "0".
+// System.out.println( "Warning - The response file chunk sizes appear to be wrong.");
+//
+// sLine = "";
+// }
+// else
+// {
+// // Check if the chunk data size is bigger than
+// // expected. If it is, then count up the number
+// // of CR LF in the data chunk and iff this number
+// // matches the difference is actual and expected
+// // chunk size, then remove all CR within the data
+// // chunk.
+// if( iEoL - iIndex > 2)
+// {
+// int iLFCount = 0;
+// int iLF = 0;
+//
+// while( (iLF = sChunkDataBlock.indexOf( sLF, iLF) + 1) > 0)
+// {
+// iLFCount++;
+// }
+//
+// if( iLFCount == (iEoL - iIndex - 2))
+// {
+// System.out.println( "Warning - chunk data size is larger than expected. Additional CR may have been added to LF within data chunk. Fixed.");
+//
+// sChunkDataBlock = sChunkDataBlock.replaceAll( sCRLF, sLF);
+// }
+// else
+// {
+// System.out.println( "Warning - chunk data size is larger than expected. Additional CR may have been added to LF within data chunk. Unable to fix.");
+// }
+// }
+//
+// sLine = getResponseLine( sResponse, sCRLF, iIndex, iEoL);
+//
+// sChunkDataBlock += sLine;
+//
+// // Get next line.
+// iIndex = iEoL;
+//
+// iEoL = sResponse.indexOf( sLF, iIndex) + 1;
+//
+// if( iEoL == 0)
+// {
+// // There are no more LF's in the file. This is
+// // probably because there is no LF at the end of
+// // the file. Assume so and make sLine = "0".
+// System.out.println( "Warning - The response file does not end with a LF.");
+//
+// sLine = "0" + sLF;
+// }
+// else
+// {
+// sLine = getResponseLine( sResponse, sCRLF, iIndex, iEoL);
+// }
+//
+// if( !isStringAHexNumber( sLine.trim()))
+// {
+// // Next chunk_size not found at position. Count the
+// // number of LF's in the block. Check if when this
+// // number * 2 is added to the offset that the pointer
+// // now points to the next chunk_size.
+// System.out.println( "Error - The next chunk_size was not found in the correct position. Check that the contents of the chunked data between " + iChunkDataBlockBegin + " and " + iChunkDataBlockEnd + " is correct.");
+// }
+// }
+//
+// sModifiedResponse += sChunkDataBlock;
+// sModifiedResponse += sLine;
+//
+// iIndex = iEoL;
+//
+// // Evaluate chunk_size value.
+// if( sLine.trim().length() > 0 && isStringAHexNumber( sLine.trim()))
+// {
+// iChunkSize = Integer.parseInt( sLine.trim(), 16);
+// }
+// else
+// {
+// System.out.println( "Warning - The response file does not appear to end with a 0 and LF characters.");
+//
+// iChunkSize = 0;
+// }
+// } while( iChunkSize > 0);
+//
+// // Now put it back into the responses
+// responses[i] = new Response(sModifiedResponse);
+//
+// }
+// else
+// {
+// if (System.getProperty("os.name").toLowerCase( ).startsWith("windows"))
+// {
+// System.out
+// .println("Windows operating system - not converting crlf's");
+// }
+// else
+// {
+// String request=new String(responses[i].getMessage());
+//
+// // check the last two digits for CRLF - if they
+// // are LFLF
+// // then this is wrong
+// // e.g. 0a 0a converts to 0d0a 0d0a
+// // I'm doing it using a matcher because this
+// // could get
+// // complicated !
+// Pattern pattern=Pattern.compile("\n");
+// Matcher matcher=pattern.matcher(request);
+// StringBuffer stringBuffer=new StringBuffer( );
+//
+// while (matcher.find( ))
+// {
+// char[] tmpStr=matcher.group( ).toCharArray( );
+// matcher.appendReplacement(stringBuffer, "\r\n");
+// }
+//
+// matcher.appendTail(stringBuffer);
+//
+// // Now put it back into the responses
+// responses[i]=new Response(stringBuffer.toString( ));
+// }
+// }
+// }
+// }
+//
+// // Irrespective of platform ensure that all responses end with \r\n\r\n
+// for(int i=0; i<responses.length; i++)
+// {
+// if (responses[i]!=null)
+// {
+// String request=new String(responses[i].getMessage());
+// // this pattern looks for any chars then any non whitespace followed directly by the EOF
+// Pattern pattern=Pattern.compile("(.*)(\\s)*$");
+// Matcher matcher=pattern.matcher(request);
+// StringBuffer stringBuffer=new StringBuffer("");
+// // We should only find one occurence (if any) of the sequence
+// if(matcher.find())
+// {
+// System.out.println( "MATCHED");
+// // and replace them with the proper sentence !
+// matcher.appendReplacement(stringBuffer, "$1\r\n\r\n");
+// }
+// else
+// {
+// System.out.println( "NOT MATCHED");
+// // We did not find the sequence so just tack on the grouping we need.
+// stringBuffer.append(request);
+// stringBuffer.append("\r\n\r\n");
+//
+// }
+// // Now put it back into the responses
+// responses[i]=new Response(stringBuffer.toString( ));
+// }
+// }
+//
+// // System.out.println( "*******************************************");
+// // System.out.println( responses[1]);
+// }
/**
* @param sResponse
@@ -618,36 +642,41 @@
* @param iIndex
* @param iEOL
*/
- private static String getResponseLine(String sResponse, String sCRLF, int iIndex, int iEOL)
- {
- String sLine = sResponse.substring( iIndex, iEOL);
-
- if( (!sLine.endsWith( sCRLF)) && (iEOL > iIndex))
- {
- sLine = sResponse.substring( iIndex, iEOL - 1) + sCRLF;
- }
-
- return sLine;
- }
+// private static String getResponseLine(String sResponse, String sCRLF, int iIndex, int iEOL)
+// {
+// String sLine = sResponse.substring( iIndex, iEOL);
+//
+// if( (!sLine.endsWith( sCRLF)) && (iEOL > iIndex))
+// {
+// sLine = sResponse.substring( iIndex, iEOL - 1) + sCRLF;
+// }
+//
+// return sLine;
+// }
+
+// private static boolean isStringAHexNumber( String sValue)
+// {
+// boolean bOutcome = true;
+// String sValidChars = "0123456789ABCDEFabcdef";
+// int iIndex = 0;
+//
+// while( bOutcome && iIndex < sValue.length())
+// {
+// if( sValidChars.indexOf( sValue.substring( iIndex, iIndex + 1)) == -1)
+// {
+// bOutcome = false;
+// }
+// else
+// {
+// iIndex++;
+// }
+// }
+//
+// return bOutcome;
+// }
- private static boolean isStringAHexNumber( String sValue)
+ public void setClosedConnection(boolean closedConnection)
{
- boolean bOutcome = true;
- String sValidChars = "0123456789ABCDEFabcdef";
- int iIndex = 0;
-
- while( bOutcome && iIndex < sValue.length())
- {
- if( sValidChars.indexOf( sValue.substring( iIndex, iIndex + 1)) == -1)
- {
- bOutcome = false;
- }
- else
- {
- iIndex++;
- }
- }
-
- return bOutcome;
+ this.closedConnection = closedConnection;
}
}
Added: webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/Response.java
URL: http://svn.apache.org/viewcvs/webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/Response.java?rev=343982&view=auto
==============================================================================
--- webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/Response.java (added)
+++ webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/Response.java Sun Nov 13 14:13:01 2005
@@ -0,0 +1,488 @@
+/*
+ * Created on 10-Nov-2005 TODO To change the template for this generated file go
+ * to Window - Preferences - Java - Code Style - Code Templates
+ */
+package org.apache.test;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+
+/**
+ * @author hawkeye TODO To change the template for this generated type comment
+ * go to Window - Preferences - Java - Code Style - Code Templates
+ */
+// We cache the entire output file in an array of char[]
+public class Response
+{
+ private static final String CR ="\r";
+ private static final String LF ="\n";
+ private static final String CRLF =CR+LF;
+ private static final String DOUBLE_CRLF =CRLF+CRLF;
+ private static final String CONTENT_LENGTH ="Content-Length:";
+
+ private char[] message;
+ private boolean chunked;
+
+ // whether the message has a "Connection: Close" http header in it.
+ private boolean hasCloseConnectionHeader;
+
+ public boolean hasCloseConnectionHeader( )
+ {
+ return hasCloseConnectionHeader;
+ }
+
+ /**
+ * Because the repositories we use accomodate the dos2unix conversion we
+ * have a problem. On unix the response files have the crlf converted to
+ * just cr. this method returns the crlf ! The HTTP header and chunk sizes
+ * need to be delimited with CR LF's. The 'server response' expected files
+ * used to mimic the response of a server when performing unit tests also
+ * need to have the correct delimiting character combinations in the fake
+ * response messages (generated by the monitor). Problems arise because the
+ * expected response files have been captured on different operating systems
+ * (Unix and Windows) and then edited using a variety of editors that
+ * interpret the CR character differently. Thus the file may be stored with
+ * or without the CR characters. Also, the souce control application can be
+ * set to convert a single LF character into a CR LF combination. The
+ * outcome of all this character manipulation is that LF's may or may not
+ * have the necessary associated CR for it to be recognised by the HTTP
+ * transport. It is not just sufficient to look for every LF and to prefix
+ * it with a CR because the context of that LF must be taken into
+ * consideration. For example, if a LF is found in the HTTP header then it
+ * definitely needs a CR prefix. This also applies when the message is
+ * chunked and the chunk size must also be delimited by the CR LF sequence.
+ * But, when a LF appears inside a chunk of data it should remain unchanged
+ * unless the chunk size is different from the actual data size between
+ * chunks, in which case the CR has probably been stripped out and needs to
+ * be replaced. Below is a low level design of what should work in all
+ * instances... Is the message chunked? NO: Convert all single LF sequences
+ * to CR+LF. NB: Because the value associated with the 'Content-Length'
+ * label is not used correctly, if the size of the file grows larger than
+ * the Content-Length value, no action is taken. Exit. YES: Convert all
+ * single LF sequences to CR+LF in the HTTP header. Set Index = location of
+ * the first 'chunk' value. Read the chunk size. While the chunk size > 0
+ * Convert any single LF sequences to CR+LF that surround the chunk value.
+ * Is the character at offset Index + chunk size equal to CR or LF? NO:
+ * Count up the number of unaccompanied LF's in the chunk. Is the difference
+ * between the expected and actual chunk data length double the number of
+ * unaccompanied LF's? NO: Error - Irreconcilable differences between
+ * expected and actual chunk data sizes. Exit. YES: Convert all single LF
+ * sequences to CR+LF in the chunk data. Continue. Index = Index + chunk
+ * size. Read the new chunk size. End of while. Exit.
+ */
+ public Response(String message)
+ {
+ this.message=message.toCharArray( );
+ // parse the message to see if it has a Connection: Close in it
+ if (message.toLowerCase( ).indexOf("connection: close")>-1)
+ {
+ hasCloseConnectionHeader=true;
+ }
+
+
+ // Find out if the message is chunked
+ deriveIsChunked( );
+
+ // emulate None OS machines when you want to test out the CRLF method
+ emulateNoneWinmachines();
+
+ // check and correct CRLF's
+ CheckAndCorrectCRLF( );
+ }
+
+ /**
+ * This method is used when we are testing out this class.
+ * It converts ALL CRLF's into LF (as it might be on a none win machine)
+ */
+ private void emulateNoneWinmachines( )
+ {
+ String msgString = new String(getMessage());
+ Pattern pattern=Pattern.compile(CRLF);
+ Matcher matcher=pattern.matcher(msgString);
+
+ if(matcher.find())
+ {
+ msgString = matcher.replaceAll(LF);
+ }
+ message = msgString.toCharArray();
+
+ }
+
+ private void deriveIsChunked( )
+ {
+ // simply look for the content length string
+ chunked=new String(message).indexOf(CONTENT_LENGTH)==-1;
+ }
+
+ public char[] getMessage( )
+ {
+ return message;
+ }
+
+ public String toString( )
+ {
+ return new String(message);
+ }
+
+ /**
+ * On platforms other than windows the CRLF's can get "helpfully" converted
+ * So, check the last two digits for CRLF - if they are LFLF then this is
+ * wrong and we will convert it to be correct. e.g. 0a 0a converts to 0d0a
+ * 0d0a
+ */
+ private void CheckAndCorrectCRLF( )
+ {
+
+ String modifiedResponse="";
+ if (chunked)
+ {
+ System.out.println("Information - Response file is chunked.");
+
+ String messageString= new String(getMessage());
+ modifiedResponse = correctHTTPHeaderSection(messageString);
+ modifiedResponse +=(correctChunkedData(getPostHTTPHeaderData(messageString)));
+ message = modifiedResponse.toCharArray();
+ }
+ else
+ {
+ if (System.getProperty("os.name").toLowerCase( ).startsWith(
+ "windows"))
+ {
+ System.out
+ .println("Windows operating system - not converting crlf's");
+ }
+ else
+ {
+ String request=new String(getMessage( ));
+
+ // check the last two digits for CRLF - if they
+ // are LFLF
+ // then this is wrong
+ // e.g. 0a 0a converts to 0d0a 0d0a
+ // I'm doing it using a matcher because this
+ // could get
+ // complicated !
+ Pattern pattern=Pattern.compile(LF);
+ Matcher matcher=pattern.matcher(request);
+ StringBuffer stringBuffer=new StringBuffer( );
+
+ while (matcher.find( ))
+ {
+ char[] tmpStr=matcher.group( ).toCharArray( );
+ matcher.appendReplacement(stringBuffer, CRLF);
+ }
+
+ matcher.appendTail(stringBuffer);
+
+ // Now put it back into the responses
+ message=stringBuffer.toString( ).toCharArray( );
+ }
+ }
+//
+// // Irrespective of platform ensure that all responses end with \r\n\r\n
+// String request=new String(getMessage( ));
+// // this pattern looks for any chars then any non whitespace followed
+// // directly by the EOF
+// Pattern pattern=Pattern.compile("(.*)(\\s)*$");
+// Matcher matcher=pattern.matcher(request);
+// StringBuffer stringBuffer=new StringBuffer("");
+// // We should only find one occurence (if any) of the sequence
+// if (matcher.find( ))
+// {
+//// System.out.println("MATCHED");
+// // and replace them with the proper sentence !
+// matcher.appendReplacement(stringBuffer, "$1\r\n\r\n");
+// }
+// else
+// {
+//// System.out.println("NOT MATCHED");
+// // We did not find the sequence so just tack on the grouping we
+// // need.
+// stringBuffer.append(request);
+// stringBuffer.append("\r\n\r\n");
+//
+// }
+// // Now put it back into the message
+// message=stringBuffer.toString( ).toCharArray( );
+ }
+
+ /**
+ * @param message2
+ * @return
+ */
+ private String getPostHTTPHeaderData(String response)
+ {
+ Pattern pattern=Pattern.compile( "(^HTTP.*["+CRLF+"]*)(.*: .*["+CRLF+"]*)*(.*)");
+ Matcher matcher = pattern.matcher(response);
+
+ if(!matcher.find())
+ {
+ System.err.println( "ERROR: Response message does not contain a correctly formatted HTTP header:" +response);
+ }
+
+ return matcher.replaceAll("$3");
+ }
+
+/**
+ * @param string the response message - HTTPheaders
+ * @return correctly formatted (as best we can) http headers.
+ */
+private String correctChunkedData(String request)
+{
+ // A chunk Is defined by
+ // <hexnumber><potentially CR><LF><any data><potentially CR><LF><hexnumber>
+ StringBuffer theCorrectedResponse = new StringBuffer();
+ String thePattern = "(\\p{XDigit}+)("+CR+"?"+LF+")";
+ String theNextChunkSizeREGEX ="("+CR+"?"+LF+")"+thePattern;
+ Pattern pattern=Pattern.compile(thePattern);
+ Pattern theNextChunkSizePattern = Pattern.compile(theNextChunkSizeREGEX);
+
+ Matcher matcher = pattern.matcher(request);
+ Matcher theNextChunkSizeMatcher = theNextChunkSizePattern.matcher(request);
+
+ int chunkStart = 0;
+ int chunkEnd=0;
+ int chunkSize = 0;
+ int nextChunkSize = -1;
+ int nextChunkStart= -1;
+ int nextChunkEnd= -1;
+
+ String nextChunkSizeString="";
+ while(matcher.find() && nextChunkSize!=0)
+ {
+ String chunkSizeString="";
+ if(nextChunkSize==-1)
+ {
+ // means this is the first time round the loop so work it out
+ chunkSizeString = request.substring(matcher.start(), matcher.end());
+ chunkSize = Integer.parseInt(chunkSizeString.trim(), 16);
+ chunkStart = matcher.end();
+ // ensure the string has the correct crlf on it
+ chunkSizeString = chunkSizeString.trim()+CRLF;
+ }
+ else
+ {
+ // we've already been round the loop and got the chunkSize
+ chunkSizeString = nextChunkSizeString;
+ chunkSize = nextChunkSize;
+ chunkStart = nextChunkStart;
+ // ensure the string has the correct crlf on it
+ // this one came with a different parsing algorithm so add on crlf to *both* ends !
+ chunkSizeString = CRLF+chunkSizeString.trim()+CRLF;
+ }
+// System.out.println( "chunkString = "+chunkSizeString.trim());
+// System.out.println( "Chunk size = "+chunkSize);
+// System.out.println( "Chunked Start="+chunkStart);
+// System.out.println( "chunkend = "+chunkEnd);
+
+
+
+ String chunkFromSize=null;
+ if(chunkStart+chunkSize>request.length())
+ {
+ System.err.println( "ChunksSize String is wrong");
+ System.err.println( "chunksStart = "+chunkStart);
+ System.err.println( "ChunkSize = "+chunkSize);
+ System.err.println( "request.length = "+request.length());
+ // We can work this out though it's probably the last or only chunk so just guess !
+ // do this later on so we don't duplicate work>
+ // chunkFromSize is null so we can see later on that we need to guess
+ }
+ else
+ {
+ chunkFromSize = request.substring(chunkStart, chunkStart+chunkSize);
+ }
+
+ // Now find the end of the chunk (and while we do that we actually find the next chunk size too !
+ theNextChunkSizeMatcher.find();
+ chunkEnd = theNextChunkSizeMatcher.start();
+ // get the nextchunkSize while we're here!
+ nextChunkSizeString = request.substring(theNextChunkSizeMatcher.start(), theNextChunkSizeMatcher.end());
+ nextChunkStart = theNextChunkSizeMatcher.end();
+ int endOfThisChunk = theNextChunkSizeMatcher.start();
+ nextChunkSize = Integer.parseInt(nextChunkSizeString.trim(), 16);
+
+
+ String chunk = request.substring(chunkStart, endOfThisChunk);
+ if(chunkFromSize==null)
+ {
+ // we need to set this value now we have probably worked out what it is
+ // this stops us from stopping but hopefully we won't fail too !
+ chunkFromSize = chunk;
+ chunkSize=chunk.length();
+ System.err.println( "Guessing the size is "+chunkFromSize.length());
+ // we now also have to take into account the chunkSize and it's \r\n
+ // test it again to see whether we made it right or not
+ // make sure we set the chunksize string
+ if(!chunkSizeString.startsWith(CR))
+ {
+ // Then it's the beginning of the message
+ chunkSizeString = ""+Integer.toHexString(chunk.length())+CRLF;
+ }
+ else
+ {
+ chunkSizeString = CRLF+Integer.toHexString(chunk.length())+CRLF;
+ }
+ }
+
+ // Check that the chunk size really is the same size as it should be.
+ if(chunk.length() !=chunkSize)
+ {
+ System.out.println( "Warning: Chunksize is not correct");
+ System.out.println( "chunk.length = "+chunk.length());
+ System.out.println( "ChunkSize = "+chunkSize);
+ System.out.println( "chunkString "+chunkSizeString);
+ // then we might be on a unix system and lost the CR of a CRLF combo
+ if (System.getProperty("os.name").toLowerCase( ).startsWith(
+ "windows"))
+ {
+ System.out.println( "Warning: Chunksize is not correct. On windows so not attempting to fix");
+ }
+ else
+ {
+ System.out.println( "Warning: Chunksize is not correct. Attempting to correct with additional \\r\\n");
+ String newChunk = chunk.replaceAll(LF, CRLF);
+ if(newChunk.length()+chunkSizeString.trim().length()+2 !=chunkSize)
+ {
+ System.err.println( "Attempt to correct the chunksize failed");
+ }
+ }
+ }
+ theCorrectedResponse.append(chunkSizeString);
+ // append the chunk to the rest of the correct messages
+ theCorrectedResponse.append(chunk);
+
+ }
+ // append the last chunk on
+ theCorrectedResponse.append(CRLF+"0"+DOUBLE_CRLF);
+ return theCorrectedResponse.toString();
+}
+
+// /**
+// * This method looks through a chunked data section and ensures that the
+// * chunksizes are correct. *
+// *
+// * @param message
+// * @return the message - corrected if necessary
+// */
+// private boolean checkBlocks(String message)
+// {
+// boolean sizesCorrect=true;
+// boolean reachedEndOfAllChunks=false;
+// int indexOfEndOfChunkSize=0;
+// while (!reachedEndOfAllChunks&&sizesCorrect)
+// {
+// // Find this chunk_size value.
+// indexOfEndOfChunkSize=message.indexOf(CRLF);
+// System.out.println("indexOfChunkSize = "+indexOfEndOfChunkSize);
+// // System.out.println( "Message ="+message);
+// System.out.println("Message.length() = "+message.length( ));
+//
+// String chunkSizeString=message.substring(0, indexOfEndOfChunkSize)
+// .trim( );
+//
+// int chunkSize=Integer.parseInt(chunkSizeString, 16);
+// System.out.println("chunkSize="+chunkSize);
+// if (chunkSize!=8192)
+// {
+// System.out.println("DEBUGGIN");
+// ;
+// }
+// if (chunkSize==0)
+// {
+// reachedEndOfAllChunks=true;
+// }
+// else
+// {
+// // move the message past the size of Chunk
+// message=message.substring(chunkSizeString.length( )
+// +CRLF.length( ));
+//
+// // check that the last two chars are CRLF
+// String lastTwoChars=message.substring(chunkSize, chunkSize+2);
+// if (!lastTwoChars.equals(CRLF))
+// {
+// System.err
+// .println("WARNING: Actual chunksize != declared chunksize: "
+// +chunkSize);
+// sizesCorrect=false;
+// }
+// else
+// {
+// // move the message on to the end of this chunk
+// message=message.substring(chunkSize+CRLF.length( ));
+// }
+// }
+//
+// }
+// return sizesCorrect;
+//
+// }
+
+ /**
+ * @param sResponse
+ * @param iIndex
+ * @param iEOL
+ */
+ private static String getResponseLine(String sResponse,
+ int iIndex, int iEOL)
+ {
+ String sLine=sResponse.substring(iIndex, iEOL);
+
+ if ((!sLine.endsWith(CRLF))&&(iEOL>iIndex))
+ {
+ sLine=sResponse.substring(iIndex, iEOL-1)+CRLF;
+ }
+
+ return sLine;
+ }
+
+ private String correctHTTPHeaderSection(String response)
+ {
+ String returnedResponse ="";
+ // Process HTTP header block. At the end of each line in
+ // the header block, if there is only a LF character,
+ // prefix it with a CR. The end of the HTTP header block
+ // is denoted by an empty line (i.e. CR LF).
+ String sLine;
+ int iIndex=0;
+ int iEoL=response.indexOf(LF, iIndex)+1;
+
+ do
+ {
+ sLine=getResponseLine(response, iIndex, iEoL);
+
+ returnedResponse+=sLine;
+
+ // Get next line.
+ iIndex=iEoL;
+
+ iEoL=response.indexOf(LF, iIndex)+1;
+ }
+ while (iEoL>0&&!sLine.equals(CRLF));
+
+ return returnedResponse;
+ }
+
+// private static boolean isStringAHexNumber(String sValue)
+// {
+// boolean bOutcome=true;
+// String sValidChars="0123456789ABCDEFabcdef";
+// int iIndex=0;
+//
+// while (bOutcome&&iIndex<sValue.length( ))
+// {
+// if (sValidChars.indexOf(sValue.substring(iIndex, iIndex+1))==-1)
+// {
+// bOutcome=false;
+// }
+// else
+// {
+// iIndex++;
+// }
+// }
+//
+// return bOutcome;
+// }
+}
Modified: webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/ResponseSender.java
URL: http://svn.apache.org/viewcvs/webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/ResponseSender.java?rev=343982&r1=343981&r2=343982&view=diff
==============================================================================
--- webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/ResponseSender.java (original)
+++ webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/ResponseSender.java Sun Nov 13 14:13:01 2005
@@ -25,14 +25,18 @@
*/
public class ResponseSender implements Runnable
{
- private char[] response;
+ private Response response;
private BufferedWriter writer;
+ // we need to keep a hold of the parent that created us so we can tell them if we closed the connection
+ private MockServerThread parent;
- ResponseSender (char[] responseToSend, BufferedWriter writerToClient)
+ ResponseSender (Response responseToSend, BufferedWriter writerToClient, MockServerThread mockServerThread)
{
+// System.out.println( "NEW RESPONDER");
response = responseToSend;
writer = writerToClient;
+ parent = mockServerThread;
}
@@ -44,8 +48,7 @@
// send the response message back to the client !
try
{
- System.out.println( "response = "+response);
- System.out.println( "nulls? "+response+", "+writer+", "+response.length);
+// System.out.println( "nulls? "+response+", "+writer+", "+response.length);
// send it in chunks
// int chunkSize=300;
// int lastPosition=0;
@@ -53,10 +56,9 @@
// {
// System.out.println( "HERE ");
// writer.write(response, lastPosition, chunkSize);
- //System.out.println( "Response = "+new String(response));
- writer.write(response);
- writer.flush();
+ writer.write(response.getMessage());
+ writer.flush();
// lastPosition+=chunkSize;
// System.out.println( "HERE "+lastPosition);
// }
@@ -66,6 +68,21 @@
exception.printStackTrace(System.err);
}
System.out.println( "ResponseSender: Sent response To Client");
+
+ if(response.hasCloseConnectionHeader())
+ {
+ // Then we need to close the connection
+ System.out.println( "ResponseSender: Closing connection now");
+ parent.setClosedConnection(true);
+ try
+ {
+ writer.close();
+ }
+ catch(IOException exception)
+ {
+ exception.printStackTrace(System.err);
+ }
+ }
}
}
Modified: webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/TestClientListener.java
URL: http://svn.apache.org/viewcvs/webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/TestClientListener.java?rev=343982&r1=343981&r2=343982&view=diff
==============================================================================
--- webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/TestClientListener.java (original)
+++ webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/TestClientListener.java Sun Nov 13 14:13:01 2005
@@ -77,11 +77,11 @@
{
try
{
-// System.out
-// .println("TestClientListener#run(): Waiting for a new client request");
+ System.out
+ .println("TestClientListener#run(): Waiting for a new client request");
clientSocket=serverSocket.accept( );
-// System.out
-// .println("TestClientListener#run():Got a client new client request");
+ System.out
+ .println("TestClientListener#run():Got a client new client request");
}
catch (SocketTimeoutException socketTimeoutException)
{