]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - lib/curlclient.php
Detect "no file" upload error and, for now at least, ignore it gracefully.
[quix0rs-gnu-social.git] / lib / curlclient.php
1 <?php
2 /**
3  * StatusNet, the distributed open-source microblogging tool
4  *
5  * Utility class for wrapping Curl
6  *
7  * PHP version 5
8  *
9  * LICENCE: This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU Affero General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU Affero General Public License for more details.
18  *
19  * You should have received a copy of the GNU Affero General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  *
22  * @category  HTTP
23  * @package   StatusNet
24  * @author    Evan Prodromou <evan@status.net>
25  * @copyright 2009 StatusNet, Inc.
26  * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
27  * @link      http://status.net/
28  */
29
30 if (!defined('STATUSNET')) {
31     exit(1);
32 }
33
34 define(CURLCLIENT_VERSION, "0.1");
35
36 /**
37  * Wrapper for Curl
38  *
39  * Makes Curl HTTP client calls within our HTTPClient framework
40  *
41  * @category HTTP
42  * @package  StatusNet
43  * @author   Evan Prodromou <evan@status.net>
44  * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
45  * @link     http://status.net/
46  */
47
48 class CurlClient extends HTTPClient
49 {
50     function __construct()
51     {
52     }
53
54     function head($url, $headers=null)
55     {
56         $ch = curl_init($url);
57
58         $this->setup($ch);
59
60         curl_setopt_array($ch,
61                           array(CURLOPT_NOBODY => true));
62
63         if (!is_null($headers)) {
64             curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
65         }
66
67         $result = curl_exec($ch);
68
69         curl_close($ch);
70
71         return $this->parseResults($result);
72     }
73
74     function get($url, $headers=null)
75     {
76         $ch = curl_init($url);
77
78         $this->setup($ch);
79
80         if (!is_null($headers)) {
81             curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
82         }
83
84         $result = curl_exec($ch);
85
86         curl_close($ch);
87
88         return $this->parseResults($result);
89     }
90
91     function post($url, $headers=null, $body=null)
92     {
93         $ch = curl_init($url);
94
95         $this->setup($ch);
96
97         curl_setopt($ch, CURLOPT_POST, true);
98
99         if (!is_null($body)) {
100             curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
101         }
102
103         if (!is_null($headers)) {
104             curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
105         }
106
107         $result = curl_exec($ch);
108
109         curl_close($ch);
110
111         return $this->parseResults($result);
112     }
113
114     function setup($ch)
115     {
116         curl_setopt_array($ch,
117                           array(CURLOPT_USERAGENT => $this->userAgent(),
118                                 CURLOPT_HEADER => true,
119                                 CURLOPT_RETURNTRANSFER => true));
120     }
121
122     function userAgent()
123     {
124         $version = curl_version();
125         return parent::userAgent() . " CurlClient/".CURLCLIENT_VERSION . " cURL/" . $version['version'];
126     }
127
128     function parseResults($results)
129     {
130         $resp = new HTTPResponse();
131
132         $lines = explode("\r\n", $results);
133
134         if (preg_match("#^HTTP/1.[01] (\d\d\d) .+$#", $lines[0], $match)) {
135             $resp->code = $match[1];
136         } else {
137             throw Exception("Bad format: initial line is not HTTP status line");
138         }
139
140         $lastk = null;
141
142         for ($i = 1; $i < count($lines); $i++) {
143             $l =& $lines[$i];
144             if (mb_strlen($l) == 0) {
145                 $resp->body = implode("\r\n", array_slice($lines, $i + 1));
146                 break;
147             }
148             if (preg_match("#^(\S+):\s+(.*)$#", $l, $match)) {
149                 $k = $match[1];
150                 $v = $match[2];
151
152                 if (array_key_exists($k, $resp->headers)) {
153                     if (is_array($resp->headers[$k])) {
154                         $resp->headers[$k][] = $v;
155                     } else {
156                         $resp->headers[$k] = array($resp->headers[$k], $v);
157                     }
158                 } else {
159                     $resp->headers[$k] = $v;
160                 }
161                 $lastk = $k;
162             } else if (preg_match("#^\s+(.*)$#", $l, $match)) {
163                 // continuation line
164                 if (is_null($lastk)) {
165                     throw Exception("Bad format: initial whitespace in headers");
166                 }
167                 $h =& $resp->headers[$lastk];
168                 if (is_array($h)) {
169                     $n = count($h);
170                     $h[$n-1] .= $match[1];
171                 } else {
172                     $h .= $match[1];
173                 }
174             }
175         }
176
177         return $resp;
178     }
179 }