-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy pathSocket.php
119 lines (96 loc) · 3.53 KB
/
Socket.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
<?php
namespace Racecore\GATracking\Client\Adapter;
use Racecore\GATracking\Client;
use Racecore\GATracking\Exception;
use Racecore\GATracking\Request;
class Socket extends Client\AbstractClientAdapter
{
private $connection = null;
/**
* Create Connection to the Google Server
* @param $endpoint
* @throws Exception\EndpointServerException
*/
private function createConenction($endpoint)
{
// port
$port = $this->getOption('ssl') == true ? 443 : 80;
// connect
$connection = @fsockopen($port == 443 ? 'ssl://' . $endpoint['host'] : $endpoint['host'], $port, $error, $errorMessage, 10);
if (!$connection || $error) {
throw new Exception\EndpointServerException('Analytics Host not reachable! Error:' . $errorMessage);
}
if ($this->getOption('async')) {
stream_set_blocking($connection, 0);
}
$this->connection = $connection;
}
/**
* Write the connection header
* @param $endpoint
* @param Request\TrackingRequest $request
* @param bool $lastData
* @return string
* @throws Exception\EndpointServerException
*/
private function writeHeader($endpoint, Request\TrackingRequest $request, $lastData = false)
{
// create data
$payloadString = http_build_query($request->getPayload());
$payloadLength = strlen($payloadString);
$header = 'POST ' . $endpoint['path'] . ' HTTP/1.1' . "\r\n" .
'Host: ' . $endpoint['host'] . "\r\n" .
'User-Agent: Google-Measurement-PHP-Client' . "\r\n" .
'Content-Length: ' . $payloadLength . "\r\n" .
($lastData ? 'Connection: Close' . "\r\n" : '') . "\r\n";
// fwrite + check if fwrite was ok
if (!fwrite($this->connection, $header) || !fwrite($this->connection, $payloadString)) {
throw new Exception\EndpointServerException('Server closed connection unexpectedly');
}
return $header;
}
/**
* Read from the current connection
* @param Request\TrackingRequest $request
* @return array|false
*/
private function readConnection(Request\TrackingRequest $request)
{
if ($this->getOption('async')) {
return false;
}
// response
$response = '';
// receive response
while (!feof($this->connection)) {
$response .= fread($this->connection, 8192);
}
// response
$responseContainer = explode("\r\n\r\n", $response, 2);
return explode("\r\n", $responseContainer[0]);
}
/**
* Send the Request Collection to a Server
* @param $url
* @param Request\TrackingRequestCollection $requestCollection
* @return Request\TrackingRequestCollection|void
* @throws Exception\EndpointServerException
*/
public function send($url, Request\TrackingRequestCollection $requestCollection)
{
// get endpoint
$endpoint = parse_url($url);
$this->createConenction($endpoint);
/** @var Request\TrackingRequest $request */
while ($requestCollection->valid()) {
$request = $requestCollection->current();
$requestCollection->next();
$this->writeHeader($endpoint, $request, !$requestCollection->valid());
$responseHeader = $this->readConnection($request);
$request->setResponseHeader($responseHeader);
}
// connection close
fclose($this->connection);
return $requestCollection;
}
}