Android 中的安全 HTTP Post [英] Secure HTTP Post in Android

查看:22
本文介绍了Android 中的安全 HTTP Post的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个非常基本的帮助类,我用它来做我所有的 Http Get/Post 东西.我正在使用 org.apache.http 库中的 HttpGet、HttpPost 和 HttpClient.我所有的东西都可以通过 HTTP 正常工作,但是一旦我尝试使用通过 HTTPS 工作的服务,我在执行请求时就会收到 ClientProtocolException.异常中唯一的消息是服务器未能以有效的 HTTP 响应进行响应".

I have a pretty basic helper class that I'm using to do all my Http Get/Post stuff. I'm using HttpGet, HttpPost, and HttpClient from the org.apache.http library. All of my stuff works fine over HTTP, but as soon as I tried to consume a service that works over HTTPS, I get a ClientProtocolException when executing the request. The only message in the exception is "The server failed to respond with a valid HTTP response".

为了测试,我使用简单的 html 表单和 Fiddler2 使用 RequestBuilder 从浏览器发送了完全相同的有效负载.我发送了无效和空的有效负载,甚至发送了上述所有带有和不带标头的内容,以查看对象构建请求的方式是否有什么奇怪的地方.

To test, I sent the exact same payload from a browser using a simple html form and Fiddler2 using the RequestBuilder. I've sent invalid and empty payloads and even sent all of the above with and without headers to see if there was something funky about the way the objects were building the request.

我在测试中使用的所有内容都为我提供了有效的 200 状态 HTTP 响应.如果我给它的不是它期望的东西,该服务只会给我一个描述错误的结构.

Everything I've used in testing gives me a valid 200 status HTTP response. The service just gives me a structure describing the error if I give it something other than what it expects.

是否需要向 HttpPost 或 HttpClient 对象添加一些特别的东西来告诉它使用 HTTPS?我是否必须明确告诉它使用不同的端口?

Is there something special I need to add to the HttpPost or HttpClient object(s) to tell it to use HTTPS? Do I have to explicitly tell it to use a different port?

我确实为 https 通信注册了错误的套接字工厂.这是我用来使用正确的套接字工厂创建 HttpClient 对象的更新方法,以防将来有人搜索此类问题:

I indeed registered the wrong socket factory for https communication. Here is the updated method that I use to create my HttpClient object with the correct socket factory just in case someone searches this kind of problem in the future:

private HttpClient createHttpClient()
{
    HttpParams params = new BasicHttpParams();
    HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
    HttpProtocolParams.setContentCharset(params, HTTP.DEFAULT_CONTENT_CHARSET);
    HttpProtocolParams.setUseExpectContinue(params, true);

    SchemeRegistry schReg = new SchemeRegistry();
    schReg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
    schReg.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
    ClientConnectionManager conMgr = new ThreadSafeClientConnManager(params, schReg);

    return new DefaultHttpClient(conMgr, params);
}

推荐答案

我不知道你为什么不能处理 HTTPS.我为自己的应用程序编写了一个帮助程序类,并且可以毫无问题地 GET/POST 到 HTTPS.我会把代码贴在这里,也许你可以看看我的代码和你的代码是否有差异.

I'm not sure why you can't handle HTTPS. I wrote a helper class for my own applications and I am able to GET/POST to HTTPS without a problem. I will post the code here and perhaps you can see if there are differences between my code and yours.

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.params.ClientPNames;
import org.apache.http.client.params.CookiePolicy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import org.json.JSONObject;

import android.util.Log;

public class HttpRequest{

    DefaultHttpClient httpClient;
    HttpContext localContext;
    private String ret;

    HttpResponse response = null;
    HttpPost httpPost = null;
    HttpGet httpGet = null;

    public HttpRequest(){
        HttpParams myParams = new BasicHttpParams();

        HttpConnectionParams.setConnectionTimeout(myParams, 10000);
        HttpConnectionParams.setSoTimeout(myParams, 10000);
        httpClient = new DefaultHttpClient(myParams);       
        localContext = new BasicHttpContext();    
    }

    public void clearCookies() {
        httpClient.getCookieStore().clear();
    }

    public void abort() {
        try {
            if (httpClient != null) {
                System.out.println("Abort.");
                httpPost.abort();
            }
        } catch (Exception e) {
            System.out.println("Your App Name Here" + e);
        }
    }

    public String sendPost(String url, String data) {
        return sendPost(url, data, null);
    }

    public String sendJSONPost(String url, JSONObject data) {
        return sendPost(url, data.toString(), "application/json");
    }

    public String sendPost(String url, String data, String contentType) {
        ret = null;

        httpClient.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.RFC_2109);

        httpPost = new HttpPost(url);
        response = null;

        StringEntity tmp = null;        

        Log.d("Your App Name Here", "Setting httpPost headers");

        httpPost.setHeader("User-Agent", "SET YOUR USER AGENT STRING HERE");
        httpPost.setHeader("Accept", "text/html,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5");

        if (contentType != null) {
            httpPost.setHeader("Content-Type", contentType);
        } else {
            httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
        }

        try {
            tmp = new StringEntity(data,"UTF-8");
        } catch (UnsupportedEncodingException e) {
            Log.e("Your App Name Here", "HttpUtils : UnsupportedEncodingException : "+e);
        }

        httpPost.setEntity(tmp);

        Log.d("Your App Name Here", url + "?" + data);

        try {
            response = httpClient.execute(httpPost,localContext);

            if (response != null) {
                ret = EntityUtils.toString(response.getEntity());
            }
        } catch (Exception e) {
            Log.e("Your App Name Here", "HttpUtils: " + e);
        }

        Log.d("Your App Name Here", "Returning value:" + ret);

        return ret;
    }

    public String sendGet(String url) {
        httpGet = new HttpGet(url);  

        try {
            response = httpClient.execute(httpGet);  
        } catch (Exception e) {
            Log.e("Your App Name Here", e.getMessage());
        }

        //int status = response.getStatusLine().getStatusCode();  

        // we assume that the response body contains the error message  
        try {
            ret = EntityUtils.toString(response.getEntity());  
        } catch (IOException e) {
            Log.e("Your App Name Here", e.getMessage());
        }

        return ret;
    }

    public InputStream getHttpStream(String urlString) throws IOException {
        InputStream in = null;
        int response = -1;

        URL url = new URL(urlString); 
        URLConnection conn = url.openConnection();

        if (!(conn instanceof HttpURLConnection))                     
            throw new IOException("Not an HTTP connection");

        try{
            HttpURLConnection httpConn = (HttpURLConnection) conn;
            httpConn.setAllowUserInteraction(false);
            httpConn.setInstanceFollowRedirects(true);
            httpConn.setRequestMethod("GET");
            httpConn.connect(); 

            response = httpConn.getResponseCode();                 

            if (response == HttpURLConnection.HTTP_OK) {
                in = httpConn.getInputStream();                                 
            }                     
        } catch (Exception e) {
            throw new IOException("Error connecting");            
        } // end try-catch

        return in;     
    }
}

这篇关于Android 中的安全 HTTP Post的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆