Bug 2326468
Deleted old copy of the GoogleHttpClient, and the unit tests.
This commit is contained in:
@@ -1,399 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed 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 com.google.android.net;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.net.TrafficStats;
|
||||
import android.os.Build;
|
||||
import android.os.SystemClock;
|
||||
import android.provider.Checkin;
|
||||
import android.util.Config;
|
||||
import android.util.Log;
|
||||
import com.android.common.AndroidHttpClient;
|
||||
import org.apache.harmony.xnet.provider.jsse.SSLClientSessionCache;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpEntityEnclosingRequest;
|
||||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.ProtocolException;
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.ResponseHandler;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.http.conn.ClientConnectionManager;
|
||||
import org.apache.http.conn.scheme.LayeredSocketFactory;
|
||||
import org.apache.http.conn.scheme.Scheme;
|
||||
import org.apache.http.conn.scheme.SchemeRegistry;
|
||||
import org.apache.http.conn.scheme.SocketFactory;
|
||||
import org.apache.http.impl.client.EntityEnclosingRequestWrapper;
|
||||
import org.apache.http.impl.client.RequestWrapper;
|
||||
import org.apache.http.params.HttpParams;
|
||||
import org.apache.http.protocol.HttpContext;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
/**
|
||||
* {@link AndroidHttpClient} wrapper that uses {@link UrlRules} to rewrite URLs
|
||||
* and otherwise tweak HTTP requests.
|
||||
*/
|
||||
public class GoogleHttpClient implements HttpClient {
|
||||
private static final String TAG = "GoogleHttpClient";
|
||||
private static final boolean LOCAL_LOGV = Config.LOGV || false;
|
||||
|
||||
/** Exception thrown when a request is blocked by the URL rules. */
|
||||
public static class BlockedRequestException extends IOException {
|
||||
private final UrlRules.Rule mRule;
|
||||
BlockedRequestException(UrlRules.Rule rule) {
|
||||
super("Blocked by rule: " + rule.mName);
|
||||
mRule = rule;
|
||||
}
|
||||
}
|
||||
|
||||
private final AndroidHttpClient mClient;
|
||||
private final ContentResolver mResolver;
|
||||
private final String mAppName, mUserAgent;
|
||||
private final ThreadLocal<Boolean> mConnectionAllocated = new ThreadLocal<Boolean>();
|
||||
|
||||
/**
|
||||
* Create an HTTP client without SSL session persistence.
|
||||
* @deprecated Use {@link #GoogleHttpClient(android.content.Context, String, boolean)}
|
||||
*/
|
||||
public GoogleHttpClient(ContentResolver resolver, String userAgent) {
|
||||
mClient = AndroidHttpClient.newInstance(userAgent);
|
||||
mResolver = resolver;
|
||||
mUserAgent = mAppName = userAgent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an HTTP client without SSL session persistence.
|
||||
* @deprecated Use {@link #GoogleHttpClient(android.content.Context, String, boolean)}
|
||||
*/
|
||||
public GoogleHttpClient(ContentResolver resolver, String appAndVersion,
|
||||
boolean gzipCapable) {
|
||||
this(resolver, null /* cache */, appAndVersion, gzipCapable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an HTTP client. Normaly this client is shared throughout an app.
|
||||
* The HTTP client will construct its User-Agent as follows:
|
||||
*
|
||||
* <appAndVersion> (<build device> <build id>)
|
||||
* or
|
||||
* <appAndVersion> (<build device> <build id>); gzip
|
||||
* (if gzip capable)
|
||||
*
|
||||
* The context has settings for URL rewriting rules and is used to enable
|
||||
* SSL session persistence.
|
||||
*
|
||||
* @param context application context.
|
||||
* @param appAndVersion Base app and version to use in the User-Agent.
|
||||
* e.g., "MyApp/1.0"
|
||||
* @param gzipCapable Whether or not this client is able to consume gzip'd
|
||||
* responses. Only used to modify the User-Agent, not other request
|
||||
* headers. Needed because Google servers require gzip in the User-Agent
|
||||
* in order to return gzip'd content.
|
||||
*/
|
||||
public GoogleHttpClient(Context context, String appAndVersion, boolean gzipCapable) {
|
||||
this(context.getContentResolver(),
|
||||
SSLClientSessionCacheFactory.getCache(context),
|
||||
appAndVersion, gzipCapable);
|
||||
}
|
||||
|
||||
private GoogleHttpClient(ContentResolver resolver,
|
||||
SSLClientSessionCache cache,
|
||||
String appAndVersion, boolean gzipCapable) {
|
||||
String userAgent = appAndVersion + " (" + Build.DEVICE + " " + Build.ID + ")";
|
||||
if (gzipCapable) {
|
||||
userAgent = userAgent + "; gzip";
|
||||
}
|
||||
|
||||
mClient = AndroidHttpClient.newInstance(userAgent, cache);
|
||||
mResolver = resolver;
|
||||
mAppName = appAndVersion;
|
||||
mUserAgent = userAgent;
|
||||
|
||||
// Wrap all the socket factories with the appropriate wrapper. (Apache
|
||||
// HTTP, curse its black and stupid heart, inspects the SocketFactory to
|
||||
// see if it's a LayeredSocketFactory, so we need two wrapper classes.)
|
||||
SchemeRegistry registry = getConnectionManager().getSchemeRegistry();
|
||||
for (String name : registry.getSchemeNames()) {
|
||||
Scheme scheme = registry.unregister(name);
|
||||
SocketFactory sf = scheme.getSocketFactory();
|
||||
if (sf instanceof LayeredSocketFactory) {
|
||||
sf = new WrappedLayeredSocketFactory((LayeredSocketFactory) sf);
|
||||
} else {
|
||||
sf = new WrappedSocketFactory(sf);
|
||||
}
|
||||
registry.register(new Scheme(name, sf, scheme.getDefaultPort()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegating wrapper for SocketFactory records when sockets are connected.
|
||||
* We use this to know whether a connection was created vs reused, to
|
||||
* gather per-app statistics about connection reuse rates.
|
||||
* (Note, we record only *connection*, not *creation* of sockets --
|
||||
* what we care about is the network overhead of an actual TCP connect.)
|
||||
*/
|
||||
private class WrappedSocketFactory implements SocketFactory {
|
||||
private SocketFactory mDelegate;
|
||||
private WrappedSocketFactory(SocketFactory delegate) { mDelegate = delegate; }
|
||||
public final Socket createSocket() throws IOException { return mDelegate.createSocket(); }
|
||||
public final boolean isSecure(Socket s) { return mDelegate.isSecure(s); }
|
||||
|
||||
public final Socket connectSocket(
|
||||
Socket s, String h, int p,
|
||||
InetAddress la, int lp, HttpParams params) throws IOException {
|
||||
mConnectionAllocated.set(Boolean.TRUE);
|
||||
return mDelegate.connectSocket(s, h, p, la, lp, params);
|
||||
}
|
||||
}
|
||||
|
||||
/** Like WrappedSocketFactory, but for the LayeredSocketFactory subclass. */
|
||||
private class WrappedLayeredSocketFactory
|
||||
extends WrappedSocketFactory implements LayeredSocketFactory {
|
||||
private LayeredSocketFactory mDelegate;
|
||||
private WrappedLayeredSocketFactory(LayeredSocketFactory sf) { super(sf); mDelegate = sf; }
|
||||
|
||||
public final Socket createSocket(Socket s, String host, int port, boolean autoClose)
|
||||
throws IOException {
|
||||
return mDelegate.createSocket(s, host, port, autoClose);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Release resources associated with this client. You must call this,
|
||||
* or significant resources (sockets and memory) may be leaked.
|
||||
*/
|
||||
public void close() {
|
||||
mClient.close();
|
||||
}
|
||||
|
||||
/** Execute a request without applying and rewrite rules. */
|
||||
public HttpResponse executeWithoutRewriting(
|
||||
HttpUriRequest request, HttpContext context)
|
||||
throws IOException {
|
||||
int code = -1;
|
||||
long start = SystemClock.elapsedRealtime();
|
||||
try {
|
||||
HttpResponse response;
|
||||
mConnectionAllocated.set(null);
|
||||
|
||||
if (NetworkStatsEntity.shouldLogNetworkStats()) {
|
||||
// TODO: if we're logging network stats, and if the apache library is configured
|
||||
// to follow redirects, count each redirect as an additional round trip.
|
||||
|
||||
int uid = android.os.Process.myUid();
|
||||
long startTx = TrafficStats.getUidTxBytes(uid);
|
||||
long startRx = TrafficStats.getUidRxBytes(uid);
|
||||
|
||||
response = mClient.execute(request, context);
|
||||
HttpEntity origEntity = response == null ? null : response.getEntity();
|
||||
if (origEntity != null) {
|
||||
// yeah, we compute the same thing below. we do need to compute this here
|
||||
// so we can wrap the HttpEntity in the response.
|
||||
long now = SystemClock.elapsedRealtime();
|
||||
long elapsed = now - start;
|
||||
NetworkStatsEntity entity = new NetworkStatsEntity(origEntity,
|
||||
mAppName, uid, startTx, startRx,
|
||||
elapsed /* response latency */, now /* processing start time */);
|
||||
response.setEntity(entity);
|
||||
}
|
||||
} else {
|
||||
response = mClient.execute(request, context);
|
||||
}
|
||||
|
||||
code = response.getStatusLine().getStatusCode();
|
||||
return response;
|
||||
} finally {
|
||||
// Record some statistics to the checkin service about the outcome.
|
||||
// Note that this is only describing execute(), not body download.
|
||||
// We assume the database writes are much faster than network I/O,
|
||||
// and not worth running in a background thread or anything.
|
||||
try {
|
||||
long elapsed = SystemClock.elapsedRealtime() - start;
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(Checkin.Stats.COUNT, 1);
|
||||
values.put(Checkin.Stats.SUM, elapsed / 1000.0);
|
||||
|
||||
values.put(Checkin.Stats.TAG, Checkin.Stats.Tag.HTTP_REQUEST + ":" + mAppName);
|
||||
mResolver.insert(Checkin.Stats.CONTENT_URI, values);
|
||||
|
||||
// No sockets and no exceptions means we successfully reused a connection
|
||||
if (mConnectionAllocated.get() == null && code >= 0) {
|
||||
values.put(Checkin.Stats.TAG, Checkin.Stats.Tag.HTTP_REUSED + ":" + mAppName);
|
||||
mResolver.insert(Checkin.Stats.CONTENT_URI, values);
|
||||
}
|
||||
|
||||
String status = code < 0 ? "IOException" : Integer.toString(code);
|
||||
values.put(Checkin.Stats.TAG,
|
||||
Checkin.Stats.Tag.HTTP_STATUS + ":" + mAppName + ":" + status);
|
||||
mResolver.insert(Checkin.Stats.CONTENT_URI, values);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Error recording stats", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String rewriteURI(String original) {
|
||||
UrlRules rules = UrlRules.getRules(mResolver);
|
||||
UrlRules.Rule rule = rules.matchRule(original);
|
||||
return rule.apply(original);
|
||||
}
|
||||
|
||||
public HttpResponse execute(HttpUriRequest request, HttpContext context)
|
||||
throws IOException {
|
||||
// Rewrite the supplied URL...
|
||||
URI uri = request.getURI();
|
||||
String original = uri.toString();
|
||||
UrlRules rules = UrlRules.getRules(mResolver);
|
||||
UrlRules.Rule rule = rules.matchRule(original);
|
||||
String rewritten = rule.apply(original);
|
||||
|
||||
if (rewritten == null) {
|
||||
Log.w(TAG, "Blocked by " + rule.mName + ": " + original);
|
||||
throw new BlockedRequestException(rule);
|
||||
} else if (rewritten == original) {
|
||||
return executeWithoutRewriting(request, context); // Pass through
|
||||
}
|
||||
|
||||
try {
|
||||
uri = new URI(rewritten);
|
||||
} catch (URISyntaxException e) {
|
||||
throw new RuntimeException("Bad URL from rule: " + rule.mName, e);
|
||||
}
|
||||
|
||||
// Wrap request so we can replace the URI.
|
||||
RequestWrapper wrapper = wrapRequest(request);
|
||||
wrapper.setURI(uri);
|
||||
request = wrapper;
|
||||
|
||||
if (LOCAL_LOGV) Log.v(TAG, "Rule " + rule.mName + ": " + original + " -> " + rewritten);
|
||||
return executeWithoutRewriting(request, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the request making it mutable.
|
||||
*/
|
||||
private static RequestWrapper wrapRequest(HttpUriRequest request)
|
||||
throws IOException {
|
||||
try {
|
||||
// We have to wrap it with the right type. Some code performs
|
||||
// instanceof checks.
|
||||
RequestWrapper wrapped;
|
||||
if (request instanceof HttpEntityEnclosingRequest) {
|
||||
wrapped = new EntityEnclosingRequestWrapper(
|
||||
(HttpEntityEnclosingRequest) request);
|
||||
} else {
|
||||
wrapped = new RequestWrapper(request);
|
||||
}
|
||||
|
||||
// Copy the headers from the original request into the wrapper.
|
||||
wrapped.resetHeaders();
|
||||
|
||||
return wrapped;
|
||||
} catch (ProtocolException e) {
|
||||
throw new ClientProtocolException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark a user agent as one Google will trust to handle gzipped content.
|
||||
* {@link AndroidHttpClient#modifyRequestToAcceptGzipResponse} is (also)
|
||||
* necessary but not sufficient -- many browsers claim to accept gzip but
|
||||
* have broken handling, so Google checks the user agent as well.
|
||||
*
|
||||
* @param originalUserAgent to modify (however you identify yourself)
|
||||
* @return user agent with a "yes, I really can handle gzip" token added.
|
||||
* @deprecated Use {@link #GoogleHttpClient(android.content.ContentResolver, String, boolean)}
|
||||
*/
|
||||
public static String getGzipCapableUserAgent(String originalUserAgent) {
|
||||
return originalUserAgent + "; gzip";
|
||||
}
|
||||
|
||||
// HttpClient wrapper methods.
|
||||
|
||||
public HttpParams getParams() {
|
||||
return mClient.getParams();
|
||||
}
|
||||
|
||||
public ClientConnectionManager getConnectionManager() {
|
||||
return mClient.getConnectionManager();
|
||||
}
|
||||
|
||||
public HttpResponse execute(HttpUriRequest request) throws IOException {
|
||||
return execute(request, (HttpContext) null);
|
||||
}
|
||||
|
||||
public HttpResponse execute(HttpHost target, HttpRequest request)
|
||||
throws IOException {
|
||||
return mClient.execute(target, request);
|
||||
}
|
||||
|
||||
public HttpResponse execute(HttpHost target, HttpRequest request,
|
||||
HttpContext context) throws IOException {
|
||||
return mClient.execute(target, request, context);
|
||||
}
|
||||
|
||||
public <T> T execute(HttpUriRequest request,
|
||||
ResponseHandler<? extends T> responseHandler)
|
||||
throws IOException, ClientProtocolException {
|
||||
return mClient.execute(request, responseHandler);
|
||||
}
|
||||
|
||||
public <T> T execute(HttpUriRequest request,
|
||||
ResponseHandler<? extends T> responseHandler, HttpContext context)
|
||||
throws IOException, ClientProtocolException {
|
||||
return mClient.execute(request, responseHandler, context);
|
||||
}
|
||||
|
||||
public <T> T execute(HttpHost target, HttpRequest request,
|
||||
ResponseHandler<? extends T> responseHandler) throws IOException,
|
||||
ClientProtocolException {
|
||||
return mClient.execute(target, request, responseHandler);
|
||||
}
|
||||
|
||||
public <T> T execute(HttpHost target, HttpRequest request,
|
||||
ResponseHandler<? extends T> responseHandler, HttpContext context)
|
||||
throws IOException, ClientProtocolException {
|
||||
return mClient.execute(target, request, responseHandler, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables cURL request logging for this client.
|
||||
*
|
||||
* @param name to log messages with
|
||||
* @param level at which to log messages (see {@link android.util.Log})
|
||||
*/
|
||||
public void enableCurlLogging(String name, int level) {
|
||||
mClient.enableCurlLogging(name, level);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables cURL logging for this client.
|
||||
*/
|
||||
public void disableCurlLogging() {
|
||||
mClient.disableCurlLogging();
|
||||
}
|
||||
}
|
||||
@@ -697,7 +697,6 @@ com.google.android.mms.ContentType
|
||||
com.google.android.mms.pdu.CharacterSets
|
||||
com.google.android.mms.pdu.PduPart
|
||||
com.google.android.mms.pdu.PduPersister
|
||||
com.google.android.net.GoogleHttpClient
|
||||
com.google.android.net.UrlRules
|
||||
com.google.android.net.UrlRules$Rule
|
||||
com.ibm.icu4jni.charset.CharsetDecoderICU
|
||||
|
||||
@@ -1,259 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed 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 com.android.unit_tests;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.provider.Settings;
|
||||
import android.test.AndroidTestCase;
|
||||
import android.test.suitebuilder.annotation.LargeTest;
|
||||
import android.test.suitebuilder.annotation.Suppress;
|
||||
|
||||
import com.google.android.net.GoogleHttpClient;
|
||||
|
||||
import com.android.internal.net.DbSSLSessionCache;
|
||||
import com.android.internal.net.DbSSLSessionCache.DatabaseHelper;
|
||||
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.Principal;
|
||||
import java.security.cert.Certificate;
|
||||
|
||||
import javax.net.ssl.SSLPeerUnverifiedException;
|
||||
import javax.net.ssl.SSLSession;
|
||||
import javax.net.ssl.SSLSessionContext;
|
||||
import javax.security.cert.X509Certificate;
|
||||
|
||||
/** Unit test for SSL session caching with {@link GoogleHttpClient}.
|
||||
* Uses network resources.
|
||||
*/
|
||||
@Suppress
|
||||
public class DbSSLSessionCacheTest extends AndroidTestCase {
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
}
|
||||
|
||||
/**
|
||||
* We want to test the actual database write - the actual hooking into
|
||||
* low-level SSL is tested.
|
||||
*/
|
||||
@LargeTest
|
||||
public void testSslCacheAdd() throws Exception {
|
||||
// Let's verify the database has the rows.
|
||||
// Use internal details of the implementation - could make the field
|
||||
// visible for testing, but it's same.
|
||||
|
||||
// Use default database
|
||||
DbSSLSessionCache cache = DbSSLSessionCache.getInstanceForPackage(getContext());
|
||||
cache.clear();
|
||||
|
||||
|
||||
makeRequestInNewContext("https://www.google.com");
|
||||
|
||||
// Verify the key was inserted
|
||||
SQLiteOpenHelper helper = new DatabaseHelper(getContext());
|
||||
Cursor query = null;
|
||||
try {
|
||||
query = helper.getReadableDatabase().query(DbSSLSessionCache.SSL_CACHE_TABLE,
|
||||
new String[] {"hostport"}, null,
|
||||
null, null, null, null);
|
||||
|
||||
assertTrue(query.moveToFirst()); // one row inserted
|
||||
String hostPort = query.getString(0);
|
||||
assertEquals(hostPort, "www.google.com:443");
|
||||
} finally {
|
||||
query.close();
|
||||
}
|
||||
}
|
||||
|
||||
@LargeTest
|
||||
public void testExpire() throws Exception {
|
||||
DatabaseHelper helper = new DatabaseHelper(getContext());
|
||||
// clean up
|
||||
DbSSLSessionCache cache = new DbSSLSessionCache(helper);
|
||||
cache.clear();
|
||||
|
||||
long t0 = System.currentTimeMillis();
|
||||
for (int i = 0; i < DbSSLSessionCache.MAX_CACHE_SIZE + 2; i++) {
|
||||
final int port = i;
|
||||
cache.putSessionData(new MockSession() {
|
||||
|
||||
public String getPeerHost() {
|
||||
return "test.host.com";
|
||||
}
|
||||
|
||||
public int getPeerPort() {
|
||||
return port;
|
||||
}
|
||||
}, new byte[256]);
|
||||
}
|
||||
long t1 = System.currentTimeMillis();
|
||||
|
||||
System.err.println("Time to insert " +
|
||||
(DbSSLSessionCache.MAX_CACHE_SIZE + 2) + " " + (t1 - t0));
|
||||
|
||||
// first entry should have port 1.
|
||||
Cursor query = helper.getReadableDatabase().query(DbSSLSessionCache.SSL_CACHE_TABLE,
|
||||
new String[] {"hostport", "session"}, null,
|
||||
null, null, null, null);
|
||||
|
||||
int cnt = query.getCount();
|
||||
|
||||
assertTrue(query.moveToFirst()); // one row inserted
|
||||
String hostPort = query.getString(0);
|
||||
assertEquals("test.host.com:2", hostPort);
|
||||
while (query.moveToNext()) {
|
||||
hostPort = query.getString(0);
|
||||
String session = query.getString(1);
|
||||
}
|
||||
long t2 = System.currentTimeMillis();
|
||||
System.err.println("Time to load " + cnt + " " + (t2 - t1));
|
||||
|
||||
query.close();
|
||||
}
|
||||
|
||||
private void makeRequestInNewContext(String url) throws IOException {
|
||||
GoogleHttpClient client = new GoogleHttpClient(getContext(), "Test",
|
||||
false /* no gzip */);
|
||||
|
||||
try {
|
||||
// Note: we must test against a real server, because the connection
|
||||
// gets established before the interceptor can crash the request.
|
||||
HttpGet method = new HttpGet(url);
|
||||
HttpResponse response = client.execute(method);
|
||||
} finally {
|
||||
client.close();
|
||||
}
|
||||
}
|
||||
|
||||
private static class MockSession implements SSLSession {
|
||||
|
||||
public String getPeerHost() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
public int getPeerPort() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public int getApplicationBufferSize() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
public String getCipherSuite() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
public long getCreationTime() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
public byte[] getId() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
public long getLastAccessedTime() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
public Certificate[] getLocalCertificates() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
public Principal getLocalPrincipal() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
public int getPacketBufferSize() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
public X509Certificate[] getPeerCertificateChain()
|
||||
throws SSLPeerUnverifiedException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
public Principal getPeerPrincipal() throws SSLPeerUnverifiedException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
public String getProtocol() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
public SSLSessionContext getSessionContext() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
public Object getValue(String name) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
public String[] getValueNames() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
public void invalidate() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
public boolean isValid() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
public void putValue(String name, Object value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
public void removeValue(String name) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed 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 com.android.unit_tests;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.provider.Checkin;
|
||||
import android.provider.Settings;
|
||||
import android.test.AndroidTestCase;
|
||||
import android.test.suitebuilder.annotation.LargeTest;
|
||||
import android.test.suitebuilder.annotation.MediumTest;
|
||||
|
||||
import com.google.android.collect.Lists;
|
||||
import com.google.android.net.GoogleHttpClient;
|
||||
|
||||
import org.apache.http.HttpException;
|
||||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.protocol.HttpContext;
|
||||
import org.apache.http.protocol.HttpRequestHandler;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/** Unit test for {@link GoogleHttpClient}. */
|
||||
public class GoogleHttpClientTest extends AndroidTestCase {
|
||||
private TestHttpServer mServer;
|
||||
private String mServerUrl;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
// Run a test server that echoes the URI back to the caller.
|
||||
mServer = new TestHttpServer();
|
||||
mServer.registerHandler("*", new HttpRequestHandler() {
|
||||
public void handle(
|
||||
HttpRequest request,
|
||||
HttpResponse response,
|
||||
HttpContext context) throws HttpException, IOException {
|
||||
String uri = request.getRequestLine().getUri();
|
||||
response.setEntity(new StringEntity(uri));
|
||||
}
|
||||
});
|
||||
|
||||
mServer.start();
|
||||
mServerUrl = "http://localhost:" + mServer.getPort() + "/";
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
if (mServer != null) mServer.shutdown();
|
||||
}
|
||||
|
||||
//
|
||||
// Fix this test to use the new mechanism to indicate that the
|
||||
// Http client is running in the UI thread
|
||||
// bug: http://b/2322326
|
||||
@LargeTest
|
||||
public void testThreadCheck() throws Exception {
|
||||
ContentResolver resolver = getContext().getContentResolver();
|
||||
GoogleHttpClient client = new GoogleHttpClient(resolver, "Test",
|
||||
false /* no gzip */);
|
||||
|
||||
try {
|
||||
// Note: we must test against a real server, because the connection
|
||||
// gets established before the interceptor can crash the request.
|
||||
HttpGet method = new HttpGet(mServerUrl);
|
||||
|
||||
// This is actually an AndroidHttpClient feature...
|
||||
// TODO: somehow test that Activity threads have the flag set?
|
||||
// Thus now uses the looper state to determine if it is in a UI
|
||||
// thread
|
||||
//AndroidHttpClient.setThreadBlocked(true);
|
||||
|
||||
try {
|
||||
client.execute(method);
|
||||
fail("\"thread forbids HTTP requests\" exception expected");
|
||||
} catch (RuntimeException e) {
|
||||
if (!e.toString().contains("forbids HTTP requests")) throw e;
|
||||
} finally {
|
||||
// AndroidHttpClient.setThreadBlocked(false);
|
||||
}
|
||||
|
||||
HttpResponse response = client.execute(method);
|
||||
assertEquals("/", EntityUtils.toString(response.getEntity()));
|
||||
} finally {
|
||||
client.close();
|
||||
}
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testUrlRewriteRules() throws Exception {
|
||||
// Don't do anything exotic; UrlRulesTest checks the actual rewriter.
|
||||
// Just make sure that URLs are, in fact, rewritten.
|
||||
|
||||
// TODO: Use a MockContentProvider/MockContentResolver instead.
|
||||
ContentResolver resolver = getContext().getContentResolver();
|
||||
GoogleHttpClient client = new GoogleHttpClient(resolver, "Test",
|
||||
false /* not gzip capable */);
|
||||
Settings.Gservices.putString(resolver,
|
||||
"url:test", "http://foo.bar/ rewrite " + mServerUrl + "new/");
|
||||
|
||||
// Update the digest, so the UrlRules cache is reloaded.
|
||||
Settings.Gservices.putString(resolver, "digest", mServerUrl);
|
||||
|
||||
try {
|
||||
HttpGet method = new HttpGet("http://foo.bar/path");
|
||||
HttpResponse response = client.execute(method);
|
||||
String body = EntityUtils.toString(response.getEntity());
|
||||
assertEquals("/new/path", body);
|
||||
} finally {
|
||||
client.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user