Passed
Push — master ( b78470...9f52d0 )
by Biao
03:56 queued 50s
created

LaravelS::setOutputStyle()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Hhxsv5\LaravelS;
4
5
use Hhxsv5\LaravelS\Illuminate\Laravel;
6
use Hhxsv5\LaravelS\Swoole\DynamicResponse;
7
use Hhxsv5\LaravelS\Swoole\Events\WorkerStartInterface;
8
use Hhxsv5\LaravelS\Swoole\Request;
9
use Hhxsv5\LaravelS\Swoole\Server;
10
use Hhxsv5\LaravelS\Swoole\StaticResponse;
11
use Hhxsv5\LaravelS\Swoole\Traits\CustomProcessTrait;
12
use Hhxsv5\LaravelS\Swoole\Traits\InotifyTrait;
13
use Hhxsv5\LaravelS\Swoole\Traits\LaravelTrait;
14
use Hhxsv5\LaravelS\Swoole\Traits\LogTrait;
15
use Hhxsv5\LaravelS\Swoole\Traits\ProcessTitleTrait;
16
use Hhxsv5\LaravelS\Swoole\Traits\TimerTrait;
17
use Illuminate\Http\Request as IlluminateRequest;
18
use Swoole\Http\Request as SwooleRequest;
19
use Swoole\Http\Response as SwooleResponse;
20
use Swoole\Http\Server as HttpServer;
21
use Swoole\WebSocket\Server as WebSocketServer;
22
use Symfony\Component\Console\Style\OutputStyle;
23
use Symfony\Component\HttpFoundation\BinaryFileResponse;
24
25
26
/**
27
 * Swoole Request => Laravel Request
28
 * Laravel Request => Laravel handle => Laravel Response
29
 * Laravel Response => Swoole Response
30
 */
31
class LaravelS extends Server
32
{
33
    /**
34
     * Fix conflicts of traits
35
     */
36
    use InotifyTrait, LaravelTrait, LogTrait, ProcessTitleTrait, TimerTrait, CustomProcessTrait {
0 ignored issues
show
Bug introduced by
The trait Hhxsv5\LaravelS\Swoole\Traits\CustomProcessTrait requires the property $pid which is not provided by Hhxsv5\LaravelS\LaravelS.
Loading history...
Bug introduced by
The trait Hhxsv5\LaravelS\Swoole\Traits\TimerTrait requires the property $pid which is not provided by Hhxsv5\LaravelS\LaravelS.
Loading history...
37
        LogTrait::log insteadof InotifyTrait, TimerTrait, CustomProcessTrait;
38
        LogTrait::logException insteadof InotifyTrait, TimerTrait, CustomProcessTrait;
39
        LogTrait::trace insteadof InotifyTrait, TimerTrait, CustomProcessTrait;
40
        LogTrait::info insteadof InotifyTrait, TimerTrait, CustomProcessTrait;
41
        LogTrait::warning insteadof InotifyTrait, TimerTrait, CustomProcessTrait;
42
        LogTrait::error insteadof InotifyTrait, TimerTrait, CustomProcessTrait;
43
        LogTrait::callWithCatchException insteadof InotifyTrait, TimerTrait, CustomProcessTrait;
44
        ProcessTitleTrait::setProcessTitle insteadof InotifyTrait, TimerTrait, CustomProcessTrait;
45
        LaravelTrait::initLaravel insteadof TimerTrait, CustomProcessTrait;
46
    }
47
48
    protected $laravelConf;
49
50
    /**
51
     * @var Laravel $laravel
52
     */
53
    protected $laravel;
54
55
    public function __construct(array $svrConf, array $laravelConf)
56
    {
57
        parent::__construct($svrConf);
58
        $this->laravelConf = $laravelConf;
59
60
        $timerCfg = isset($this->conf['timer']) ? $this->conf['timer'] : [];
61
        $timerCfg['process_prefix'] = $svrConf['process_prefix'];
62
        $this->swoole->timerProcess = $this->addTimerProcess($this->swoole, $timerCfg, $this->laravelConf);
0 ignored issues
show
Bug introduced by
The property timerProcess does not seem to exist on Swoole\Http\Server.
Loading history...
Bug introduced by
The property timerProcess does not seem to exist on Swoole\WebSocket\Server.
Loading history...
63
64
        $inotifyCfg = isset($this->conf['inotify_reload']) ? $this->conf['inotify_reload'] : [];
65
        if (!isset($inotifyCfg['watch_path'])) {
66
            $inotifyCfg['watch_path'] = $this->laravelConf['root_path'];
67
        }
68
        $inotifyCfg['process_prefix'] = $svrConf['process_prefix'];
69
        $this->swoole->inotifyProcess = $this->addInotifyProcess($this->swoole, $inotifyCfg);
0 ignored issues
show
Bug introduced by
The property inotifyProcess does not seem to exist on Swoole\Http\Server.
Loading history...
Bug introduced by
The property inotifyProcess does not seem to exist on Swoole\WebSocket\Server.
Loading history...
70
71
        $processes = isset($this->conf['processes']) ? $this->conf['processes'] : [];
72
        $this->swoole->customProcesses = $this->addCustomProcesses($this->swoole, $svrConf['process_prefix'], $processes, $this->laravelConf);
0 ignored issues
show
Bug introduced by
The property customProcesses does not seem to exist on Swoole\Http\Server.
Loading history...
Bug introduced by
The property customProcesses does not seem to exist on Swoole\WebSocket\Server.
Loading history...
73
    }
74
75
    protected function bindWebSocketEvent()
76
    {
77
        parent::bindWebSocketEvent();
78
79
        if ($this->enableWebSocket) {
80
            $eventHandler = function ($method, array $params) {
81
                $this->callWithCatchException(function () use ($method, $params) {
82
                    call_user_func_array([$this->getWebSocketHandler(), $method], $params);
83
                });
84
            };
85
86
            $this->swoole->on('Open', function (WebSocketServer $server, SwooleRequest $request) use ($eventHandler) {
87
                // Start Laravel's lifetime, then support session ...middleware.
88
                $laravelRequest = $this->convertRequest($this->laravel, $request);
89
                $this->laravel->bindRequest($laravelRequest);
90
                $this->laravel->handleDynamic($laravelRequest);
91
                $eventHandler('onOpen', func_get_args());
92
                $this->laravel->saveSession();
93
                $this->laravel->cleanSession();
94
            });
95
        }
96
    }
97
98
    public function onWorkerStart(HttpServer $server, $workerId)
99
    {
100
        parent::onWorkerStart($server, $workerId);
101
102
        // To implement gracefully reload
103
        // Delay to create Laravel
104
        // Delay to include Laravel's autoload.php
105
        $this->laravel = $this->initLaravel($this->laravelConf, $this->swoole);
106
107
        // Fire workerStart event
108
        $this->fireEvent('workerStart', WorkerStartInterface::class, func_get_args());
109
    }
110
111
    protected function convertRequest(Laravel $laravel, SwooleRequest $request)
112
    {
113
        $rawGlobals = $laravel->getRawGlobals();
114
        $server = isset($rawGlobals['_SERVER']) ? $rawGlobals['_SERVER'] : [];
115
        $env = isset($rawGlobals['_ENV']) ? $rawGlobals['_ENV'] : [];
116
        return (new Request($request))->toIlluminateRequest($server, $env);
117
    }
118
119
    public function onRequest(SwooleRequest $swooleRequest, SwooleResponse $swooleResponse)
120
    {
121
        try {
122
            parent::onRequest($swooleRequest, $swooleResponse);
123
            $laravelRequest = $this->convertRequest($this->laravel, $swooleRequest);
124
            $this->laravel->bindRequest($laravelRequest);
125
            $this->laravel->fireEvent('laravels.received_request', [$laravelRequest]);
126
            $success = $this->handleStaticResource($this->laravel, $laravelRequest, $swooleResponse);
127
            if ($success === false) {
128
                $this->handleDynamicResource($this->laravel, $laravelRequest, $swooleResponse);
129
            }
130
        } catch (\Exception $e) {
131
            $this->handleException($e, $swooleResponse);
132
        } catch (\Throwable $e) {
133
            $this->handleException($e, $swooleResponse);
134
        }
135
    }
136
137
    /**
138
     * @param \Exception|\Throwable $e
139
     * @param SwooleResponse $response
140
     */
141
    protected function handleException($e, SwooleResponse $response)
142
    {
143
        $error = sprintf(
144
            'onRequest: Uncaught exception "%s"([%d]%s) at %s:%s, %s%s',
145
            get_class($e),
146
            $e->getCode(),
147
            $e->getMessage(),
148
            $e->getFile(),
149
            $e->getLine(),
150
            PHP_EOL,
151
            $e->getTraceAsString()
152
        );
153
        $this->error($error);
154
        try {
155
            $response->status(500);
156
            $response->end('Oops! An unexpected error occurred: ' . $e->getMessage());
157
        } catch (\Exception $e) {
158
            $this->logException($e);
159
        }
160
    }
161
162
    protected function handleStaticResource(Laravel $laravel, IlluminateRequest $laravelRequest, SwooleResponse $swooleResponse)
163
    {
164
        // For Swoole < 1.9.17
165
        if (!empty($this->conf['handle_static'])) {
166
            $laravelResponse = $laravel->handleStatic($laravelRequest);
167
            if ($laravelResponse !== false) {
168
                $laravelResponse->headers->set('Server', $this->conf['server'], true);
169
                $laravel->fireEvent('laravels.generated_response', [$laravelRequest, $laravelResponse]);
170
                (new StaticResponse($swooleResponse, $laravelResponse))->send($this->conf['enable_gzip']);
171
                return true;
172
            }
173
        }
174
        return false;
175
    }
176
177
    protected function handleDynamicResource(Laravel $laravel, IlluminateRequest $laravelRequest, SwooleResponse $swooleResponse)
178
    {
179
        $laravelResponse = $laravel->handleDynamic($laravelRequest);
180
        $laravelResponse->headers->set('Server', $this->conf['server'], true);
181
        $laravel->fireEvent('laravels.generated_response', [$laravelRequest, $laravelResponse]);
182
        $laravel->clean();
183
        if ($laravelResponse instanceof BinaryFileResponse) {
184
            $response = new StaticResponse($swooleResponse, $laravelResponse);
185
        } else {
186
            $response = new DynamicResponse($swooleResponse, $laravelResponse);
187
        }
188
        $response->send($this->conf['enable_gzip']);
189
        $response = null;
190
        unset($response);
191
        return true;
192
    }
193
194
    /**
195
     * @var OutputStyle $outputStyle
196
     */
197
    protected static $outputStyle;
198
199
    public static function setOutputStyle(OutputStyle $outputStyle)
200
    {
201
        static::$outputStyle = $outputStyle;
202
    }
203
204
    public static function getOutputStyle()
205
    {
206
        return static::$outputStyle;
207
    }
208
}
209