Skip to content

Commit 6a964d5

Browse files
committed
Support for file uploads
1 parent 496bc54 commit 6a964d5

File tree

4 files changed

+78
-1
lines changed

4 files changed

+78
-1
lines changed

src/Igorw/CgiHttpKernel/CgiHttpKernel.php

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
use Symfony\Component\HttpFoundation\Response;
77
use Symfony\Component\HttpFoundation\ParameterBag;
88
use Symfony\Component\HttpFoundation\Cookie;
9+
use Symfony\Component\HttpFoundation\FileBag;
10+
use Symfony\Component\HttpFoundation\File\UploadedFile;
911
use Symfony\Component\HttpKernel\HttpKernelInterface;
1012
use Symfony\Component\Process\ProcessBuilder;
1113

@@ -28,12 +30,19 @@ public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQ
2830
return new Response('The requested file could not be found.', 404);
2931
}
3032

31-
$requestBody = $request->getContent() ?: $this->getUrlEncodedParameterBag($request->request);
33+
$requestBody = $this->getRequestBody($request);
34+
35+
if (count($request->files)) {
36+
$boundary = $this->getMimeBoundary();
37+
$request->headers->set('Content-Type', 'multipart/form-data; boundary='.$boundary);
38+
$requestBody = $this->encodeMultipartFiles($boundary, $request->files);
39+
}
3240

3341
$builder = ProcessBuilder::create()
3442
->add('php-cgi')
3543
->add('-d expose_php=Off')
3644
->add('-d cgi.force_redirect=Off')
45+
->add('-d html_errors=Off')
3746
->add($filename)
3847
->setInput($requestBody)
3948
->setEnv('SCRIPT_NAME', '/'.$filename)
@@ -72,6 +81,11 @@ public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQ
7281
return $response;
7382
}
7483

84+
private function getRequestBody(Request $request)
85+
{
86+
return $request->getContent() ?: $this->getUrlEncodedParameterBag($request->request);
87+
}
88+
7589
private function getStatusCode(array $headers)
7690
{
7791
if (isset($headers['Status'])) {
@@ -144,4 +158,42 @@ private function getUrlEncodedParameterBag(ParameterBag $bag)
144158
{
145159
return http_build_query($bag->all());
146160
}
161+
162+
private function encodeMultipartFiles($boundary, FileBag $files)
163+
{
164+
$mimeBoundary = '--'.$boundary."\r\n";
165+
166+
$data = '';
167+
foreach ($files->all() as $name => $file) {
168+
$data .= $mimeBoundary;
169+
$data .= $this->encodeMultipartFile($name, $file);
170+
$data .= $mimeBoundary;
171+
}
172+
$data .= "\r\n";
173+
174+
return $data;
175+
}
176+
177+
private function encodeMultipartFile($name, UploadedFile $file)
178+
{
179+
$eol = "\r\n";
180+
181+
$content = file_get_contents($file);
182+
183+
$data = '';
184+
$data .= sprintf('Content-Disposition: form-data; name="%s"; filename="%s"'.$eol,
185+
$name,
186+
$file->getClientOriginalName());
187+
$data .= sprintf('Content-Type: %s'.$eol,
188+
$file->getClientMimeType());
189+
$data .= 'Content-Transfer-Encoding: base64'.$eol.$eol;
190+
$data .= chunk_split(base64_encode($content)).$eol;
191+
192+
return $data;
193+
}
194+
195+
private function getMimeBoundary()
196+
{
197+
return md5('cgi-http-kernel');
198+
}
147199
}

tests/Igorw/CgiHttpKernel/CgiHttpKernelTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Igorw\CgiHttpKernel;
44

55
use Symfony\Component\HttpFoundation\Request;
6+
use Symfony\Component\HttpFoundation\File\UploadedFile;
67

78
class CgiHttpKernelTest extends \PHPUnit_Framework_TestCase
89
{
@@ -211,4 +212,22 @@ public function scriptNameShouldBeFrontControllerWithCustomFrontController()
211212

212213
$this->assertSame('/silex.php', $response->getContent());
213214
}
215+
216+
/** @test */
217+
public function uploadShouldPutFileInFiles()
218+
{
219+
$file = new UploadedFile(__DIR__.'/Fixtures/sadkitten.gif', 'sadkitten.gif', 'image/gif');
220+
221+
$request = Request::create('/upload.php', 'POST');
222+
$request->files->add(array('kitten' => $file));
223+
$response = $this->kernel->handle($request);
224+
225+
$expected = implode("\n", array(
226+
'sadkitten.gif',
227+
'image/gif',
228+
'1304444',
229+
'1',
230+
));
231+
$this->assertSame($expected."\n", $response->getContent());
232+
}
214233
}
931 KB
Loading
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?php
2+
3+
echo $_FILES['kitten']['name']."\n";
4+
echo $_FILES['kitten']['type']."\n";
5+
echo $_FILES['kitten']['size']."\n";
6+
echo file_exists($_FILES['kitten']['tmp_name'])."\n";

0 commit comments

Comments
 (0)