Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 76f80e9

Browse filesBrowse files
committed
feature #28807 [HttpFoundation] Make ResponseHeaderBag::makeDisposition static (fabpot)
This PR was merged into the 4.2-dev branch. Discussion ---------- [HttpFoundation] Make ResponseHeaderBag::makeDisposition static | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes-ish | BC breaks? | no | Deprecations? | no <!-- don't forget to update UPGRADE-*.md and src/**/CHANGELOG.md files --> | Tests pass? | yes | Fixed tickets | #27851 | License | MIT | Doc PR | n/a <!-- Write a short README entry for your feature/bugfix here (replace this comment block.) This will help people understand your PR and can be used as a start of the Doc PR. Additionally: - Bug fixes must be submitted against the lowest branch where they apply (lowest branches are regularly merged to upper ones so they get the fixes too). - Features and deprecations must be submitted against the master branch. --> Commits ------- d29b410 [HttpFoundation] made ResponseHeaderBag::makeDisposition static
2 parents 2b34f2b + d29b410 commit 76f80e9
Copy full SHA for 76f80e9

File tree

Expand file treeCollapse file tree

4 files changed

+102
-97
lines changed
Filter options
Expand file treeCollapse file tree

4 files changed

+102
-97
lines changed

‎src/Symfony/Component/HttpFoundation/HeaderUtils.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpFoundation/HeaderUtils.php
+51Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
*/
1919
class HeaderUtils
2020
{
21+
const DISPOSITION_ATTACHMENT = 'attachment';
22+
const DISPOSITION_INLINE = 'inline';
23+
2124
/**
2225
* This class should not be instantiated.
2326
*/
@@ -143,6 +146,54 @@ public static function unquote(string $s): string
143146
return preg_replace('/\\\\(.)|"/', '$1', $s);
144147
}
145148

149+
/**
150+
* Generates a HTTP Content-Disposition field-value.
151+
*
152+
* @param string $disposition One of "inline" or "attachment"
153+
* @param string $filename A unicode string
154+
* @param string $filenameFallback A string containing only ASCII characters that
155+
* is semantically equivalent to $filename. If the filename is already ASCII,
156+
* it can be omitted, or just copied from $filename
157+
*
158+
* @return string A string suitable for use as a Content-Disposition field-value
159+
*
160+
* @throws \InvalidArgumentException
161+
*
162+
* @see RFC 6266
163+
*/
164+
public static function makeDisposition(string $disposition, string $filename, string $filenameFallback = ''): string
165+
{
166+
if (!\in_array($disposition, array(self::DISPOSITION_ATTACHMENT, self::DISPOSITION_INLINE))) {
167+
throw new \InvalidArgumentException(sprintf('The disposition must be either "%s" or "%s".', self::DISPOSITION_ATTACHMENT, self::DISPOSITION_INLINE));
168+
}
169+
170+
if ('' === $filenameFallback) {
171+
$filenameFallback = $filename;
172+
}
173+
174+
// filenameFallback is not ASCII.
175+
if (!preg_match('/^[\x20-\x7e]*$/', $filenameFallback)) {
176+
throw new \InvalidArgumentException('The filename fallback must only contain ASCII characters.');
177+
}
178+
179+
// percent characters aren't safe in fallback.
180+
if (false !== strpos($filenameFallback, '%')) {
181+
throw new \InvalidArgumentException('The filename fallback cannot contain the "%" character.');
182+
}
183+
184+
// path separators aren't allowed in either.
185+
if (false !== strpos($filename, '/') || false !== strpos($filename, '\\') || false !== strpos($filenameFallback, '/') || false !== strpos($filenameFallback, '\\')) {
186+
throw new \InvalidArgumentException('The filename and the fallback cannot contain the "/" and "\\" characters.');
187+
}
188+
189+
$params = array('filename' => $filenameFallback);
190+
if ($filename !== $filenameFallback) {
191+
$params['filename*'] = "utf-8''".rawurlencode($filename);
192+
}
193+
194+
return $disposition.'; '.self::toString($params, ';');
195+
}
196+
146197
private static function groupParts(array $matches, string $separators): array
147198
{
148199
$separator = $separators[0];

‎src/Symfony/Component/HttpFoundation/ResponseHeaderBag.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpFoundation/ResponseHeaderBag.php
+2-42Lines changed: 2 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -251,51 +251,11 @@ public function clearCookie($name, $path = '/', $domain = null, $secure = false,
251251
}
252252

253253
/**
254-
* Generates a HTTP Content-Disposition field-value.
255-
*
256-
* @param string $disposition One of "inline" or "attachment"
257-
* @param string $filename A unicode string
258-
* @param string $filenameFallback A string containing only ASCII characters that
259-
* is semantically equivalent to $filename. If the filename is already ASCII,
260-
* it can be omitted, or just copied from $filename
261-
*
262-
* @return string A string suitable for use as a Content-Disposition field-value
263-
*
264-
* @throws \InvalidArgumentException
265-
*
266-
* @see RFC 6266
254+
* @see HeaderUtils::makeDisposition()
267255
*/
268256
public function makeDisposition($disposition, $filename, $filenameFallback = '')
269257
{
270-
if (!\in_array($disposition, array(self::DISPOSITION_ATTACHMENT, self::DISPOSITION_INLINE))) {
271-
throw new \InvalidArgumentException(sprintf('The disposition must be either "%s" or "%s".', self::DISPOSITION_ATTACHMENT, self::DISPOSITION_INLINE));
272-
}
273-
274-
if ('' == $filenameFallback) {
275-
$filenameFallback = $filename;
276-
}
277-
278-
// filenameFallback is not ASCII.
279-
if (!preg_match('/^[\x20-\x7e]*$/', $filenameFallback)) {
280-
throw new \InvalidArgumentException('The filename fallback must only contain ASCII characters.');
281-
}
282-
283-
// percent characters aren't safe in fallback.
284-
if (false !== strpos($filenameFallback, '%')) {
285-
throw new \InvalidArgumentException('The filename fallback cannot contain the "%" character.');
286-
}
287-
288-
// path separators aren't allowed in either.
289-
if (false !== strpos($filename, '/') || false !== strpos($filename, '\\') || false !== strpos($filenameFallback, '/') || false !== strpos($filenameFallback, '\\')) {
290-
throw new \InvalidArgumentException('The filename and the fallback cannot contain the "/" and "\\" characters.');
291-
}
292-
293-
$params = array('filename' => $filenameFallback);
294-
if ($filename !== $filenameFallback) {
295-
$params['filename*'] = "utf-8''".rawurlencode($filename);
296-
}
297-
298-
return $disposition.'; '.HeaderUtils::toString($params, ';');
258+
return HeaderUtils::makeDisposition((string) $disposition, (string) $filename, (string) $filenameFallback);
299259
}
300260

301261
/**

‎src/Symfony/Component/HttpFoundation/Tests/HeaderUtilsTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpFoundation/Tests/HeaderUtilsTest.php
+49Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,4 +82,53 @@ public function testUnquote()
8282
$this->assertEquals('foo "bar"', HeaderUtils::unquote('"foo \"\b\a\r\""'));
8383
$this->assertEquals('foo \\ bar', HeaderUtils::unquote('"foo \\\\ bar"'));
8484
}
85+
86+
/**
87+
* @expectedException \InvalidArgumentException
88+
*/
89+
public function testMakeDispositionInvalidDisposition()
90+
{
91+
HeaderUtils::makeDisposition('invalid', 'foo.html');
92+
}
93+
94+
/**
95+
* @dataProvider provideMakeDisposition
96+
*/
97+
public function testMakeDisposition($disposition, $filename, $filenameFallback, $expected)
98+
{
99+
$this->assertEquals($expected, HeaderUtils::makeDisposition($disposition, $filename, $filenameFallback));
100+
}
101+
102+
public function provideMakeDisposition()
103+
{
104+
return array(
105+
array('attachment', 'foo.html', 'foo.html', 'attachment; filename=foo.html'),
106+
array('attachment', 'foo.html', '', 'attachment; filename=foo.html'),
107+
array('attachment', 'foo bar.html', '', 'attachment; filename="foo bar.html"'),
108+
array('attachment', 'foo "bar".html', '', 'attachment; filename="foo \\"bar\\".html"'),
109+
array('attachment', 'foo%20bar.html', 'foo bar.html', 'attachment; filename="foo bar.html"; filename*=utf-8\'\'foo%2520bar.html'),
110+
array('attachment', 'föö.html', 'foo.html', 'attachment; filename=foo.html; filename*=utf-8\'\'f%C3%B6%C3%B6.html'),
111+
);
112+
}
113+
114+
/**
115+
* @dataProvider provideMakeDispositionFail
116+
* @expectedException \InvalidArgumentException
117+
*/
118+
public function testMakeDispositionFail($disposition, $filename)
119+
{
120+
HeaderUtils::makeDisposition($disposition, $filename);
121+
}
122+
123+
public function provideMakeDispositionFail()
124+
{
125+
return array(
126+
array('attachment', 'foo%20bar.html'),
127+
array('attachment', 'foo/bar.html'),
128+
array('attachment', '/foo.html'),
129+
array('attachment', 'foo\bar.html'),
130+
array('attachment', '\foo.html'),
131+
array('attachment', 'föö.html'),
132+
);
133+
}
85134
}

‎src/Symfony/Component/HttpFoundation/Tests/ResponseHeaderBagTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpFoundation/Tests/ResponseHeaderBagTest.php
-55Lines changed: 0 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -250,26 +250,6 @@ public function testGetCookiesWithInvalidArgument()
250250
$bag->getCookies('invalid_argument');
251251
}
252252

253-
/**
254-
* @expectedException \InvalidArgumentException
255-
*/
256-
public function testMakeDispositionInvalidDisposition()
257-
{
258-
$headers = new ResponseHeaderBag();
259-
260-
$headers->makeDisposition('invalid', 'foo.html');
261-
}
262-
263-
/**
264-
* @dataProvider provideMakeDisposition
265-
*/
266-
public function testMakeDisposition($disposition, $filename, $filenameFallback, $expected)
267-
{
268-
$headers = new ResponseHeaderBag();
269-
270-
$this->assertEquals($expected, $headers->makeDisposition($disposition, $filename, $filenameFallback));
271-
}
272-
273253
public function testToStringDoesntMessUpHeaders()
274254
{
275255
$headers = new ResponseHeaderBag();
@@ -284,41 +264,6 @@ public function testToStringDoesntMessUpHeaders()
284264
$this->assertEquals(array('text/html'), $allHeaders['Content-type']);
285265
}
286266

287-
public function provideMakeDisposition()
288-
{
289-
return array(
290-
array('attachment', 'foo.html', 'foo.html', 'attachment; filename=foo.html'),
291-
array('attachment', 'foo.html', '', 'attachment; filename=foo.html'),
292-
array('attachment', 'foo bar.html', '', 'attachment; filename="foo bar.html"'),
293-
array('attachment', 'foo "bar".html', '', 'attachment; filename="foo \\"bar\\".html"'),
294-
array('attachment', 'foo%20bar.html', 'foo bar.html', 'attachment; filename="foo bar.html"; filename*=utf-8\'\'foo%2520bar.html'),
295-
array('attachment', 'föö.html', 'foo.html', 'attachment; filename=foo.html; filename*=utf-8\'\'f%C3%B6%C3%B6.html'),
296-
);
297-
}
298-
299-
/**
300-
* @dataProvider provideMakeDispositionFail
301-
* @expectedException \InvalidArgumentException
302-
*/
303-
public function testMakeDispositionFail($disposition, $filename)
304-
{
305-
$headers = new ResponseHeaderBag();
306-
307-
$headers->makeDisposition($disposition, $filename);
308-
}
309-
310-
public function provideMakeDispositionFail()
311-
{
312-
return array(
313-
array('attachment', 'foo%20bar.html'),
314-
array('attachment', 'foo/bar.html'),
315-
array('attachment', '/foo.html'),
316-
array('attachment', 'foo\bar.html'),
317-
array('attachment', '\foo.html'),
318-
array('attachment', 'föö.html'),
319-
);
320-
}
321-
322267
public function testDateHeaderAddedOnCreation()
323268
{
324269
$now = time();

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.