|
1 <?php |
|
2 /** |
|
3 * Session handler for persistent requests and default parameters |
|
4 * |
|
5 * @package Requests |
|
6 * @subpackage Session Handler |
|
7 */ |
|
8 |
|
9 /** |
|
10 * Session handler for persistent requests and default parameters |
|
11 * |
|
12 * Allows various options to be set as default values, and merges both the |
|
13 * options and URL properties together. A base URL can be set for all requests, |
|
14 * with all subrequests resolved from this. Base options can be set (including |
|
15 * a shared cookie jar), then overridden for individual requests. |
|
16 * |
|
17 * @package Requests |
|
18 * @subpackage Session Handler |
|
19 */ |
|
20 class Requests_Session { |
|
21 /** |
|
22 * Base URL for requests |
|
23 * |
|
24 * URLs will be made absolute using this as the base |
|
25 * @var string|null |
|
26 */ |
|
27 public $url = null; |
|
28 |
|
29 /** |
|
30 * Base headers for requests |
|
31 * @var array |
|
32 */ |
|
33 public $headers = array(); |
|
34 |
|
35 /** |
|
36 * Base data for requests |
|
37 * |
|
38 * If both the base data and the per-request data are arrays, the data will |
|
39 * be merged before sending the request. |
|
40 * |
|
41 * @var array |
|
42 */ |
|
43 public $data = array(); |
|
44 |
|
45 /** |
|
46 * Base options for requests |
|
47 * |
|
48 * The base options are merged with the per-request data for each request. |
|
49 * The only default option is a shared cookie jar between requests. |
|
50 * |
|
51 * Values here can also be set directly via properties on the Session |
|
52 * object, e.g. `$session->useragent = 'X';` |
|
53 * |
|
54 * @var array |
|
55 */ |
|
56 public $options = array(); |
|
57 |
|
58 /** |
|
59 * Create a new session |
|
60 * |
|
61 * @param string|null $url Base URL for requests |
|
62 * @param array $headers Default headers for requests |
|
63 * @param array $data Default data for requests |
|
64 * @param array $options Default options for requests |
|
65 */ |
|
66 public function __construct($url = null, $headers = array(), $data = array(), $options = array()) { |
|
67 $this->url = $url; |
|
68 $this->headers = $headers; |
|
69 $this->data = $data; |
|
70 $this->options = $options; |
|
71 |
|
72 if (empty($this->options['cookies'])) { |
|
73 $this->options['cookies'] = new Requests_Cookie_Jar(); |
|
74 } |
|
75 } |
|
76 |
|
77 /** |
|
78 * Get a property's value |
|
79 * |
|
80 * @param string $key Property key |
|
81 * @return mixed|null Property value, null if none found |
|
82 */ |
|
83 public function __get($key) { |
|
84 if (isset($this->options[$key])) { |
|
85 return $this->options[$key]; |
|
86 } |
|
87 |
|
88 return null; |
|
89 } |
|
90 |
|
91 /** |
|
92 * Set a property's value |
|
93 * |
|
94 * @param string $key Property key |
|
95 * @param mixed $value Property value |
|
96 */ |
|
97 public function __set($key, $value) { |
|
98 $this->options[$key] = $value; |
|
99 } |
|
100 |
|
101 /** |
|
102 * Remove a property's value |
|
103 * |
|
104 * @param string $key Property key |
|
105 */ |
|
106 public function __isset($key) { |
|
107 return isset($this->options[$key]); |
|
108 } |
|
109 |
|
110 /** |
|
111 * Remove a property's value |
|
112 * |
|
113 * @param string $key Property key |
|
114 */ |
|
115 public function __unset($key) { |
|
116 if (isset($this->options[$key])) { |
|
117 unset($this->options[$key]); |
|
118 } |
|
119 } |
|
120 |
|
121 /**#@+ |
|
122 * @see request() |
|
123 * @param string $url |
|
124 * @param array $headers |
|
125 * @param array $options |
|
126 * @return Requests_Response |
|
127 */ |
|
128 /** |
|
129 * Send a GET request |
|
130 */ |
|
131 public function get($url, $headers = array(), $options = array()) { |
|
132 return $this->request($url, $headers, null, Requests::GET, $options); |
|
133 } |
|
134 |
|
135 /** |
|
136 * Send a HEAD request |
|
137 */ |
|
138 public function head($url, $headers = array(), $options = array()) { |
|
139 return $this->request($url, $headers, null, Requests::HEAD, $options); |
|
140 } |
|
141 |
|
142 /** |
|
143 * Send a DELETE request |
|
144 */ |
|
145 public function delete($url, $headers = array(), $options = array()) { |
|
146 return $this->request($url, $headers, null, Requests::DELETE, $options); |
|
147 } |
|
148 /**#@-*/ |
|
149 |
|
150 /**#@+ |
|
151 * @see request() |
|
152 * @param string $url |
|
153 * @param array $headers |
|
154 * @param array $data |
|
155 * @param array $options |
|
156 * @return Requests_Response |
|
157 */ |
|
158 /** |
|
159 * Send a POST request |
|
160 */ |
|
161 public function post($url, $headers = array(), $data = array(), $options = array()) { |
|
162 return $this->request($url, $headers, $data, Requests::POST, $options); |
|
163 } |
|
164 |
|
165 /** |
|
166 * Send a PUT request |
|
167 */ |
|
168 public function put($url, $headers = array(), $data = array(), $options = array()) { |
|
169 return $this->request($url, $headers, $data, Requests::PUT, $options); |
|
170 } |
|
171 |
|
172 /** |
|
173 * Send a PATCH request |
|
174 * |
|
175 * Note: Unlike {@see post} and {@see put}, `$headers` is required, as the |
|
176 * specification recommends that should send an ETag |
|
177 * |
|
178 * @link https://tools.ietf.org/html/rfc5789 |
|
179 */ |
|
180 public function patch($url, $headers, $data = array(), $options = array()) { |
|
181 return $this->request($url, $headers, $data, Requests::PATCH, $options); |
|
182 } |
|
183 /**#@-*/ |
|
184 |
|
185 /** |
|
186 * Main interface for HTTP requests |
|
187 * |
|
188 * This method initiates a request and sends it via a transport before |
|
189 * parsing. |
|
190 * |
|
191 * @see Requests::request() |
|
192 * |
|
193 * @throws Requests_Exception On invalid URLs (`nonhttp`) |
|
194 * |
|
195 * @param string $url URL to request |
|
196 * @param array $headers Extra headers to send with the request |
|
197 * @param array|null $data Data to send either as a query string for GET/HEAD requests, or in the body for POST requests |
|
198 * @param string $type HTTP request type (use Requests constants) |
|
199 * @param array $options Options for the request (see {@see Requests::request}) |
|
200 * @return Requests_Response |
|
201 */ |
|
202 public function request($url, $headers = array(), $data = array(), $type = Requests::GET, $options = array()) { |
|
203 $request = $this->merge_request(compact('url', 'headers', 'data', 'options')); |
|
204 |
|
205 return Requests::request($request['url'], $request['headers'], $request['data'], $type, $request['options']); |
|
206 } |
|
207 |
|
208 /** |
|
209 * Send multiple HTTP requests simultaneously |
|
210 * |
|
211 * @see Requests::request_multiple() |
|
212 * |
|
213 * @param array $requests Requests data (see {@see Requests::request_multiple}) |
|
214 * @param array $options Global and default options (see {@see Requests::request}) |
|
215 * @return array Responses (either Requests_Response or a Requests_Exception object) |
|
216 */ |
|
217 public function request_multiple($requests, $options = array()) { |
|
218 foreach ($requests as $key => $request) { |
|
219 $requests[$key] = $this->merge_request($request, false); |
|
220 } |
|
221 |
|
222 $options = array_merge($this->options, $options); |
|
223 |
|
224 // Disallow forcing the type, as that's a per request setting |
|
225 unset($options['type']); |
|
226 |
|
227 return Requests::request_multiple($requests, $options); |
|
228 } |
|
229 |
|
230 /** |
|
231 * Merge a request's data with the default data |
|
232 * |
|
233 * @param array $request Request data (same form as {@see request_multiple}) |
|
234 * @param boolean $merge_options Should we merge options as well? |
|
235 * @return array Request data |
|
236 */ |
|
237 protected function merge_request($request, $merge_options = true) { |
|
238 if ($this->url !== null) { |
|
239 $request['url'] = Requests_IRI::absolutize($this->url, $request['url']); |
|
240 $request['url'] = $request['url']->uri; |
|
241 } |
|
242 |
|
243 if (empty($request['headers'])) { |
|
244 $request['headers'] = array(); |
|
245 } |
|
246 $request['headers'] = array_merge($this->headers, $request['headers']); |
|
247 |
|
248 if (empty($request['data'])) { |
|
249 if (is_array($this->data)) { |
|
250 $request['data'] = $this->data; |
|
251 } |
|
252 } |
|
253 elseif (is_array($request['data']) && is_array($this->data)) { |
|
254 $request['data'] = array_merge($this->data, $request['data']); |
|
255 } |
|
256 |
|
257 if ($merge_options !== false) { |
|
258 $request['options'] = array_merge($this->options, $request['options']); |
|
259 |
|
260 // Disallow forcing the type, as that's a per request setting |
|
261 unset($request['options']['type']); |
|
262 } |
|
263 |
|
264 return $request; |
|
265 } |
|
266 } |