X-Git-Url: http://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2Fapi%2FApiFormatBase.php;h=234fcfdd5e3702774319ec730cf8aaf847a74b8d;hb=362a962c8db517f435843af45f0747ead6878252;hp=471ce21553b1b313b2eacd6205f46278a9bc2810;hpb=e69bcfad17d67da5113cdd75276a5f7b5cefb123;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/api/ApiFormatBase.php b/includes/api/ApiFormatBase.php index 471ce21553..234fcfdd5e 100644 --- a/includes/api/ApiFormatBase.php +++ b/includes/api/ApiFormatBase.php @@ -65,8 +65,7 @@ abstract class ApiFormatBase extends ApiBase { * @note If $this->getIsWrappedHtml() || $this->getIsHtml(), you'll very * likely want to fall back to this class's version. * @since 1.27 - * @return string Generally this should be "api-result.$ext", and must be - * encoded for inclusion in a Content-Disposition header's filename parameter. + * @return string Generally this should be "api-result.$ext" */ public function getFilename() { if ( $this->getIsWrappedHtml() ) { @@ -212,10 +211,25 @@ abstract class ApiFormatBase extends ApiBase { // Set a Content-Disposition header so something downloading an API // response uses a halfway-sensible filename (T128209). + $header = 'Content-Disposition: inline'; $filename = $this->getFilename(); - $this->getMain()->getRequest()->response()->header( - "Content-Disposition: inline; filename=\"{$filename}\"" - ); + $compatFilename = mb_convert_encoding( $filename, 'ISO-8859-1' ); + if ( preg_match( '/^[0-9a-zA-Z!#$%&\'*+\-.^_`|~]+$/', $compatFilename ) ) { + $header .= '; filename=' . $compatFilename; + } else { + $header .= '; filename="' + . preg_replace( '/([\0-\x1f"\x5c\x7f])/', '\\\\$1', $compatFilename ) . '"'; + } + if ( $compatFilename !== $filename ) { + $value = "UTF-8''" . rawurlencode( $filename ); + // rawurlencode() encodes more characters than RFC 5987 specifies. Unescape the ones it allows. + $value = strtr( $value, [ + '%21' => '!', '%23' => '#', '%24' => '$', '%26' => '&', '%2B' => '+', '%5E' => '^', + '%60' => '`', '%7C' => '|', + ] ); + $header .= '; filename*=' . $value; + } + $this->getMain()->getRequest()->response()->header( $header ); } /** @@ -284,7 +298,7 @@ abstract class ApiFormatBase extends ApiBase { if ( $this->getIsWrappedHtml() ) { // This is a special output mode mainly intended for ApiSandbox use - $time = microtime( true ) - $this->getConfig()->get( 'RequestTime' ); + $time = $this->getMain()->getRequest()->getElapsedTime(); $json = FormatJson::encode( [ 'status' => (int)( $this->mHttpStatus ?: 200 ), @@ -301,7 +315,7 @@ abstract class ApiFormatBase extends ApiBase { false, FormatJson::ALL_OK ); - // T68776: wfMangleFlashPolicy() is needed to avoid a nasty bug in + // T68776: OutputHandler::mangleFlashPolicy() avoids a nasty bug in // Flash, but what it does isn't friendly for the API, so we need to // work around it. if ( preg_match( '/\<\s*cross-domain-policy\s*\>/i', $json ) ) {