ILIAS  release_4-3 Revision
 All Data Structures Namespaces Files Functions Variables Groups Pages
ParanoidHTTPFetcher.php
Go to the documentation of this file.
1 <?php
2 
19 require_once "Auth/Yadis/HTTPFetcher.php";
20 
21 require_once "Auth/OpenID.php";
22 
31  {
32  $this->reset();
33  }
34 
35  function reset()
36  {
37  $this->headers = array();
38  $this->data = "";
39  }
40 
44  function _writeHeader($ch, $header)
45  {
46  array_push($this->headers, rtrim($header));
47  return strlen($header);
48  }
49 
53  function _writeData($ch, $data)
54  {
55  if (strlen($this->data) > 1024*Auth_OpenID_FETCHER_MAX_RESPONSE_KB) {
56  return 0;
57  } else {
58  $this->data .= $data;
59  return strlen($data);
60  }
61  }
62 
66  function supportsSSL()
67  {
68  $v = curl_version();
69  if(is_array($v)) {
70  return in_array('https', $v['protocols']);
71  } elseif (is_string($v)) {
72  return preg_match('/OpenSSL/i', $v);
73  } else {
74  return 0;
75  }
76  }
77 
78  function get($url, $extra_headers = null)
79  {
80  if (!$this->canFetchURL($url)) {
81  return null;
82  }
83 
84  $stop = time() + $this->timeout;
85  $off = $this->timeout;
86 
87  $redir = true;
88 
89  while ($redir && ($off > 0)) {
90  $this->reset();
91 
92  $c = curl_init();
93 
94  if ($c === false) {
96  "curl_init returned false; could not " .
97  "initialize for URL '%s'", $url);
98  return null;
99  }
100 
101  if (defined('CURLOPT_NOSIGNAL')) {
102  curl_setopt($c, CURLOPT_NOSIGNAL, true);
103  }
104 
105  if (!$this->allowedURL($url)) {
106  Auth_OpenID::log("Fetching URL not allowed: %s",
107  $url);
108  return null;
109  }
110 
111  curl_setopt($c, CURLOPT_WRITEFUNCTION,
112  array($this, "_writeData"));
113  curl_setopt($c, CURLOPT_HEADERFUNCTION,
114  array($this, "_writeHeader"));
115 
116  if ($extra_headers) {
117  curl_setopt($c, CURLOPT_HTTPHEADER, $extra_headers);
118  }
119 
120  $cv = curl_version();
121  if(is_array($cv)) {
122  $curl_user_agent = 'curl/'.$cv['version'];
123  } else {
124  $curl_user_agent = $cv;
125  }
126  curl_setopt($c, CURLOPT_USERAGENT,
127  Auth_OpenID_USER_AGENT.' '.$curl_user_agent);
128  curl_setopt($c, CURLOPT_TIMEOUT, $off);
129  curl_setopt($c, CURLOPT_URL, $url);
130 
131  if (defined('Auth_OpenID_VERIFY_HOST')) {
132  curl_setopt($c, CURLOPT_SSL_VERIFYPEER, true);
133  curl_setopt($c, CURLOPT_SSL_VERIFYHOST, 2);
134  }
135  curl_exec($c);
136 
137  $code = curl_getinfo($c, CURLINFO_HTTP_CODE);
138  $body = $this->data;
139  $headers = $this->headers;
140 
141  if (!$code) {
142  Auth_OpenID::log("Got no response code when fetching %s", $url);
143  Auth_OpenID::log("CURL error (%s): %s",
144  curl_errno($c), curl_error($c));
145  return null;
146  }
147 
148  if (in_array($code, array(301, 302, 303, 307))) {
149  $url = $this->_findRedirect($headers, $url);
150  $redir = true;
151  } else {
152  $redir = false;
153  curl_close($c);
154 
155  if (defined('Auth_OpenID_VERIFY_HOST') &&
156  $this->isHTTPS($url)) {
157  Auth_OpenID::log('OpenID: Verified SSL host %s using '.
158  'curl/get', $url);
159  }
160  $new_headers = array();
161 
162  foreach ($headers as $header) {
163  if (strpos($header, ': ')) {
164  list($name, $value) = explode(': ', $header, 2);
165  $new_headers[$name] = $value;
166  }
167  }
168 
170  "Successfully fetched '%s': GET response code %s",
171  $url, $code);
172 
173  return new Auth_Yadis_HTTPResponse($url, $code,
174  $new_headers, $body);
175  }
176 
177  $off = $stop - time();
178  }
179 
180  return null;
181  }
182 
183  function post($url, $body, $extra_headers = null)
184  {
185  if (!$this->canFetchURL($url)) {
186  return null;
187  }
188 
189  $this->reset();
190 
191  $c = curl_init();
192 
193  if (defined('CURLOPT_NOSIGNAL')) {
194  curl_setopt($c, CURLOPT_NOSIGNAL, true);
195  }
196 
197  curl_setopt($c, CURLOPT_POST, true);
198  curl_setopt($c, CURLOPT_POSTFIELDS, $body);
199  curl_setopt($c, CURLOPT_TIMEOUT, $this->timeout);
200  curl_setopt($c, CURLOPT_URL, $url);
201  curl_setopt($c, CURLOPT_WRITEFUNCTION,
202  array($this, "_writeData"));
203 
204  if (defined('Auth_OpenID_VERIFY_HOST')) {
205  curl_setopt($c, CURLOPT_SSL_VERIFYPEER, true);
206  curl_setopt($c, CURLOPT_SSL_VERIFYHOST, 2);
207  }
208 
209  curl_exec($c);
210 
211  $code = curl_getinfo($c, CURLINFO_HTTP_CODE);
212 
213  if (!$code) {
214  Auth_OpenID::log("Got no response code when fetching %s", $url);
215  Auth_OpenID::log("CURL error (%s): %s",
216  curl_errno($c), curl_error($c));
217  return null;
218  }
219 
220  if (defined('Auth_OpenID_VERIFY_HOST') && $this->isHTTPS($url)) {
221  Auth_OpenID::log('OpenID: Verified SSL host %s using '.
222  'curl/post', $url);
223  }
224  $body = $this->data;
225 
226  curl_close($c);
227 
228  $new_headers = $extra_headers;
229 
230  foreach ($this->headers as $header) {
231  if (strpos($header, ': ')) {
232  list($name, $value) = explode(': ', $header, 2);
233  $new_headers[$name] = $value;
234  }
235 
236  }
237 
238  Auth_OpenID::log("Successfully fetched '%s': POST response code %s",
239  $url, $code);
240 
241  return new Auth_Yadis_HTTPResponse($url, $code,
242  $new_headers, $body);
243  }
244 }
245