}
/**
- * Build a Content-Disposition header value per RFC 6266
+ * Build a Content-Disposition header value per RFC 6266.
*
* @param $type string One of (attachment, inline)
* @param $filename string Suggested file name (should not contain slashes)
* @return string
* @since 1.20
*/
- final public static function makeContentDisposition( $type, $filename ) {
+ final public static function makeContentDisposition( $type, $filename = '' ) {
+ $parts = array();
+
$type = strtolower( $type );
- $type = in_array( $type, array( 'inline', 'attachment' ) ) ? $type : 'inline';
- return "$type; filename*=UTF-8''" . rawurlencode( basename( $filename ) );
+ if ( !in_array( $type, array( 'inline', 'attachment' ) ) ) {
+ throw new MWException( "Invalid Content-Disposition type '$type'." );
+ }
+ $parts[] = $type;
+
+ if ( strlen( $filename ) ) {
+ $parts[] = "filename*=UTF-8''" . rawurlencode( basename( $filename ) );
+ }
+
+ return implode( ';', $parts );
}
/**
return false;
}
+ /**
+ * @param $disposition string Content-Disposition header value
+ * @return string Truncated Content-Disposition header value to meet Swift limits
+ */
+ protected function truncDisp( $disposition ) {
+ $res = '';
+ foreach ( explode( ';', $disposition ) as $part ) {
+ $part = trim( $part );
+ $new = ( $res === '' ) ? $part : "{$res};{$part}";
+ if ( strlen( $new ) <= 255 ) {
+ $res = $new;
+ } else {
+ break; // too long; sigh
+ }
+ }
+ return $res;
+ }
+
/**
* @see FileBackendStore::doCreateInternal()
* @return Status
}
// Set the Content-Disposition header if requested
if ( isset( $params['disposition'] ) ) {
- $obj->headers['Content-Disposition'] = $params['disposition'];
+ $obj->headers['Content-Disposition'] = $this->truncDisp( $params['disposition'] );
}
if ( !empty( $params['async'] ) ) { // deferred
$op = $obj->write_async( $params['content'] );
}
// Set the Content-Disposition header if requested
if ( isset( $params['disposition'] ) ) {
- $obj->headers['Content-Disposition'] = $params['disposition'];
+ $obj->headers['Content-Disposition'] = $this->truncDisp( $params['disposition'] );
}
if ( !empty( $params['async'] ) ) { // deferred
wfSuppressWarnings();
$dstObj = new CF_Object( $dContObj, $dstRel, false, false ); // skip HEAD
$hdrs = array(); // source file headers to override with new values
if ( isset( $params['disposition'] ) ) {
- $hdrs['Content-Disposition'] = $params['disposition'];
+ $hdrs['Content-Disposition'] = $this->truncDisp( $params['disposition'] );
}
if ( !empty( $params['async'] ) ) { // deferred
$op = $sContObj->copy_object_to_async( $srcRel, $dContObj, $dstRel, null, $hdrs );
$dstObj = new CF_Object( $dContObj, $dstRel, false, false ); // skip HEAD
$hdrs = array(); // source file headers to override with new values
if ( isset( $params['disposition'] ) ) {
- $hdrs['Content-Disposition'] = $params['disposition'];
+ $hdrs['Content-Disposition'] = $this->truncDisp( $params['disposition'] );
}
if ( !empty( $params['async'] ) ) { // deferred
$op = $sContObj->move_object_to_async( $srcRel, $dContObj, $dstRel, null, $hdrs );