【问题标题】:CURL HTTP2 request卷曲 HTTP2 请求
【发布时间】:2016-02-24 13:18:15
【问题描述】:

我想知道是否有人成功地使用 CURL 通过新的 APNS API (HTTP2) 发送了推送通知。

APNs Provider API page 上给出的示例请求

请求必须是这样的:

标题

\- END_STREAM

\+ END_HEADERS

:method = POST

:scheme = https

:path = /3/device/00fc13adff785122b4ad28809a3420982341241421348097878e577c991de8f0

host = api.development.push.apple.com

apns-id = eabeae54-14a8-11e5-b60b-1697f925ec7b

apns-expiration = 0

apns-priority = 10

content-length = 33

数据

\+ END_STREAM

{ "aps" : { "alert" : "Hello" } }

但是使用以下命令我得到错误“curl:(16)HTTP/2 流 1 没有完全关闭:error_code = 8”:

curl \

--verbose \

--http2 \

--cert <APPLICATION_CERT_FILE> \

--key <APPLICATION_KEY_FILE> \

--header "Content-Type: application/json" \

--header ":method: POST" \

--header ":path: /3/device/<DEVICE ID>" \

--data '{ "aps" : { "alert" : "Hello" } }' \

https://api.development.push.apple.com

有什么建议吗?

【问题讨论】:

    标签: curl


    【解决方案1】:

    我已使用以下方法从 cURL 成功发送推送通知:

    curl -v -d '{"aps":{"alert":"Test Push","sound":"default"}}' \
    --cert /path/to/cert/cert.pem:SECURE_PASSWORD \
    -H "apns-topic: com.app.identifier" --http2 \
    https://api.development.push.apple.com/3/device/DEVICE_ID
    

    这是使用curl版本7.48.0,由homebrew安装:

    $ curl --version
    curl 7.48.0 (x86_64-apple-darwin15.4.0) libcurl/7.48.0 OpenSSL/1.0.2g zlib/1.2.5 nghttp2/1.9.1
    Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp 
    Features: IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP HTTP2 UnixSockets 
    

    但是请注意,在生产服务器上使用我们的开发证书时,我遇到了与您相同的错误:https://api.push.apple.com/

    curl: (16) HTTP/2 流 1 未完全关闭:error_code = 8

    【讨论】:

    • 感谢您指出 dev 与 prod URL。那是我的确切问题!
    • 从 macOS High Sierra 开始,内置的“curl”命令现在支持 http2,因此您无需使用 home-brew 来安装备用“curl”。
    • 是的;我也犯了 https URL 的错误,需要 api.sandbox.push.apple.com 进行开发,
    【解决方案2】:

    基于证书的提供者身份验证

    curl -v
         -d '{"aps":{"alert":"hello"}}'
         -H "apns-topic: <your app bundle ID>" 
         --http2 
         --cert cert.pem
         https://api.push.apple.com/3/device/<device token>
    

    基于令牌的提供者身份验证

    curl -v 
         -d '{"aps":{"alert":"hello"}}'
         -H "apns-topic: <your app bundle ID>" 
         -H "authorization: bearer xxxx.yyyy.zzzz" 
         --http2
         https://api.push.apple.com/3/device/<device token>
    

    您需要生成 JWT 令牌并使用 ES256 对其进行签名。这超出了这里的范围(通过 Google 快速搜索很容易找到许多库)。

    【讨论】:

      【解决方案3】:
      1. remove --header ":method: POST" (--data 将使其使用 POST)

      2. 删除 -header ":path: /3/device/"

        :path 部分是您想要在 URL 中主机名右侧的内容,因此请指定一个 URL,例如 https://api.development.push.apple.com/3/device/&lt;DEVICE ID&gt;

      3. 也就是说,出现这样的 HTTP/2 级别的流错误是非常出乎意料的,并且宁愿在某处指示较低级别的问题...

      【讨论】:

      • 感谢您的回答。关键是在 C(推送服务器)中实现之前先尝试命令行。问题是到 api.development.push.apple.com 的连接必须首先初始化并在工作人员初始化阶段保持持久性。然后必须根据目标设备更改路径来完成请求...
      • 我无法在初始化时给出所有 URL 的列表。原因是设备 ID 根本无法提前知道,因为它是一个等待传入请求的服务器,这些请求应该包含这些 ID。甚至守护进程也会提前知道它们(但事实并非如此),有成千上万的设备正在注册/取消注册,每个 ID 都会创建自己的路径...... HTTP2 旨在保持与主主机的连接并执行查询通过这种独特的连接,使用不同的路径。为每条路径保留一个专用连接已成为过去,而 HTTP2 想要废弃的东西。
      • 关于低级错误,我注意到即使删除无效的 --header ":path..." 仍然会发生。但是使用指向有效文件的 --cert--key 选项如下: curl --verbose --http2 --cert --key --header "Content-Type: application/json" --data '{ "aps" : { "alert" : "Hello" } }' api.development.push.apple.com跨度>
      • 我无法确定问题是否来自 libnghttp2 但可以肯定的是它在以下 if 语句中输入:if(stream- >error_code != NGHTTP2_NO_ERROR)...
      • 如果我删除 --cert ...--key ... 命令最终返回服务器回复的内容: curl --verbose --http2 --header "Content-Type: application/json" --data '{ "aps" : { "alert" : "Hello" } }' api.development.push.apple.com,但当然该请求不能被处理,因为 APNS 需要客户端证书才能工作。
      猜你喜欢
      • 2018-09-20
      • 2019-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-25
      • 2021-05-31
      • 2011-04-23
      • 2019-03-31
      相关资源
      最近更新 更多