Completed
Push — main ( 87ff1c...380c84 )
by huang
07:19 queued 06:04
created

Response   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 145
Duplicated Lines 0 %

Test Coverage

Coverage 65.85%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 101
c 1
b 0
f 0
dl 0
loc 145
ccs 27
cts 41
cp 0.6585
rs 10
wmc 24

6 Methods

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