2012-04-27 22 views
12

私はHTTPSリクエストにHttpClientを使用しています。 ICSにアップグレードした後、一部のユーザーが3G接続で接続する際の問題を報告しています。Android:Scheme 'http'はICS 4.0.4に登録されていません。

編集:ほとんどはプロキシを使用しているようですが、プロキシを使用してローカルでT-Mobile SIMを再現できます。

ログは、このスタックトレースを持っている:

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) 

当社のエンドポイントはHTTPSのみですので、我々は意図的に私たちのSchemeRegistryでHTTPエンドポイントを登録しません。 HTTPにリダイレクトする場所(AFAIK)はありません。ここで

は、HTTPSクライアントのためのHttpClientをセットアップするコードは次のとおりです。

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; 

注:私たちは、複数のスレッド間でこのHttpClientをインスタンスを共有します。

答えて

3

問題を一部のキャリアは、4.0.4アップデートで無効なプロキシ定義を押していたということのようでした。これでHTTPSが破損しましたが、HTTPが正常に機能しました(たとえば、Google Playは機能しませんでした)。

HttpClient要求を実行してフラグを設定するときに、無効なプロキシエントリを修正する以外にも、IllegalStateExceptionをキャッチすることが考えられます。このコードはすべてのプロキシをバイパスします:

hc = new DefaultHttpClient(manager, params); 
    if (BYPASS_PROXY) 
     hc.setRoutePlanner(new DefaultHttpRoutePlanner(registry)); 
+7

BYPASS_PROXYとは何ですか?なぜ私たちはいつもこのルートプランナーを使用できませんか?このソリューションは安全です(例:httpsを使用していますか? –

+0

あなたはコードがそのトリックです。それはただ突然3G(Telenor、スウェーデン)上で私のために起こり始めた。これを常時オンにすることで潜在的な問題はありますか? – apanloco

+0

常にオンにするのに問題がありますか? –

1

私は新しいSchemeRegistryを作成しません。私は、ThreadSafeClientConnManager.getSchemeRegistry()からデフォルトのものを取ります。この方法では、すでにサポートされているすべてのスキームが含まれている可能性があります。

httpの部分は通信事業者のプロキシから取得できます。

+0

詳細を共有できますか?私は、スレッドセーフまたは単一のクライアント接続マネージャからデフォルトのスキームレジストリを取得する方法を見つけませんでした。 – apanloco

+0

どういう意味ですか? 'manager.getSchemeRegistry()'はそれを達成していませんか? – njzk2

+0

ThreadSafeClientConnManagerとSingleClientConnManagerコンストラクタ内でSchemeRegistryが必要なので、まず最初に与えたいものを返すだけです。 – apanloco

6

stacktraceから、私は両方(http、https)を登録し、それが動作しないかどうかを確認することをお勧めします。

あなたは、@ SchemeRegistry.getScheme()のトレースにドリルダウンして、Apacheソースのjarを含めてデバッグできるはずです。

Thisスレッドが役立ちます。以下は

は サンプルSSL ConnectionMgrはandroidhttpclient LIBSに... ICSにOKテストされます。

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; 
} 
関連する問題