Http соединение Android - PullRequest
       3

Http соединение Android

4 голосов
/ 02 июня 2011

У меня есть приложение, которое подключается к веб-службе, использующей действующий сертификат Entrust.Разница лишь в том, что это подстановочный SSL.

Проблема в том, что я получаю

ERROR/NoHttpResponseException(5195): org.apache.http.NoHttpResponseException: The target server failed to respond

, когда я нахожусь на 3G.Когда на WIFI это работает, на симуляторе это работает, привязывая симулятор через мои телефоны, 3G работает.Но приложение на моем телефоне от 3G не работает вообще.Протестировано на HTC Legend CM7.0.3 (2.3.3) и Nexus S 2.3.3 в двух разных сетях (Virgin Mobile Canada и Fido).

У меня есть дамп PCAP с моего устройства, который показывает некоторую ошибку,но я не очень хорошо понимаю.

Номер подтверждения: Сломан TCP.Поле подтверждения является ненулевым, в то время как флаг ACK не установлен

Я попытался исправить это вопрос этот вопрос .Я не знаю, куда еще идти.

Кстати, веб-сервис работает с браузером на 3G.

Мы также используем базовую аутентификацию с HttpRequestInterceptor.

Я думаю, что это все детали, которые я могу дать.Если нужно что-то еще, не стесняйтесь спрашивать.

Этот вопрос тоже связан, я пробовал оба исправления, ни один из них не работает.

Я начинаю думать, что это может быть лучше подходит для serverfault.com

Это дамп файл и скриншот

PCAP

Редактировать 2

Это код, который я использую для подключения к рассматриваемому веб-сервису.

protected HttpEntity sendData(List<NameValuePair> pairs, String method)
            throws ClientProtocolException, IOException,
            AuthenticationException {

        pairs.add(new BasicNameValuePair(KEY_SECURITY, KEY));
        pairs.add(new BasicNameValuePair(LANG_KEY, lang));
        pairs.add(new BasicNameValuePair(OS_KEY, OS));
        pairs.add(new BasicNameValuePair(MODEL_KEY, model));
        pairs.add(new BasicNameValuePair(CARRIER_KEY, carrier));

        DefaultHttpClient client = getClient();

        HttpPost post = new HttpPost();
        try {
            post.setHeader("Content-Type", "application/x-www-form-urlencoded");
            post.setEntity(new UrlEncodedFormEntity(pairs));
        } catch (UnsupportedEncodingException e1) {
            Log.e("UnsupportedEncodingException", e1.toString());
        }

        URI uri = URI.create(method);

        post.setURI(uri);

        client.addRequestInterceptor(preemptiveAuth, 0);

        HttpHost target = new HttpHost(host, port, protocol);
        HttpContext httpContext = new BasicHttpContext();

        HttpResponse response = client.execute(target, post, httpContext);
        int statusCode = response.getStatusLine().getStatusCode();

        if (statusCode == 401) {
            throw new AuthenticationException("Invalid username or password");
        }

        return response.getEntity();
    }

Ответы [ 3 ]

2 голосов
/ 22 июня 2011

Мы наконец нашли проблему. Это не было связано с кодом.

Это был обратный DNS, время ожидания которого истекло. Поскольку я не получил никакого ответа от обратного DNS, моя сессия apache / ssl была преждевременно закрыта.

Используя DNS Google на рутированном устройстве, это сработало.

Теперь осталось только исправить наш обратный DNS.

Вот обходной путь: http://code.google.com/p/android/issues/detail?id=13117#c14

Вызовите этот метод в вашем экземпляре DefaultHttpClient или AndroidHttpClient. Это предотвратит обратный поиск DNS.

private void workAroundReverseDnsBugInHoneycombAndEarlier(HttpClient client) {
    // Android had a bug where HTTPS made reverse DNS lookups (fixed in Ice Cream Sandwich) 
    // http://code.google.com/p/android/issues/detail?id=13117
    SocketFactory socketFactory = new LayeredSocketFactory() {
        SSLSocketFactory delegate = SSLSocketFactory.getSocketFactory();
        @Override public Socket createSocket() throws IOException {
            return delegate.createSocket();
        }
        @Override public Socket connectSocket(Socket sock, String host, int port,
                InetAddress localAddress, int localPort, HttpParams params) throws IOException {
            return delegate.connectSocket(sock, host, port, localAddress, localPort, params);
        }
        @Override public boolean isSecure(Socket sock) throws IllegalArgumentException {
            return delegate.isSecure(sock);
        }
        @Override public Socket createSocket(Socket socket, String host, int port,
                boolean autoClose) throws IOException {
            injectHostname(socket, host);
            return delegate.createSocket(socket, host, port, autoClose);
        }
        private void injectHostname(Socket socket, String host) {
            try {
                Field field = InetAddress.class.getDeclaredField("hostName");
                field.setAccessible(true);
                field.set(socket.getInetAddress(), host);
            } catch (Exception ignored) {
            }
        }
    };
    client.getConnectionManager().getSchemeRegistry()
            .register(new Scheme("https", socketFactory, 443));
}
1 голос
/ 10 июня 2011

Вы пробовали решение, упомянутое в HttpClient на Android: NoHttpResponseException через UMTS / 3G ?

Копировать ниже


Я наконец избавился от этой проблемы: просто HTTP-заголовок, который был плохо обработан сервером squid в дороге:

Ожидается: 100-Continue

Кажется, он по умолчанию там, где DefaultHttpClient включенAndroid SDK.Чтобы решить эту проблему, просто добавьте это в свой код:

  HttpProtocolParams.setUseExpectContinue(httpClient.getParams(), false);
0 голосов
/ 10 июня 2011
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();

nameValuePairs.add(new BasicNameValuePair("year","1980"));

//http post

try{

        HttpClient httpclient = new DefaultHttpClient();

        HttpPost httppost = new HttpPost("http://example.com/getAllPeopleBornAfter.php");

        httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

        HttpResponse response = httpclient.execute(httppost);
        HttpEntity entity = response.getEntity();

InputStream is = entity.getContent();

}catch(Exception e){

        Log.e("log_tag", "Error in http connection "+e.toString());

}

//convert response to string

try{

BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);

        StringBuilder sb = new StringBuilder();

String line = null;

while ((line = reader.readLine()) != null) {

                sb.append(line + "n");

}

        is.close();

       result=sb.toString();

}catch(Exception e){

        Log.e("log_tag", "Error converting result "+e.toString());

}

см. Этот код для http-соединения

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...