Send Push Notification to APNS through proxy

2019-08-28 01:15发布

i've read different question similar to mine, but no answer works for me:

$deviceToken = 'token';

$passphrase = 'passphrase';

$message = 'Questa è una notifica!';

////////////////////////////////////////////////////////////////////////////////

$ctx = stream_context_create();
$options = array('http' => array('proxy' => 'tcp://proxy.net:8080', 'request_fulluri' => true));

stream_context_create($options);
stream_context_set_option($ctx, 'ssl', 'local_cert', 'cert.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);

// Open a connection to the APNS server
$fp = stream_socket_client(
    'ssl://gateway.sandbox.push.apple.com:2195', $err,
    $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);

the error is

Failed to connect: 110 Connection timed out 

i've tried to change $option value with:

$options = array('ssl' => array('proxy' => 'tcp://proxy.net:8080', 'request_fulluri' => true));

but nothing work, the proxy is absolutly minimal and direct connection are not possible.

Any suggestion about something to ask to IT division?

UPDATE

port 2195 is open

1条回答
唯我独甜
2楼-- · 2019-08-28 01:40

If your proxy support CONNECT method you need to connect first to the proxy then ask the proxy to connect you to apns server and finally switch up SSL.

$apns_settings = array(
        "host" => 'gateway.sandbox.push.apple.com',
        "port" => 2195,
        "certificate" => 'ipad.pem',
        "passphrase" => '',
);

$proxy = 'proxyhttp:8080';

$context_options = array(
        'ssl' => array(
                'local_cert' => $apns_settings["certificate"],
                'passphrase' => $apns_settings["passphrase"],
                'peer_name' => $apns_settings["host"],
                'SNI_server_name' => $apns_settings["host"],
        ),
);
$stream_context = stream_context_create($context_options);
// connection to your proxy server
$apns = stream_socket_client('tcp://'.$proxy, $error, $errorString, 2, STREAM_CLIENT_CONNECT, $stream_context);
// destination host and port must be accepted by proxy
$connect_via_proxy = "CONNECT ".$apns_settings["host"].":".$apns_settings["port"]." HTTP/1.1\r\n".
"Host: ".$apns_settings["host"].":".$apns_settings["port"]."\n".
"User-Agent: SimplePush\n".
"Proxy-Connection: Keep-Alive\n\n";
fwrite($apns,$connect_via_proxy,strlen($connect_via_proxy));
// read whole response and check successful "HTTP/1.0 200 Connection established"
if($response = fread($apns,1024)) {
        $parts = explode(' ',$response);
        if($parts[1] !== '200') { 
                die('Connection error: '.trim($response));
        } else {
                echo "R:".$response.":R\n";
        }
} else {
        die('Timeout or other error');
}
echo "Proxy opened communication...\n";
// switch to SSL encrypted communication using local certificate from $context_options
if (stream_socket_enable_crypto($apns,true,STREAM_CRYPTO_METHOD_TLS_CLIENT))
    echo "Switched to SSL OK...\n";
else
    die('some error in SSL negociation');

You can after this use the stream as normal.

Have a look at this code here: Fork of SimplePush.php

查看更多
登录 后发表回答