安全HTTP邮政安卓 [英] Secure HTTP Post in Android

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

问题描述

我有我用来做我所有的HTTP GET / POST东东pretty的基本辅助类。我使用HTTPGET,HttpPost,并HttpClient的从org.apache.http库。我所有的东西工作正常通过HTTP,但只要我试图消耗的作品通过HTTPS服务,我执行请求时得到ClientProtocolException。在异常的唯一的消息是服务器无法使用有效的HTTP响应应对。

要测试,我用一个简单的HTML表单,并使用Fiddler2的RequestBuilder发送完全相同的有效载荷从浏览器。我已经发送无效和空洞的有效载荷,甚至发送上述所有的有和无头,看看是否有一些时髦的有关对象正在构建的请求的方式。

一切我在测试中使用给了我一个有效的200状态的HTTP响应。这项服务只是给了我一个结构描述错误,如果我给它的东西比它希望其他。

有没有我需要添加到HttpPost或HttpClient的对象(S)来告诉它使用HTTPS一些特别的东西?我必须明确地告诉它使用不同的端口?

编辑:

我的确注册了错误的套接字工厂HTTPS通信。下面是我用来创建我用正确的套接字工厂,以防万一有人HttpClient的对象更新的方法搜索这类问题在未来的:

 私人HttpClient的createHttpClient()
{
    的HttpParams PARAMS =新BasicHttpParams();
    HttpProtocolParams.setVersion(参数,可以HttpVersion.HTTP_1_1);
    HttpProtocolParams.setContentCharset(参数,可以HTTP.DEFAULT_CONTENT_CHARSET);
    HttpProtocolParams.setUseExpectContinue(参数,可以真正的);

    SchemeRegistry schReg =新SchemeRegistry();
    schReg.register(新计划(HTTP,PlainSocketFactory.getSocketFactory(),80));
    schReg.register(新计划(https开头,SSLSocketFactory.getSocketFactory(),443));
    ClientConnectionManager conMgr =新ThreadSafeClientConnManager(参数,可以schReg);

    返回新DefaultHttpClient(co​​nMgr,则params);
}
 

解决方案

我不知道为什么你不能处理HTTPS。我写了一个辅助类,为我自己的应用程序,我能GET / POST到HTTPS没有问题。我将在这里发布的code,也许你可以看看是否有与我的code和你的不同之处。

 进口java.io.IOException异常;
进口的java.io.InputStream;
进口java.io.UnsupportedEncodingException;
进口java.net.HttpURLConnection中;
进口的java.net.URL;
进口java.net.URLConnection中;

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

进口android.util.Log;

公共类的Htt prequest {

    DefaultHttpClient HttpClient的;
    HttpContext的localContext;
    私人字符串RET;

    HTT presponse响应= NULL;
    HttpPost httpPost = NULL;
    HTTPGET HTTPGET = NULL;

    公众的Htt prequest(){
        的HttpParams myParams =新BasicHttpParams();

        HttpConnectionParams.setConnectionTimeout(myParams,10000);
        HttpConnectionParams.setSoTimeout(myParams,10000);
        HttpClient的=新DefaultHttpClient(myParams);
        localContext =新BasicHttpContext();
    }

    公共无效clearCookies(){
        httpClient.getCookieStore()清()。
    }

    公共无效中止(){
        尝试 {
            如果(HttpClient的!= NULL){
                的System.out.println(取消);
                httpPost.abort();
            }
        }赶上(例外五){
            的System.out.println(您的应用程序名称这里+ E);
        }
    }

    公共字符串sendPost(URL字符串,字符串数据){
        返回sendPost(URL,数据,空);
    }

    公共字符串sendJSONPost(字符串URL,JSONObject的数据){
        返回sendPost(URL,data.toString(),应用/ JSON);
    }

    公共字符串sendPost(URL字符串,字符串数据,字符串的contentType){
        RET = NULL;

        httpClient.getParams()的setParameter(ClientPNames.COOKIE_POLICY,CookiePolicy.RFC_2109)。

        httpPost =新HttpPost(URL);
        响应=无效;

        StringEntity TMP = NULL;

        Log.d(您的应用程序名称在这里,设置httpPost头);

        httpPost.setHeader(用户代理,设置您的用户代理字符串HERE);
        httpPost.setHeader(接受, "text/html,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5");

        如果(的contentType!= NULL){
            httpPost.setHeader(内容类型,则contentType);
        } 其他 {
            httpPost.setHeader(内容类型,应用程序/ x-WWW的形式urlen codeD);
        }

        尝试 {
            TMP =新StringEntity(数据,UTF-8);
        }赶上(UnsupportedEncodingException E){
            Log.e(您的应用程序名称在这里,HttpUtils:UnsupportedEncodingException:+ E);
        }

        httpPost.setEntity(TMP);

        Log.d(您的应用程序名称在这里,网址+ +数据?);

        尝试 {
            响应= httpClient.execute(httpPost,localContext);

            如果(响应!= NULL){
                RET = EntityUtils.toString(response.getEntity());
            }
        }赶上(例外五){
            Log.e(您的应用程序名称在这里,HttpUtils:+ E);
        }

        Log.d(您的应用程序名称在这里,返回值+ RET);

        返回RET;
    }

    公共字符串sendGet(字符串URL){
        HTTPGET =新HTTPGET(URL);

        尝试 {
            响应= httpClient.execute(HTTPGET);
        }赶上(例外五){
            Log.e(您的应用程序名称在这里,e.getMessage());
        }

        // INT状态= response.getStatusLine()的getStatus code();

        //我们假设响应体包含错误消息
        尝试 {
            RET = EntityUtils.toString(response.getEntity());
        }赶上(IOException异常E){
            Log.e(您的应用程序名称在这里,e.getMessage());
        }

        返回RET;
    }

    公众的InputStream getHttpStream(字符串urlString)抛出IOException异常{
        在的InputStream = NULL;
        INT响应= -1;

        网址URL =新的URL(urlString);
        URLConnection的康恩= url.openConnection();

        如果(!(康涅狄格州的instanceof的HttpURLConnection))
            抛出新的IOException异常(不是一个HTTP连接);

        尝试{
            HttpURLConnection的httpConn =(HttpURLConnection类),康涅狄格州;
            httpConn.setAllowUserInteraction(假);
            httpConn.setInstanceFollowRedirects(真正的);
            httpConn.setRequestMethod(GET);
            httpConn.connect();

            响应= httpConn.getResponse code();

            如果(响应== HttpURLConnection.HTTP_OK){
                在= httpConn.getInputStream();
            }
        }赶上(例外五){
            抛出新的IOException异常(错误连接);
        } //结束的try-catch

        返回;
    }
}
 

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".

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.

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.

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?

EDIT:

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);
}

解决方案

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;     
    }
}

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

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