Exemplo n.º 1
0
 /**
  * Downloads a package archive from an http URL.
  * 
  * @param	string		$httpUrl
  * @param	string		$prefix
  * @return	string		path to the dowloaded file
  */
 public static function downloadFileFromHttp($httpUrl, $prefix = 'package')
 {
     $extension = strrchr($httpUrl, '.');
     //$newFileName = self::getTemporaryFilename($prefix.'_', $extension);
     $newFileName = self::getTemporaryFilename($prefix . '_');
     $localFile = new File($newFileName);
     // the file to write.
     // get proxy
     $options = array();
     if (PROXY_SERVER_HTTP) {
         $options['http']['proxy'] = PROXY_SERVER_HTTP;
     }
     // first look if php's built-in fopen() is available, and if so, use it.
     if (function_exists('fopen') && ini_get('allow_url_fopen')) {
         $remoteFile = new File($httpUrl, 'rb', $options);
         // the file to read.
         // get the content of the remote file and write it to a local file.
         while (!$remoteFile->eof()) {
             $buffer = $remoteFile->gets(4096);
             $localFile->write($buffer);
         }
     } else {
         $port = 80;
         $parsedUrl = parse_url($httpUrl);
         $host = $parsedUrl['host'];
         $path = $parsedUrl['path'];
         require_once WCF_DIR . 'lib/system/io/RemoteFile.class.php';
         $remoteFile = new RemoteFile($host, $port, 30, $options);
         // the file to read.
         if (!isset($remoteFile)) {
             $localFile->close();
             unlink($newFileName);
             throw new SystemException("cannot connect to http host '" . $host . "'", 14000);
         }
         // build and send the http request.
         $request = "GET " . $path . (!empty($parsedUrl['query']) ? '?' . $parsedUrl['query'] : '') . " HTTP/1.0\r\n";
         $request .= "User-Agent: HTTP.PHP (FileUtil.class.php; WoltLab Community Framework/" . WCF_VERSION . "; " . WCF::getLanguage()->getLanguageCode() . ")\r\n";
         $request .= "Accept: */*\r\n";
         $request .= "Accept-Language: " . WCF::getLanguage()->getLanguageCode() . "\r\n";
         $request .= "Host: " . $host . "\r\n";
         $request .= "Connection: Close\r\n\r\n";
         $remoteFile->puts($request);
         $waiting = true;
         $readResponse = array();
         // read http response.
         while (!$remoteFile->eof()) {
             $readResponse[] = $remoteFile->gets();
             // look if we are done with transferring the requested file.
             if ($waiting) {
                 if (rtrim($readResponse[count($readResponse) - 1]) == '') {
                     $waiting = false;
                 }
             } else {
                 // look if the webserver sent an error http statuscode
                 // This has still to be checked if really sufficient!
                 $arrayHeader = array('201', '301', '302', '303', '307', '404');
                 foreach ($arrayHeader as $code) {
                     $error = strpos($readResponse[0], $code);
                 }
                 if ($error !== false) {
                     $localFile->close();
                     unlink($newFileName);
                     throw new SystemException("file " . $path . " not found at host '" . $host . "'", 14001);
                 }
                 // write to the target system.
                 $localFile->write($readResponse[count($readResponse) - 1]);
             }
         }
     }
     $remoteFile->close();
     $localFile->close();
     return $newFileName;
 }
Exemplo n.º 2
0
 /**
  * Sends a request to a remote (update) server.
  * 
  * @param	string		$url
  * @param	array		$values
  * @param	array		$authData
  * @return	array		$response
  */
 protected static function sendRequest($url, $values = array(), $authData = array())
 {
     // default values
     $host = '';
     $path = '/';
     $port = 80;
     $postString = '';
     // parse url
     $parsedURL = parse_url($url);
     if (!empty($parsedURL['host'])) {
         $host = $parsedURL['host'];
     }
     if (!empty($parsedURL['path'])) {
         $path = $parsedURL['path'];
     }
     if (!empty($parsedURL['query'])) {
         $postString = $parsedURL['query'];
     }
     if (!empty($parsedURL['port'])) {
         $port = $parsedURL['port'];
     }
     // connect to server
     $options = array();
     if (PROXY_SERVER_HTTP) {
         $options['http']['proxy'] = PROXY_SERVER_HTTP;
     }
     require_once WCF_DIR . 'lib/system/io/RemoteFile.class.php';
     $remoteFile = new RemoteFile($host, $port, 30, $options);
     // Build and send the http request
     $request = "POST " . $path . " HTTP/1.0\r\n";
     if (isset($authData['authType'])) {
         $request .= "Authorization: Basic " . base64_encode($authData['htUsername'] . ":" . $authData['htPassword']) . "\r\n";
     }
     $request .= "User-Agent: HTTP.PHP (PackageUpdate.class.php; WoltLab Community Framework/" . WCF_VERSION . "; " . WCF::getLanguage()->getLanguageCode() . ")\r\n";
     $request .= "Accept: */*\r\n";
     $request .= "Accept-Language: " . WCF::getLanguage()->getLanguageCode() . "\r\n";
     $request .= "Host: " . $host . "\r\n";
     // build post string
     foreach ($values as $name => $value) {
         if (!empty($postString)) {
             $postString .= '&';
         }
         $postString .= $name . '=' . $value;
     }
     // send content type and length
     $request .= "Content-Type: application/x-www-form-urlencoded\r\n";
     $request .= "Content-Length: " . strlen($postString) . "\r\n";
     // if it is a POST request, there MUST be a blank line before the POST data, but there MUST NOT be
     // another blank line before, and of course there must be another blank line at the end of the request!
     $request .= "\r\n";
     if (!empty($postString)) {
         $request .= $postString . "\r\n";
     }
     // send close
     $request .= "Connection: Close\r\n\r\n";
     // send request
     $remoteFile->puts($request);
     unset($request, $postString);
     // define response vars
     $header = $content = '';
     // fetch the response.
     while (!$remoteFile->eof()) {
         $line = $remoteFile->gets();
         if (rtrim($line) != '') {
             $header .= $line;
         } else {
             break;
         }
     }
     while (!$remoteFile->eof()) {
         $content .= $remoteFile->gets();
     }
     // clean up and return the server's response.
     $remoteFile->close();
     // get http status code / line
     $httpStatusCode = 0;
     $httpStatusLine = '';
     if (preg_match('%http/\\d\\.\\d (\\d{3})[^\\n]*%i', $header, $match)) {
         $httpStatusLine = trim($match[0]);
         $httpStatusCode = $match[1];
     }
     // catch http 301 Moved Permanently
     // catch http 302 Found
     // catch http 303 See Other
     if ($httpStatusCode == 301 || $httpStatusCode == 302 || $httpStatusCode == 303) {
         // find location
         if (preg_match('/location:([^\\n]*)/i', $header, $match)) {
             $location = trim($match[1]);
             if ($location != $url) {
                 return self::sendRequest($location, $values, $authData);
             }
         }
     }
     // catch other http codes here
     return array('httpStatusLine' => $httpStatusLine, 'httpStatusCode' => $httpStatusCode, 'header' => $header, 'content' => $content);
 }