| 
									
										
										
										
											2009-10-28 17:28:00 -04:00
										 |  |  | <?php | 
					
						
							| 
									
										
										
										
											2009-09-15 21:50:19 -04:00
										 |  |  | /** | 
					
						
							| 
									
										
										
										
											2009-09-15 22:31:52 -04:00
										 |  |  |  * StatusNet, the distributed open-source microblogging tool | 
					
						
							| 
									
										
										
										
											2009-09-15 21:50:19 -04:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Utility class for wrapping Curl | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * PHP version 5 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * LICENCE: This program is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  |  * it under the terms of the GNU Affero General Public License as published by | 
					
						
							|  |  |  |  * the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  |  * (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU Affero General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU Affero General Public License | 
					
						
							|  |  |  |  * along with this program.  If not, see <http://www.gnu.org/licenses/>. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @category  HTTP | 
					
						
							| 
									
										
										
										
											2009-09-15 22:31:52 -04:00
										 |  |  |  * @package   StatusNet | 
					
						
							| 
									
										
										
										
											2009-09-15 21:50:19 -04:00
										 |  |  |  * @author    Evan Prodromou <evan@status.net> | 
					
						
							|  |  |  |  * @copyright 2009 StatusNet, Inc. | 
					
						
							|  |  |  |  * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 | 
					
						
							| 
									
										
										
										
											2009-09-15 22:31:52 -04:00
										 |  |  |  * @link      http://status.net/ | 
					
						
							| 
									
										
										
										
											2009-09-15 21:50:19 -04:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if (!defined('STATUSNET')) { | 
					
						
							|  |  |  |     exit(1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | define(CURLCLIENT_VERSION, "0.1"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Wrapper for Curl | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Makes Curl HTTP client calls within our HTTPClient framework | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @category HTTP | 
					
						
							| 
									
										
										
										
											2009-09-15 22:31:52 -04:00
										 |  |  |  * @package  StatusNet | 
					
						
							| 
									
										
										
										
											2009-09-15 21:50:19 -04:00
										 |  |  |  * @author   Evan Prodromou <evan@status.net> | 
					
						
							|  |  |  |  * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 | 
					
						
							| 
									
										
										
										
											2009-09-15 22:31:52 -04:00
										 |  |  |  * @link     http://status.net/ | 
					
						
							| 
									
										
										
										
											2009-09-15 21:50:19 -04:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class CurlClient extends HTTPClient | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     function __construct() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function head($url, $headers=null) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $ch = curl_init($url); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $this->setup($ch); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         curl_setopt_array($ch, | 
					
						
							|  |  |  |                           array(CURLOPT_NOBODY => true)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-15 21:55:36 -04:00
										 |  |  |         if (!is_null($headers)) { | 
					
						
							|  |  |  |             curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $result = curl_exec($ch); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         curl_close($ch); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $this->parseResults($result); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function get($url, $headers=null) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $ch = curl_init($url); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $this->setup($ch); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!is_null($headers)) { | 
					
						
							|  |  |  |             curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-15 21:50:19 -04:00
										 |  |  |         $result = curl_exec($ch); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-15 21:55:36 -04:00
										 |  |  |         curl_close($ch); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-15 21:50:19 -04:00
										 |  |  |         return $this->parseResults($result); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-15 22:14:15 -04:00
										 |  |  |     function post($url, $headers=null, $body=null) | 
					
						
							| 
									
										
										
										
											2009-09-15 22:05:57 -04:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2009-09-15 22:14:15 -04:00
										 |  |  |         $ch = curl_init($url); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $this->setup($ch); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         curl_setopt($ch, CURLOPT_POST, true); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!is_null($body)) { | 
					
						
							|  |  |  |             curl_setopt($ch, CURLOPT_POSTFIELDS, $body); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!is_null($headers)) { | 
					
						
							|  |  |  |             curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $result = curl_exec($ch); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         curl_close($ch); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $this->parseResults($result); | 
					
						
							| 
									
										
										
										
											2009-09-15 22:05:57 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-15 21:50:19 -04:00
										 |  |  |     function setup($ch) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         curl_setopt_array($ch, | 
					
						
							| 
									
										
										
										
											2009-09-15 22:05:57 -04:00
										 |  |  |                           array(CURLOPT_USERAGENT => $this->userAgent(), | 
					
						
							| 
									
										
										
										
											2009-09-15 21:50:19 -04:00
										 |  |  |                                 CURLOPT_HEADER => true, | 
					
						
							| 
									
										
										
										
											2009-09-15 21:55:36 -04:00
										 |  |  |                                 CURLOPT_RETURNTRANSFER => true)); | 
					
						
							| 
									
										
										
										
											2009-09-15 21:50:19 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function userAgent() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $version = curl_version(); | 
					
						
							|  |  |  |         return parent::userAgent() . " CurlClient/".CURLCLIENT_VERSION . " cURL/" . $version['version']; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function parseResults($results) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $resp = new HTTPResponse(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $lines = explode("\r\n", $results); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (preg_match("#^HTTP/1.[01] (\d\d\d) .+$#", $lines[0], $match)) { | 
					
						
							|  |  |  |             $resp->code = $match[1]; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             throw Exception("Bad format: initial line is not HTTP status line"); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $lastk = null; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for ($i = 1; $i < count($lines); $i++) { | 
					
						
							|  |  |  |             $l =& $lines[$i]; | 
					
						
							|  |  |  |             if (mb_strlen($l) == 0) { | 
					
						
							|  |  |  |                 $resp->body = implode("\r\n", array_slice($lines, $i + 1)); | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             if (preg_match("#^(\S+):\s+(.*)$#", $l, $match)) { | 
					
						
							|  |  |  |                 $k = $match[1]; | 
					
						
							|  |  |  |                 $v = $match[2]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (array_key_exists($k, $resp->headers)) { | 
					
						
							|  |  |  |                     if (is_array($resp->headers[$k])) { | 
					
						
							|  |  |  |                         $resp->headers[$k][] = $v; | 
					
						
							|  |  |  |                     } else { | 
					
						
							|  |  |  |                         $resp->headers[$k] = array($resp->headers[$k], $v); | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } else { | 
					
						
							|  |  |  |                     $resp->headers[$k] = $v; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 $lastk = $k; | 
					
						
							|  |  |  |             } else if (preg_match("#^\s+(.*)$#", $l, $match)) { | 
					
						
							|  |  |  |                 // continuation line
 | 
					
						
							|  |  |  |                 if (is_null($lastk)) { | 
					
						
							|  |  |  |                     throw Exception("Bad format: initial whitespace in headers"); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 $h =& $resp->headers[$lastk]; | 
					
						
							|  |  |  |                 if (is_array($h)) { | 
					
						
							|  |  |  |                     $n = count($h); | 
					
						
							|  |  |  |                     $h[$n-1] .= $match[1]; | 
					
						
							|  |  |  |                 } else { | 
					
						
							|  |  |  |                     $h .= $match[1]; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $resp; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } |