forked from yiisoft/yii2-httpclient
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Response.php
193 lines (180 loc) · 5.68 KB
/
Response.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\httpclient;
use yii\web\Cookie;
use yii\web\HeaderCollection;
/**
* Response represents HTTP request response.
*
* @property boolean $isOk Whether response is OK. This property is read-only.
* @property string $statusCode Status code. This property is read-only.
*
* @author Paul Klimov <klimov.paul@gmail.com>
* @since 2.0
*/
class Response extends Message
{
/**
* @inheritdoc
*/
public function getData()
{
$data = parent::getData();
if ($data === null) {
$content = $this->getContent();
if (!empty($content)) {
$data = $this->getParser()->parse($this);
$this->setData($data);
}
}
return $data;
}
/**
* @inheritdoc
*/
public function getCookies()
{
$cookieCollection = parent::getCookies();
if ($cookieCollection->getCount() === 0 && $this->getHeaders()->has('set-cookie')) {
$cookieStrings = $this->getHeaders()->get('set-cookie', [], false);
foreach ($cookieStrings as $cookieString) {
$cookieCollection->add($this->parseCookie($cookieString));
}
}
return $cookieCollection;
}
/**
* Returns status code.
* @throws Exception on failure.
* @return string status code.
*/
public function getStatusCode()
{
$headers = $this->getHeaders();
if ($headers->has('http-code')) {
// take into account possible 'follow location'
$statusCodeHeaders = $headers->get('http-code', null, false);
return empty($statusCodeHeaders) ? null : end($statusCodeHeaders);
}
throw new Exception('Unable to get status code: referred header information is missing.');
}
/**
* Checks if response status code is OK (status code = 20x)
* @return boolean whether response is OK.
*/
public function getIsOk()
{
return strncmp('20', $this->getStatusCode(), 2) === 0;
}
/**
* Returns default format automatically detected from headers and content.
* @return null|string format name, 'null' - if detection failed.
*/
protected function defaultFormat()
{
$format = $this->detectFormatByHeaders($this->getHeaders());
if ($format === null) {
$format = $this->detectFormatByContent($this->getContent());
}
return $format;
}
/**
* Detects format from headers.
* @param HeaderCollection $headers source headers.
* @return null|string format name, 'null' - if detection failed.
*/
protected function detectFormatByHeaders(HeaderCollection $headers)
{
$contentType = $headers->get('content-type');
if (!empty($contentType)) {
if (stripos($contentType, 'json') !== false) {
return Client::FORMAT_JSON;
}
if (stripos($contentType, 'urlencoded') !== false) {
return Client::FORMAT_URLENCODED;
}
if (stripos($contentType, 'xml') !== false) {
return Client::FORMAT_XML;
}
}
return null;
}
/**
* Detects response format from raw content.
* @param string $content raw response content.
* @return null|string format name, 'null' - if detection failed.
*/
protected function detectFormatByContent($content)
{
if (preg_match('/^\\{.*\\}$/is', $content)) {
return Client::FORMAT_JSON;
}
if (preg_match('/^[^=|^&]+=[^=|^&]+(&[^=|^&]+=[^=|^&]+)*$/', $content)) {
return Client::FORMAT_URLENCODED;
}
if (preg_match('/^<.*>$/s', $content)) {
return Client::FORMAT_XML;
}
return null;
}
/**
* Parses cookie value string, creating a [[Cookie]] instance.
* @param string $cookieString cookie header string.
* @return Cookie cookie object.
*/
private function parseCookie($cookieString)
{
$params = [];
$pairs = explode(';', $cookieString);
foreach ($pairs as $number => $pair) {
$pair = trim($pair);
if (strpos($pair, '=') === false) {
$params[$this->normalizeCookieParamName($pair)] = true;
} else {
list($name, $value) = explode('=', $pair, 2);
if ($number === 0) {
$params['name'] = $name;
$params['value'] = urldecode($value);
} else {
$params[$this->normalizeCookieParamName($name)] = urldecode($value);
}
}
}
$cookie = new Cookie();
foreach ($params as $name => $value) {
if ($cookie->canSetProperty($name)) {
// Cookie string may contain custom unsupported params
$cookie->$name = $value;
}
}
return $cookie;
}
/**
* @param string $rawName raw cookie parameter name.
* @return string name of [[Cookie]] field.
*/
private function normalizeCookieParamName($rawName)
{
static $nameMap = [
'expires' => 'expire',
'httponly' => 'httpOnly',
'max-age' => 'maxAge',
];
$name = strtolower($rawName);
if (isset($nameMap[$name])) {
$name = $nameMap[$name];
}
return $name;
}
/**
* @return ParserInterface message parser instance.
*/
private function getParser()
{
return $this->client->getParser($this->getFormat());
}
}