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
|
<?php
declare(strict_types=1);
namespace OpenTelemetry\SDK\Common\Export\Stream;
use ErrorException;
use function fopen;
use function implode;
use function is_resource;
use LogicException;
use OpenTelemetry\SDK\Common\Export\TransportFactoryInterface;
use OpenTelemetry\SDK\Common\Export\TransportInterface;
use function restore_error_handler;
use function set_error_handler;
use function sprintf;
use function stream_context_create;
/**
* @psalm-internal \OpenTelemetry
*/
final class StreamTransportFactory implements TransportFactoryInterface
{
/**
* @param string|resource $endpoint
* @param array<string, string|string[]> $headers
* @param string|string[]|null $compression
*
* @psalm-template CONTENT_TYPE of string
* @psalm-param CONTENT_TYPE $contentType
* @psalm-return TransportInterface<CONTENT_TYPE>
*/
public function create(
$endpoint,
string $contentType,
array $headers = [],
$compression = null,
float $timeout = 10.,
int $retryDelay = 100,
int $maxRetries = 3,
?string $cacert = null,
?string $cert = null,
?string $key = null
): TransportInterface {
assert(!empty($endpoint));
$stream = is_resource($endpoint)
? $endpoint
: self::createStream(
$endpoint,
$contentType,
$headers,
$timeout,
$cacert,
$cert,
$key,
);
return new StreamTransport($stream, $contentType);
}
/**
* @throws ErrorException
* @return resource
*/
private static function createStream(
string $endpoint,
string $contentType,
array $headers = [],
float $timeout = 10.,
?string $cacert = null,
?string $cert = null,
?string $key = null
) {
$context = stream_context_create([
'http' => [
'method' => 'POST',
'header' => self::createHeaderArray($contentType, $headers),
'timeout' => $timeout,
],
'ssl' => [
'cafile' => $cacert,
'local_cert' => $cert,
'local_pk' => $key,
],
]);
set_error_handler(static function (int $errno, string $errstr, string $errfile, int $errline): bool {
throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
});
/**
* @psalm-suppress PossiblyNullArgument
*/
try {
$stream = fopen($endpoint, 'ab', false, $context);
} finally {
restore_error_handler();
}
/** @phan-suppress-next-line PhanPossiblyUndeclaredVariable */
if (!$stream) {
throw new LogicException(sprintf('Failed opening stream "%s"', $endpoint));
}
return $stream;
}
private static function createHeaderArray(string $contentType, array $headers): array
{
$header = [];
$header[] = sprintf('Content-Type: %s', $contentType);
foreach ($headers as $name => $value) {
$header[] = sprintf('%s: %s', $name, implode(', ', (array) $value));
}
return $header;
}
}
|