Response.php 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. <?php
  2. namespace Qiniu\Http;
  3. /**
  4. * HTTP response Object
  5. */
  6. final class Response
  7. {
  8. public $statusCode;
  9. public $headers;
  10. public $body;
  11. public $error;
  12. private $jsonData;
  13. public $duration;
  14. /** @var array Mapping of status codes to reason phrases */
  15. private static $statusTexts = array(
  16. 100 => 'Continue',
  17. 101 => 'Switching Protocols',
  18. 102 => 'Processing',
  19. 200 => 'OK',
  20. 201 => 'Created',
  21. 202 => 'Accepted',
  22. 203 => 'Non-Authoritative Information',
  23. 204 => 'No Content',
  24. 205 => 'Reset Content',
  25. 206 => 'Partial Content',
  26. 207 => 'Multi-Status',
  27. 208 => 'Already Reported',
  28. 226 => 'IM Used',
  29. 300 => 'Multiple Choices',
  30. 301 => 'Moved Permanently',
  31. 302 => 'Found',
  32. 303 => 'See Other',
  33. 304 => 'Not Modified',
  34. 305 => 'Use Proxy',
  35. 307 => 'Temporary Redirect',
  36. 308 => 'Permanent Redirect',
  37. 400 => 'Bad Request',
  38. 401 => 'Unauthorized',
  39. 402 => 'Payment Required',
  40. 403 => 'Forbidden',
  41. 404 => 'Not Found',
  42. 405 => 'Method Not Allowed',
  43. 406 => 'Not Acceptable',
  44. 407 => 'Proxy Authentication Required',
  45. 408 => 'Request Timeout',
  46. 409 => 'Conflict',
  47. 410 => 'Gone',
  48. 411 => 'Length Required',
  49. 412 => 'Precondition Failed',
  50. 413 => 'Request Entity Too Large',
  51. 414 => 'Request-URI Too Long',
  52. 415 => 'Unsupported Media Type',
  53. 416 => 'Requested Range Not Satisfiable',
  54. 417 => 'Expectation Failed',
  55. 422 => 'Unprocessable Entity',
  56. 423 => 'Locked',
  57. 424 => 'Failed Dependency',
  58. 425 => 'Reserved for WebDAV advanced collections expired proposal',
  59. 426 => 'Upgrade required',
  60. 428 => 'Precondition Required',
  61. 429 => 'Too Many Requests',
  62. 431 => 'Request Header Fields Too Large',
  63. 500 => 'Internal Server Error',
  64. 501 => 'Not Implemented',
  65. 502 => 'Bad Gateway',
  66. 503 => 'Service Unavailable',
  67. 504 => 'Gateway Timeout',
  68. 505 => 'HTTP Version Not Supported',
  69. 506 => 'Variant Also Negotiates (Experimental)',
  70. 507 => 'Insufficient Storage',
  71. 508 => 'Loop Detected',
  72. 510 => 'Not Extended',
  73. 511 => 'Network Authentication Required',
  74. );
  75. /**
  76. * @param int $code 状态码
  77. * @param double $duration 请求时长
  78. * @param array $headers 响应头部
  79. * @param string $body 响应内容
  80. * @param string $error 错误描述
  81. */
  82. public function __construct($code, $duration, array $headers = array(), $body = null, $error = null)
  83. {
  84. $this->statusCode = $code;
  85. $this->duration = $duration;
  86. $this->headers = $headers;
  87. $this->body = $body;
  88. $this->error = $error;
  89. $this->jsonData = null;
  90. if ($error !== null) {
  91. return;
  92. }
  93. if ($body === null) {
  94. if ($code >= 400) {
  95. $this->error = self::$statusTexts[$code];
  96. }
  97. return;
  98. }
  99. if (self::isJson($headers)) {
  100. try {
  101. $jsonData = self::bodyJson($body);
  102. if ($code >= 400) {
  103. $this->error = $body;
  104. if ($jsonData['error'] !== null) {
  105. $this->error = $jsonData['error'];
  106. }
  107. }
  108. $this->jsonData = $jsonData;
  109. } catch (\InvalidArgumentException $e) {
  110. $this->error = $body;
  111. if ($code >= 200 && $code < 300) {
  112. $this->error = $e->getMessage();
  113. }
  114. }
  115. } elseif ($code >= 400) {
  116. $this->error = $body;
  117. }
  118. return;
  119. }
  120. public function json()
  121. {
  122. return $this->jsonData;
  123. }
  124. private static function bodyJson($body)
  125. {
  126. return \Qiniu\json_decode((string) $body, true, 512);
  127. }
  128. public function xVia()
  129. {
  130. $via = $this->headers['X-Via'];
  131. if ($via === null) {
  132. $via = $this->headers['X-Px'];
  133. }
  134. if ($via === null) {
  135. $via = $this->headers['Fw-Via'];
  136. }
  137. return $via;
  138. }
  139. public function xLog()
  140. {
  141. return $this->headers['X-Log'];
  142. }
  143. public function xReqId()
  144. {
  145. return $this->headers['X-Reqid'];
  146. }
  147. public function ok()
  148. {
  149. return $this->statusCode >= 200 && $this->statusCode < 300 && $this->error === null;
  150. }
  151. public function needRetry()
  152. {
  153. $code = $this->statusCode;
  154. if ($code < 0 || ($code / 100 === 5 and $code !== 579) || $code === 996) {
  155. return true;
  156. }
  157. }
  158. private static function isJson($headers)
  159. {
  160. return array_key_exists('Content-Type', $headers) &&
  161. strpos($headers['Content-Type'], 'application/json') === 0;
  162. }
  163. }