HttpError.php 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. <?php
  2. /**
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation; either version 2 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License along
  14. * with this program; if not, write to the Free Software Foundation, Inc.,
  15. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  16. * http://www.gnu.org/copyleft/gpl.html
  17. *
  18. * @file
  19. */
  20. use MediaWiki\Logger\LoggerFactory;
  21. /**
  22. * Show an error that looks like an HTTP server error.
  23. * Replacement for wfHttpError().
  24. *
  25. * @since 1.19
  26. * @ingroup Exception
  27. */
  28. class HttpError extends MWException {
  29. private $httpCode, $header, $content;
  30. /**
  31. * @param int $httpCode HTTP status code to send to the client
  32. * @param string|Message $content Content of the message
  33. * @param string|Message|null $header Content of the header (\<title\> and \<h1\>)
  34. */
  35. public function __construct( $httpCode, $content, $header = null ) {
  36. parent::__construct( $content );
  37. $this->httpCode = (int)$httpCode;
  38. $this->header = $header;
  39. $this->content = $content;
  40. }
  41. /**
  42. * We don't want the default exception logging as we got our own logging set
  43. * up in self::report.
  44. *
  45. * @see MWException::isLoggable
  46. *
  47. * @since 1.24
  48. * @return bool
  49. */
  50. public function isLoggable() {
  51. return false;
  52. }
  53. /**
  54. * Returns the HTTP status code supplied to the constructor.
  55. *
  56. * @return int
  57. */
  58. public function getStatusCode() {
  59. return $this->httpCode;
  60. }
  61. /**
  62. * Report and log the HTTP error.
  63. * Sends the appropriate HTTP status code and outputs an
  64. * HTML page with an error message.
  65. */
  66. public function report() {
  67. $this->doLog();
  68. HttpStatus::header( $this->httpCode );
  69. header( 'Content-type: text/html; charset=utf-8' );
  70. print $this->getHTML();
  71. }
  72. private function doLog() {
  73. $logger = LoggerFactory::getInstance( 'HttpError' );
  74. $content = $this->content;
  75. if ( $content instanceof Message ) {
  76. $content = $content->text();
  77. }
  78. $context = [
  79. 'file' => $this->getFile(),
  80. 'line' => $this->getLine(),
  81. 'http_code' => $this->httpCode,
  82. ];
  83. $logMsg = "$content ({http_code}) from {file}:{line}";
  84. if ( $this->getStatusCode() < 500 ) {
  85. $logger->info( $logMsg, $context );
  86. } else {
  87. $logger->error( $logMsg, $context );
  88. }
  89. }
  90. /**
  91. * Returns HTML for reporting the HTTP error.
  92. * This will be a minimal but complete HTML document.
  93. *
  94. * @return string HTML
  95. */
  96. public function getHTML() {
  97. if ( $this->header === null ) {
  98. $titleHtml = htmlspecialchars( HttpStatus::getMessage( $this->httpCode ) );
  99. } elseif ( $this->header instanceof Message ) {
  100. $titleHtml = $this->header->escaped();
  101. } else {
  102. $titleHtml = htmlspecialchars( $this->header );
  103. }
  104. if ( $this->content instanceof Message ) {
  105. $contentHtml = $this->content->escaped();
  106. } else {
  107. $contentHtml = nl2br( htmlspecialchars( $this->content ) );
  108. }
  109. return "<!DOCTYPE html>\n" .
  110. "<html><head><title>$titleHtml</title></head>\n" .
  111. "<body><h1>$titleHtml</h1><p>$contentHtml</p></body></html>\n";
  112. }
  113. }