180 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			180 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| n<?php
 | |
| /**
 | |
|  * StatusNet, the distributed open-source microblogging tool
 | |
|  *
 | |
|  * 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
 | |
|  * @package   StatusNet
 | |
|  * @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
 | |
|  * @link      http://status.net/
 | |
|  */
 | |
| 
 | |
| if (!defined('STATUSNET')) {
 | |
|     exit(1);
 | |
| }
 | |
| 
 | |
| define(CURLCLIENT_VERSION, "0.1");
 | |
| 
 | |
| /**
 | |
|  * Wrapper for Curl
 | |
|  *
 | |
|  * Makes Curl HTTP client calls within our HTTPClient framework
 | |
|  *
 | |
|  * @category HTTP
 | |
|  * @package  StatusNet
 | |
|  * @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
 | |
|  * @link     http://status.net/
 | |
|  */
 | |
| 
 | |
| 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));
 | |
| 
 | |
|         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);
 | |
|         }
 | |
| 
 | |
|         $result = curl_exec($ch);
 | |
| 
 | |
|         curl_close($ch);
 | |
| 
 | |
|         return $this->parseResults($result);
 | |
|     }
 | |
| 
 | |
|     function post($url, $headers=null, $body=null)
 | |
|     {
 | |
|         $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);
 | |
|     }
 | |
| 
 | |
|     function setup($ch)
 | |
|     {
 | |
|         curl_setopt_array($ch,
 | |
|                           array(CURLOPT_USERAGENT => $this->userAgent(),
 | |
|                                 CURLOPT_HEADER => true,
 | |
|                                 CURLOPT_RETURNTRANSFER => true));
 | |
|     }
 | |
| 
 | |
|     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;
 | |
|     }
 | |
| }
 |