Parallelise http transfers for trip planner tester
[busui.git] / lib / rolling-curl / .svn / text-base / RollingCurl.php.svn-base
maxious 1 <?php
2 /*
3 Authored by Josh Fraser (www.joshfraser.com)
4 Released under Apache License 2.0
5
6 Maintained by Alexander Makarov, http://rmcreative.ru/
7
8 $Id$
9 */
10
11 /**
12 * Class that represent a single curl request
13 */
14 class RollingCurlRequest {
15 public $url = false;
16 public $method = 'GET';
17 public $post_data = null;
18 public $headers = null;
19 public $options = null;
20
21 /**
22 * @param string $url
23 * @param string $method
24 * @param $post_data
25 * @param $headers
26 * @param $options
27 * @return void
28 */
29 function __construct($url, $method = "GET", $post_data = null, $headers = null, $options = null) {
30 $this->url = $url;
31 $this->method = $method;
32 $this->post_data = $post_data;
33 $this->headers = $headers;
34 $this->options = $options;
35 }
36
37 /**
38 * @return void
39 */
40 public function __destruct() {
41 unset($this->url, $this->method, $this->post_data, $this->headers, $this->options);
42 }
43 }
44
45 /**
46 * RollingCurl custom exception
47 */
48 class RollingCurlException extends Exception {
49 }
50
51 /**
52 * Class that holds a rolling queue of curl requests.
53 *
54 * @throws RollingCurlException
55 */
56 class RollingCurl {
57 /**
58 * @var int
59 *
60 * Window size is the max number of simultaneous connections allowed.
61 *
62 * REMEMBER TO RESPECT THE SERVERS:
63 * Sending too many requests at one time can easily be perceived
64 * as a DOS attack. Increase this window_size if you are making requests
65 * to multiple servers or have permission from the receving server admins.
66 */
67 private $window_size = 5;
68
69 /**
70 * @var float
71 *
72 * Timeout is the timeout used for curl_multi_select.
73 */
74 private $timeout = 10;
75
76 /**
77 * @var string|array
78 *
79 * Callback function to be applied to each result.
80 */
81 private $callback;
82
83 /**
84 * @var array
85 *
86 * Set your base options that you want to be used with EVERY request.
87 */
88 protected $options = array(
89 CURLOPT_SSL_VERIFYPEER => 0,
90 CURLOPT_RETURNTRANSFER => 1,
91 CURLOPT_CONNECTTIMEOUT => 30,
92 CURLOPT_TIMEOUT => 30
93 );
94
95 /**
96 * @var array
97 */
98 private $headers = array();
99
100 /**
101 * @var Request[]
102 *
103 * The request queue
104 */
105 private $requests = array();
106
107 /**
108 * @var RequestMap[]
109 *
110 * Maps handles to request indexes
111 */
112 private $requestMap = array();
113
114 /**
115 * @param $callback
116 * Callback function to be applied to each result.
117 *
118 * Can be specified as 'my_callback_function'
119 * or array($object, 'my_callback_method').
120 *
121 * Function should take three parameters: $response, $info, $request.
122 * $response is response body, $info is additional curl info.
123 * $request is the original request
124 *
125 * @return void
126 */
127 function __construct($callback = null) {
128 $this->callback = $callback;
129 }
130
131 /**
132 * @param string $name
133 * @return mixed
134 */
135 public function __get($name) {
136 return (isset($this->{$name})) ? $this->{$name} : null;
137 }
138
139 /**
140 * @param string $name
141 * @param mixed $value
142 * @return bool
143 */
144 public function __set($name, $value) {
145 // append the base options & headers
146 if ($name == "options" || $name == "headers") {
147 $this->{$name} = $value + $this->{$name};
148 } else {
149 $this->{$name} = $value;
150 }
151 return true;
152 }
153
154 /**
155 * Add a request to the request queue
156 *
157 * @param Request $request
158 * @return bool
159 */
160 public function add($request) {
161 $this->requests[] = $request;
162 return true;
163 }
164
165 /**
166 * Create new Request and add it to the request queue
167 *
168 * @param string $url
169 * @param string $method
170 * @param $post_data
171 * @param $headers
172 * @param $options
173 * @return bool
174 */
175 public function request($url, $method = "GET", $post_data = null, $headers = null, $options = null) {
176 $this->requests[] = new RollingCurlRequest($url, $method, $post_data, $headers, $options);
177 return true;
178 }
179
180 /**
181 * Perform GET request
182 *
183 * @param string $url
184 * @param $headers
185 * @param $options
186 * @return bool
187 */
188 public function get($url, $headers = null, $options = null) {
189 return $this->request($url, "GET", null, $headers, $options);
190 }
191
192 /**
193 * Perform POST request
194 *
195 * @param string $url
196 * @param $post_data
197 * @param $headers
198 * @param $options
199 * @return bool
200 */
201 public function post($url, $post_data = null, $headers = null, $options = null) {
202 return $this->request($url, "POST", $post_data, $headers, $options);
203 }
204
205 /**
206 * Execute processing
207 *
208 * @param int $window_size Max number of simultaneous connections
209 * @return string|bool
210 */
211 public function execute($window_size = null) {
212 // rolling curl window must always be greater than 1
213 if (sizeof($this->requests) == 1) {
214 return $this->single_curl();
215 } else {
216 // start the rolling curl. window_size is the max number of simultaneous connections
217 return $this->rolling_curl($window_size);
218 }
219 }
220
221 /**
222 * Performs a single curl request
223 *
224 * @access private
225 * @return string
226 */
227 private function single_curl() {
228 $ch = curl_init();
229 $request = array_shift($this->requests);
230 $options = $this->get_options($request);
231 curl_setopt_array($ch, $options);
232 $output = curl_exec($ch);
233 $info = cu