Completed
Push — main ( dcb65b...a508c0 )
by huang
03:35
created

Response   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 147
Duplicated Lines 0 %

Test Coverage

Coverage 82.93%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 101
c 1
b 0
f 0
dl 0
loc 147
ccs 34
cts 41
cp 0.8293
rs 10
wmc 24

6 Methods

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