Response::needRetry()   A
last analyzed

Complexity

Conditions 5
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

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