[HttpFoundation] implemented RFC6266 (Content-Disposition header)
references: * http://trac.tools.ietf.org/wg/httpbis/trac/wiki/ContentDispositionProducerAdvice * https://github.com/mnot/sweet/blob/master/lib/index.js * http://www.mnot.net/blog/2011/09/02/rfc6266_and_content-disposition
This commit is contained in:
parent
e7b2d2d659
commit
dccd2d560f
@ -22,6 +22,7 @@ To get the diff between two versions, go to https://github.com/symfony/symfony/c
|
||||
|
||||
* added support for the PATCH method in Request
|
||||
* removed the ContentTypeMimeTypeGuesser class as it is deprecated and never used on PHP 5.3
|
||||
* added ResponseHeaderBag::makeDisposition() (implements RFC 6266)
|
||||
|
||||
### Translation
|
||||
|
||||
|
@ -200,6 +200,50 @@ class ResponseHeaderBag extends HeaderBag
|
||||
$this->setCookie(new Cookie($name, null, 1, $path, $domain));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a HTTP Content-Disposition field-value.
|
||||
*
|
||||
* @param string $disposition One of "inline" or "attachment"
|
||||
* @param string $filename A unicode string
|
||||
* @param string $filenameFallback A string containing only ASCII characters that
|
||||
* is semantically equivalent to $filename. If the filename is already ASCII,
|
||||
* it can be omitted, or just copied from $filename
|
||||
*
|
||||
* @return string A string suitable for use as a Content-Disposition field-value.
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
* @see RFC 6266
|
||||
*/
|
||||
public function makeDisposition($disposition, $filename, $filenameFallback = '')
|
||||
{
|
||||
if (!$filenameFallback) {
|
||||
$filenameFallback = $filename;
|
||||
}
|
||||
|
||||
// filenameFallback is not ASCII.
|
||||
if (!preg_match('/^[\x20-\x7e]*$/', $filenameFallback)) {
|
||||
throw new \InvalidArgumentException('The filename fallback must only contain ASCII characters.');
|
||||
}
|
||||
|
||||
// percent characters aren't safe in fallback.
|
||||
if (false !== strpos($filenameFallback, '%')) {
|
||||
throw new \InvalidArgumentException('The filename fallback cannot contain the "%" character.');
|
||||
}
|
||||
|
||||
// path separators aren't allowed in either.
|
||||
if (preg_match('#[/\\\\]#', $filename) || preg_match('#[/\\\\]#', $filenameFallback)) {
|
||||
throw new \InvalidArgumentException('The filename and the fallback cannot contain the "/" and "\\" characters.');
|
||||
}
|
||||
|
||||
$output = sprintf('%s; filename="%s"', $disposition, str_replace(array('\\', '"'), array('\\\\', '\\"'), $filenameFallback));
|
||||
|
||||
if ($filename != $filenameFallback) {
|
||||
$output .= sprintf("; filename*=utf-8''%s", str_replace(array("'", '(', ')', '*'), array('%27', '%28', '%29', '%2A'), urlencode($filename)));
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the calculated value of the cache-control header.
|
||||
*
|
||||
|
@ -118,4 +118,49 @@ class ResponseHeaderBagTest extends \PHPUnit_Framework_TestCase
|
||||
$cookies = $bag->getCookies(ResponseHeaderBag::COOKIES_ARRAY);
|
||||
$this->assertFalse(isset($cookies['foo.bar']));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideMakeDisposition
|
||||
*/
|
||||
public function testMakeDisposition($disposition, $filename, $filenameFallback, $expected)
|
||||
{
|
||||
$headers = new ResponseHeaderBag();
|
||||
|
||||
$this->assertEquals($expected, $headers->makeDisposition($disposition, $filename, $filenameFallback));
|
||||
}
|
||||
|
||||
public function provideMakeDisposition()
|
||||
{
|
||||
return array(
|
||||
array('attachment', 'foo.html', 'foo.html', 'attachment; filename="foo.html"'),
|
||||
array('attachment', 'foo.html', '', 'attachment; filename="foo.html"'),
|
||||
array('attachment', 'foo bar.html', '', 'attachment; filename="foo bar.html"'),
|
||||
array('attachment', 'foo "bar".html', '', 'attachment; filename="foo \\"bar\\".html"'),
|
||||
array('attachment', 'foo%20bar.html', 'foo bar.html', 'attachment; filename="foo bar.html"; filename*=utf-8\'\'foo%2520bar.html'),
|
||||
array('attachment', 'föö.html', 'foo.html', 'attachment; filename="foo.html"; filename*=utf-8\'\'f%C3%B6%C3%B6.html'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideMakeDispositionFail
|
||||
* @expectedException \InvalidArgumentException
|
||||
*/
|
||||
public function testMakeDispositionFail($disposition, $filename)
|
||||
{
|
||||
$headers = new ResponseHeaderBag();
|
||||
|
||||
$headers->makeDisposition($disposition, $filename);
|
||||
}
|
||||
|
||||
public function provideMakeDispositionFail()
|
||||
{
|
||||
return array(
|
||||
array('attachment', 'foo%20bar.html'),
|
||||
array('attachment', 'foo/bar.html'),
|
||||
array('attachment', '/foo.html'),
|
||||
array('attachment', 'foo\bar.html'),
|
||||
array('attachment', '\foo.html'),
|
||||
array('attachment', 'föö.html'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user