Skip to content

Instantly share code, notes, and snippets.

@LiamKarlMitchell
Last active July 14, 2022 08:22
Show Gist options
  • Save LiamKarlMitchell/18f1e43ae6b772864d1b6a6ec1f71ba9 to your computer and use it in GitHub Desktop.
Save LiamKarlMitchell/18f1e43ae6b772864d1b6a6ec1f71ba9 to your computer and use it in GitHub Desktop.
Adds content length to Lighthouse POST responses.
<?php
// Thanks to: https://laracasts.com/discuss/channels/general-discussion/add-content-length-header-on-views
// In relation to a bug for graphql code generator in an upstream dependency, I needed to add a Content-Length header.
// Temporary workaround for this.
// See: https://github.com/dotansimha/graphql-code-generator/issues/7934
// See: https://github.com/nodejs/undici/issues/1414
// https://github.com/nodejs/undici/issues/1490
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class AddContentLengthLighthouse
{
/**
* Handle an incoming request.
*
* @param Request $request
* @param Closure $next
*
* @return mixed
*/
public function handle($request, Closure $next)
{
$response = $next($request);
$method = $request->method();
if ($method === 'POST' && $request->getRequestUri() === config('lighthouse.route.uri', '/graphql')) {
// to be sure nothing was already output (by an echo statement or something)
if (headers_sent() || ob_get_contents() != '') {
return $response;
}
$content = $response->content();
$contentLength = mb_strlen($content);
$useCompressedOutput = ($contentLength && isset($_SERVER['HTTP_ACCEPT_ENCODING'])
&& strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false);
if ($useCompressedOutput) {
// In order to accurately set Content-Length, we have to compress the data ourselves
// rather than letting PHP do it automatically.
$compressedContent = gzencode($content, 9, FORCE_GZIP);
$compressedContentLength = strlen($compressedContent);
if ($compressedContentLength / $contentLength < 0.9) {
if (ini_get('zlib.output_compression')) {
ini_set('zlib.output_compression', false);
}
$response->header('Content-Encoding', 'gzip');
$response->setContent($compressedContent);
$contentLength = $compressedContentLength;
}
}
// compressed or not, sets the Content-Length
$response->header('Content-Length', $contentLength);
}
return $response;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment