Bump version from rc.0 to rc.2
[lhc/web/wiklou.git] / includes / api / ApiFormatBase.php
index 5e14e30..234fcfd 100644 (file)
@@ -1,9 +1,5 @@
 <?php
 /**
- *
- *
- * Created on Sep 19, 2006
- *
  * Copyright © 2006 Yuri Astrakhan "<Firstname><Lastname>@gmail.com"
  *
  * This program is free software; you can redistribute it and/or modify
@@ -69,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() ) {
@@ -216,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 );
        }
 
        /**
@@ -288,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 ),
@@ -305,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 ) ) {