123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 |
- <?php
- /*
- * This file is part of the Symfony package.
- *
- * (c) Fabien Potencier <fabien@symfony.com>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
- namespace Symfony\Bridge\PsrHttpMessage\Factory;
- use Psr\Http\Message\ResponseFactoryInterface;
- use Psr\Http\Message\ResponseInterface;
- use Psr\Http\Message\ServerRequestFactoryInterface;
- use Psr\Http\Message\ServerRequestInterface;
- use Psr\Http\Message\StreamFactoryInterface;
- use Psr\Http\Message\UploadedFileFactoryInterface;
- use Psr\Http\Message\UploadedFileInterface;
- use Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface;
- use Symfony\Component\HttpFoundation\BinaryFileResponse;
- use Symfony\Component\HttpFoundation\File\UploadedFile;
- use Symfony\Component\HttpFoundation\Request;
- use Symfony\Component\HttpFoundation\Response;
- use Symfony\Component\HttpFoundation\StreamedResponse;
- /**
- * Builds Psr\HttpMessage instances using a PSR-17 implementation.
- *
- * @author Antonio J. García Lagar <aj@garcialagar.es>
- * @author Aurélien Pillevesse <aurelienpillevesse@hotmail.fr>
- */
- class PsrHttpFactory implements HttpMessageFactoryInterface
- {
- private $serverRequestFactory;
- private $streamFactory;
- private $uploadedFileFactory;
- private $responseFactory;
- public function __construct(ServerRequestFactoryInterface $serverRequestFactory, StreamFactoryInterface $streamFactory, UploadedFileFactoryInterface $uploadedFileFactory, ResponseFactoryInterface $responseFactory)
- {
- $this->serverRequestFactory = $serverRequestFactory;
- $this->streamFactory = $streamFactory;
- $this->uploadedFileFactory = $uploadedFileFactory;
- $this->responseFactory = $responseFactory;
- }
- /**
- * {@inheritdoc}
- *
- * @return ServerRequestInterface
- */
- public function createRequest(Request $symfonyRequest)
- {
- $uri = $symfonyRequest->server->get('QUERY_STRING', '');
- $uri = $symfonyRequest->getSchemeAndHttpHost().$symfonyRequest->getBaseUrl().$symfonyRequest->getPathInfo().('' !== $uri ? '?'.$uri : '');
- $request = $this->serverRequestFactory->createServerRequest(
- $symfonyRequest->getMethod(),
- $uri,
- $symfonyRequest->server->all()
- );
- foreach ($symfonyRequest->headers->all() as $name => $value) {
- try {
- $request = $request->withHeader($name, $value);
- } catch (\InvalidArgumentException $e) {
- // ignore invalid header
- }
- }
- $body = $this->streamFactory->createStreamFromResource($symfonyRequest->getContent(true));
- if (method_exists(Request::class, 'getContentTypeFormat')) {
- $format = $symfonyRequest->getContentTypeFormat();
- } else {
- $format = $symfonyRequest->getContentType();
- }
- if ('json' === $format) {
- $parsedBody = json_decode($symfonyRequest->getContent(), true, 512, \JSON_BIGINT_AS_STRING);
- if (!\is_array($parsedBody)) {
- $parsedBody = null;
- }
- } else {
- $parsedBody = $symfonyRequest->request->all();
- }
- $request = $request
- ->withBody($body)
- ->withUploadedFiles($this->getFiles($symfonyRequest->files->all()))
- ->withCookieParams($symfonyRequest->cookies->all())
- ->withQueryParams($symfonyRequest->query->all())
- ->withParsedBody($parsedBody)
- ;
- foreach ($symfonyRequest->attributes->all() as $key => $value) {
- $request = $request->withAttribute($key, $value);
- }
- return $request;
- }
- /**
- * Converts Symfony uploaded files array to the PSR one.
- */
- private function getFiles(array $uploadedFiles): array
- {
- $files = [];
- foreach ($uploadedFiles as $key => $value) {
- if (null === $value) {
- $files[$key] = $this->uploadedFileFactory->createUploadedFile($this->streamFactory->createStream(), 0, \UPLOAD_ERR_NO_FILE);
- continue;
- }
- if ($value instanceof UploadedFile) {
- $files[$key] = $this->createUploadedFile($value);
- } else {
- $files[$key] = $this->getFiles($value);
- }
- }
- return $files;
- }
- /**
- * Creates a PSR-7 UploadedFile instance from a Symfony one.
- */
- private function createUploadedFile(UploadedFile $symfonyUploadedFile): UploadedFileInterface
- {
- return $this->uploadedFileFactory->createUploadedFile(
- $this->streamFactory->createStreamFromFile(
- $symfonyUploadedFile->getRealPath()
- ),
- (int) $symfonyUploadedFile->getSize(),
- $symfonyUploadedFile->getError(),
- $symfonyUploadedFile->getClientOriginalName(),
- $symfonyUploadedFile->getClientMimeType()
- );
- }
- /**
- * {@inheritdoc}
- *
- * @return ResponseInterface
- */
- public function createResponse(Response $symfonyResponse)
- {
- $response = $this->responseFactory->createResponse($symfonyResponse->getStatusCode(), Response::$statusTexts[$symfonyResponse->getStatusCode()] ?? '');
- if ($symfonyResponse instanceof BinaryFileResponse && !$symfonyResponse->headers->has('Content-Range')) {
- $stream = $this->streamFactory->createStreamFromFile(
- $symfonyResponse->getFile()->getPathname()
- );
- } else {
- $stream = $this->streamFactory->createStreamFromFile('php://temp', 'wb+');
- if ($symfonyResponse instanceof StreamedResponse || $symfonyResponse instanceof BinaryFileResponse) {
- ob_start(function ($buffer) use ($stream) {
- $stream->write($buffer);
- return '';
- }, 1);
- $symfonyResponse->sendContent();
- ob_end_clean();
- } else {
- $stream->write($symfonyResponse->getContent());
- }
- }
- $response = $response->withBody($stream);
- $headers = $symfonyResponse->headers->all();
- $cookies = $symfonyResponse->headers->getCookies();
- if (!empty($cookies)) {
- $headers['Set-Cookie'] = [];
- foreach ($cookies as $cookie) {
- $headers['Set-Cookie'][] = $cookie->__toString();
- }
- }
- foreach ($headers as $name => $value) {
- try {
- $response = $response->withHeader($name, $value);
- } catch (\InvalidArgumentException $e) {
- // ignore invalid header
- }
- }
- $protocolVersion = $symfonyResponse->getProtocolVersion();
- $response = $response->withProtocolVersion($protocolVersion);
- return $response;
- }
- }
|