Esempio n. 1
0
 /**
  * Report and log the HTTP error.
  * Sends the appropriate HTTP status code and outputs an
  * HTML page with an error message.
  */
 public function report()
 {
     $this->doLog();
     HttpStatus::header($this->httpCode);
     header('Content-type: text/html; charset=utf-8');
     print $this->getHTML();
 }
Esempio n. 2
0
 public function execute($par = '')
 {
     $this->getOutput()->disable();
     if (wfReadOnly()) {
         // HTTP 423 Locked
         HttpStatus::header(423);
         print 'Wiki is in read-only mode';
         return;
     } elseif (!$this->getRequest()->wasPosted()) {
         HttpStatus::header(400);
         print 'Request must be POSTed';
         return;
     }
     $optional = array('maxjobs' => 0, 'maxtime' => 30, 'type' => false, 'async' => true);
     $required = array_flip(array('title', 'tasks', 'signature', 'sigexpiry'));
     $params = array_intersect_key($this->getRequest()->getValues(), $required + $optional);
     $missing = array_diff_key($required, $params);
     if (count($missing)) {
         HttpStatus::header(400);
         print 'Missing parameters: ' . implode(', ', array_keys($missing));
         return;
     }
     $squery = $params;
     unset($squery['signature']);
     $correctSignature = self::getQuerySignature($squery, $this->getConfig()->get('SecretKey'));
     $providedSignature = $params['signature'];
     $verified = is_string($providedSignature) && hash_equals($correctSignature, $providedSignature);
     if (!$verified || $params['sigexpiry'] < time()) {
         HttpStatus::header(400);
         print 'Invalid or stale signature provided';
         return;
     }
     // Apply any default parameter values
     $params += $optional;
     if ($params['async']) {
         // Client will usually disconnect before checking the response,
         // but it needs to know when it is safe to disconnect. Until this
         // reaches ignore_user_abort(), it is not safe as the jobs won't run.
         ignore_user_abort(true);
         // jobs may take a bit of time
         // HTTP 202 Accepted
         HttpStatus::header(202);
         ob_flush();
         flush();
         // Once the client receives this response, it can disconnect
     }
     // Do all of the specified tasks...
     if (in_array('jobs', explode('|', $params['tasks']))) {
         $runner = new JobRunner(LoggerFactory::getInstance('runJobs'));
         $response = $runner->run(array('type' => $params['type'], 'maxJobs' => $params['maxjobs'] ? $params['maxjobs'] : 1, 'maxTime' => $params['maxtime'] ? $params['maxjobs'] : 30));
         if (!$params['async']) {
             print FormatJson::encode($response, true);
         }
     }
 }
Esempio n. 3
0
# big mess.
if (ob_get_level() == 0) {
    require_once "{$IP}/includes/OutputHandler.php";
    ob_start('wfOutputHandler');
}
if (!defined('MW_NO_SETUP')) {
    require_once "{$IP}/includes/Setup.php";
}
# Multiple DBs or commits might be used; keep the request as transactional as possible
if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'POST') {
    ignore_user_abort(true);
}
if (!defined('MW_API') && RequestContext::getMain()->getRequest()->getHeader('Promise-Non-Write-API-Action')) {
    header('Cache-Control: no-cache');
    header('Content-Type: text/html; charset=utf-8');
    HttpStatus::header(400);
    $error = wfMessage('nonwrite-api-promise-error')->escaped();
    $content = <<<EOT
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8" /></head>
<body>
{$error}
</body>
</html>

EOT;
    header('Content-Length: ' . strlen($content));
    echo $content;
    die;
}
Esempio n. 4
0
 /**
  * Output an HTTP status code header
  * @since 1.26
  * @param int $code Status code
  */
 public function statusHeader($code)
 {
     HttpStatus::header($code);
 }
Esempio n. 5
0
 /**
  * Respond with HTTP 304 Not Modified if appropiate.
  *
  * If there's an If-None-Match header, respond with a 304 appropriately
  * and clear out the output buffer. If the client cache is too old then do nothing.
  *
  * @param ResourceLoaderContext $context
  * @param string $etag ETag header value
  * @return bool True if HTTP 304 was sent and output handled
  */
 protected function tryRespondNotModified(ResourceLoaderContext $context, $etag)
 {
     // See RFC 2616 § 14.26 If-None-Match
     // http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.26
     $clientKeys = $context->getRequest()->getHeader('If-None-Match', WebRequest::GETHEADER_LIST);
     // Never send 304s in debug mode
     if ($clientKeys !== false && !$context->getDebug() && in_array($etag, $clientKeys)) {
         // There's another bug in ob_gzhandler (see also the comment at
         // the top of this function) that causes it to gzip even empty
         // responses, meaning it's impossible to produce a truly empty
         // response (because the gzip header is always there). This is
         // a problem because 304 responses have to be completely empty
         // per the HTTP spec, and Firefox behaves buggily when they're not.
         // See also http://bugs.php.net/bug.php?id=51579
         // To work around this, we tear down all output buffering before
         // sending the 304.
         wfResetOutputBuffers(true);
         HttpStatus::header(304);
         $this->sendResponseHeaders($context, $etag, false);
         return true;
     }
     return false;
 }
Esempio n. 6
0
/**
 * Provide a simple HTTP error.
 *
 * @param int|string $code
 * @param string $label
 * @param string $desc
 */
function wfHttpError($code, $label, $desc)
{
    global $wgOut;
    HttpStatus::header($code);
    if ($wgOut) {
        $wgOut->disable();
        $wgOut->sendCacheControl();
    }
    header('Content-type: text/html; charset=utf-8');
    print '<!DOCTYPE html>' . '<html><head><title>' . htmlspecialchars($label) . '</title></head><body><h1>' . htmlspecialchars($label) . '</h1><p>' . nl2br(htmlspecialchars($desc)) . "</p></body></html>\n";
}
Esempio n. 7
0
/**
 * Output a thumbnail generation error message
 *
 * @param int $status
 * @param string $msgHtml HTML
 * @return void
 */
function wfThumbError($status, $msgHtml)
{
    global $wgShowHostnames;
    header('Cache-Control: no-cache');
    header('Content-Type: text/html; charset=utf-8');
    if ($status == 400 || $status == 404 || $status == 429) {
        HttpStatus::header($status);
    } elseif ($status == 403) {
        HttpStatus::header(403);
        header('Vary: Cookie');
    } else {
        HttpStatus::header(500);
    }
    if ($wgShowHostnames) {
        header('X-MW-Thumbnail-Renderer: ' . wfHostname());
        $url = htmlspecialchars(isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '');
        $hostname = htmlspecialchars(wfHostname());
        $debug = "<!-- {$url} -->\n<!-- {$hostname} -->\n";
    } else {
        $debug = '';
    }
    $content = <<<EOT
<!DOCTYPE html>
<html><head>
<meta charset="UTF-8" />
<title>Error generating thumbnail</title>
</head>
<body>
<h1>Error generating thumbnail</h1>
<p>
{$msgHtml}
</p>
{$debug}
</body>
</html>

EOT;
    header('Content-Length: ' . strlen($content));
    echo $content;
}
Esempio n. 8
0
 /**
  * Call this function used in preparation before streaming a file.
  * This function does the following:
  * (a) sends Last-Modified, Content-type, and Content-Disposition headers
  * (b) cancels any PHP output buffering and automatic gzipping of output
  * (c) sends Content-Length header based on HTTP_IF_MODIFIED_SINCE check
  *
  * @param string $path Storage path or file system path
  * @param array|bool $info File stat info with 'mtime' and 'size' fields
  * @param array $headers Additional headers to send
  * @param bool $sendErrors Send error messages if errors occur (like 404)
  * @return int|bool READY_STREAM, NOT_MODIFIED, or false on failure
  */
 public static function prepareForStream($path, $info, $headers = array(), $sendErrors = true)
 {
     if (!is_array($info)) {
         if ($sendErrors) {
             HttpStatus::header(404);
             header('Cache-Control: no-cache');
             header('Content-Type: text/html; charset=utf-8');
             $encFile = htmlspecialchars($path);
             $encScript = htmlspecialchars($_SERVER['SCRIPT_NAME']);
             echo "<html><body>\n\t\t\t\t\t<h1>File not found</h1>\n\t\t\t\t\t<p>Although this PHP script ({$encScript}) exists, the file requested for output\n\t\t\t\t\t({$encFile}) does not.</p>\n\t\t\t\t\t</body></html>\n\t\t\t\t\t";
         }
         return false;
     }
     // Sent Last-Modified HTTP header for client-side caching
     header('Last-Modified: ' . wfTimestamp(TS_RFC2822, $info['mtime']));
     // Cancel output buffering and gzipping if set
     wfResetOutputBuffers();
     $type = self::contentTypeFromPath($path);
     if ($type && $type != 'unknown/unknown') {
         header("Content-type: {$type}");
     } else {
         // Send a content type which is not known to Internet Explorer, to
         // avoid triggering IE's content type detection. Sending a standard
         // unknown content type here essentially gives IE license to apply
         // whatever content type it likes.
         header('Content-type: application/x-wiki');
     }
     // Don't stream it out as text/html if there was a PHP error
     if (headers_sent()) {
         echo "Headers already sent, terminating.\n";
         return false;
     }
     // Send additional headers
     foreach ($headers as $header) {
         header($header);
     }
     // Don't send if client has up to date cache
     if (!empty($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
         $modsince = preg_replace('/;.*$/', '', $_SERVER['HTTP_IF_MODIFIED_SINCE']);
         if (wfTimestamp(TS_UNIX, $info['mtime']) <= strtotime($modsince)) {
             ini_set('zlib.output_compression', 0);
             HttpStatus::header(304);
             return self::NOT_MODIFIED;
             // ok
         }
     }
     header('Content-Length: ' . $info['size']);
     return self::READY_STREAM;
     // ok
 }
Esempio n. 9
0
 /**
  * Construct the header and output it
  */
 function sendHeaders()
 {
     if ($this->mResponseCode) {
         // For back-compat, it is supported that mResponseCode be a string like " 200 OK"
         // (with leading space and the status message after). Cast response code to an integer
         // to take advantage of PHP's conversion rules which will turn "  200 OK" into 200.
         // http://php.net/string#language.types.string.conversion
         $n = intval(trim($this->mResponseCode));
         HttpStatus::header($n);
     }
     header("Content-Type: " . $this->mContentType);
     if ($this->mLastModified) {
         header("Last-Modified: " . $this->mLastModified);
     } else {
         header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
     }
     if ($this->mCacheDuration) {
         # If CDN caches are configured, tell them to cache the response,
         # and tell the client to always check with the CDN. Otherwise,
         # tell the client to use a cached copy, without a way to purge it.
         if ($this->mConfig->get('UseSquid')) {
             # Expect explicit purge of the proxy cache, but require end user agents
             # to revalidate against the proxy on each visit.
             # Surrogate-Control controls our CDN, Cache-Control downstream caches
             if ($this->mConfig->get('UseESI')) {
                 header('Surrogate-Control: max-age=' . $this->mCacheDuration . ', content="ESI/1.0"');
                 header('Cache-Control: s-maxage=0, must-revalidate, max-age=0');
             } else {
                 header('Cache-Control: s-maxage=' . $this->mCacheDuration . ', must-revalidate, max-age=0');
             }
         } else {
             # Let the client do the caching. Cache is not purged.
             header("Expires: " . gmdate("D, d M Y H:i:s", time() + $this->mCacheDuration) . " GMT");
             header("Cache-Control: s-maxage={$this->mCacheDuration}," . "public,max-age={$this->mCacheDuration}");
         }
     } else {
         # always expired, always modified
         header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
         // Date in the past
         header("Cache-Control: no-cache, must-revalidate");
         // HTTP/1.1
         header("Pragma: no-cache");
         // HTTP/1.0
     }
     if ($this->mVary) {
         header("Vary: " . $this->mVary);
     }
 }
Esempio n. 10
0
/**
 * Issue a standard HTTP 403 Forbidden header ($msg1-a message index, not a message) and an
 * error message ($msg2, also a message index), (both required) then end the script
 * subsequent arguments to $msg2 will be passed as parameters only for replacing in $msg2
 * @param string $msg1
 * @param string $msg2
 */
function wfForbidden($msg1, $msg2)
{
    global $wgImgAuthDetails;
    $args = func_get_args();
    array_shift($args);
    array_shift($args);
    $args = isset($args[0]) && is_array($args[0]) ? $args[0] : $args;
    $msgHdr = wfMessage($msg1)->escaped();
    $detailMsgKey = $wgImgAuthDetails ? $msg2 : 'badaccess-group0';
    $detailMsg = wfMessage($detailMsgKey, $args)->escaped();
    wfDebugLog('img_auth', "wfForbidden Hdr: " . wfMessage($msg1)->inLanguage('en')->text() . " Msg: " . wfMessage($msg2, $args)->inLanguage('en')->text());
    HttpStatus::header(403);
    header('Cache-Control: no-cache');
    header('Content-Type: text/html; charset=utf-8');
    echo <<<ENDS
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>{$msgHdr}</title>
</head>
<body>
<h1>{$msgHdr}</h1>
<p>{$detailMsg}</p>
</body>
</html>
ENDS;
}
Esempio n. 11
0
 private static function statusHeader($code)
 {
     if (!headers_sent()) {
         HttpStatus::header($code);
     }
 }
Esempio n. 12
0
 /**
  * Send out a standard 404 message for a file
  *
  * @param string $fname Full name and path of the file to stream
  * @param integer $flags Bitfield of STREAM_* constants
  * @since 1.24
  */
 public static function send404Message($fname, $flags = 0)
 {
     if (($flags & self::STREAM_HEADLESS) == 0) {
         HttpStatus::header(404);
         header('Cache-Control: no-cache');
         header('Content-Type: text/html; charset=utf-8');
     }
     $encFile = htmlspecialchars($fname);
     $encScript = htmlspecialchars($_SERVER['SCRIPT_NAME']);
     echo "<!DOCTYPE html><html><body>\n\t\t\t<h1>File not found</h1>\n\t\t\t<p>Although this PHP script ({$encScript}) exists, the file requested for output\n\t\t\t({$encFile}) does not.</p>\n\t\t\t</body></html>\n\t\t\t";
 }