Skip to content

Commit 5859fc5

Browse files
committed
Merge branch 'pr12620'
2 parents 7edc8dc + 7503fa1 commit 5859fc5

File tree

9 files changed

+76
-27
lines changed

9 files changed

+76
-27
lines changed

README.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,10 +164,6 @@ You may gracefully restart the Octane server's application workers using the `oc
164164
php artisan octane:reload
165165
```
166166

167-
### Debugging
168-
169-
Because Octane starts a long running process that continually serves requests to your application, it is not possible to use the `dump` helper. Instead, we recommend using [Telescope](https://github.com/laravel/telescope), [Ray](https://spatie.be/products/ray), [Debug Bar](https://github.com/barryvdh/laravel-debugbar), or [logging](https://laravel.com/docs/logging).
170-
171167
### Dependency Injection & Octane
172168

173169
Since Octane boots your application once and keeps it in memory while serving requests, there are a few caveats you should consider while building your application. For example, the `register` and `boot` methods of your application's service providers will only be executed once when the request worker initially boots. On subsequent requests, the same application instance will be reused.

src/Contracts/Client.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Illuminate\Foundation\Application;
66
use Illuminate\Http\Request;
7+
use Laravel\Octane\OctaneResponse;
78
use Laravel\Octane\RequestContext;
89
use Symfony\Component\HttpFoundation\Response;
910
use Throwable;
@@ -22,10 +23,10 @@ public function marshalRequest(RequestContext $context): array;
2223
* Send the response to the server.
2324
*
2425
* @param \Laravel\Octane\RequestContext $context
25-
* @param \Symfony\Component\HttpFoundation\Response $response
26+
* @param \Laravel\Octane\OctaneResponse $response
2627
* @return void
2728
*/
28-
public function respond(RequestContext $context, Response $response): void;
29+
public function respond(RequestContext $context, OctaneResponse $response): void;
2930

3031
/**
3132
* Send an error message to the server.

src/OctaneResponse.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
namespace Laravel\Octane;
4+
5+
use Symfony\Component\HttpFoundation\Response;
6+
7+
class OctaneResponse
8+
{
9+
public function __construct(public Response $response, public ?string $outputBuffer = null)
10+
{
11+
}
12+
}

src/RoadRunner/RoadRunnerClient.php

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,12 @@
88
use Laravel\Octane\Contracts\StoppableClient;
99
use Laravel\Octane\MarshalsPsr7RequestsAndResponses;
1010
use Laravel\Octane\Octane;
11+
use Laravel\Octane\OctaneResponse;
1112
use Laravel\Octane\RequestContext;
1213
use Spiral\RoadRunner\Http\PSR7Worker;
14+
use Symfony\Component\HttpFoundation\BinaryFileResponse;
1315
use Symfony\Component\HttpFoundation\Response;
16+
use Symfony\Component\HttpFoundation\StreamedResponse;
1417
use Throwable;
1518

1619
class RoadRunnerClient implements Client, StoppableClient
@@ -39,12 +42,20 @@ public function marshalRequest(RequestContext $context): array
3942
* Send the response to the server.
4043
*
4144
* @param \Laravel\Octane\RequestContext $context
42-
* @param \Symfony\Component\HttpFoundation\Response $response
45+
* @param \Laravel\Octane\OctaneResponse $octaneResponse
4346
* @return void
4447
*/
45-
public function respond(RequestContext $context, Response $response): void
48+
public function respond(RequestContext $context, OctaneResponse $octaneResponse): void
4649
{
47-
$this->client->respond($this->toPsr7Response($response));
50+
if ($octaneResponse->outputBuffer &&
51+
! $octaneResponse->response instanceof StreamedResponse &&
52+
! $octaneResponse->response instanceof BinaryFileResponse) {
53+
$octaneResponse->response->setContent(
54+
$octaneResponse->outputBuffer.$octaneResponse->response->getContent()
55+
);
56+
}
57+
58+
$this->client->respond($this->toPsr7Response($octaneResponse->response));
4859
}
4960

5061
/**

src/Swoole/SwooleClient.php

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Laravel\Octane\Contracts\ServesStaticFiles;
1010
use Laravel\Octane\MimeType;
1111
use Laravel\Octane\Octane;
12+
use Laravel\Octane\OctaneResponse;
1213
use Laravel\Octane\RequestContext;
1314
use Swoole\Http\Response as SwooleResponse;
1415
use Symfony\Component\HttpFoundation\BinaryFileResponse;
@@ -98,13 +99,13 @@ public function serveStaticFile(Request $request, RequestContext $context): void
9899
* Send the response to the server.
99100
*
100101
* @param \Laravel\Octane\RequestContext $context
101-
* @param \Symfony\Component\HttpFoundation\Response $response
102+
* @param \Laravel\Octane\OctaneResponse $octaneResponse
102103
* @return void
103104
*/
104-
public function respond(RequestContext $context, Response $response): void
105+
public function respond(RequestContext $context, OctaneResponse $octaneResponse): void
105106
{
106-
$this->sendResponseHeaders($response, $context->swooleResponse);
107-
$this->sendResponseContent($response, $context->swooleResponse);
107+
$this->sendResponseHeaders($octaneResponse->response, $context->swooleResponse);
108+
$this->sendResponseContent($octaneResponse, $context->swooleResponse);
108109
}
109110

110111
/**
@@ -150,23 +151,41 @@ public function sendResponseHeaders(Response $response, SwooleResponse $swooleRe
150151
/**
151152
* Send the headers from the Illuminate response to the Swoole response.
152153
*
153-
* @param \Symfony\Component\HtpFoundation\Response $response
154+
* @param \Laravel\Octane\OctaneResponse $response
154155
* @param \Swoole\Http\Response $response
155156
* @return void
156157
*/
157-
protected function sendResponseContent(Response $response, SwooleResponse $swooleResponse): void
158+
protected function sendResponseContent(OctaneResponse $octaneResponse, SwooleResponse $swooleResponse): void
158159
{
159-
if ($response instanceof StreamedResponse && property_exists($response, 'output')) {
160-
$swooleResponse->end($response->output);
160+
if ($octaneResponse->response instanceof BinaryFileResponse) {
161+
$swooleResponse->sendfile($octaneResponse->response->getFile()->getPathname());
161162

162163
return;
163-
} elseif ($response instanceof BinaryFileResponse) {
164-
$swooleResponse->sendfile($response->getFile()->getPathname());
164+
}
165+
166+
if ($octaneResponse->outputBuffer) {
167+
$swooleResponse->write($octaneResponse->outputBuffer);
168+
}
169+
170+
if ($octaneResponse->response instanceof StreamedResponse) {
171+
ob_start(function ($data) use ($swooleResponse) {
172+
if (strlen($data) > 0) {
173+
$swooleResponse->write($data);
174+
}
175+
176+
return '';
177+
}, 1);
178+
179+
$octaneResponse->response->sendContent();
180+
181+
ob_end_clean();
182+
183+
$swooleResponse->end();
165184

166185
return;
167186
}
168187

169-
$content = $response->getContent();
188+
$content = $octaneResponse->response->getContent();
170189

171190
$length = strlen($content);
172191

src/Testing/Fakes/FakeClient.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
use Illuminate\Foundation\Application;
66
use Illuminate\Http\Request;
77
use Laravel\Octane\Contracts\Client;
8+
use Laravel\Octane\OctaneResponse;
89
use Laravel\Octane\RequestContext;
9-
use Symfony\Component\HttpFoundation\Response;
1010
use Throwable;
1111

1212
class FakeClient implements Client
@@ -24,9 +24,9 @@ public function marshalRequest(RequestContext $context): array
2424
return [$context->request, $context];
2525
}
2626

27-
public function respond(RequestContext $context, Response $response): void
27+
public function respond(RequestContext $context, OctaneResponse $octaneResponse): void
2828
{
29-
$this->responses[] = $response;
29+
$this->responses[] = $octaneResponse->response;
3030
}
3131

3232
public function error(Throwable $e, Application $app, Request $request, RequestContext $context): void

src/Worker.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,12 +86,20 @@ public function handle(Request $request, RequestContext $context): void
8686
try {
8787
$responded = false;
8888

89+
ob_start();
90+
91+
$response = $gateway->handle($request);
92+
93+
$output = ob_get_contents();
94+
95+
ob_end_clean();
96+
8997
// Here we will actually hand the incoming request to the Laravel application so
9098
// it can generate a response. We'll send this response back to the client so
9199
// it can be returned to a browser. This gateway will also dispatch events.
92100
$this->client->respond(
93101
$context,
94-
$response = $gateway->handle($request),
102+
$octaneResponse = new OctaneResponse($response, $output),
95103
);
96104

97105
$responded = true;
@@ -105,7 +113,7 @@ public function handle(Request $request, RequestContext $context): void
105113
// After the request handling process has completed we will unset some variables
106114
// plus reset the current application state back to its original state before
107115
// it was cloned. Then we will be ready for the next worker iteration loop.
108-
unset($gateway, $sandbox, $request, $response);
116+
unset($gateway, $sandbox, $request, $response, $octaneResponse, $output);
109117

110118
CurrentApplication::set($this->app);
111119
}

tests/RoadRunnerClientTest.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Illuminate\Http\Request;
77
use Illuminate\Http\Response;
88
use Laminas\Diactoros\ServerRequestFactory;
9+
use Laravel\Octane\OctaneResponse;
910
use Laravel\Octane\RequestContext;
1011
use Laravel\Octane\RoadRunner\RoadRunnerClient;
1112
use Mockery;
@@ -42,7 +43,7 @@ public function test_respond_method_send_response_to_roadrunner()
4243

4344
$client->respond(new RequestContext([
4445
'psr7Request' => $psr7Request,
45-
]), new Response('Hello World', 200));
46+
]), new OctaneResponse(new Response('Hello World', 200)));
4647
}
4748

4849
/** @doesNotPerformAssertions @test */

tests/SwooleClientTest.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Exception;
66
use Illuminate\Http\Request;
77
use Illuminate\Http\Response;
8+
use Laravel\Octane\OctaneResponse;
89
use Laravel\Octane\RequestContext;
910
use Laravel\Octane\Swoole\SwooleClient;
1011
use Mockery;
@@ -129,7 +130,7 @@ public function test_respond_method_send_response_to_swoole()
129130

130131
$client->respond(new RequestContext([
131132
'swooleResponse' => $swooleResponse,
132-
]), new Response('Hello World', 200, ['Content-Type' => 'text/html']));
133+
]), new OctaneResponse(new Response('Hello World', 200, ['Content-Type' => 'text/html'])));
133134
}
134135

135136
/** @doesNotPerformAssertions @test */

0 commit comments

Comments
 (0)