Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(316)

Unified Diff: net/test/android/javatests/src/org/chromium/net/test/util/TestWebServer.java

Issue 2705963002: (Android) Removing deprecated org.apache.http.* classes (Closed)
Patch Set: 2nd version - cleanups/fixes Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « android_webview/javatests/src/org/chromium/android_webview/test/LoadUrlTest.java ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/test/android/javatests/src/org/chromium/net/test/util/TestWebServer.java
diff --git a/net/test/android/javatests/src/org/chromium/net/test/util/TestWebServer.java b/net/test/android/javatests/src/org/chromium/net/test/util/TestWebServer.java
index ab6f5cda413ee382dd0258492cc3b242f1b695d5..4b5730d19f9f3a23802d413e02d95ec80d2bfced 100644
--- a/net/test/android/javatests/src/org/chromium/net/test/util/TestWebServer.java
+++ b/net/test/android/javatests/src/org/chromium/net/test/util/TestWebServer.java
@@ -9,28 +9,17 @@ import android.util.Base64;
import android.util.Log;
import android.util.Pair;
-import org.apache.http.Header;
-import org.apache.http.HttpException;
-import org.apache.http.HttpRequest;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpStatus;
-import org.apache.http.HttpVersion;
-import org.apache.http.RequestLine;
-import org.apache.http.StatusLine;
-import org.apache.http.entity.ByteArrayEntity;
-import org.apache.http.impl.DefaultHttpServerConnection;
-import org.apache.http.impl.cookie.DateUtils;
-import org.apache.http.message.BasicHttpResponse;
-import org.apache.http.params.BasicHttpParams;
-import org.apache.http.params.CoreProtocolPNames;
-import org.apache.http.params.HttpParams;
-
+import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintStream;
import java.net.MalformedURLException;
import java.net.ServerSocket;
import java.net.Socket;
+import java.net.SocketException;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
@@ -40,11 +29,12 @@ import java.security.KeyStore;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
+import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
-import java.util.Hashtable;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import javax.net.ssl.HostnameVerifier;
@@ -62,14 +52,13 @@ import javax.net.ssl.X509TrustManager;
* for loopback testing without the need to setup tcp forwarding to the
* host computer.
*
- * Based heavily on the CTSWebServer in Android.
+ * Originally based heavily on the CTSWebServer in Android.
*/
public class TestWebServer {
private static final String TAG = "TestWebServer";
private static TestWebServer sInstance;
private static TestWebServer sSecureInstance;
- private static Hashtable<Integer, String> sReasons;
private final ServerThread mServerThread;
private String mServerUri;
@@ -106,7 +95,7 @@ public class TestWebServer {
private final Object mLock = new Object();
private final Map<String, Response> mResponseMap = new HashMap<String, Response>();
private final Map<String, Integer> mResponseCountMap = new HashMap<String, Integer>();
- private final Map<String, HttpRequest> mLastRequestMap = new HashMap<String, HttpRequest>();
+ private final Map<String, List<String>> mLastRequestMap = new HashMap<String, List<String>>();
/**
* Create and start a local HTTP server instance.
@@ -403,7 +392,7 @@ public class TestWebServer {
/**
* Returns the last HttpRequest at this path. Can return null if it is never requested.
*/
- public HttpRequest getLastRequest(String requestPath) {
+ public List<String> getLastRequest(String requestPath) {
synchronized (mLock) {
if (!mLastRequestMap.containsKey(requestPath))
throw new IllegalArgumentException("Path not set: " + requestPath);
@@ -475,11 +464,28 @@ public class TestWebServer {
}
}
- private void servedResponseFor(String path, HttpRequest request) {
- synchronized (mLock) {
- mResponseCountMap.put(path, Integer.valueOf(
- mResponseCountMap.get(path).intValue() + 1));
- mLastRequestMap.put(path, request);
+ public static List<String> getMatchingHeadersValues(List<String> request, String headerName) {
+ List<String> matchingHeaders = new ArrayList<String>();
+ for (int j = 1; j < request.size(); j++) {
+ if (request.get(j).isEmpty()) break;
+ if (request.get(j)
+ .toLowerCase(Locale.ENGLISH)
+ .startsWith(headerName.toLowerCase(Locale.ENGLISH) + ": ")) {
+ matchingHeaders.add(request.get(j).substring(headerName.length() + 2));
+ }
+ }
+ return matchingHeaders;
+ }
+
+ private static class WebServerPrintStream extends PrintStream {
+ WebServerPrintStream(OutputStream out) {
+ super(out);
+ }
+
+ @Override
+ public void println(String s) {
+ Log.w(TAG, s);
+ super.println(s);
}
}
@@ -491,131 +497,111 @@ public class TestWebServer {
* <p>If there is an action associated with the response, it will be executed inside of
* this function.
*
- * @throws InterruptedException
+ * @throws NoSuchAlgorithmException, IOException
*/
- private HttpResponse getResponse(HttpRequest request) throws InterruptedException {
- assert Thread.currentThread() == mServerThread
- : "getResponse called from non-server thread";
-
- RequestLine requestLine = request.getRequestLine();
- HttpResponse httpResponse = null;
- Log.i(TAG, requestLine.getMethod() + ": " + requestLine.getUri());
- String uriString = requestLine.getUri();
- URI uri = URI.create(uriString);
- String path = uri.getPath();
-
- Response response = null;
+ private void outputResponse(List<String> requestLines, WebServerPrintStream stream)
+ throws NoSuchAlgorithmException, IOException {
+ assert Thread.currentThread()
+ == mServerThread : "outputResponse called from non-server thread";
+ assert requestLines.get(0).split(" ").length
+ == 3 : "Incorrect header sent to outputResponse";
+
+ // Don't dump headers to decrease log.
+ Log.w(TAG, requestLines.get(0));
+
+ final String bodyTemplate = "<html><head><title>%s</title></head>"
+ + "<body>%s</body></html>";
+
+ boolean copyHeadersToResponse = true;
+ boolean copyBinaryBodyToResponse = false;
+ boolean contentLengthAlreadyIncluded = false;
+ boolean contentTypeAlreadyIncluded = false;
+ String path = URI.create(requestLines.get(0).split(" ")[1]).getPath();
+ StringBuilder textBody = new StringBuilder();
+
+ Response response;
synchronized (mLock) {
response = mResponseMap.get(path);
}
- if (response == null) {
- httpResponse = createResponse(HttpStatus.SC_NOT_FOUND);
- } else if (response.mIsNotFound) {
- httpResponse = createResponse(HttpStatus.SC_NOT_FOUND);
- for (Pair<String, String> header : response.mResponseHeaders) {
- httpResponse.addHeader(header.first, header.second);
+
+ if (response == null || response.mIsNotFound) {
+ stream.println("HTTP/1.0 404 Not Found");
+ textBody.append(String.format(bodyTemplate, "Not Found", "Not Found"));
+ } else if (response.mForWebSocket) {
+ List<String> keyHeaders = getMatchingHeadersValues(requestLines, "Sec-WebSocket-Key");
+ if (keyHeaders.size() == 1) {
+ stream.println("HTTP/1.0 101 Switching Protocols");
+ stream.println(
+ "Sec-WebSocket-Accept: " + computeWebSocketAccept(keyHeaders.get(0)));
+ } else {
+ stream.println("HTTP/1.0 404 Not Found");
+ textBody.append(String.format(bodyTemplate, "Not Found", "Not Found"));
+ copyHeadersToResponse = false;
}
- servedResponseFor(path, request);
} else if (response.mIsNoContent) {
- httpResponse = createResponse(HttpStatus.SC_NO_CONTENT);
- httpResponse.setHeader("Content-Length", "0");
- servedResponseFor(path, request);
- } else if (response.mIsEmptyResponse) {
- httpResponse = createResponse(HttpStatus.SC_FORBIDDEN); // arbitrary failure status
- httpResponse.setHeader("Content-Length", "0");
- servedResponseFor(path, request);
+ stream.println("HTTP/1.0 200 OK");
+ copyHeadersToResponse = false;
} else if (response.mIsRedirect) {
- httpResponse = createResponse(HttpStatus.SC_MOVED_TEMPORARILY);
- for (Pair<String, String> header : response.mResponseHeaders) {
- httpResponse.addHeader(header.first, header.second);
- }
- servedResponseFor(path, request);
- } else if (response.mForWebSocket) {
- Header[] keys = request.getHeaders("Sec-WebSocket-Key");
- try {
- if (keys.length == 1) {
- final String key = keys[0].getValue();
- httpResponse = createResponse(HttpStatus.SC_SWITCHING_PROTOCOLS);
- for (Pair<String, String> header : response.mResponseHeaders) {
- httpResponse.addHeader(header.first, header.second);
- }
- httpResponse.addHeader("Sec-WebSocket-Accept", computeWebSocketAccept(key));
- } else {
- httpResponse = createResponse(HttpStatus.SC_NOT_FOUND);
- }
- } catch (NoSuchAlgorithmException e) {
- httpResponse = createResponse(HttpStatus.SC_NOT_FOUND);
- }
- servedResponseFor(path, request);
+ stream.println("HTTP/1.0 302 Found");
+ textBody.append(String.format(bodyTemplate, "Found", "Found"));
+ } else if (response.mIsEmptyResponse) {
+ stream.println("HTTP/1.0 403 Forbidden");
+ copyHeadersToResponse = false;
} else {
if (response.mResponseAction != null) response.mResponseAction.run();
- httpResponse = createResponse(HttpStatus.SC_OK);
- ByteArrayEntity entity = createEntity(response.mResponseData);
- httpResponse.setEntity(entity);
- httpResponse.setHeader("Content-Length", "" + entity.getContentLength());
- for (Pair<String, String> header : response.mResponseHeaders) {
- httpResponse.addHeader(header.first, header.second);
- }
- servedResponseFor(path, request);
+ stream.println("HTTP/1.0 200 OK");
+ copyBinaryBodyToResponse = true;
}
- StatusLine sl = httpResponse.getStatusLine();
- Log.i(TAG, sl.getStatusCode() + "(" + sl.getReasonPhrase() + ")");
- if (path.endsWith(".js")) {
- httpResponse.addHeader("Content-Type", "application/javascript");
+ if (response != null) {
+ if (copyHeadersToResponse) {
+ for (Pair<String, String> header : response.mResponseHeaders) {
+ stream.println(header.first + ": " + header.second);
+ if (header.first.toLowerCase(Locale.ENGLISH).equals("content-length")) {
+ contentLengthAlreadyIncluded = true;
+ } else if (header.first.toLowerCase(Locale.ENGLISH).equals("content-type")) {
+ contentTypeAlreadyIncluded = true;
+ }
+ }
+ }
+ synchronized (mLock) {
+ mResponseCountMap.put(
+ path, Integer.valueOf(mResponseCountMap.get(path).intValue() + 1));
+ mLastRequestMap.put(path, requestLines);
+ }
}
- setDateHeaders(httpResponse);
- return httpResponse;
- }
+ // RFC 1123
+ final SimpleDateFormat dateFormat =
+ new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
- private void setDateHeaders(HttpResponse response) {
- response.addHeader("Date", DateUtils.formatDate(new Date(), DateUtils.PATTERN_RFC1123));
- }
+ // Using print and println() because we don't want to dump it into log.
+ stream.print("Date: " + dateFormat.format(new Date()));
+ stream.println();
- /**
- * Create an empty response with the given status.
- */
- private HttpResponse createResponse(int status) {
- HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_0, status, null);
- String reason = null;
-
- // This synchronized silences findbugs.
- synchronized (TestWebServer.class) {
- if (sReasons == null) {
- sReasons = new Hashtable<Integer, String>();
- sReasons.put(HttpStatus.SC_UNAUTHORIZED, "Unauthorized");
- sReasons.put(HttpStatus.SC_NOT_FOUND, "Not Found");
- sReasons.put(HttpStatus.SC_FORBIDDEN, "Forbidden");
- sReasons.put(HttpStatus.SC_MOVED_TEMPORARILY, "Moved Temporarily");
+ if (textBody.length() != 0) {
+ if (!contentTypeAlreadyIncluded && (path.endsWith(".html") || path.endsWith(".htm"))) {
+ stream.println("Content-Type: text/html");
}
- // Fill in error reason. Avoid use of the ReasonPhraseCatalog, which is
- // Locale-dependent.
- reason = sReasons.get(status);
- }
-
- if (reason != null) {
- StringBuilder buf = new StringBuilder("<html><head><title>");
- buf.append(reason);
- buf.append("</title></head><body>");
- buf.append(reason);
- buf.append("</body></html>");
- ByteArrayEntity entity = createEntity(buf.toString().getBytes());
- response.setEntity(entity);
- response.setHeader("Content-Length", "" + entity.getContentLength());
- response.setReasonPhrase(reason);
+ stream.println("Content-Length: " + textBody.length());
+ stream.println();
+ stream.print(textBody.toString());
+ } else if (copyBinaryBodyToResponse) {
+ if (!contentTypeAlreadyIncluded && path.endsWith(".js")) {
+ stream.println("Content-Type: application/javascript");
+ } else if (!contentTypeAlreadyIncluded
+ && (path.endsWith(".html") || path.endsWith(".htm"))) {
+ stream.println("Content-Type: text/html");
+ }
+ if (!contentLengthAlreadyIncluded) {
+ stream.println("Content-Length: " + response.mResponseData.length);
+ }
+ stream.println();
+ stream.write(response.mResponseData);
+ } else {
+ stream.println();
}
- return response;
- }
-
- /**
- * Create a string entity for the given content.
- */
- private ByteArrayEntity createEntity(byte[] data) {
- ByteArrayEntity entity = new ByteArrayEntity(data);
- entity.setContentType("text/html");
- return entity;
}
/**
@@ -629,7 +615,7 @@ public class TestWebServer {
md.update(key);
md.update(guid);
byte[] output = md.digest();
- return Base64.encodeToString(output, Base64.DEFAULT);
+ return Base64.encodeToString(output, Base64.NO_WRAP);
}
private static class ServerThread extends Thread {
@@ -749,49 +735,43 @@ public class TestWebServer {
@Override
public void run() {
- HttpParams params = new BasicHttpParams();
- params.setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_0);
- while (!getIsCancelled()) {
- Socket socket = null;
- try {
- socket = mSocket.accept();
+ try {
+ while (!getIsCancelled()) {
+ BufferedReader inputStream = null;
+ WebServerPrintStream outputStream = null;
+ Socket socket = mSocket.accept();
setCurrentRequestSocket(socket);
+ try {
+ inputStream =
+ new BufferedReader(new InputStreamReader(socket.getInputStream()));
+ List<String> lines = new ArrayList<String>();
+ String line;
+
+ while (true) {
+ if (getIsCancelled()) return;
+ line = inputStream.readLine();
+ // We ignore message body if any.
+ if (line == null || line.length() == 0) break;
+ lines.add(line);
+ }
- DefaultHttpServerConnection conn = new DefaultHttpServerConnection();
- conn.bind(socket, params);
-
- if (getIsCancelled()) continue;
- HttpRequest request = conn.receiveRequestHeader();
- HttpResponse response = mServer.getResponse(request);
- conn.sendResponseHeader(response);
- conn.sendResponseEntity(response);
-
- conn.close();
- socket = null;
- } catch (IOException e) {
- // normal during shutdown, ignore
- Log.w(TAG, e);
- } catch (HttpException e) {
- Log.w(TAG, e);
- } catch (InterruptedException e) {
- Log.w(TAG, e);
- } catch (UnsupportedOperationException e) {
- // DefaultHttpServerConnection's close() throws an
- // UnsupportedOperationException.
- Log.w(TAG, e);
- } finally {
- // Since DefaultHttpServerConnection can raise an exception
- // during conn.close() (in the case of SSL), we always force
- // the socket to close, since it may be left open. This will
- // be a no-op if the connection managed to close the socket.
- if (socket != null) {
- try {
- socket.close();
- } catch (IOException ignored) {
- // safe to ignore
+ if (lines.size() == 0) {
+ Log.w(TAG, "Empty request");
+ } else {
+ outputStream = new WebServerPrintStream(socket.getOutputStream());
+ mServer.outputResponse(lines, outputStream);
}
+ } finally {
+ // We ignore keep-alive header.
+ if (outputStream != null) outputStream.close();
+ if (inputStream != null) inputStream.close();
+ socket.close();
}
}
+ } catch (SocketException e) {
+ } catch (NoSuchAlgorithmException ignore) {
+ } catch (IOException e) {
+ Log.w(TAG, e);
}
}
}
« no previous file with comments | « android_webview/javatests/src/org/chromium/android_webview/test/LoadUrlTest.java ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698