/**
  * Gets the package_update.xml from an update server.
  * 
  * @param	\wcf\data\package\update\server\PackageUpdateServer	$updateServer
  * @param	boolean							$forceHTTP
  */
 protected function getPackageUpdateXML(PackageUpdateServer $updateServer, $forceHTTP = false)
 {
     $settings = array();
     $authData = $updateServer->getAuthData();
     if ($authData) {
         $settings['auth'] = $authData;
     }
     $secureConnection = $updateServer->attemptSecureConnection();
     if ($secureConnection && !$forceHTTP) {
         $settings['timeout'] = 5;
     }
     $request = new HTTPRequest($updateServer->getListURL($forceHTTP), $settings);
     if ($updateServer->apiVersion == '2.1') {
         $metaData = $updateServer->getMetaData();
         if (isset($metaData['list']['etag'])) {
             $request->addHeader('if-none-match', $metaData['list']['etag']);
         }
         if (isset($metaData['list']['lastModified'])) {
             $request->addHeader('if-modified-since', $metaData['list']['lastModified']);
         }
     }
     try {
         $request->execute();
         $reply = $request->getReply();
     } catch (HTTPUnauthorizedException $e) {
         throw new PackageUpdateUnauthorizedException($request, $updateServer);
     } catch (SystemException $e) {
         $reply = $request->getReply();
         $statusCode = is_array($reply['statusCode']) ? reset($reply['statusCode']) : $reply['statusCode'];
         // status code 0 is a connection timeout
         if (!$statusCode && $secureConnection) {
             if (preg_match('~https?://(?:update|store)\\.woltlab\\.com~', $updateServer->serverURL)) {
                 // woltlab.com servers are most likely to be available, thus we assume that SSL connections are dropped
                 RemoteFile::disableSSL();
             }
             // retry via http
             $this->getPackageUpdateXML($updateServer, true);
             return;
         }
         throw new SystemException(WCF::getLanguage()->get('wcf.acp.package.update.error.listNotFound') . ' (' . $statusCode . ')');
     }
     // parse given package update xml
     $allNewPackages = false;
     if ($updateServer->apiVersion == '2.0' || $reply['statusCode'] != 304) {
         $allNewPackages = $this->parsePackageUpdateXML($reply['body']);
     }
     $data = array('lastUpdateTime' => TIME_NOW, 'status' => 'online', 'errorMessage' => '');
     // check if server indicates support for a newer API
     if ($updateServer->apiVersion == '2.0' && !empty($reply['httpHeaders']['wcf-update-server-api'])) {
         $apiVersions = explode(' ', reset($reply['httpHeaders']['wcf-update-server-api']));
         if (in_array('2.1', $apiVersions)) {
             $data['apiVersion'] = '2.1';
         }
     }
     $metaData = array();
     if ($updateServer->apiVersion == '2.1' || isset($data['apiVersion']) && $data['apiVersion'] == '2.1') {
         if (empty($reply['httpHeaders']['etag']) && empty($reply['httpHeaders']['last-modified'])) {
             throw new SystemException("Missing required HTTP headers 'etag' and 'last-modified'.");
         } else {
             if (empty($reply['httpHeaders']['wcf-update-server-ssl'])) {
                 throw new SystemException("Missing required HTTP header 'wcf-update-server-ssl'.");
             }
         }
         $metaData['list'] = array();
         if (!empty($reply['httpHeaders']['etag'])) {
             $metaData['list']['etag'] = reset($reply['httpHeaders']['etag']);
         }
         if (!empty($reply['httpHeaders']['last-modified'])) {
             $metaData['list']['lastModified'] = reset($reply['httpHeaders']['last-modified']);
         }
         $metaData['ssl'] = reset($reply['httpHeaders']['wcf-update-server-ssl']) == 'true' ? true : false;
     }
     $data['metaData'] = serialize($metaData);
     unset($request, $reply);
     if ($allNewPackages !== false) {
         // purge package list
         $sql = "DELETE FROM\twcf" . WCF_N . "_package_update\n\t\t\t\tWHERE\t\tpackageUpdateServerID = ?";
         $statement = WCF::getDB()->prepareStatement($sql);
         $statement->execute(array($updateServer->packageUpdateServerID));
         // save packages
         if (!empty($allNewPackages)) {
             $this->savePackageUpdates($allNewPackages, $updateServer->packageUpdateServerID);
         }
         unset($allNewPackages);
     }
     // update server status
     $updateServerEditor = new PackageUpdateServerEditor($updateServer);
     $updateServerEditor->update($data);
 }