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
120
121
122
123
124
125
126
127
128
129
130
131
132
|
<?php
/**
* High-performance PHP process supervisor and load balancer written in Go
*
* @author Wolfy-J
*/
namespace Spiral\RoadRunner;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Zend\Diactoros;
/**
* Manages PSR-7 request and response.
*/
class PSR7Client
{
/**
* @varWorker
*/
private $worker;
/**
* @param Worker $worker
*/
public function __construct(Worker $worker)
{
$this->worker = $worker;
}
/**
* @return Worker
*/
public function getWorker(): Worker
{
return $this->worker;
}
/**
* @return ServerRequestInterface|null
*/
public function acceptRequest()
{
$body = $this->worker->receive($ctx);
if (empty($body) && empty($ctx)) {
// termination request
return null;
}
if (empty($ctx = json_decode($ctx, true))) {
// invalid context
return null;
}
parse_str($ctx['rawQuery'], $query);
$bodyStream = 'php://input';
$parsedBody = null;
if ($ctx['parsed']) {
$parsedBody = json_decode($body, true);
} elseif ($body != null) {
$bodyStream = new Diactoros\Stream("php://memory", "rwb");
$bodyStream->write($body);
}
return new Diactoros\ServerRequest(
$_SERVER,
$this->wrapUploads($ctx['uploads']),
$ctx['uri'],
$ctx['method'],
$bodyStream,
$ctx['headers'],
$ctx['cookies'],
$query,
$parsedBody,
$ctx['protocol']
);
}
/**
* Send response to the application server.
*
* @param ResponseInterface $response
*/
public function respond(ResponseInterface $response)
{
$headers = $response->getHeaders();
if (empty($headers)) {
// this is required to represent empty header set as map and not as array
$headers = new \stdClass();
}
$this->worker->send($response->getBody(), json_encode([
'status' => $response->getStatusCode(),
'headers' => $headers
]));
}
/**
* Wraps all uploaded files with UploadedFile.
*
* @param array $files
*
* @return array
*/
private function wrapUploads($files): array
{
if (empty($files)) {
return [];
}
$result = [];
foreach ($files as $index => $file) {
if (!isset($file['name'])) {
$result[$index] = $this->wrapUploads($file);
continue;
}
$result[$index] = new Diactoros\UploadedFile(
$file['tmpName'],
$file['size'],
$file['error'],
$file['name'],
$file['type']
);
}
return $result;
}
}
|