20

I found a similar question at Sending HTTP/2 POST request in Ruby But I want to update my server with PHP

The new Apple push notification HTTP/2 based API described here: https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/APNsProviderAPI.html

Anyone with HTTP/2 experience help me with making a request as a client in PHP.

Community
  • 1
  • 1
mthuong
  • 407
  • 1
  • 5
  • 13

4 Answers4

23

The CURL extension for PHP >= 5.5.24 has support for HTTP/2. (since this commit)

You also need a libcurl installed — the underlying library that the curl functions use — with HTTP/2 support enabled. That means a libcurl newer than 7.38.0 but really, the newer the better. Libcurl has to have been built with HTTP/2 support explicitly enabled, using the --with-nghttp2 flag at compile time.

Just use curl as you'd normally use it, and set the CURLOPT_HTTP_VERSION option to use HTTP/2 by passing in CURL_HTTP_VERSION_2_0. Then you'll get the request upgraded to version 2 if the client and server both support it.

Prior to PHP 5.5.24, if libcurl has been built with HTTP/2 support, you can pass in the int value of CURL_HTTP_VERSION_2_0 explicitly as PHP will still pass it through to libcurl. Currently, it has a value of 3 — this should not change, but could.

if (!defined('CURL_HTTP_VERSION_2_0')) {
    define('CURL_HTTP_VERSION_2_0', 3);
}

$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
Daniel Stenberg
  • 54,736
  • 17
  • 146
  • 222
  • I tried installing both versions 5.6.21 and 7.0.6 of XAMPP on both Mac and Linux, but I'm always getting this error: `HTTP/2 client preface string missing or corrupt. Hex dump for received bytes ...`. Do you know how I can solve this? I'm able to send push notifications from the command line, but in PHP it doesn't work. – Nickkk Jun 26 '16 at 10:28
  • I would like to understand if push notifications with HTTP/2 and curl 7.38.0 will work in shared hosting environment? Previously shared hosting providers would block ports 2195 and 2196 due to security reasons hence push notification using TCP socket would not be possible. – Raj Pawan Gumdal Jun 29 '16 at 18:54
  • 1
    @raj: that's a totally separate question, not suitable for a comment to an answer... – Daniel Stenberg Jun 30 '16 at 06:49
  • This also requires openSSL 1.0.2 which is not available via yum update on centOS 6, even though 1.0.1 is now 5 years old and counting. – andreszs Sep 01 '17 at 14:04
6

Having PHP >= 5.5.24 is not enough to make a HTTP/2 request with curl, even if CURL_HTTP_VERSION_2_0 is defined. You will get an error message like the following if you try to make a request to APNS (Apple Push Notification Service):

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

Since curl is a binding for libcurl, you must also have curl with http/2 enabled.

For a sample code, see my answer to a similar question here on SO

For install procedure, you can follow this tutorial

Community
  • 1
  • 1
tiempor3al
  • 449
  • 3
  • 6
  • 1
    thanks! This worked. Though I checked the request headers using `CURLINFO_HEADER_OUT` and it shows `HTTP/1.1`. But it's working now, where it wasn't working before. – andho Aug 12 '16 at 04:36
  • 1
    I have PHP 5.6, curl 7.54 (with HTTP2 support) and OpenSSL 1.0.1 yet `CURL_HTTP_VERSION_2_0` is still undefined, any ideas why? Apple returns an `Unexpected HTTP/1.x request` error message when attempting to connect. – andreszs Aug 03 '17 at 16:45
  • 1
    @Andrew check that your curl OpenSSL version is above 1.0.1. I ended up needlessly recompiling my PHP version to finally discover that Apple APNs require a never version of TLS. – Larcho Aug 10 '17 at 22:14
  • @andreszs I had the same problem until I simply restarted apache with `sudo apachectl restart` – tharkay Dec 28 '17 at 12:53
2

At the current moment there is no direct HTTP/2 support in PHP.

There is an idea to add such a support in the future direct to PHP: https://wiki.php.net/ideas/php6#http2_support

The 3rd Party library Guzzle https://github.com/guzzle/guzzle supports HTTP/2, if the correct php and curl version are installed:

use GuzzleHttp\Client;

$client = new Client();
$client->get('https://http2.akamai.com/demo/tile-0.png', [
    'version' => 2.0,
    'debug' => true,
]);
Gennadiy Litvinyuk
  • 1,536
  • 12
  • 21
0

Check out the Apache and CLI PHP Docker images I built for this purpose that add HTTP/2 support to the official PHP 5.6 docker library. This gets rid of any HTTP/2 client preface string missing or corrupt errors.

Once you have the right environment, having tried several JWS/JWT libraries for PHP I only found Spomky-Labs/jose to work perfectly with APNs.

Norbert
  • 21
  • 3