* (bug 39284) jquery.tablesorter should not consider "."" or "?"" to be a currency.
* (bug 39273) "Show changes" should not be incorrectly displayed in the Live Preview state.
* Made body-content lang attribute honor the variant language when it is set.
+* (bug 36761) "Mark pages as visited" now submits previously established filter options.
+* (bug 39635) PostgreSQL LOCK IN SHARE MODE option is a syntax error.
+* (bug 36329) Accesskey tooltips for Firefox 14 on Mac should use "ctrl-option-" prefix.
=== API changes in 1.20 ===
* (bug 34316) Add ability to retrieve maximum upload size from MediaWiki API.
* (bug 34927) Output media_type for list=filearchive.
* (bug 28814) add properties to output of action=parse.
* (bug 33224) add variants of content language to meta=siteinfo.
-* (bug 36761) "Mark pages as visited" now submits previously established filter options.
* (bug 32643) action=purge with forcelinkupdate no longer crashes when ratelimit is reached.
* The paraminfo module now also contains result properties for most modules.
* (bug 32348) Allow descending order for list=alllinks.
* (bug 38904) prop=revisions&rvstart=... no longer blows up when continuing.
* (bug 39032) ApiQuery generates help in constructor.
* (bug 11142) Improve file extension blacklist error reporting in API upload.
-* (bug 39635) PostgreSQL LOCK IN SHARE MODE option is a syntax error.
-* (bug 36329) Accesskey tooltips for Firefox 14 on Mac should use "ctrl-option-" prefix.
* (bug 39665) Cache AllowedGenerator array so it doesn't autoload all query classes
on every request.
}
/**
- * 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 );