【问题标题】:What the difference between java HttpsURLConnection and python HTTPSConnection?java HttpsURLConnection 和 python HTTPSConnection 有什么区别?
【发布时间】:2012-08-01 15:09:55
【问题描述】:

我想将开源项目android-market-api 从 java 移植到 python。但现在我陷入了 https 问题。 当我使用 HTTPSConnection 请求https://android.clients.google.com/market/api/ApiRequest 时,它总是返回 403。经过一些调试,我认为 java HttpsURLCollection 和 python HTTPSConnection 之间可能存在一些差异。

Python 端口:

headers = {
    'Cookie': 'ANDROIDSECURE=' + auth_key,
    'User-Agent': 'Android-Market/2 (sapphire PLAT-RC33); gzip',
    'Content-Type': 'application/x-www-form-urlencoded',
    'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.7',
    'Accept': 'text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2',
    'Connection': 'keep-alive'
}
conn = httplib.HTTPSConnection('android.clients.google.com')
conn.request('POST', '/market/api/ApiRequest', 'version=2&request=' + urlsafe_b64encode(data), headers)

源java代码:

TrustManager[] trustAllCerts = new TrustManager[]{
        new X509TrustManager() {
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                return null;
            }
            public void checkClientTrusted(
                java.security.cert.X509Certificate[] certs, String authType) {
            }
            public void checkServerTrusted(
                java.security.cert.X509Certificate[] certs, String authType) {
            }
        }
    };

SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier()
{
    public boolean verify(String arg0, SSLSession arg1) {
        return true;
    }
});

URL url = new URL("https://android.clients.google.com/market/api/ApiRequest");
HttpsURLConnection cnx = (HttpsURLConnection)url.openConnection();
cnx.setDoOutput(true);
cnx.setRequestMethod("POST");
cnx.setRequestProperty("Cookie","ANDROIDSECURE=" + this.getAuthSubToken());
cnx.setRequestProperty("User-Agent", "Android-Market/2 (sapphire PLAT-RC33); gzip");
cnx.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
cnx.setRequestProperty("Accept-Charset","ISO-8859-1,utf-8;q=0.7,*;q=0.7");
String request64 = Base64.encodeBytes(request,Base64.URL_SAFE);
String requestData = "version="+PROTOCOL_VERSION+"&request="+request64;
cnx.setFixedLengthStreamingMode(requestData.getBytes("UTF-8").length);
OutputStream os = cnx.getOutputStream();
os.write(requestData.getBytes());
os.close();

【问题讨论】:

  • 您需要conn.getresponse().read() 才能发出下一个请求。要生成 x-www-form-urlencoded' 内容,您可以使用:urllib.urlencode(dict(version=2, request=data))
  • 强烈建议您考虑使用 requests 而不是 httplib
  • 您应该在提出此类问题之前阅读 Javadoc,或者实际上应该阅读 Javadoc。不同之处在于它们并不相同。真的没什么好说的了。
  • @EJP:据我所知,这两个代码片段应该产生完全相同的 http 请求(即使 TLS 部分都什么都不做)。

标签: java python https


【解决方案1】:

403 表示请求成功,即"the provided credentials were successfully authenticated but that the credentials still do not grant the client permission to access the resource" 例如,没有正确的标头,我得到的正文是400 而不是403

这里有一个更完整的例子来说明如何make https request using httplib

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-02
    • 2010-09-19
    • 1970-01-01
    • 2012-09-04
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多