Author: alf
Date: Sun Oct 14 01:22:03 2007
New Revision: 584508
URL: http://svn.apache.org/viewvc?rev=584508&view=rev
Log:
Do not use Reader and Writer classes for writing response, because it will use
the default content encoding of the JRE, causing the reply from the mirror to
not be an exact copy of the incoming request. Therefore, rather use InputStream
and OutputStream.
If the mirror gets a header specifying the content length, we know how much
data to read, and therefore we can allow the reading to block waiting for more
data to appear.
For chunked transfer, we still have to only read until there is no more data,
and not block to wait for more.
Add unit test for the mirror thread. This will expose the problems of the
previous version of the HttpMirrorThread, and show that the version of
HttpMirrorThread in this changelist works.
Added:
jakarta/jmeter/trunk/test/src/org/apache/jmeter/protocol/http/control/TestHTTPMirrorThread.java
Modified:
jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/HttpMirrorThread.java
Modified:
jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/HttpMirrorThread.java
URL:
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/HttpMirrorThread.java?rev=584508&r1=584507&r2=584508&view=diff
==============================================================================
---
jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/HttpMirrorThread.java
(original)
+++
jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/HttpMirrorThread.java
Sun Oct 14 01:22:03 2007
@@ -18,15 +18,19 @@
package org.apache.jmeter.protocol.http.control;
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
import java.net.Socket;
+import org.apache.jmeter.util.JMeterUtils;
import org.apache.jorphan.logging.LoggingManager;
import org.apache.jorphan.util.JOrphanUtils;
import org.apache.log.Logger;
+import org.apache.oro.text.regex.MatchResult;
+import org.apache.oro.text.regex.Pattern;
+import org.apache.oro.text.regex.PatternMatcherInput;
+import org.apache.oro.text.regex.Perl5Compiler;
+import org.apache.oro.text.regex.Perl5Matcher;
/**
* Thread to handle one client request. Gets the request from the client and
@@ -35,55 +39,140 @@
public class HttpMirrorThread extends Thread {
private static final Logger log = LoggingManager.getLoggerForClass();
- private static final char[] CRLF = new char[] {(byte) 13, (byte) 10};
+ private static final String ISO_8859_1 = "ISO-8859-1"; //$NON-NLS-1$
+ private static final byte[] CRLF = { 0x0d, 0x0a };
/** Socket to client. */
- private final Socket clientSocket;
+ private final Socket clientSocket;
- public HttpMirrorThread(Socket _clientSocket) {
- this.clientSocket=_clientSocket;
- }
-
- /**
- * Main processing method for the HttpMirror object
- */
- public void run() {
- log.info("Starting thread");
- BufferedReader in = null;
- PrintWriter out = null;
- // Seems to fail unless we wait a short while before opening
the streams
- try {
- Thread.sleep(200);
- } catch (InterruptedException e) {
- }
- try {
- in = new BufferedReader(new
InputStreamReader(clientSocket.getInputStream()));
- out = new PrintWriter(new
OutputStreamWriter(clientSocket.getOutputStream()));
- out.print("HTTP/1.0 200 OK"); //$NON-NLS-1$
- out.write(CRLF);
- out.print("Content-Type: text/plain"); //$NON-NLS-1$
- out.write(CRLF);
- out.write(CRLF);
- out.flush();
- String line;
- while((line = in.readLine()) != null){
- out.print(line);
- out.write(CRLF);
- if (line.length()==0) break;
- }
- int c;
- while(in.ready() && (c = in.read()) != -1) {
- out.write(c);
- }
- out.flush();
- } catch (Exception e) {
- log.error("", e);
- } finally {
- JOrphanUtils.closeQuietly(out);
- JOrphanUtils.closeQuietly(in);
- JOrphanUtils.closeQuietly(clientSocket);
- }
- log.info("End of Thread");
- }
-
-}
\ No newline at end of file
+ public HttpMirrorThread(Socket _clientSocket) {
+ this.clientSocket=_clientSocket;
+ }
+
+ /**
+ * Main processing method for the HttpMirror object
+ */
+ public void run() {
+ log.info("Starting thread");
+ BufferedInputStream in = null;
+ BufferedOutputStream out = null;
+
+ try {
+ in = new BufferedInputStream(clientSocket.getInputStream());
+ out = new BufferedOutputStream(clientSocket.getOutputStream());
+ // The headers are written using ISO_8859_1 encoding
+ out.write("HTTP/1.0 200 OK".getBytes(ISO_8859_1));
+ out.write(CRLF);
+ out.write("Content-Type: text/plain".getBytes(ISO_8859_1));
+ out.write(CRLF);
+ out.write(CRLF);
+ out.flush();
+
+ // Read the header part, we will be looking for a content-length
+ // header, so we know how much we should read.
+ // We assume headers are in ISO_8859_1
+ // If we do not find such a header, we will just have to read until
+ // we have to block to read more, until we support chunked transfer
+ int contentLength = -1;
+ boolean isChunked = false;
+ byte[] buffer = new byte[1024];
+ StringBuffer headers = new StringBuffer();
+ int length = 0;
+ boolean haveAllHeaders = false;
+ int positionOfBody = 0;
+ while(!haveAllHeaders && ((length = in.read(buffer)) != -1)) {
+ headers.append(new String(buffer, 0, length, ISO_8859_1));
+ // Check if we have read all the headers
+ positionOfBody = getPositionOfBody(headers.toString());
+ haveAllHeaders = positionOfBody > 0;
+ }
+
+ // Write the headers
+ out.write(headers.toString().getBytes(ISO_8859_1));
+
+ // Check if we have found a content-length header
+ String contentLengthHeaderValue =
getRequestHeaderValue(headers.toString(), "Content-Length"); //$NON-NLS-1$
+ if(contentLengthHeaderValue != null) {
+ contentLength = new
Integer(contentLengthHeaderValue).intValue();
+ }
+ String transferEncodingHeaderValue =
getRequestHeaderValue(headers.toString(), "Transfer-Encoding"); //$NON-NLS-1$
+ if(transferEncodingHeaderValue != null) {
+ isChunked =
transferEncodingHeaderValue.equalsIgnoreCase("chunked"); //$NON-NLS-1$
+ // We only support chunked transfer encoding
+ if(!isChunked) {
+ log.error("Transfer-Encoding header set, the value is not
supported : " + transferEncodingHeaderValue);
+ }
+ }
+
+ // If we know the content lenght, we can allow the reading of
+ // the request to block until more data arrives.
+ // If it is chunked transfer, we cannot allow the reading to
+ // block, because we do not know when to stop reading, because
+ // the chunked transfer is not properly supported yet
+ length = 0;
+ if(contentLength > 0) {
+ // Check how much of the body we have already read as part of
reading
+ // the headers
+ // We subtract two bytes for the crlf divider between header
and body
+ int totalReadBytes = headers.toString().length() -
positionOfBody - 2;
+
+ // We know when to stop reading, so we can allow the read
method to block
+ while((totalReadBytes < contentLength) && ((length =
in.read(buffer)) != -1)) {
+ out.write(buffer, 0, length);
+
+ totalReadBytes += length;
+ }
+ }
+ else if (isChunked) {
+ // It is chunked transfer encoding, which we do not really
support yet.
+ // So we just read without blocking, because we do not know
when to
+ // stop reading, so we cannot block
+ // TODO propery implement support for chunked transfer, i.e. to
+ // know when we have read the whole request, and therefore
allow
+ // the reading to block
+ while(in.available() > 0 && ((length = in.read(buffer)) !=
-1)) {
+ out.write(buffer, 0, length);
+ }
+ }
+ else {
+ log.error("No content-length header found, and it is not
chunked transfer, we cannot read the request");
+ }
+ out.flush();
+ } catch (Exception e) {
+ log.error("", e);
+ } finally {
+ JOrphanUtils.closeQuietly(out);
+ JOrphanUtils.closeQuietly(in);
+ JOrphanUtils.closeQuietly(clientSocket);
+ }
+ log.info("End of Thread");
+ }
+
+ private String getRequestHeaderValue(String requestHeaders, String
headerName) {
+ Perl5Matcher localMatcher = JMeterUtils.getMatcher();
+ String expression = ".*" + headerName + ": (\\d*).*"; // $NON-NLS-1$
$NON-NLS-2$
+ Pattern pattern = JMeterUtils.getPattern(expression,
Perl5Compiler.READ_ONLY_MASK | Perl5Compiler.CASE_INSENSITIVE_MASK |
Perl5Compiler.SINGLELINE_MASK);
+ if(localMatcher.matches(requestHeaders, pattern)) {
+ // The value is in the first group, group 0 is the whole match
+ return localMatcher.getMatch().group(1);
+ }
+ else {
+ return null;
+ }
+ }
+
+ private int getPositionOfBody(String stringToCheck) {
+ Perl5Matcher localMatcher = JMeterUtils.getMatcher();
+ // The headers and body are divided by a blank line
+ String regularExpression = "^.$"; // $NON-NLS-1$
+ Pattern pattern = JMeterUtils.getPattern(regularExpression,
Perl5Compiler.READ_ONLY_MASK | Perl5Compiler.CASE_INSENSITIVE_MASK |
Perl5Compiler.MULTILINE_MASK);
+
+ PatternMatcherInput input = new PatternMatcherInput(stringToCheck);
+ while(localMatcher.contains(input, pattern)) {
+ MatchResult match = localMatcher.getMatch();
+ return match.beginOffset(0);
+ }
+ // No divider was found
+ return -1;
+ }
+}
Added:
jakarta/jmeter/trunk/test/src/org/apache/jmeter/protocol/http/control/TestHTTPMirrorThread.java
URL:
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/test/src/org/apache/jmeter/protocol/http/control/TestHTTPMirrorThread.java?rev=584508&view=auto
==============================================================================
---
jakarta/jmeter/trunk/test/src/org/apache/jmeter/protocol/http/control/TestHTTPMirrorThread.java
(added)
+++
jakarta/jmeter/trunk/test/src/org/apache/jmeter/protocol/http/control/TestHTTPMirrorThread.java
Sun Oct 14 01:22:03 2007
@@ -0,0 +1,372 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.jmeter.protocol.http.control;
+
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.Socket;
+/*
+import org.apache.jmeter.engine.util.ValueReplacer;
+import org.apache.jmeter.protocol.http.control.HttpMirrorControl;
+import org.apache.jmeter.protocol.http.sampler.HTTPSampler2;
+import org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase;
+import org.apache.jmeter.protocol.http.util.EncoderCache;
+import org.apache.jmeter.protocol.http.util.HTTPArgument;
+import org.apache.jmeter.testelement.TestPlan;
+import org.apache.jmeter.threads.JMeterContextService;
+import org.apache.jmeter.threads.JMeterVariables;
+import org.apache.jmeter.util.JMeterUtils;
+import org.apache.oro.text.regex.MatchResult;
+import org.apache.oro.text.regex.Pattern;
+import org.apache.oro.text.regex.PatternMatcherInput;
+import org.apache.oro.text.regex.Perl5Compiler;
+import org.apache.oro.text.regex.Perl5Matcher;
+*/
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import junit.extensions.TestSetup;
+
+/**
+ * Class for testing the HTTPMirrorThread, which is handling the
+ * incoming requests for the HTTPMirrorServer
+ */
+public class TestHTTPMirrorThread extends TestCase {
+ /** The encodings used for http headers and control information */
+ private final static String ISO_8859_1 = "ISO-8859-1"; // $NON-NLS-1$
+ private final static String UTF_8 = "UTF-8"; // $NON-NLS-1$
+
+ private static final byte[] CRLF = { 0x0d, 0x0a };
+ private final static int HTTP_SERVER_PORT = 8080;
+
+ public TestHTTPMirrorThread(String arg0) {
+ super(arg0);
+ }
+
+ public static Test suite(){
+ TestSetup setup = new TestSetup(new
TestSuite(TestHTTPMirrorThread.class)){
+ private HttpMirrorServer httpServer;
+
+ protected void setUp() throws Exception {
+ // Start the http server
+ httpServer = new HttpMirrorServer(HTTP_SERVER_PORT);
+ httpServer.start();
+ // Allow some time for the server to start
+ Thread.sleep(500);
+ }
+
+ protected void tearDown() throws Exception {
+ // Shutdown the http server
+ httpServer.stopServer();
+ httpServer = null;
+ }
+ };
+ return setup;
+ };
+
+ public void testGetRequest() throws Exception {
+ // Connect to the http server, and do a simple http get
+ Socket clientSocket = new Socket("localhost", HTTP_SERVER_PORT);
+ OutputStream outputStream = clientSocket.getOutputStream();
+ InputStream inputStream = clientSocket.getInputStream();
+
+ // Write to the socket
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ // Headers
+ bos.write("GET / HTTP 1.1".getBytes(ISO_8859_1));
+ bos.write(CRLF);
+ bos.write("Host: localhost".getBytes(ISO_8859_1));
+ bos.write(CRLF);
+ bos.write(CRLF);
+ bos.close();
+ outputStream.write(bos.toByteArray());
+
+ // Read the response
+ ByteArrayOutputStream response = new ByteArrayOutputStream();
+ byte[] buffer = new byte[1024];
+ int length = 0;
+ while(( length = inputStream.read(buffer)) != -1) {
+ response.write(buffer, 0, length);
+ }
+ response.close();
+ byte[] mirroredResponse = getMirroredResponse(response.toByteArray());
+ // Check that the request and response matches
+ checkArraysHaveSameContent(bos.toByteArray(), mirroredResponse);
+ // Close the connection
+ clientSocket.close();
+
+ // Connect to the http server, and do a simple http get, with
+ // a pause in the middle of transmitting the header
+ clientSocket = new Socket("localhost", HTTP_SERVER_PORT);
+ outputStream = clientSocket.getOutputStream();
+ inputStream = clientSocket.getInputStream();
+
+ // Write to the socket
+ bos = new ByteArrayOutputStream();
+ // Headers
+ bos.write("GET / HTTP 1.1".getBytes(ISO_8859_1));
+ bos.write(CRLF);
+ // Write the start of the headers, and then sleep, so that the mirror
+ // thread will have to block to wait for more data to appear
+ bos.close();
+ byte[] firstChunk = bos.toByteArray();
+ outputStream.write(firstChunk);
+ Thread.sleep(300);
+ // Write the rest of the headers
+ bos = new ByteArrayOutputStream();
+ bos.write("Host: localhost".getBytes(ISO_8859_1));
+ bos.write(CRLF);
+ bos.write(CRLF);
+ bos.close();
+ byte[] secondChunk = bos.toByteArray();
+ outputStream.write(secondChunk);
+ // Read the response
+ response = new ByteArrayOutputStream();
+ buffer = new byte[1024];
+ length = 0;
+ while((length = inputStream.read(buffer)) != -1) {
+ response.write(buffer, 0, length);
+ }
+ response.close();
+ mirroredResponse = getMirroredResponse(response.toByteArray());
+ // The content sent
+ bos = new ByteArrayOutputStream();
+ bos.write(firstChunk);
+ bos.write(secondChunk);
+ bos.close();
+ // Check that the request and response matches
+ checkArraysHaveSameContent(bos.toByteArray(), mirroredResponse);
+ // Close the connection
+ clientSocket.close();
+ }
+
+ public void testPostRequest() throws Exception {
+ // Connect to the http server, and do a simple http post
+ Socket clientSocket = new Socket("localhost", HTTP_SERVER_PORT);
+ OutputStream outputStream = clientSocket.getOutputStream();
+ InputStream inputStream = clientSocket.getInputStream();
+ // Construct body
+ StringBuffer postBodyBuffer = new StringBuffer();
+ for(int i = 0; i < 1000; i++) {
+ postBodyBuffer.append("abc");
+ }
+ byte[] postBody = postBodyBuffer.toString().getBytes(ISO_8859_1);
+
+ // Write to the socket
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ // Headers
+ bos.write("GET / HTTP 1.1".getBytes(ISO_8859_1));
+ bos.write(CRLF);
+ bos.write("Host: localhost".getBytes(ISO_8859_1));
+ bos.write(CRLF);
+ bos.write(("Content-type: text/plain; charset=" +
ISO_8859_1).getBytes(ISO_8859_1));
+ bos.write(CRLF);
+ bos.write(("Content-length: " + postBody.length).getBytes(ISO_8859_1));
+ bos.write(CRLF);
+ bos.write(CRLF);
+ bos.write(postBody);
+ bos.close();
+ // Write the headers and body
+ outputStream.write(bos.toByteArray());
+ // Read the response
+ ByteArrayOutputStream response = new ByteArrayOutputStream();
+ byte[] buffer = new byte[1024];
+ int length = 0;
+ while((length = inputStream.read(buffer)) != -1) {
+ response.write(buffer, 0, length);
+ }
+ response.close();
+ byte[] mirroredResponse = getMirroredResponse(response.toByteArray());
+ // Check that the request and response matches
+ checkArraysHaveSameContent(bos.toByteArray(), mirroredResponse);
+ // Close the connection
+ clientSocket.close();
+
+ // Connect to the http server, and do a simple http post, with
+ // a pause after transmitting the headers
+ clientSocket = new Socket("localhost", HTTP_SERVER_PORT);
+ outputStream = clientSocket.getOutputStream();
+ inputStream = clientSocket.getInputStream();
+
+ // Write to the socket
+ bos = new ByteArrayOutputStream();
+ // Headers
+ bos.write("GET / HTTP 1.1".getBytes(ISO_8859_1));
+ bos.write(CRLF);
+ bos.write("Host: localhost".getBytes(ISO_8859_1));
+ bos.write(CRLF);
+ bos.write(("Content-type: text/plain; charset=" +
ISO_8859_1).getBytes(ISO_8859_1));
+ bos.write(CRLF);
+ bos.write(("Content-length: " + postBody.length).getBytes(ISO_8859_1));
+ bos.write(CRLF);
+ bos.write(CRLF);
+ bos.close();
+ // Write the headers, and then sleep
+ bos.close();
+ byte[] firstChunk = bos.toByteArray();
+ outputStream.write(firstChunk);
+ Thread.sleep(300);
+
+ // Write the body
+ byte[] secondChunk = postBody;
+ outputStream.write(secondChunk);
+ // Read the response
+ response = new ByteArrayOutputStream();
+ buffer = new byte[1024];
+ length = 0;
+ while((length = inputStream.read(buffer)) != -1) {
+ response.write(buffer, 0, length);
+ }
+ response.close();
+ mirroredResponse = getMirroredResponse(response.toByteArray());
+ // The content sent
+ bos = new ByteArrayOutputStream();
+ bos.write(firstChunk);
+ bos.write(secondChunk);
+ bos.close();
+ // Check that the request and response matches
+ checkArraysHaveSameContent(bos.toByteArray(), mirroredResponse);
+ // Close the connection
+ clientSocket.close();
+
+ // Connect to the http server, and do a simple http post with utf-8
+ // encoding of the body, which caused problems when reader/writer
+ // classes were used in the HttpMirrorThread
+ clientSocket = new Socket("localhost", HTTP_SERVER_PORT);
+ outputStream = clientSocket.getOutputStream();
+ inputStream = clientSocket.getInputStream();
+ // Construct body
+ postBodyBuffer = new StringBuffer();
+ for(int i = 0; i < 1000; i++) {
+ postBodyBuffer.append("\u0364\u00c5\u2052");
+ }
+ postBody = postBodyBuffer.toString().getBytes(UTF_8);
+
+ // Write to the socket
+ bos = new ByteArrayOutputStream();
+ // Headers
+ bos.write("GET / HTTP 1.1".getBytes(ISO_8859_1));
+ bos.write(CRLF);
+ bos.write("Host: localhost".getBytes(ISO_8859_1));
+ bos.write(CRLF);
+ bos.write(("Content-type: text/plain; charset=" +
UTF_8).getBytes(ISO_8859_1));
+ bos.write(CRLF);
+ bos.write(("Content-length: " + postBody.length).getBytes(ISO_8859_1));
+ bos.write(CRLF);
+ bos.write(CRLF);
+ bos.close();
+ // Write the headers, and then sleep
+ bos.close();
+ firstChunk = bos.toByteArray();
+ outputStream.write(firstChunk);
+ Thread.sleep(300);
+
+ // Write the body
+ secondChunk = postBody;
+ outputStream.write(secondChunk);
+ // Read the response
+ response = new ByteArrayOutputStream();
+ buffer = new byte[1024];
+ length = 0;
+ while((length = inputStream.read(buffer)) != -1) {
+ response.write(buffer, 0, length);
+ }
+ response.close();
+ mirroredResponse = getMirroredResponse(response.toByteArray());
+ // The content sent
+ bos = new ByteArrayOutputStream();
+ bos.write(firstChunk);
+ bos.write(secondChunk);
+ bos.close();
+ // Check that the request and response matches
+ checkArraysHaveSameContent(bos.toByteArray(), mirroredResponse);
+ // Close the connection
+ clientSocket.close();
+ }
+/*
+ public void testPostRequestChunked() throws Exception {
+ // TODO - implement testing of chunked post request
+ }
+*/
+
+ /**
+ * Check that the the two byte arrays have identical content
+ *
+ * @param expected
+ * @param actual
+ * @throws UnsupportedEncodingException
+ */
+ private void checkArraysHaveSameContent(byte[] expected, byte[] actual)
throws UnsupportedEncodingException {
+ if(expected != null && actual != null) {
+ if(expected.length != actual.length) {
+ System.out.println(">>>>>>>>>>>>>>>>>>>> (expected) : length "
+ expected.length);
+ System.out.println(new String(expected,"UTF-8"));
+ System.out.println("==================== (actual) : length " +
actual.length);
+ System.out.println(new String(actual,"UTF-8"));
+ System.out.println("<<<<<<<<<<<<<<<<<<<<");
+ fail("arrays have different length, expected is " +
expected.length + ", actual is " + actual.length);
+ }
+ else {
+ for(int i = 0; i < expected.length; i++) {
+ if(expected[i] != actual[i]) {
+ System.out.println(">>>>>>>>>>>>>>>>>>>> (expected) :
length " + expected.length);
+ System.out.println(new String(expected,0,i+1));
+ System.out.println("==================== (actual) :
length " + actual.length);
+ System.out.println(new String(actual,0,i+1));
+ System.out.println("<<<<<<<<<<<<<<<<<<<<");
+/*
+ // Useful to when debugging
+ for(int j = 0; j < expected.length; j++) {
+ System.out.print(expected[j] + " ");
+ }
+ System.out.println();
+ for(int j = 0; j < actual.length; j++) {
+ System.out.print(actual[j] + " ");
+ }
+ System.out.println();
+*/
+ fail("byte at position " + i + " is different,
expected is " + expected[i] + ", actual is " + actual[i]);
+ }
+ }
+ }
+ }
+ else {
+ fail("expected or actual byte arrays were null");
+ }
+ }
+
+ private byte[] getMirroredResponse(byte[] allResponse) {
+ // The response includes the headers from the mirror server,
+ // we want to skip those, to only keep the content mirrored.
+ // Look for the first CRLFCRLF section
+ int startOfMirrorResponse = 0;
+ for(int i = 0; i < allResponse.length; i++) {
+ // TODO : This is a bit fragile
+ if(allResponse[i] == 0x0d && allResponse[i+1] == 0x0a
&& allResponse[i+2] == 0x0d && allResponse[i+3] == 0x0a) {
+ startOfMirrorResponse = i + 4;
+ break;
+ }
+ }
+ byte[] mirrorResponse = new byte[allResponse.length -
startOfMirrorResponse];
+ System.arraycopy(allResponse, startOfMirrorResponse, mirrorResponse,
0, mirrorResponse.length);
+ return mirrorResponse;
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]