How do I send a HTTP/2 POST request in PHP
Asked Answered
S

4

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.

Spoil answered 5/1, 2016 at 8:4 Comment(0)
H
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);
Hudibrastic answered 5/1, 2016 at 10:44 Comment(4)
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.Meissner
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.Beckybecloud
@raj: that's a totally separate question, not suitable for a comment to an answer...Hudibrastic
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.Underling
N
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

Natividadnativism answered 16/1, 2016 at 20:57 Comment(4)
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.Vicereine
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.Underling
@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.Gerianne
@Underling I had the same problem until I simply restarted apache with sudo apachectl restartKrysta
T
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,
]);
Thanet answered 5/1, 2016 at 8:47 Comment(0)
W
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.

Wyn answered 1/1, 2017 at 15:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.