1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
15:
16: 17: 18:
19: require_once "Auth/Yadis/HTTPFetcher.php";
20:
21: require_once "Auth/OpenID.php";
22:
23: 24: 25: 26: 27: 28:
29: class Auth_Yadis_ParanoidHTTPFetcher extends Auth_Yadis_HTTPFetcher {
30: function Auth_Yadis_ParanoidHTTPFetcher()
31: {
32: $this->reset();
33: }
34:
35: function reset()
36: {
37: $this->headers = array();
38: $this->data = "";
39: }
40:
41: 42: 43:
44: function _writeHeader($ch, $header)
45: {
46: array_push($this->headers, rtrim($header));
47: return strlen($header);
48: }
49:
50: 51: 52:
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:
63: 64: 65:
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) {
95: Auth_OpenID::log(
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:
158: }
159: $new_headers = array();
160:
161: foreach ($headers as $header) {
162: if (strpos($header, ': ')) {
163: list($name, $value) = explode(': ', $header, 2);
164: $new_headers[$name] = $value;
165: }
166: }
167:
168:
169:
170: return new Auth_Yadis_HTTPResponse($url, $code,
171: $new_headers, $body);
172: }
173:
174: $off = $stop - time();
175: }
176:
177: return null;
178: }
179:
180: function post($url, $body, $extra_headers = null)
181: {
182: if (!$this->canFetchURL($url)) {
183: return null;
184: }
185:
186: $this->reset();
187:
188: $c = curl_init();
189:
190: if (defined('CURLOPT_NOSIGNAL')) {
191: curl_setopt($c, CURLOPT_NOSIGNAL, true);
192: }
193:
194: curl_setopt($c, CURLOPT_POST, true);
195: curl_setopt($c, CURLOPT_POSTFIELDS, $body);
196: curl_setopt($c, CURLOPT_TIMEOUT, $this->timeout);
197: curl_setopt($c, CURLOPT_URL, $url);
198: curl_setopt($c, CURLOPT_WRITEFUNCTION,
199: array($this, "_writeData"));
200:
201: if (defined('Auth_OpenID_VERIFY_HOST')) {
202: curl_setopt($c, CURLOPT_SSL_VERIFYPEER, true);
203: curl_setopt($c, CURLOPT_SSL_VERIFYHOST, 2);
204: }
205:
206: curl_exec($c);
207:
208: $code = curl_getinfo($c, CURLINFO_HTTP_CODE);
209:
210: if (!$code) {
211: Auth_OpenID::log("Got no response code when fetching %s", $url);
212: Auth_OpenID::log("CURL error (%s): %s",
213: curl_errno($c), curl_error($c));
214: return null;
215: }
216:
217: if (defined('Auth_OpenID_VERIFY_HOST') && $this->isHTTPS($url)) {
218: Auth_OpenID::log('OpenID: Verified SSL host %s using '.
219: 'curl/post', $url);
220: }
221: $body = $this->data;
222:
223: curl_close($c);
224:
225: $new_headers = $extra_headers;
226:
227: foreach ($this->headers as $header) {
228: if (strpos($header, ': ')) {
229: list($name, $value) = explode(': ', $header, 2);
230: $new_headers[$name] = $value;
231: }
232:
233: }
234:
235: Auth_OpenID::log("Successfully fetched '%s': POST response code %s",
236: $url, $code);
237:
238: return new Auth_Yadis_HTTPResponse($url, $code,
239: $new_headers, $body);
240: }
241: }
242:
243: