如何强制 CURL 要求 http/1.1?或者也许有另一个问题,不确定
我有一段代码(让我们将其命名为Code A)在一个框架中工作,我想让它在另一个框架中工作。工作代码段使用 CURL 发出成功的 POST 请求,如下所示(请求CURLOPT_VERBOSE 打开):
* Connected to android.clients.google.com (216.58.209.238) port 443 (#0)
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
* CAfile: /Applications/MAMP/Library/OpenSSL/cert.pem
CApath: none
* SSL connection using TLSv1.2 / ECDHE-ECDSA-AES128-GCM-SHA256
* ALPN, server accepted to use http/1.1
* Server certificate:
* subject: C=US; ST=California; L=Mountain View; O=Google Inc; CN=*.google.com
* start date: Jan 18 19:17:59 2017 GMT
* expire date: Apr 12 18:51:00 2017 GMT
* subjectAltName: host "android.clients.google.com" matched cert's "android.clients.google.com"
* issuer: C=US; O=Google Inc; CN=Google Internet Authority G2
* SSL certificate verify ok.
> POST /auth HTTP/1.1
Host: android.clients.google.com
Accept: */*
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Content-Length: 97
这里的http框架(yii2 / httpclient,具体来说)有太多的依赖项,无法将其引入其他项目,因此我尝试在低级别上重新创建它,如下所示(让我们将其命名为代码B):
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, 'post-data-here');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, 'https://android.clients.google.com/auth');
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type: application/x-www-form-urlencoded; charset=UTF-8"]); // just because I'm desperate
curl_setopt($ch, CURLOPT_VERBOSE, true);
$content = curl_exec($ch);
我希望有相同的结果,但这就是我得到的:
* Connected to android.clients.google.com (216.58.209.238) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
* Server certificate: *.google.com
* Server certificate: Google Internet Authority G2
* Server certificate: GeoTrust Global CA
> POST /auth HTTP/1.1
Host: android.clients.google.com
Accept: */*
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Content-Length: 97
* upload completely sent off: 97 out of 97 bytes
< HTTP/1.1 200 OK
< Content-Type: text/plain; charset=utf-8
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: Mon, 01 Jan 1990 00:00:00 GMT
< Date: Fri, 27 Jan 2017 12:07:12 GMT
< X-Content-Type-Options: nosniff
< X-Frame-Options: SAMEORIGIN
< X-XSS-Protection: 1; mode=block
< Server: GSE
< Alt-Svc: clear
< Accept-Ranges: none
< Vary: Accept-Encoding
< Transfer-Encoding: chunked
<HTML>
<HEAD>
<TITLE>HTTP Version Not Supported</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000">
<H1>HTTP Version Not Supported</H1>
<H2>Error 505</H2>
</BODY>
</HTML>
而不是有效的响应,我得到“错误505:HTTP版本不受支持”。我看到的唯一区别是工作代码尝试“ALPN,提供http / 1.1”,而后一个代码不这样做。之后是证书部分,但它从未在代码A中提及过,所以我不确定它做了什么来提供它。
两个版本的代码都运行在同一台服务器上,相同版本的 PHP (5.6) 和 CURL (7.51.0)。详细日志的差异在发送任何数据之前就开始了,所以我想这不是关于任何数据或标头设置不正确。
到目前为止,我尝试过什么(效果很少或根本没有效果):
- curl_setopt($ch,CURLOPT_SSL_ENABLE_ALPN,等等) - 不起作用,因为根本没有定义CURLOPT_SSL_ENABLE_ALPN(尽管它必须在这个版本的CURL中,不确定出了什么问题)
- curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,随便什么)
- curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,随便什么)
- curl_setopt($ch,CURLOPT_SSLVERSION,随便什么)
- 其他一些绝望的愚蠢的东西,我甚至羞于在这里展示
我试图尽可能深入地学习工作代码,但似乎它没有在简单的HTTP POST上做任何事情。我跟踪了它所做的每一个curl_setopt,似乎只有这些curl_setopt我在代码中使用,没有什么额外的。尽管如此,它的工作原理,而我的代码不起作用。
我尝试使用命令行进行相同的操作:
$ curl https://android.clients.google.com/auth -v --http1.1 -X POST --no-alpn --no-npn --data "copypasted-post-data-from-code-B-and-yes-its-urlencoded"
得到正确的结果:
* Trying 216.58.209.238...
* TCP_NODELAY set
* Connected to android.clients.google.com (216.58.209.238) port 443 (#0)
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
* CAfile: /Applications/MAMP/Library/OpenSSL/cert.pem
CApath: none
...
> POST /auth HTTP/1.1
> Host: android.clients.google.com
> User-Agent: curl/7.51.0
> Accept: */*
> Content-Length: 97
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 97 out of 97 bytes
< HTTP/1.1 200 OK
< Content-Type: text/plain; charset=utf-8
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: Mon, 01 Jan 1990 00:00:00 GMT
< Date: Fri, 27 Jan 2017 13:22:27 GMT
< X-Content-Type-Options: nosniff
< X-Frame-Options: SAMEORIGIN
< X-XSS-Protection: 1; mode=block
< Server: GSE
< Alt-Svc: clear
< Accept-Ranges: none
< Vary: Accept-Encoding
< Transfer-Encoding: chunked
<
SID=BAD_COOKIE
LSID=BAD_COOKIE
Auth=here-s-the-data-i-need