add chunked encoding to response

This commit is contained in:
hmm 2014-09-02 14:36:43 +08:00
parent 1bfbbde54d
commit 9a668ddf5e
4 changed files with 120 additions and 215 deletions

File diff suppressed because one or more lines are too long

View File

@ -21,6 +21,7 @@ import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManager;
import org.apache.commons.httpclient.ChunkedOutputStream;
import org.apache.commons.httpclient.HttpMethod; import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
@ -115,12 +116,12 @@ public class RequestHandler implements Runnable {
int BUF_SIZE = rs < ss ? ss : rs; int BUF_SIZE = rs < ss ? ss : rs;
byte[] buf = new byte[BUF_SIZE]; byte[] buf = new byte[BUF_SIZE];
try{ try {
initClientServerConnections(this.clientSocket); initClientServerConnections(this.clientSocket);
}catch(SilentException e){ } catch (SilentException e) {
return; return;
} }
this.header.buildRequestHeader(serverConnection); this.header.buildRequestHeader(serverConnection);
log.trace("set request header"); log.trace("set request header");
byte[] requestBody; byte[] requestBody;
@ -149,9 +150,9 @@ public class RequestHandler implements Runnable {
log.trace("wrote " + Integer.toString(len) + " bytes"); log.trace("wrote " + Integer.toString(len) + " bytes");
num += len; num += len;
} }
//close send request to remote server // close send request to remote server
serverOut.flush(); serverOut.flush();
serverOut.close(); serverOut.close();
requestBody = this.buffer.toByteArray(); requestBody = this.buffer.toByteArray();
log.trace("transferred rest of request body"); log.trace("transferred rest of request body");
} else { } else {
@ -160,11 +161,12 @@ public class RequestHandler implements Runnable {
} }
this.clientSocket.shutdownInput(); this.clientSocket.shutdownInput();
this.serverIn = serverConnection.getInputStream(); this.serverIn = serverConnection.getInputStream();
synchronized (mutex) { synchronized (mutex) {
// this.proxyServer.processRequest(this.header, requestBody); // this.proxyServer.processRequest(this.header,
// log.trace("processed request"); // requestBody);
// log.trace("processed request");
this.buffer.reset(); this.buffer.reset();
int len; int len;
@ -182,7 +184,7 @@ public class RequestHandler implements Runnable {
try { try {
this.clientOut.write(changeHeaderToByte( this.clientOut.write(changeHeaderToByte(
serverConnection.getHeaderFields(), serverConnection.getHeaderFields(),
responseModel.getResponse().length)); responseModel));
this.clientOut.write(responseModel.getResponse()); this.clientOut.write(responseModel.getResponse());
} catch (SocketException e) { } catch (SocketException e) {
@ -208,7 +210,7 @@ public class RequestHandler implements Runnable {
} }
private byte[] changeHeaderToByte(Map<String, List<String>> headerMap, private byte[] changeHeaderToByte(Map<String, List<String>> headerMap,
int responseLen) { ResponseModel responseModel) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for (String key : headerMap.keySet()) { for (String key : headerMap.keySet()) {
@ -216,20 +218,45 @@ public class RequestHandler implements Runnable {
sb.append(changeList2String(headerMap.get(key)) + "\r\n"); sb.append(changeList2String(headerMap.get(key)) + "\r\n");
continue; continue;
} }
if (key.equals("Transfer-Encoding")) { if(key.equals("Content-Length") && headerMap.get(key).get(0).equals("-1")){
sb.append("Content-Length: "+responseModel.getResponse().length +"\r\n");
continue; continue;
} }
if (key.equals("Transfer-Encoding") && headerMap.get(key).get(0).equals("chunked")) {
responseModel.setResponse(buildResponseBodyToChunked(responseModel.getResponse()));
}
sb.append(key + ": " + changeList2String(headerMap.get(key)) sb.append(key + ": " + changeList2String(headerMap.get(key))
+ "\r\n"); + "\r\n");
} }
// change response length
if (headerMap.get("Content-Length") == null) {
sb.append("Content-Length: " + responseLen).append("\r\n");
}
sb.append("\r\n"); sb.append("\r\n");
return sb.toString().getBytes(); return sb.toString().getBytes();
} }
private byte[] buildResponseBodyToChunked(byte[] responseBytes) {
ChunkedOutputStream chunkedOutputStream = null;
try {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
chunkedOutputStream = new ChunkedOutputStream(byteArrayOutputStream);
chunkedOutputStream.write(responseBytes,0,responseBytes.length);
chunkedOutputStream.finish();
chunkedOutputStream.flush();
return byteArrayOutputStream.toByteArray();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally{
if(chunkedOutputStream != null){
try {
chunkedOutputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return responseBytes;
}
private String changeList2String(List<String> headers) { private String changeList2String(List<String> headers) {
if (headers == null) if (headers == null)
return ""; return "";

View File

@ -8,6 +8,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import org.apache.commons.httpclient.ChunkedInputStream; import org.apache.commons.httpclient.ChunkedInputStream;
import org.apache.commons.httpclient.ChunkedOutputStream;
import org.apache.commons.io.output.ByteArrayOutputStream; import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.bench4q.recorder.httpcapture.ResponseModel; import org.bench4q.recorder.httpcapture.ResponseModel;
@ -71,29 +72,6 @@ public class ResponseParser {
return result; return result;
} }
private String preprocess(String respString) {
return respString.toLowerCase();
}
private String parseContentLength(Map<String, List<String>> map) {
List<String> values = map.get("Content-Length:");
if (values != null) {
return values.get(0);
}
return "-1";
}
private String parseContentEncoding(Map<String, List<String>> map) {
String ret = "";
List<String> values = map.get("Content-Encoding:");
if (values != null) {
return values.get(0);
}
return null;
}
private String parseCharset(HttpURLConnection httpURLConnection) { private String parseCharset(HttpURLConnection httpURLConnection) {
String ret = null; String ret = null;
@ -129,39 +107,7 @@ public class ResponseParser {
return httpURLConnection.getHeaderField("Transfer-Encoding"); return httpURLConnection.getHeaderField("Transfer-Encoding");
} }
private byte[] buildResponseBody() {
ByteArrayInputStream in = new ByteArrayInputStream(this.getResponse(),
0, this.getResponse().length);
ChunkedInputStream chunkedIS = null;
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
chunkedIS = new ChunkedInputStream(in);
int tempByte;
while ((tempByte = chunkedIS.read()) != -1) {
out.write(tempByte);
}
return out.toByteArray();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
if (chunkedIS != null) {
chunkedIS.close();
}
if (out != null) {
out.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return null;
}
private void parseResponseBody() { private void parseResponseBody() {
ContentDecoder contentDecoder = ContentDecoder.createDecoder(this ContentDecoder contentDecoder = ContentDecoder.createDecoder(this
@ -194,6 +140,9 @@ public class ResponseParser {
charset = Charset.forName("utf-8"); charset = Charset.forName("utf-8");
logger.error(e, e); logger.error(e, e);
} }
return contentEncoder.encoderContent(responseBody.getBytes(charset)); byte[] responseBytes = responseBody.getBytes(charset);
responseBytes = contentEncoder.encoderContent(responseBytes);
return responseBytes;
} }
} }

View File

@ -18,59 +18,59 @@ import org.junit.Test;
public class Test_RequestHandler { public class Test_RequestHandler {
private static final int PORT = 8910; private static final int PORT = 8910;
@Test // @Test
public void test() { // public void test() {
try { // try {
ProxyServer proxyServer = new ProxyServer(PORT); // ProxyServer proxyServer = new ProxyServer(PORT);
Bench4qCodeGenerator observer = new Bench4qCodeGenerator( // Bench4qCodeGenerator observer = new Bench4qCodeGenerator(
new Bench4qTestScriptAdapter(new RunScenarioModel())); // new Bench4qTestScriptAdapter(new RunScenarioModel()));
proxyServer.addObserver(observer); // proxyServer.addObserver(observer);
RequestHandler requestHandler = new RequestHandler(proxyServer, // RequestHandler requestHandler = new RequestHandler(proxyServer,
proxyServer.getServerSocket().accept()); // proxyServer.getServerSocket().accept());
requestHandler.run(); // requestHandler.run();
} catch (IOException e) { // } catch (IOException e) {
e.printStackTrace(); // e.printStackTrace();
} // }
} // }
//
@Test // @Test
public void test2() { // public void test2() {
new SendRequest().run(); // new SendRequest().run();
} // }
//
private static class SendRequest implements Runnable { // private static class SendRequest implements Runnable {
private HttpClient httpClient = new HttpClient(); // private HttpClient httpClient = new HttpClient();
//
@SuppressWarnings("deprecation") // @SuppressWarnings("deprecation")
public void run() { // public void run() {
HostConfiguration hostConfiguration = new HostConfiguration(); // HostConfiguration hostConfiguration = new HostConfiguration();
hostConfiguration.setProxy("127.0.0.1", PORT); // hostConfiguration.setProxy("127.0.0.1", PORT);
httpClient.setHostConfiguration(hostConfiguration); // httpClient.setHostConfiguration(hostConfiguration);
// CustomGetMethod get = new CustomGetMethod("http://www.baidu.com"); //// CustomGetMethod get = new CustomGetMethod("http://www.baidu.com");
GetMethod get = new GetMethod("http://www.baidu.com"); // GetMethod get = new GetMethod("http://www.baidu.com");
//
try { // try {
get.addRequestHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"); // get.addRequestHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
get.addRequestHeader("Accept-Language", "zh-CN,zh;q=0.8"); // get.addRequestHeader("Accept-Language", "zh-CN,zh;q=0.8");
get.addRequestHeader("Cache-Control", "max-age=0"); // get.addRequestHeader("Cache-Control", "max-age=0");
get.addRequestHeader("Accept-Encoding", "gzip,deflate,sdch"); // get.addRequestHeader("Accept-Encoding", "gzip,deflate,sdch");
get.addRequestHeader("Cookie","__zpspc=188.1.1409195668.1409195668.1%234%7C%7C%7C%7C%7C; BDUSS=E45eXUtamxkY2JUbS12ZjFUSmJPbWdmUU13Ri1ZVHlzWWx2S1B3YXRxRVNUU1pVQVFBQUFBJCQAAAAAAAAAAAEAAAAOfOsxd29uYW5ndW8xMQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABLA~lMSwP5Tc; cflag=65535%3A1; BD_UPN=123143; BD_HOME=1; BAIDUID=12B697CB05FD662D2CA4416FF118FCD8:FG=1; BDRCVFR[feWj1Vr5u3D]=I67x6TjHwwYf0; BD_CK_SAM=1; H_PS_PSSID=8307_5228_1466_7800_8235_8488_8057_6506_6017_8251_7607_7799_8483_8457_8167_8509_8435_8382_8114; BD_HOME=1"); // get.addRequestHeader("Cookie","__zpspc=188.1.1409195668.1409195668.1%234%7C%7C%7C%7C%7C; BDUSS=E45eXUtamxkY2JUbS12ZjFUSmJPbWdmUU13Ri1ZVHlzWWx2S1B3YXRxRVNUU1pVQVFBQUFBJCQAAAAAAAAAAAEAAAAOfOsxd29uYW5ndW8xMQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABLA~lMSwP5Tc; cflag=65535%3A1; BD_UPN=123143; BD_HOME=1; BAIDUID=12B697CB05FD662D2CA4416FF118FCD8:FG=1; BDRCVFR[feWj1Vr5u3D]=I67x6TjHwwYf0; BD_CK_SAM=1; H_PS_PSSID=8307_5228_1466_7800_8235_8488_8057_6506_6017_8251_7607_7799_8483_8457_8167_8509_8435_8382_8114; BD_HOME=1");
//
int statusCode = this.httpClient.executeMethod(get); // int statusCode = this.httpClient.executeMethod(get);
System.out.println(statusCode); // System.out.println(statusCode);
System.out.println(new String(get.getResponseBody(),Charset.forName("utf-8"))); // System.out.println(new String(get.getResponseBody(),Charset.forName("utf-8")));
} catch (URIException e) { // } catch (URIException e) {
// TODO Auto-generated catch block // // TODO Auto-generated catch block
e.printStackTrace(); // e.printStackTrace();
} catch (HttpException e) { // } catch (HttpException e) {
// TODO Auto-generated catch block // // TODO Auto-generated catch block
e.printStackTrace(); // e.printStackTrace();
} catch (IOException e) { // } catch (IOException e) {
// TODO Auto-generated catch block // // TODO Auto-generated catch block
e.printStackTrace(); // e.printStackTrace();
} // }
//
} // }
//
} // }
} }