Skip to content

Commit dce4850

Browse files
committed
feat: implement safe response handling to manage Content-Length header for binary responses
1 parent 7f23172 commit dce4850

4 files changed

Lines changed: 35 additions & 10 deletions

File tree

src/debug.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,33 @@ function ddless_log(string $msg): void {
3333

3434
ddless_log("[ddless] debug.php loaded, DEBUG_MODE=" . (getenv('DDLESS_DEBUG_MODE') ?: 'not set') . "\n");
3535

36+
function ddless_safe_send_response($response): void {
37+
if (php_sapi_name() !== 'cli-server') {
38+
$response->send();
39+
return;
40+
}
41+
42+
$isBinary = $response instanceof \Symfony\Component\HttpFoundation\BinaryFileResponse;
43+
44+
if ($isBinary) {
45+
$file = $response->getFile();
46+
$content = file_get_contents($file->getPathname());
47+
$response->headers->set('Content-Type', $response->headers->get('Content-Type'));
48+
foreach ($response->headers->allPreserveCase() as $name => $values) {
49+
if (strtolower($name) === 'content-length') continue;
50+
foreach ((array) $values as $v) {
51+
header("{$name}: {$v}", strtolower($name) !== 'set-cookie');
52+
}
53+
}
54+
http_response_code($response->getStatusCode());
55+
header('Content-Length: ' . strlen($content));
56+
echo $content;
57+
} else {
58+
$response->headers->remove('Content-Length');
59+
$response->send();
60+
}
61+
}
62+
3663
// PHP 7.4 compatibility polyfills for PHP 8.0+ string functions
3764
if (!function_exists('str_starts_with')) {
3865
function str_starts_with(string $haystack, string $needle): bool {

src/frameworks/laravel/http_request.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -655,8 +655,7 @@ function ddless_response_status_text(int $statusCode): ?string
655655
echo $capturedBodyContent;
656656
}
657657
} else {
658-
$response->headers->remove('Content-Length');
659-
$response->send();
658+
ddless_safe_send_response($response);
660659
if (is_string($responseBodyContent)) {
661660
$capturedBodyContent = $responseBodyContent;
662661
}

src/frameworks/symfony/http_request.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -580,8 +580,7 @@ function ddless_response_status_text(int $statusCode): ?string
580580
echo $capturedBodyContent;
581581
}
582582
} else {
583-
$response->headers->remove('Content-Length');
584-
$response->send();
583+
ddless_safe_send_response($response);
585584
if (is_string($responseBodyContent)) {
586585
$capturedBodyContent = $responseBodyContent;
587586
}

src/frameworks/tempest/http_request.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -671,13 +671,13 @@ function ddless_response_status_text(int $statusCode): ?string
671671
echo $responseBodyContent;
672672
}
673673
} else {
674-
// Non-CLI: send response directly
675674
if (is_object($response) && method_exists($response, 'send')) {
676-
ob_start();
677-
$response->send();
678-
header_remove('Content-Length');
679-
$bodyOutput = ob_get_clean();
680-
$capturedBodyContent = is_string($bodyOutput) ? $bodyOutput : $responseBodyContent;
675+
if (function_exists('ddless_safe_send_response')) {
676+
ddless_safe_send_response($response);
677+
} else {
678+
$response->send();
679+
}
680+
$capturedBodyContent = $responseBodyContent;
681681
} else {
682682
if (is_string($responseBodyContent)) {
683683
echo $responseBodyContent;

0 commit comments

Comments
 (0)