Revision: 3020
Author: olavmrk
Date: Thu Jan 19 05:13:55 2012
Log: metarefresh: Also reuse old metadata when fetching metadata fails.
Thanks to Dick Visser for implementing this!
http://code.google.com/p/simplesamlphp/source/detail?r=3020
Modified:
/trunk/modules/metarefresh/lib/MetaLoader.php
=======================================
--- /trunk/modules/metarefresh/lib/MetaLoader.php Thu Nov 17 00:08:31 2011
+++ /trunk/modules/metarefresh/lib/MetaLoader.php Thu Jan 19 05:13:55 2012
@@ -45,11 +45,92 @@
*/
public function loadSource($source) {
+ // Build new HTTP context
+ $context = $this->createContext($source);
+
+ // GET!
+ try {
+ list($data, $responseHeaders) =
SimpleSAML_Utilities::fetch($source['src'], $context, TRUE);
+ } catch(Exception $e) {
+ SimpleSAML_Logger::warning('metarefresh: ' .
$e->getMessage());
+ }
+
+ // We have response headers, so the request succeeded
+ if(isset($responseHeaders)) {
+
+ // 200 OK
+ if(preg_match('@^HTTP/1\.[01]\s200\s@',
$responseHeaders[0])) {
+
+ if (isset($source['conditionalGET']) &&
$source['conditionalGET']) {
+ // Stale or no metadata, so a fresh copy
+ SimpleSAML_Logger::debug('Downloaded
fresh copy');
+ }
+
+ $entities = $this->loadXML($data, $source);
+
+ foreach($entities as $entity) {
+
+ if(isset($source['blacklist'])) {
+ if(!empty($source['blacklist']) && in_array($entity->getEntityID(),
$source['blacklist'])) {
+ SimpleSAML_Logger::info('Skipping "' . $entity->getEntityID() . '"
- blacklisted.' . "\n");
+ continue;
+ }
+ }
+
+ if(isset($source['whitelist'])) {
+ if(!empty($source['whitelist']) && !in_array($entity->getEntityID(),
$source['whitelist'])) {
+ SimpleSAML_Logger::info('Skipping "' . $entity->getEntityID() . '"
- not in the whitelist.' . "\n");
+ continue;
+ }
+ }
+
+ if(array_key_exists('validateFingerprint', $source) &&
$source['validateFingerprint'] !== NULL) {
+
if(!$entity->validateFingerprint($source['validateFingerprint'])) {
+ SimpleSAML_Logger::info('Skipping "' . $entity->getEntityId() . '"
- could not verify signature.' . "\n");
+ continue;
+ }
+ }
+
+ $template = NULL;
+ if (array_key_exists('template', $source)) $template =
$source['template'];
+
+ $this->addMetadata($source['src'],
$entity->getMetadata1xSP(), 'shib13-sp-remote', $template);
+ $this->addMetadata($source['src'],
$entity->getMetadata1xIdP(), 'shib13-idp-remote', $template);
+ $this->addMetadata($source['src'],
$entity->getMetadata20SP(), 'saml20-sp-remote', $template);
+ $this->addMetadata($source['src'],
$entity->getMetadata20IdP(), 'saml20-idp-remote', $template);
+ $attributeAuthorities =
$entity->getAttributeAuthorities();
+ if (!empty($attributeAuthorities)) {
+ $this->addMetadata($source['src'],
$attributeAuthorities[0], 'attributeauthority-remote', $template);
+ }
+ }
+
+ $this->saveState($source, $responseHeaders);
+ }
+
+ // 304 response
+ if(preg_match('@^HTTP/1\.[01]\s304\s@',
$responseHeaders[0])) {
+ SimpleSAML_Logger::debug('Received HTTP 304 (Not Modified) -
attempting to re-use cached metadata');
+ $this->addCachedMetadata($source);
+ }
+
+ } else {
+ // No response headers, this means the request failed in some way, so
re-use old data
+ SimpleSAML_Logger::debug('No response from ' . $source['src'] . ' -
attempting to re-use cached metadata');
+ $this->addCachedMetadata($source);
+ }
+ }
+
+ /**
+ * Create HTTP context, with any available caches taken into account
+ */
+ private function createContext($source) {
+
$context = NULL;
$config = SimpleSAML_Configuration::getInstance();
$name = $config->getString('technicalcontact_name', NULL);
$mail = $config->getString('technicalcontact_email', NULL);
+
$rawheader = "User-Agent: SimpleSAMLphp metarefresh, run by $name
<$mail>\r\n";
if (isset($source['conditionalGET']) &&
$source['conditionalGET']) {
@@ -67,24 +148,12 @@
}
}
- // Build new HTTP context
- $context = array('http' => array('header' => $rawheader));
+ return array('http' => array('header' => $rawheader));
+ }
- // GET!
- try {
- list($data, $responseHeaders) =
SimpleSAML_Utilities::fetch($source['src'], $context, TRUE);
- } catch(Exception $e) {
- SimpleSAML_Logger::warning('metarefresh: Failed to retrieve
metadata. ' . $e->getMessage());
- }
-
- //SimpleSAML_Logger::debug('All response headers: ' .
var_export($responsHeaders,1));
- $status = $responseHeaders[0];
-
- if(preg_match('@^HTTP/1\.[01]\s304\s@', $status ) &&
isset($this->oldMetadataSrc)) {
- // Not-Modified. This could only have happened if 'conditionalGET' was
used.
- SimpleSAML_Logger::debug('Received \'' . $status . '\', re-using cached
metadata');
-
+ private function addCachedMetadata($source) {
+ if(isset($this->oldMetadataSrc)) {
foreach(self::$types as $type) {
foreach($this->oldMetadataSrc->getMetadataSet($type) as $entity) {
if(array_key_exists('metarefresh:src',
$entity)) {
@@ -95,64 +164,15 @@
}
}
}
- } else {
-
- // Stale or no metadata, so a fresh copy
- if (isset($source['conditionalGET']) &&
$source['conditionalGET']) {
- SimpleSAML_Logger::debug('Downloaded fresh
copy');
- }
-
- $entities = array();
- try{
- $doc = new DOMDocument();
- $res = $doc->loadXML($data);
- if($res !== TRUE) {
- throw new Exception('Failed to read XML
from ' . $source['src']);
- }
- if($doc->documentElement === NULL) throw new Exception('Opened file
is not an XML document: ' . $source['src']);
- $entities =
SimpleSAML_Metadata_SAMLParser::parseDescriptorsElement($doc->documentElement);
- } catch(Exception $e) {
- SimpleSAML_Logger::warning('metarefresh: Failed to retrieve
metadata. ' . $e->getMessage());
- }
-
- foreach($entities as $entity) {
-
- if(isset($source['blacklist'])) {
- if(!empty($source['blacklist']) && in_array($entity->getEntityID(),
$source['blacklist'])) {
- SimpleSAML_Logger::info('Skipping "' . $entity->getEntityID() . '"
- blacklisted.' . "\n");
- continue;
- }
- }
-
- if(isset($source['whitelist'])) {
- if(!empty($source['whitelist']) && !in_array($entity->getEntityID(),
$source['whitelist'])) {
- SimpleSAML_Logger::info('Skipping "' . $entity->getEntityID() . '"
- not in the whitelist.' . "\n");
- continue;
- }
- }
-
- if(array_key_exists('validateFingerprint', $source) &&
$source['validateFingerprint'] !== NULL) {
-
if(!$entity->validateFingerprint($source['validateFingerprint'])) {
- SimpleSAML_Logger::info('Skipping "' . $entity->getEntityId() . '" -
could not verify signature.' . "\n");
- continue;
- }
- }
-
- $template = NULL;
- if (array_key_exists('template', $source)) $template =
$source['template'];
-
- $this->addMetadata($source['src'],
$entity->getMetadata1xSP(), 'shib13-sp-remote', $template);
- $this->addMetadata($source['src'],
$entity->getMetadata1xIdP(), 'shib13-idp-remote', $template);
- $this->addMetadata($source['src'],
$entity->getMetadata20SP(), 'saml20-sp-remote', $template);
- $this->addMetadata($source['src'],
$entity->getMetadata20IdP(), 'saml20-idp-remote', $template);
- $attributeAuthorities =
$entity->getAttributeAuthorities();
- if (!empty($attributeAuthorities)) {
- $this->addMetadata($source['src'],
$attributeAuthorities[0], 'attributeauthority-remote', $template);
- }
- }
- }
-
- // Save state for this src
+ }
+ }
+
+
+ /**
+ * Store caching state data for a source
+ */
+ private function saveState($source, $responseHeaders) {
+
if (isset($source['conditionalGET']) &&
$source['conditionalGET']) {
// Headers section
@@ -172,11 +192,32 @@
}
}
}
+
/**
- * This function write the state array back to disk
+ * Parse XML metadata and return entities
*/
- public function writeState() {
+ private function loadXML($data, $source) {
+ $entities = array();
+ try {
+ $doc = new DOMDocument();
+ $res = $doc->loadXML($data);
+ if($res !== TRUE) {
+ throw new Exception('Failed to read XML from '
. $source['src']);
+ }
+ if($doc->documentElement === NULL) throw new Exception('Opened file is
not an XML document: ' . $source['src']);
+ $entities =
SimpleSAML_Metadata_SAMLParser::parseDescriptorsElement($doc->documentElement);
+ } catch(Exception $e) {
+ SimpleSAML_Logger::warning('metarefresh: Failed to retrieve
metadata. ' . $e->getMessage());
+ }
+ return $entities;
+ }
+
+
+ /**
+ * This function writes the state array back to disk
+ */
+ public function writeState() {
if($this->changed) {
SimpleSAML_Logger::debug('Writing: ' .
$this->stateFile);
SimpleSAML_Utilities::writeFile(
@@ -187,6 +228,7 @@
);
}
}
+
/**
* This function writes the metadata to stdout.
@@ -213,9 +255,7 @@
echo("\n");
}
}
-
-
-
+
/**
* This function adds metadata from the specified file to the list of
metadata.
--
You received this message because you are subscribed to the Google Groups
"simpleSAMLphp commits" group.
To post to this group, send email to simplesamlphp-commits@googlegroups.com.
To unsubscribe from this group, send email to
simplesamlphp-commits+unsubscr...@googlegroups.com.
For more options, visit this group at
http://groups.google.com/group/simplesamlphp-commits?hl=en.