1<?php
2
3/**
4 * This module contains the HTTP fetcher interface
5 *
6 * PHP versions 4 and 5
7 *
8 * LICENSE: See the COPYING file included in this distribution.
9 *
10 * @package OpenID
11 * @author JanRain, Inc. <openid@janrain.com>
12 * @copyright 2005-2008 Janrain, Inc.
13 * @license http://www.apache.org/licenses/LICENSE-2.0 Apache
14 */
15
16/**
17 * Require logging functionality
18 */
19require_once "Auth/OpenID.php";
20
21define('Auth_OpenID_FETCHER_MAX_RESPONSE_KB', 1024);
22define('Auth_OpenID_USER_AGENT',
23       'php-openid/'.Auth_OpenID_VERSION.' (php/'.phpversion().')');
24
25class Auth_Yadis_HTTPResponse {
26    function Auth_Yadis_HTTPResponse($final_url = null, $status = null,
27                                         $headers = null, $body = null)
28    {
29        $this->final_url = $final_url;
30        $this->status = $status;
31        $this->headers = $headers;
32        $this->body = $body;
33    }
34}
35
36/**
37 * This class is the interface for HTTP fetchers the Yadis library
38 * uses.  This interface is only important if you need to write a new
39 * fetcher for some reason.
40 *
41 * @access private
42 * @package OpenID
43 */
44class Auth_Yadis_HTTPFetcher {
45
46    var $timeout = 20; // timeout in seconds.
47
48    /**
49     * Return whether a URL can be fetched.  Returns false if the URL
50     * scheme is not allowed or is not supported by this fetcher
51     * implementation; returns true otherwise.
52     *
53     * @return bool
54     */
55    function canFetchURL($url)
56    {
57        if ($this->isHTTPS($url) && !$this->supportsSSL()) {
58            Auth_OpenID::log("HTTPS URL unsupported fetching %s",
59                             $url);
60            return false;
61        }
62
63        if (!$this->allowedURL($url)) {
64            Auth_OpenID::log("URL fetching not allowed for '%s'",
65                             $url);
66            return false;
67        }
68
69        return true;
70    }
71
72    /**
73     * Return whether a URL should be allowed. Override this method to
74     * conform to your local policy.
75     *
76     * By default, will attempt to fetch any http or https URL.
77     */
78    function allowedURL($url)
79    {
80        return $this->URLHasAllowedScheme($url);
81    }
82
83    /**
84     * Does this fetcher implementation (and runtime) support fetching
85     * HTTPS URLs?  May inspect the runtime environment.
86     *
87     * @return bool $support True if this fetcher supports HTTPS
88     * fetching; false if not.
89     */
90    function supportsSSL()
91    {
92        trigger_error("not implemented", E_USER_ERROR);
93    }
94
95    /**
96     * Is this an https URL?
97     *
98     * @access private
99     */
100    function isHTTPS($url)
101    {
102        return (bool)preg_match('/^https:\/\//i', $url);
103    }
104
105    /**
106     * Is this an http or https URL?
107     *
108     * @access private
109     */
110    function URLHasAllowedScheme($url)
111    {
112        return (bool)preg_match('/^https?:\/\//i', $url);
113    }
114
115    /**
116     * @access private
117     */
118    function _findRedirect($headers, $url)
119    {
120        foreach ($headers as $line) {
121            if (strpos(strtolower($line), "location: ") === 0) {
122                $parts = explode(" ", $line, 2);
123                $loc = $parts[1];
124                $ppos = strpos($loc, "://");
125                if ($ppos === false || $ppos > strpos($loc, "/")) {
126                  /* no host; add it */
127                  $hpos = strpos($url, "://");
128                  $prt = substr($url, 0, $hpos+3);
129                  $url = substr($url, $hpos+3);
130                  if (substr($loc, 0, 1) == "/") {
131                    /* absolute path */
132                    $fspos = strpos($url, "/");
133                    if ($fspos) $loc = $prt.substr($url, 0, $fspos).$loc;
134                    else $loc = $prt.$url.$loc;
135                  } else {
136                    /* relative path */
137                    $pp = $prt;
138                    while (1) {
139                      $xpos = strpos($url, "/");
140                      if ($xpos === false) break;
141                      $apos = strpos($url, "?");
142                      if ($apos !== false && $apos < $xpos) break;
143                      $apos = strpos($url, "&");
144                      if ($apos !== false && $apos < $xpos) break;
145                      $pp .= substr($url, 0, $xpos+1);
146                      $url = substr($url, $xpos+1);
147                    }
148                    $loc = $pp.$loc;
149                  }
150                }
151                return $loc;
152            }
153        }
154        return null;
155    }
156
157    /**
158     * Fetches the specified URL using optional extra headers and
159     * returns the server's response.
160     *
161     * @param string $url The URL to be fetched.
162     * @param array $extra_headers An array of header strings
163     * (e.g. "Accept: text/html").
164     * @return mixed $result An array of ($code, $url, $headers,
165     * $body) if the URL could be fetched; null if the URL does not
166     * pass the URLHasAllowedScheme check or if the server's response
167     * is malformed.
168     */
169    function get($url, $headers = null)
170    {
171        trigger_error("not implemented", E_USER_ERROR);
172    }
173}
174
175