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 Spiral\RoadRunner\Worker;
use Zend\Diactoros\ServerRequest;
use Zend\Diactoros\Stream;
use Zend\Diactoros\UploadedFile;
/**
* Spiral Framework, SpiralScout LLC.
*
* @package spiralFramework
* @author Anton Titov (Wolfy-J)
* @copyright ©2009-2011
*/
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 Stream("php://memory", "rwb");
$bodyStream->write($body);
}
return new 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)
{
$this->worker->send($response->getBody(), json_encode([
'status' => $response->getStatusCode(),
'headers' => $response->getHeaders()
]));
}
/**
* 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] = new UploadedFile(
$file['tmpName'],
$file['size'],
$file['error'],
$file['name'],
$file['type']
);
continue;
}
$result[$index] = $this->wrapUploads($file);
}
return $result;
}
}
|