2016-04-17 19 views
3

Ich habe Fehlermeldung, wenn ich Push-Nachricht an APNs über PHP7 + cURL senden.PHP7, HTTP2 mit cURL

Fehlermeldung:

�@@�HTTP/2 client preface string missing or corrupt. Hex dump for received bytes: 

Ich denke, es wegen PHP7 ist aber nicht ganz sicher. mit phpinfo() kann ich sehen, dass keine mod_ssl geladen, aber aus dem Internet sagt PHP7 Unterstützung ssl von Natur aus so openssl.so ist nicht mehr im System vorhanden. Auch ist es seltsam mit phpinfo() Ich sah die openssl-Version ist 1.0.1e, die mit redhat7 kommt, nicht die, die ich von der Quelle installiert habe.

Ich installierte php7 von yum, und der Rest, OpenSSL, nghttp, rotation von der Quelle installiert.

Php Code:

$ch = curl_init(); 

curl_setopt($ch, CURLOPT_HTTP_VERSION, 3); 
//curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0); 
curl_setopt($ch, CURLOPT_URL, $url); 
curl_setopt($ch, CURLOPT_POSTFIELDS, $alert); 
curl_setopt($ch, CURLOPT_HTTPHEADER, array("apns-topic: $apns_topic")); 
curl_setopt($ch, CURLOPT_SSLCERT, $pemfile); 
curl_setopt($ch, CURLOPT_SSLCERTPASSWD, $pempwd); 
$response = curl_exec($ch); 

Der Server ist REDHAT 7. Umwelt Info wie folgt zu finden ist.

$ openssl version 
OpenSSL 1.0.2g 1 Mar 2016 

curl --version 
curl 7.48.0 (x86_64-pc-linux-gnu) libcurl/7.48.0 OpenSSL/1.0.2g nghttp2/1.9.2 
Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp 
Features: IPv6 Largefile NTLM NTLM_WB SSL TLS-SRP HTTP2 UnixSockets 

$ php --version 
PHP 7.0.5 (cli) (built: Apr 2 2016 13:08:13) (NTS) 
Copyright (c) 1997-2016 The PHP Group 
Zend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies 

$ curl --http2 -I https://nghttp2.org 
HTTP/2.0 200 
date:Sun, 17 Apr 2016 13:15:27 GMT 
content-type:text/html 
last-modified:Sat, 16 Apr 2016 14:56:04 GMT 
etag:"57125284-1a0a" 
accept-ranges:bytes 
content-length:6666 
x-backend-header-rtt:0.001459 
strict-transport-security:max-age=31536000 
server:nghttpx nghttp2/1.10.0-DEV 
via:2 nghttpx 
x-frame-options:SAMEORIGIN 
x-xss-protection:1; mode=block 
x-content-type-options:nosniff 

Auch kann ich Befehlszeile verwenden Push-Nachricht auf mein Handy senden:

curl -d '{"aps":{"alert":"test message","sound":"default"}}' --cert /xxx/xxx.pem:xxxx -H "apns-topic:chs.itsme" --http2 https://api.development.push.apple.com/3/device/85f0257xxxxx 
+0

http://stackoverflow.com/questions/34684099/new-apns-provider-api-and-php/34831873#34831873 –

+0

Vielen Dank. Ich habe diesen Beitrag gesehen, aber mein Problem nicht gelöst. –

+0

Einen neuen Link veröffentlicht, bitte sehen Sie es sich an. –

Antwort

1

Ich habe ein gleiches Problem gewesen und fand den Hauptgrund heraus ist ein certifcate der Root-CA.

Die unten ist mein env:

  • curl: 7,48
  • openssl: 1.0.2g
  • php: 5.6.18

Warum?

Der Hauptgrund ist ein Zertifikat. Insbesondere ein Zertifikat der Stammzertifizierungsstelle. Der Fehler kann auftreten, wenn er nicht vorhanden ist oder einen falschen Pfad in Ihrem System hat.

Und Sie müssen wissen, wie CURLOPT_SSL_VERIFYPEER über dieses Problem zu umgehen. Wenn Sie CURLOPT_SSL_VERIFYPEER Option undefine, wird es einen Standardwert, true haben. Mit dieser Option können Sie das SSL-Zertifikat des Endpunkthosts überprüfen, um ein Sicherheitsproblem wie man in the middle Angriff zu vermeiden. Außerdem verwendet es ein Zertifikat der Stammzertifizierungsstelle, die Ihr System während des Verifizierungsprozesses installiert hat.

Lösung 1

Check-out oder ein Zertifikat der Stammzertifizierungsstelle installieren Im Allgemeinen wird es mit einem OpenSSL installiert. Wenn Sie eine Fehlermeldung erhalten haben, wurde sie nicht im entsprechenden Pfad installiert oder existiert nicht.

So überprüfen Sie die Datei mit dem folgenden Befehl aus.

$ php -r "var_dump(openssl_get_cert_locations());"

ein Beispiel für das Ergebnis:

array(8) { 
    ["default_cert_file"]=> 
    string(38) "/usr/local/openssl-1.0.2g/ssl/cert.pem" 
    ["default_cert_file_env"]=> 
    string(13) "SSL_CERT_FILE" 
    ["default_cert_dir"]=> 
    string(35) "/usr/local/openssl-1.0.2g/ssl/certs" 
    ["default_cert_dir_env"]=> 
    string(12) "SSL_CERT_DIR" 
    ["default_private_dir"]=> 
    string(37) "/usr/local/openssl-1.0.2g/ssl/private" 
    ["default_default_cert_area"]=> 
    string(29) "/usr/local/openssl-1.0.2g/ssl" 
    ["ini_cafile"]=> 
    string(0) "" 
    ["ini_capath"]=> 
    string(0) "" 
} 

In dem oben genannten, der Standard-cert Dateipfad ist "/usr/local/openssl-1.0.2g/ssl/cert.pem" .Hätten Sie ein Zertifikat der Stammzertifizierungsstelle dort? Wenn Sie es aber in einem anderen Pfad haben, verschieben Sie es in den Standard-Cert-Dateipfad mit dem Dateinamen "cert.pem". Wenn Sie es nicht haben, müssen Sie es herunterladen, wie http://curl.haxx.se/ca/cacert.pem.

$ wget http://curl.haxx.se/ca/cacert.pem

dann in der Wegvorgabe cert-Datei verschieben.

Lösung 2

CURLOPT_SSL_VERIFYPEER => false

Diese Option kann Ihr Problem lösen. Aber es ist möglich, Ihr System gegen the man in the middle Angriff zu exponieren.