Android: Esquema 'http' no registrado en ICS 4.0.4 con proxy
Estoy utilizando HttpClient para HTTPS peticiones, que ha funcionado bien hasta ahora. Después de actualizar a ICS, algunos usuarios reportan problemas de conexión en las conexiones 3G.
EDIT: La mayoría de ellos parecen estar usando un proxy, y puedo reproducirlo localmente con un T-Mobile SIM usando su proxy.
- ¿Por qué el agente de usuario se envía como "Apache-HttpClient / UNAVAILABLE (java 1.4)"
- Cómo cambiar de HttpClient a HttpUrlConnection
- Java.lang.NoSuchFieldError: org.apache.http.message.BasicLineFormatter.INSTANCE
- Cómo utilizar DefaultHttpClient en Android?
- Android: excepción no captada lanzada por el finalizador
Los registros tienen este seguimiento de pila:
java.lang.IllegalStateException: Scheme 'http' not registered. org.apache.http.conn.scheme.SchemeRegistry.getScheme(SchemeRegistry.java:80) org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:126) org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164) org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119) org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360) org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555) org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487) org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
Nuestro punto final es HTTPS solamente, por lo que no se registra un punto final HTTP en nuestro SchemeRegistry a propósito. No hay ningún lugar (AFAIK) donde se redirija a HTTP.
Aquí está el código que configura el HttpClient para el cliente HTTPS:
DefaultHttpClient ret = null; // sets up parameters HttpParams params = new BasicHttpParams(); HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); HttpProtocolParams.setContentCharset(params, "utf-8"); params.setBooleanParameter("http.protocol.expect-continue", false); HttpConnectionParams.setConnectionTimeout(params, DEFAULT_CONN_TIMEOUT_MSEC); HttpConnectionParams.setSoTimeout(params, timeoutMsec); HttpConnectionParams.setStaleCheckingEnabled(params, true); SchemeRegistry registry = new SchemeRegistry(); final SocketFactory sslSocketFactory = getPreferredSSLSocketFactory(); registry.register(new Scheme("https", sslSocketFactory, 443)); ThreadSafeClientConnManager manager = new ThreadSafeClientConnManager(params, registry); ret = new DefaultHttpClient(manager, params); // for preemptive authentication // http://dlinsin.blogspot.com/2009/08/http-basic-authentication-with-android.html ret.addRequestInterceptor(preemptiveAuth, 0); ret.setCookieStore(communalCookieJar); SimpleCredentialsProvider credProvider = new SimpleCredentialsProvider(getAccountPreferences()); ret.setCredentialsProvider(credProvider); return ret;
Nota: Compartimos esta instancia de HttpClient entre múltiples subprocesos.
- Solicitud de aplicaciones para Android Servicio WCF (SerializationException - utf-8 related)
- HttpClientBuilder falta en Android?
- WebView con cliente HTTP personalizado
- Proyecto de Android que utiliza httpclient -> http.client (apache), método post / get
- Problema de compilación de Gradle: actualización de Quickblox y httpclient en el último SDK23 de Android
- Android HttpClient, DefaultHttpClient, HttpPost
- ¿Cuál es la forma estándar de publicar el objeto JSON junto con el archivo utilizando MultipartEntityBuilder y el cliente HTTP en Android
- Android Rest Client
De su stacktrace, sugeriría que registre ambos (http, https) y vea si eso no funciona.
Usted debe ser capaz de depurarlo mediante la inclusión de jarras de fuente de apache – profundizar en la traza @ SchemeRegistry.getScheme ().
Este hilo puede ayudar.
A continuación se comprueba que está bien en ICS … Sample SSL ConnectionMgr en androidhttpclient libs:
static X509TrustManager tm = new X509TrustManager() { public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException { } public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException { } public X509Certificate[] getAcceptedIssuers() { return null; } }; MyConnectionManager(SchemeRegistry scheme){ super(scheme); } public static MyConnectionManager getInstance() { if (instance == null){ SSLContext ctx=null; try { ctx = SSLContext.getInstance("TLS"); ctx.init(null, new TrustManager[]{tm}, null); } catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (KeyManagementException e) { // TODO Auto-generated catch block e.printStackTrace(); } SchemeRegistry schemeRegistry = new SchemeRegistry(); schemeRegistry.register( new Scheme("http", 80,PlainSocketFactory.getSocketFactory())); schemeRegistry.register(new Scheme("https", 443, SSLSocketFactory.getSocketFactory())); instance = new MyConnectionManager(schemeRegistry); // Increase max total connection to 200 instance.setMaxTotal(15); // Increase default max connection per route to 20 instance.setDefaultMaxPerRoute(15); // Increase max connections for localhost:80 to 50 HttpHost localhost = new HttpHost("picasaweb.google.com", 443); instance.setMaxForRoute(new HttpRoute(localhost), 10); } return instance; }
El problema parecía ser que algunas compañías empujaban definiciones de proxy no válidas con la actualización 4.0.4. Esto rompió HTTPS pero HTTP funcionó correctamente (Google Play no funcionó, por ejemplo).
Una posible solución (además de arreglar la entrada de proxy no válida) es capturar IllegalStateException al realizar solicitudes HttpClient y establecer un indicador. Este código omitirá cualquier proxies:
hc = new DefaultHttpClient(manager, params); if (BYPASS_PROXY) hc.setRoutePlanner(new DefaultHttpRoutePlanner(registry));
No crearía un nuevo SchemeRegistry. Tomaría el predeterminado de ThreadSafeClientConnManager.getSchemeRegistry (). De esta forma, probablemente contiene todo tipo de esquemas ya compatibles.
La parte http puede provenir del proxy de su operador.