549 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
		
		
			
		
	
	
			549 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
|   | <?php | ||
|  | 
 | ||
|  | /** | ||
|  |  * The OpenID and Yadis discovery implementation for OpenID 1.2. | ||
|  |  */ | ||
|  | 
 | ||
|  | require_once "Auth/OpenID.php"; | ||
|  | require_once "Auth/OpenID/Parse.php"; | ||
|  | require_once "Auth/OpenID/Message.php"; | ||
|  | require_once "Auth/Yadis/XRIRes.php"; | ||
|  | require_once "Auth/Yadis/Yadis.php"; | ||
|  | 
 | ||
|  | // XML namespace value
 | ||
|  | define('Auth_OpenID_XMLNS_1_0', 'http://openid.net/xmlns/1.0'); | ||
|  | 
 | ||
|  | // Yadis service types
 | ||
|  | define('Auth_OpenID_TYPE_1_2', 'http://openid.net/signon/1.2'); | ||
|  | define('Auth_OpenID_TYPE_1_1', 'http://openid.net/signon/1.1'); | ||
|  | define('Auth_OpenID_TYPE_1_0', 'http://openid.net/signon/1.0'); | ||
|  | define('Auth_OpenID_TYPE_2_0_IDP', 'http://specs.openid.net/auth/2.0/server'); | ||
|  | define('Auth_OpenID_TYPE_2_0', 'http://specs.openid.net/auth/2.0/signon'); | ||
|  | define('Auth_OpenID_RP_RETURN_TO_URL_TYPE', | ||
|  |        'http://specs.openid.net/auth/2.0/return_to'); | ||
|  | 
 | ||
|  | function Auth_OpenID_getOpenIDTypeURIs() | ||
|  | { | ||
|  |     return array(Auth_OpenID_TYPE_2_0_IDP, | ||
|  |                  Auth_OpenID_TYPE_2_0, | ||
|  |                  Auth_OpenID_TYPE_1_2, | ||
|  |                  Auth_OpenID_TYPE_1_1, | ||
|  |                  Auth_OpenID_TYPE_1_0, | ||
|  |                  Auth_OpenID_RP_RETURN_TO_URL_TYPE); | ||
|  | } | ||
|  | 
 | ||
|  | /** | ||
|  |  * Object representing an OpenID service endpoint. | ||
|  |  */ | ||
|  | class Auth_OpenID_ServiceEndpoint { | ||
|  |     function Auth_OpenID_ServiceEndpoint() | ||
|  |     { | ||
|  |         $this->claimed_id = null; | ||
|  |         $this->server_url = null; | ||
|  |         $this->type_uris = array(); | ||
|  |         $this->local_id = null; | ||
|  |         $this->canonicalID = null; | ||
|  |         $this->used_yadis = false; // whether this came from an XRDS
 | ||
|  |         $this->display_identifier = null; | ||
|  |     } | ||
|  | 
 | ||
|  |     function getDisplayIdentifier() | ||
|  |     { | ||
|  |         if ($this->display_identifier) { | ||
|  |             return $this->display_identifier; | ||
|  |         } | ||
|  |         if (! $this->claimed_id) { | ||
|  |           return $this->claimed_id; | ||
|  |         } | ||
|  |         $parsed = parse_url($this->claimed_id); | ||
|  |         $scheme = $parsed['scheme']; | ||
|  |         $host = $parsed['host']; | ||
|  |         $path = $parsed['path']; | ||
|  |         if (array_key_exists('query', $parsed)) { | ||
|  |             $query = $parsed['query']; | ||
|  |             $no_frag = "$scheme://$host$path?$query"; | ||
|  |         } else { | ||
|  |             $no_frag = "$scheme://$host$path"; | ||
|  |         } | ||
|  |         return $no_frag; | ||
|  |     } | ||
|  | 
 | ||
|  |     function usesExtension($extension_uri) | ||
|  |     { | ||
|  |         return in_array($extension_uri, $this->type_uris); | ||
|  |     } | ||
|  | 
 | ||
|  |     function preferredNamespace() | ||
|  |     { | ||
|  |         if (in_array(Auth_OpenID_TYPE_2_0_IDP, $this->type_uris) || | ||
|  |             in_array(Auth_OpenID_TYPE_2_0, $this->type_uris)) { | ||
|  |             return Auth_OpenID_OPENID2_NS; | ||
|  |         } else { | ||
|  |             return Auth_OpenID_OPENID1_NS; | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     /* | ||
|  |      * Query this endpoint to see if it has any of the given type | ||
|  |      * URIs. This is useful for implementing other endpoint classes | ||
|  |      * that e.g. need to check for the presence of multiple versions | ||
|  |      * of a single protocol. | ||
|  |      * | ||
|  |      * @param $type_uris The URIs that you wish to check | ||
|  |      * | ||
|  |      * @return all types that are in both in type_uris and | ||
|  |      * $this->type_uris | ||
|  |      */ | ||
|  |     function matchTypes($type_uris) | ||
|  |     { | ||
|  |         $result = array(); | ||
|  |         foreach ($type_uris as $test_uri) { | ||
|  |             if ($this->supportsType($test_uri)) { | ||
|  |                 $result[] = $test_uri; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         return $result; | ||
|  |     } | ||
|  | 
 | ||
|  |     function supportsType($type_uri) | ||
|  |     { | ||
|  |         // Does this endpoint support this type?
 | ||
|  |         return ((in_array($type_uri, $this->type_uris)) || | ||
|  |                 (($type_uri == Auth_OpenID_TYPE_2_0) && | ||
|  |                  $this->isOPIdentifier())); | ||
|  |     } | ||
|  | 
 | ||
|  |     function compatibilityMode() | ||
|  |     { | ||
|  |         return $this->preferredNamespace() != Auth_OpenID_OPENID2_NS; | ||
|  |     } | ||
|  | 
 | ||
|  |     function isOPIdentifier() | ||
|  |     { | ||
|  |         return in_array(Auth_OpenID_TYPE_2_0_IDP, $this->type_uris); | ||
|  |     } | ||
|  | 
 | ||
|  |     function fromOPEndpointURL($op_endpoint_url) | ||
|  |     { | ||
|  |         // Construct an OP-Identifier OpenIDServiceEndpoint object for
 | ||
|  |         // a given OP Endpoint URL
 | ||
|  |         $obj = new Auth_OpenID_ServiceEndpoint(); | ||
|  |         $obj->server_url = $op_endpoint_url; | ||
|  |         $obj->type_uris = array(Auth_OpenID_TYPE_2_0_IDP); | ||
|  |         return $obj; | ||
|  |     } | ||
|  | 
 | ||
|  |     function parseService($yadis_url, $uri, $type_uris, $service_element) | ||
|  |     { | ||
|  |         // Set the state of this object based on the contents of the
 | ||
|  |         // service element.  Return true if successful, false if not
 | ||
|  |         // (if findOPLocalIdentifier returns false).
 | ||
|  |         $this->type_uris = $type_uris; | ||
|  |         $this->server_url = $uri; | ||
|  |         $this->used_yadis = true; | ||
|  | 
 | ||
|  |         if (!$this->isOPIdentifier()) { | ||
|  |             $this->claimed_id = $yadis_url; | ||
|  |             $this->local_id = Auth_OpenID_findOPLocalIdentifier( | ||
|  |                                                     $service_element, | ||
|  |                                                     $this->type_uris); | ||
|  |             if ($this->local_id === false) { | ||
|  |                 return false; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         return true; | ||
|  |     } | ||
|  | 
 | ||
|  |     function getLocalID() | ||
|  |     { | ||
|  |         // Return the identifier that should be sent as the
 | ||
|  |         // openid.identity_url parameter to the server.
 | ||
|  |         if ($this->local_id === null && $this->canonicalID === null) { | ||
|  |             return $this->claimed_id; | ||
|  |         } else { | ||
|  |             if ($this->local_id) { | ||
|  |                 return $this->local_id; | ||
|  |             } else { | ||
|  |                 return $this->canonicalID; | ||
|  |             } | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     /* | ||
|  |      * Parse the given document as XRDS looking for OpenID services. | ||
|  |      * | ||
|  |      * @return array of Auth_OpenID_ServiceEndpoint or null if the | ||
|  |      * document cannot be parsed. | ||
|  |      */ | ||
|  |     function fromXRDS($uri, $xrds_text) | ||
|  |     { | ||
|  |         $xrds =& Auth_Yadis_XRDS::parseXRDS($xrds_text); | ||
|  | 
 | ||
|  |         if ($xrds) { | ||
|  |             $yadis_services = | ||
|  |               $xrds->services(array('filter_MatchesAnyOpenIDType')); | ||
|  |             return Auth_OpenID_makeOpenIDEndpoints($uri, $yadis_services); | ||
|  |         } | ||
|  | 
 | ||
|  |         return null; | ||
|  |     } | ||
|  | 
 | ||
|  |     /* | ||
|  |      * Create endpoints from a DiscoveryResult. | ||
|  |      * | ||
|  |      * @param discoveryResult Auth_Yadis_DiscoveryResult | ||
|  |      * @return array of Auth_OpenID_ServiceEndpoint or null if | ||
|  |      * endpoints cannot be created. | ||
|  |      */ | ||
|  |     function fromDiscoveryResult($discoveryResult) | ||
|  |     { | ||
|  |         if ($discoveryResult->isXRDS()) { | ||
|  |             return Auth_OpenID_ServiceEndpoint::fromXRDS( | ||
|  |                                      $discoveryResult->normalized_uri, | ||
|  |                                      $discoveryResult->response_text); | ||
|  |         } else { | ||
|  |             return Auth_OpenID_ServiceEndpoint::fromHTML( | ||
|  |                                      $discoveryResult->normalized_uri, | ||
|  |                                      $discoveryResult->response_text); | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     function fromHTML($uri, $html) | ||
|  |     { | ||
|  |         $discovery_types = array( | ||
|  |                                  array(Auth_OpenID_TYPE_2_0, | ||
|  |                                        'openid2.provider', 'openid2.local_id'), | ||
|  |                                  array(Auth_OpenID_TYPE_1_1, | ||
|  |                                        'openid.server', 'openid.delegate') | ||
|  |                                  ); | ||
|  | 
 | ||
|  |         $services = array(); | ||
|  | 
 | ||
|  |         foreach ($discovery_types as $triple) { | ||
|  |             list($type_uri, $server_rel, $delegate_rel) = $triple; | ||
|  | 
 | ||
|  |             $urls = Auth_OpenID_legacy_discover($html, $server_rel, | ||
|  |                                                 $delegate_rel); | ||
|  | 
 | ||
|  |             if ($urls === false) { | ||
|  |                 continue; | ||
|  |             } | ||
|  | 
 | ||
|  |             list($delegate_url, $server_url) = $urls; | ||
|  | 
 | ||
|  |             $service = new Auth_OpenID_ServiceEndpoint(); | ||
|  |             $service->claimed_id = $uri; | ||
|  |             $service->local_id = $delegate_url; | ||
|  |             $service->server_url = $server_url; | ||
|  |             $service->type_uris = array($type_uri); | ||
|  | 
 | ||
|  |             $services[] = $service; | ||
|  |         } | ||
|  | 
 | ||
|  |         return $services; | ||
|  |     } | ||
|  | 
 | ||
|  |     function copy() | ||
|  |     { | ||
|  |         $x = new Auth_OpenID_ServiceEndpoint(); | ||
|  | 
 | ||
|  |         $x->claimed_id = $this->claimed_id; | ||
|  |         $x->server_url = $this->server_url; | ||
|  |         $x->type_uris = $this->type_uris; | ||
|  |         $x->local_id = $this->local_id; | ||
|  |         $x->canonicalID = $this->canonicalID; | ||
|  |         $x->used_yadis = $this->used_yadis; | ||
|  | 
 | ||
|  |         return $x; | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | function Auth_OpenID_findOPLocalIdentifier($service, $type_uris) | ||
|  | { | ||
|  |     // Extract a openid:Delegate value from a Yadis Service element.
 | ||
|  |     // If no delegate is found, returns null.  Returns false on
 | ||
|  |     // discovery failure (when multiple delegate/localID tags have
 | ||
|  |     // different values).
 | ||
|  | 
 | ||
|  |     $service->parser->registerNamespace('openid', | ||
|  |                                         Auth_OpenID_XMLNS_1_0); | ||
|  | 
 | ||
|  |     $service->parser->registerNamespace('xrd', | ||
|  |                                         Auth_Yadis_XMLNS_XRD_2_0); | ||
|  | 
 | ||
|  |     $parser =& $service->parser; | ||
|  | 
 | ||
|  |     $permitted_tags = array(); | ||
|  | 
 | ||
|  |     if (in_array(Auth_OpenID_TYPE_1_1, $type_uris) || | ||
|  |         in_array(Auth_OpenID_TYPE_1_0, $type_uris)) { | ||
|  |         $permitted_tags[] = 'openid:Delegate'; | ||
|  |     } | ||
|  | 
 | ||
|  |     if (in_array(Auth_OpenID_TYPE_2_0, $type_uris)) { | ||
|  |         $permitted_tags[] = 'xrd:LocalID'; | ||
|  |     } | ||
|  | 
 | ||
|  |     $local_id = null; | ||
|  | 
 | ||
|  |     foreach ($permitted_tags as $tag_name) { | ||
|  |         $tags = $service->getElements($tag_name); | ||
|  | 
 | ||
|  |         foreach ($tags as $tag) { | ||
|  |             $content = $parser->content($tag); | ||
|  | 
 | ||
|  |             if ($local_id === null) { | ||
|  |                 $local_id = $content; | ||
|  |             } else if ($local_id != $content) { | ||
|  |                 return false; | ||
|  |             } | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     return $local_id; | ||
|  | } | ||
|  | 
 | ||
|  | function filter_MatchesAnyOpenIDType(&$service) | ||
|  | { | ||
|  |     $uris = $service->getTypes(); | ||
|  | 
 | ||
|  |     foreach ($uris as $uri) { | ||
|  |         if (in_array($uri, Auth_OpenID_getOpenIDTypeURIs())) { | ||
|  |             return true; | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     return false; | ||
|  | } | ||
|  | 
 | ||
|  | function Auth_OpenID_bestMatchingService($service, $preferred_types) | ||
|  | { | ||
|  |     // Return the index of the first matching type, or something
 | ||
|  |     // higher if no type matches.
 | ||
|  |     //
 | ||
|  |     // This provides an ordering in which service elements that
 | ||
|  |     // contain a type that comes earlier in the preferred types list
 | ||
|  |     // come before service elements that come later. If a service
 | ||
|  |     // element has more than one type, the most preferred one wins.
 | ||
|  | 
 | ||
|  |     foreach ($preferred_types as $index => $typ) { | ||
|  |         if (in_array($typ, $service->type_uris)) { | ||
|  |             return $index; | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     return count($preferred_types); | ||
|  | } | ||
|  | 
 | ||
|  | function Auth_OpenID_arrangeByType($service_list, $preferred_types) | ||
|  | { | ||
|  |     // Rearrange service_list in a new list so services are ordered by
 | ||
|  |     // types listed in preferred_types.  Return the new list.
 | ||
|  | 
 | ||
|  |     // Build a list with the service elements in tuples whose
 | ||
|  |     // comparison will prefer the one with the best matching service
 | ||
|  |     $prio_services = array(); | ||
|  |     foreach ($service_list as $index => $service) { | ||
|  |         $prio_services[] = array(Auth_OpenID_bestMatchingService($service, | ||
|  |                                                         $preferred_types), | ||
|  |                                  $index, $service); | ||
|  |     } | ||
|  | 
 | ||
|  |     sort($prio_services); | ||
|  | 
 | ||
|  |     // Now that the services are sorted by priority, remove the sort
 | ||
|  |     // keys from the list.
 | ||
|  |     foreach ($prio_services as $index => $s) { | ||
|  |         $prio_services[$index] = $prio_services[$index][2]; | ||
|  |     } | ||
|  | 
 | ||
|  |     return $prio_services; | ||
|  | } | ||
|  | 
 | ||
|  | // Extract OP Identifier services.  If none found, return the rest,
 | ||
|  | // sorted with most preferred first according to
 | ||
|  | // OpenIDServiceEndpoint.openid_type_uris.
 | ||
|  | //
 | ||
|  | // openid_services is a list of OpenIDServiceEndpoint objects.
 | ||
|  | //
 | ||
|  | // Returns a list of OpenIDServiceEndpoint objects."""
 | ||
|  | function Auth_OpenID_getOPOrUserServices($openid_services) | ||
|  | { | ||
|  |     $op_services = Auth_OpenID_arrangeByType($openid_services, | ||
|  |                                      array(Auth_OpenID_TYPE_2_0_IDP)); | ||
|  | 
 | ||
|  |     $openid_services = Auth_OpenID_arrangeByType($openid_services, | ||
|  |                                      Auth_OpenID_getOpenIDTypeURIs()); | ||
|  | 
 | ||
|  |     if ($op_services) { | ||
|  |         return $op_services; | ||
|  |     } else { | ||
|  |         return $openid_services; | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | function Auth_OpenID_makeOpenIDEndpoints($uri, $yadis_services) | ||
|  | { | ||
|  |     $s = array(); | ||
|  | 
 | ||
|  |     if (!$yadis_services) { | ||
|  |         return $s; | ||
|  |     } | ||
|  | 
 | ||
|  |     foreach ($yadis_services as $service) { | ||
|  |         $type_uris = $service->getTypes(); | ||
|  |         $uris = $service->getURIs(); | ||
|  | 
 | ||
|  |         // If any Type URIs match and there is an endpoint URI
 | ||
|  |         // specified, then this is an OpenID endpoint
 | ||
|  |         if ($type_uris && | ||
|  |             $uris) { | ||
|  |             foreach ($uris as $service_uri) { | ||
|  |                 $openid_endpoint = new Auth_OpenID_ServiceEndpoint(); | ||
|  |                 if ($openid_endpoint->parseService($uri, | ||
|  |                                                    $service_uri, | ||
|  |                                                    $type_uris, | ||
|  |                                                    $service)) { | ||
|  |                     $s[] = $openid_endpoint; | ||
|  |                 } | ||
|  |             } | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     return $s; | ||
|  | } | ||
|  | 
 | ||
|  | function Auth_OpenID_discoverWithYadis($uri, &$fetcher, | ||
|  |               $endpoint_filter='Auth_OpenID_getOPOrUserServices', | ||
|  |               $discover_function=null) | ||
|  | { | ||
|  |     // Discover OpenID services for a URI. Tries Yadis and falls back
 | ||
|  |     // on old-style <link rel='...'> discovery if Yadis fails.
 | ||
|  | 
 | ||
|  |     // Might raise a yadis.discover.DiscoveryFailure if no document
 | ||
|  |     // came back for that URI at all.  I don't think falling back to
 | ||
|  |     // OpenID 1.0 discovery on the same URL will help, so don't bother
 | ||
|  |     // to catch it.
 | ||
|  |     if ($discover_function === null) { | ||
|  |         $discover_function = array('Auth_Yadis_Yadis', 'discover'); | ||
|  |     } | ||
|  | 
 | ||
|  |     $openid_services = array(); | ||
|  | 
 | ||
|  |     $response = call_user_func_array($discover_function, | ||
|  |                                      array($uri, &$fetcher)); | ||
|  | 
 | ||
|  |     $yadis_url = $response->normalized_uri; | ||
|  |     $yadis_services = array(); | ||
|  | 
 | ||
|  |     if ($response->isFailure()) { | ||
|  |         return array($uri, array()); | ||
|  |     } | ||
|  | 
 | ||
|  |     $openid_services = Auth_OpenID_ServiceEndpoint::fromXRDS( | ||
|  |                                          $yadis_url, | ||
|  |                                          $response->response_text); | ||
|  | 
 | ||
|  |     if (!$openid_services) { | ||
|  |         if ($response->isXRDS()) { | ||
|  |             return Auth_OpenID_discoverWithoutYadis($uri, | ||
|  |                                                     $fetcher); | ||
|  |         } | ||
|  | 
 | ||
|  |         // Try to parse the response as HTML to get OpenID 1.0/1.1
 | ||
|  |         // <link rel="...">
 | ||
|  |         $openid_services = Auth_OpenID_ServiceEndpoint::fromHTML( | ||
|  |                                         $yadis_url, | ||
|  |                                         $response->response_text); | ||
|  |     } | ||
|  | 
 | ||
|  |     $openid_services = call_user_func_array($endpoint_filter, | ||
|  |                                             array(&$openid_services)); | ||
|  | 
 | ||
|  |     return array($yadis_url, $openid_services); | ||
|  | } | ||
|  | 
 | ||
|  | function Auth_OpenID_discoverURI($uri, &$fetcher) | ||
|  | { | ||
|  |     $uri = Auth_OpenID::normalizeUrl($uri); | ||
|  |     return Auth_OpenID_discoverWithYadis($uri, $fetcher); | ||
|  | } | ||
|  | 
 | ||
|  | function Auth_OpenID_discoverWithoutYadis($uri, &$fetcher) | ||
|  | { | ||
|  |     $http_resp = @$fetcher->get($uri); | ||
|  | 
 | ||
|  |     if ($http_resp->status != 200 and $http_resp->status != 206) { | ||
|  |         return array($uri, array()); | ||
|  |     } | ||
|  | 
 | ||
|  |     $identity_url = $http_resp->final_url; | ||
|  | 
 | ||
|  |     // Try to parse the response as HTML to get OpenID 1.0/1.1 <link
 | ||
|  |     // rel="...">
 | ||
|  |     $openid_services = Auth_OpenID_ServiceEndpoint::fromHTML( | ||
|  |                                            $identity_url, | ||
|  |                                            $http_resp->body); | ||
|  | 
 | ||
|  |     return array($identity_url, $openid_services); | ||
|  | } | ||
|  | 
 | ||
|  | function Auth_OpenID_discoverXRI($iname, &$fetcher) | ||
|  | { | ||
|  |     $resolver = new Auth_Yadis_ProxyResolver($fetcher); | ||
|  |     list($canonicalID, $yadis_services) = | ||
|  |         $resolver->query($iname, | ||
|  |                          Auth_OpenID_getOpenIDTypeURIs(), | ||
|  |                          array('filter_MatchesAnyOpenIDType')); | ||
|  | 
 | ||
|  |     $openid_services = Auth_OpenID_makeOpenIDEndpoints($iname, | ||
|  |                                                        $yadis_services); | ||
|  | 
 | ||
|  |     $openid_services = Auth_OpenID_getOPOrUserServices($openid_services); | ||
|  | 
 | ||
|  |     for ($i = 0; $i < count($openid_services); $i++) { | ||
|  |         $openid_services[$i]->canonicalID = $canonicalID; | ||
|  |         $openid_services[$i]->claimed_id = $canonicalID; | ||
|  |         $openid_services[$i]->display_identifier = $iname; | ||
|  |     } | ||
|  | 
 | ||
|  |     // FIXME: returned xri should probably be in some normal form
 | ||
|  |     return array($iname, $openid_services); | ||
|  | } | ||
|  | 
 | ||
|  | function Auth_OpenID_discover($uri, &$fetcher) | ||
|  | { | ||
|  |     // If the fetcher (i.e., PHP) doesn't support SSL, we can't do
 | ||
|  |     // discovery on an HTTPS URL.
 | ||
|  |     if ($fetcher->isHTTPS($uri) && !$fetcher->supportsSSL()) { | ||
|  |         return array($uri, array()); | ||
|  |     } | ||
|  | 
 | ||
|  |     if (Auth_Yadis_identifierScheme($uri) == 'XRI') { | ||
|  |         $result = Auth_OpenID_discoverXRI($uri, $fetcher); | ||
|  |     } else { | ||
|  |         $result = Auth_OpenID_discoverURI($uri, $fetcher); | ||
|  |     } | ||
|  | 
 | ||
|  |     // If the fetcher doesn't support SSL, we can't interact with
 | ||
|  |     // HTTPS server URLs; remove those endpoints from the list.
 | ||
|  |     if (!$fetcher->supportsSSL()) { | ||
|  |         $http_endpoints = array(); | ||
|  |         list($new_uri, $endpoints) = $result; | ||
|  | 
 | ||
|  |         foreach ($endpoints as $e) { | ||
|  |             if (!$fetcher->isHTTPS($e->server_url)) { | ||
|  |                 $http_endpoints[] = $e; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         $result = array($new_uri, $http_endpoints); | ||
|  |     } | ||
|  | 
 | ||
|  |     return $result; | ||
|  | } | ||
|  | 
 | ||
|  | ?>
 |