1313use Symfony \Bundle \FrameworkBundle \Controller \AbstractController ;
1414use Symfony \Component \HttpFoundation \JsonResponse ;
1515use Symfony \Component \HttpFoundation \Request ;
16+ use Symfony \Component \HttpFoundation \Response ;
1617use Symfony \Component \HttpFoundation \StreamedResponse ;
1718use Symfony \Component \HttpKernel \Exception \HttpException ;
1819use Symfony \Component \HttpKernel \Exception \NotFoundHttpException ;
1920use Symfony \Component \Messenger \MessageBusInterface ;
2021use Symfony \Component \Routing \Annotation \Route ;
2122use Symfony \Component \Routing \Generator \UrlGeneratorInterface ;
22- use Symfony \Component \Routing \RouterInterface ;
2323
2424final class RepoController extends AbstractController
2525{
@@ -41,32 +41,42 @@ public function __construct(
4141 * @Route("/packages.json", host="{organization}{sep1}repo{sep2}{domain}", name="repo_packages", methods={"GET"}, defaults={"domain":"%domain%","sep1"="%organization_separator%","sep2"="%domain_separator%"}, requirements={"domain"="%domain%","sep1"="%organization_separator%","sep2"="%domain_separator%"})
4242 * @Cache(public=false)
4343 */
44- public function packages (Request $ request , Organization $ organization ): JsonResponse
44+ public function packages (Request $ request , Organization $ organization ): Response
4545 {
4646 $ packageNames = $ this ->packageQuery ->getAllNames ($ organization ->id ());
47- [$ lastModified , $ packages ] = $ this ->packageManager ->findProviders ($ organization ->alias (), $ packageNames );
48-
49- $ response = (new JsonResponse ([
50- 'packages ' => $ packages ,
51- 'available-packages ' => array_map (static fn (PackageName $ packageName ) => $ packageName ->name (), $ packageNames ),
52- 'metadata-url ' => '/p2/%package%.json ' ,
53- 'notify-batch ' => $ this ->generateUrl ('repo_package_downloads ' , [
54- 'organization ' => $ organization ->alias (),
55- ], UrlGeneratorInterface::ABSOLUTE_URL ),
56- 'search ' => 'https://packagist.org/search.json?q=%query%&type=%type% ' ,
57- 'mirrors ' => [
58- [
59- 'dist-url ' => $ this ->generateUrl (
60- 'organization_repo_url ' ,
61- ['organization ' => $ organization ->alias ()],
62- RouterInterface::ABSOLUTE_URL
63- ).'dists/%package%/%version%/%reference%.%type% ' ,
64- 'preferred ' => true ,
47+ [$ lastModified , $ loader ] = $ this ->packageManager ->findProviders ($ organization ->alias (), $ packageNames );
48+
49+ $ response = (new StreamedResponse (function () use ($ organization , $ packageNames , $ loader ): void {
50+ $ outputStream = \fopen ('php://output ' , 'wb ' );
51+ if (false === $ outputStream ) {
52+ throw new HttpException (500 , 'Could not open output stream to send binary file. ' ); // @codeCoverageIgnore
53+ }
54+
55+ \fwrite ($ outputStream , ' ' );
56+ \flush ();
57+ \fwrite ($ outputStream , \json_encode ([
58+ 'packages ' => $ loader (),
59+ 'available-packages ' => array_map (static fn (PackageName $ packageName ) => $ packageName ->name (), $ packageNames ),
60+ 'metadata-url ' => '/p2/%package%.json ' ,
61+ 'providers-url ' => '/p2/%package%.json ' ,
62+ 'notify-batch ' => $ this ->generateUrl ('repo_package_downloads ' , [
63+ 'organization ' => $ organization ->alias (),
64+ ], UrlGeneratorInterface::ABSOLUTE_URL ),
65+ 'search ' => 'https://packagist.org/search.json?q=%query%&type=%type% ' ,
66+ 'mirrors ' => [
67+ [
68+ 'dist-url ' => $ this ->generateUrl (
69+ 'organization_repo_url ' ,
70+ ['organization ' => $ organization ->alias ()],
71+ UrlGeneratorInterface::ABSOLUTE_URL
72+ ).'dists/%package%/%version%/%reference%.%type% ' ,
73+ 'preferred ' => true ,
74+ ],
6575 ],
66- ],
67- ]))
68- -> setPrivate ( )
69- -> setLastModified ( $ lastModified );
76+ ], JsonResponse:: DEFAULT_ENCODING_OPTIONS ));
77+ }, Response:: HTTP_OK , [ ' Content-Type ' => ' application/json ' , ' X-Accel-Buffering ' => ' no ' ]))
78+ -> setLastModified ( $ lastModified )
79+ -> setPrivate ( );
7080
7181 $ response ->isNotModified ($ request );
7282
@@ -149,18 +159,27 @@ public function downloads(Request $request, Organization $organization): JsonRes
149159 * requirements={"domain"="%domain%","package"="%package_name_pattern%","sep1"="%organization_separator%","sep2"="%domain_separator%"})
150160 * @Cache(public=false)
151161 */
152- public function providerV2 (Request $ request , Organization $ organization , string $ package ): JsonResponse
162+ public function providerV2 (Request $ request , Organization $ organization , string $ package ): Response
153163 {
154- [$ lastModified , $ providerData ] = $ this ->packageManager ->findProviders (
164+ [$ lastModified , $ loader ] = $ this ->packageManager ->findProviders (
155165 $ organization ->alias (),
156166 [new PackageName ('' , $ package )]
157167 );
158168
159- if ($ providerData === [] ) {
169+ if ($ lastModified === null ) {
160170 throw new NotFoundHttpException ();
161171 }
162172
163- $ response = (new JsonResponse ($ providerData ))
173+ $ response = (new StreamedResponse (function () use ($ loader ): void {
174+ $ outputStream = \fopen ('php://output ' , 'wb ' );
175+ if (false === $ outputStream ) {
176+ throw new HttpException (500 , 'Could not open output stream to send binary file. ' ); // @codeCoverageIgnore
177+ }
178+
179+ \fwrite ($ outputStream , ' ' );
180+ \flush ();
181+ \fwrite ($ outputStream , \json_encode ($ loader (), JsonResponse::DEFAULT_ENCODING_OPTIONS ));
182+ }, Response::HTTP_OK , ['Content-Type ' => 'application/json ' , 'X-Accel-Buffering ' => 'no ' ]))
164183 ->setLastModified ($ lastModified )
165184 ->setPrivate ();
166185
0 commit comments