コード例 #1
0
 /**
  * Uses curl or fsock to make a request to a remote server. Returns the
  * response.
  *
  * @param string $Url The full url to the page being requested (including http://)
  * @param integer $Timeout How long to allow for this request. Default Garden.SocketTimeout or 1, 0 to never timeout
  * @param boolean $FollowRedirects Whether or not to follow 301 and 302 redirects. Defaults false.
  * @return string Response (no headers)
  */
 function ProxyRequest($Url, $Timeout = FALSE, $FollowRedirects = FALSE)
 {
     $OriginalTimeout = $Timeout;
     if ($Timeout === FALSE) {
         $Timeout = C('Garden.SocketTimeout', 1.0);
     }
     $UrlParts = parse_url($Url);
     $Scheme = GetValue('scheme', $UrlParts, 'http');
     $Host = GetValue('host', $UrlParts, '');
     $Port = GetValue('port', $UrlParts, $Scheme == 'https' ? '443' : '80');
     $Path = GetValue('path', $UrlParts, '');
     $Query = GetValue('query', $UrlParts, '');
     // Get the cookie.
     $Cookie = '';
     $EncodeCookies = C('Garden.Cookie.Urlencode', TRUE);
     foreach ($_COOKIE as $Key => $Value) {
         if (strncasecmp($Key, 'XDEBUG', 6) == 0) {
             continue;
         }
         if (strlen($Cookie) > 0) {
             $Cookie .= '; ';
         }
         $EValue = $EncodeCookies ? urlencode($Value) : $Value;
         $Cookie .= "{$Key}={$EValue}";
     }
     $Response = '';
     if (function_exists('curl_init')) {
         //$Url = $Scheme.'://'.$Host.$Path;
         $Handler = curl_init();
         curl_setopt($Handler, CURLOPT_URL, $Url);
         curl_setopt($Handler, CURLOPT_PORT, $Port);
         curl_setopt($Handler, CURLOPT_SSL_VERIFYPEER, FALSE);
         curl_setopt($Handler, CURLOPT_HEADER, 1);
         curl_setopt($Handler, CURLOPT_USERAGENT, ArrayValue('HTTP_USER_AGENT', $_SERVER, 'Vanilla/2.0'));
         curl_setopt($Handler, CURLOPT_RETURNTRANSFER, 1);
         if ($Cookie != '') {
             curl_setopt($Handler, CURLOPT_COOKIE, $Cookie);
         }
         if ($Timeout > 0) {
             curl_setopt($Handler, CURLOPT_TIMEOUT, $Timeout);
         }
         // TIM @ 2010-06-28: Commented this out because it was forcing all requests with parameters to be POST. Same for the $Url above
         //
         //if ($Query != '') {
         //   curl_setopt($Handler, CURLOPT_POST, 1);
         //   curl_setopt($Handler, CURLOPT_POSTFIELDS, $Query);
         //}
         $Response = curl_exec($Handler);
         $Success = TRUE;
         if ($Response == FALSE) {
             $Success = FALSE;
             $Response = '';
             throw new Exception(curl_error($Handler));
         }
         curl_close($Handler);
     } else {
         if (function_exists('fsockopen')) {
             $Referer = Gdn_Url::WebRoot(TRUE);
             // Make the request
             $Pointer = @fsockopen($Host, $Port, $ErrorNumber, $Error, $Timeout);
             if (!$Pointer) {
                 throw new Exception(sprintf(T('Encountered an error while making a request to the remote server (%1$s): [%2$s] %3$s'), $Url, $ErrorNumber, $Error));
             }
             stream_set_timeout($Pointer, $Timeout);
             if (strlen($Cookie) > 0) {
                 $Cookie = "Cookie: {$Cookie}\r\n";
             }
             $HostHeader = $Host . ($Port != 80 ? ":{$Port}" : '');
             $Header = "GET {$Path}?{$Query} HTTP/1.1\r\n" . "Host: {$HostHeader}\r\n" . "User-Agent: " . ArrayValue('HTTP_USER_AGENT', $_SERVER, 'Vanilla/2.0') . "\r\n" . "Accept: */*\r\n" . "Accept-Charset: utf-8;\r\n" . "Referer: {$Referer}\r\n" . "Connection: close\r\n";
             if ($Cookie != '') {
                 $Header .= $Cookie;
             }
             $Header .= "\r\n";
             // Send the headers and get the response
             fputs($Pointer, $Header);
             while ($Line = fread($Pointer, 4096)) {
                 $Response .= $Line;
             }
             @fclose($Pointer);
             $Bytes = strlen($Response);
             $Response = trim($Response);
             $Success = TRUE;
             $StreamInfo = stream_get_meta_data($Pointer);
             if (GetValue('timed_out', $StreamInfo, FALSE) === TRUE) {
                 $Success = FALSE;
                 $Response = "Operation timed out after {$Timeout} seconds with {$Bytes} bytes received.";
             }
         } else {
             throw new Exception(T('Encountered an error while making a request to the remote server: Your PHP configuration does not allow curl or fsock requests.'));
         }
     }
     if (!$Success) {
         return $Response;
     }
     $ResponseHeaderData = trim(substr($Response, 0, strpos($Response, "\r\n\r\n")));
     $Response = trim(substr($Response, strpos($Response, "\r\n\r\n") + 4));
     $ResponseHeaderLines = explode("\n", trim($ResponseHeaderData));
     $Status = array_shift($ResponseHeaderLines);
     $ResponseHeaders = array();
     $ResponseHeaders['HTTP'] = trim($Status);
     /* get the numeric status code. 
      * - trim off excess edge whitespace, 
      * - split on spaces, 
      * - get the 2nd element (as a single element array), 
      * - pop the first (only) element off it... 
      * - return that.
      */
     $ResponseHeaders['StatusCode'] = array_pop(array_slice(explode(' ', trim($Status)), 1, 1));
     foreach ($ResponseHeaderLines as $Line) {
         $Line = explode(':', trim($Line));
         $Key = trim(array_shift($Line));
         $Value = trim(implode(':', $Line));
         $ResponseHeaders[$Key] = $Value;
     }
     if ($FollowRedirects) {
         $Code = GetValue('StatusCode', $ResponseHeaders, 200);
         if (in_array($Code, array(301, 302))) {
             if (array_key_exists('Location', $ResponseHeaders)) {
                 $Location = AbsoluteSource(GetValue('Location', $ResponseHeaders), $Url);
                 return ProxyRequest($Location, $OriginalTimeout, $FollowRedirects);
             }
         }
     }
     return $Response;
 }
コード例 #2
0
 /**
  *
  *
  * @param bool $Enabled
  * @param bool $OnlyUpdates
  * @return array|bool
  * @throws Exception
  */
 public function getAddonUpdates($Enabled = false, $OnlyUpdates = true)
 {
     // Get the addons on this site.
     $MyAddons = $this->GetAddons($Enabled);
     // Build the query for them.
     $Slugs = array_keys($MyAddons);
     array_map('urlencode', $Slugs);
     $SlugsString = implode(',', $Slugs);
     $Url = $this->AddonSiteUrl . '/addon/getlist.json?ids=' . $SlugsString;
     $SiteAddons = ProxyRequest($Url);
     $UpdateAddons = array();
     if ($SiteAddons) {
         $SiteAddons = val('Addons', json_decode($SiteAddons, true));
         $UpdateAddons = $this->CompareAddons($MyAddons, $SiteAddons);
     }
     return $UpdateAddons;
 }
コード例 #3
0
   public function UpdateProxy() {
      $Fields = $_POST;
      foreach ($Fields as $Field => $Value) {
         if (get_magic_quotes_gpc()) {
            if (is_array($Value)) {
               $Count = count($Value);
               for ($i = 0; $i < $Count; ++$i) {
                  $Value[$i] = stripslashes($Value[$i]);
               }
            } else {
               $Value = stripslashes($Value);
            }
            $Fields[$Field] = $Value;
         }
      }
      
		$UpdateCheckUrl = C('Garden.UpdateCheckUrl', 'http://vanillaforums.org/addons/update');
      echo ProxyRequest($UpdateCheckUrl.'?'.http_build_query($Fields));
      $Database = Gdn::Database();
      $Database->CloseConnection();
   }
コード例 #4
0
   protected function _GetForeignCredentials($ForeignIdentityUrl) {
   
      // Get the contents of the Authentication Url (timeout 5 seconds);
      @session_write_close();
      $Response = ProxyRequest($ForeignIdentityUrl, 5);
      
      if ($Response) {
      
         $ReadMode = strtolower(C("Garden.Authenticators.proxy.RemoteFormat", "ini"));
         switch ($ReadMode) {
            case 'ini':
               $Result = @parse_ini_string($Response);
               break;
               
            case 'json':
               $Result = @json_decode($Response);
               break;
               
            default:
               throw new Exception("Unexpected value '$ReadMode' for 'Garden.Authenticators.proxy.RemoteFormat'");
         }
         
         if ($Result) {
            $ReturnArray = array(
               'Email'        => ArrayValue('Email', $Result),
               'Name'         => ArrayValue('Name', $Result),
               'UniqueID'     => ArrayValue('UniqueID', $Result),
               'TransientKey' => ArrayValue('TransientKey', $Result, NULL)
            );

            if (isset($Result['Roles']))
               $ReturnArray['Roles'] = $Result['Roles'];

            return $ReturnArray;
         }
      }
      return FALSE;
   }
コード例 #5
0
ファイル: class.statistics.php プロジェクト: Raz0r/Garden
 /**
  * This is the asynchronous callback
  * 
  * This method is triggerd on every page request via a callback AJAX request
  * so that it may execute asychronously and reduce lag for users. It tracks
  * views, handles registration for new installations, and sends stats every 
  * day as needed.
  * 
  * @return void;
  */
 public function Tick()
 {
     // If we're local and not allowed, or just directly disabled, gtfo
     if (!self::CheckIsEnabled()) {
         return;
     }
     if (Gdn::Session()->CheckPermission('Garden.Settings.Manage')) {
         if (Gdn::Get('Garden.Analytics.Notify', FALSE) !== FALSE) {
             $CallMessage = '<span class="InformSprite Bandaid"></span> ';
             $CallMessage .= sprintf(T("There's a problem with Vanilla Analytics that needs your attention.<br/> Handle it <a href=\"%s\">here &raquo;</a>"), Url('dashboard/statistics'));
             Gdn::Controller()->InformMessage($CallMessage, array('CssClass' => 'HasSprite'));
         }
     }
     // If the config file is not writable, gtfo
     $ConfFile = PATH_LOCAL_CONF . DS . 'config.php';
     if (!is_writable($ConfFile)) {
         return;
     }
     $InstallationID = Gdn::InstallationID();
     // Check if we're registered with the central server already. If not, this request is
     // hijacked and used to perform that task instead of sending stats or recording a tick.
     if (is_null($InstallationID)) {
         $AttemptedRegistration = Gdn::Get('Garden.Analytics.Registering', FALSE);
         // If we last attempted to register less than 60 seconds ago, do nothing. Could still be working.
         if ($AttemptedRegistration !== FALSE && time() - $AttemptedRegistration < 60) {
             return;
         }
         return $this->Register();
     }
     // Add a pageview entry.
     $TimeSlot = date('Ymd');
     $Px = Gdn::Database()->DatabasePrefix;
     try {
         Gdn::Database()->Query("insert into {$Px}AnalyticsLocal (TimeSlot, Views) values (:TimeSlot, 1)\n         on duplicate key update Views = Views+1", array(':TimeSlot' => $TimeSlot));
     } catch (Exception $e) {
         // If we just tried to run the structure, and failed, don't blindly try again.
         // Just disable ourselves quietly.
         if (Gdn::Get('Garden.Analytics.AutoStructure', FALSE)) {
             SaveToConfig('Garden.Analytics.Enabled', FALSE);
             Gdn::Set('Garden.Analytics.AutoStructure', NULL);
             return;
         }
         // If we get here, insert failed. Try proxyconnect to the utility structure
         Gdn::Set('Garden.Analytics.AutoStructure', TRUE);
         ProxyRequest(Url('utility/update', TRUE), 0, FALSE);
     }
     // If we get here and this is true, we successfully ran the auto structure. Remove config flag.
     if (Gdn::Get('Garden.Analytics.AutoStructure', FALSE)) {
         Gdn::Set('Garden.Analytics.AutoStructure', NULL);
     }
     // Fire an event for plugins to track their own stats.
     // TODO: Make this analyze the path and throw a specific event (this event will change in future versions).
     $this->EventArguments['Path'] = Gdn::Request()->Post('Path');
     $this->FireEvent('Tick');
     // If we get here, the installation is registered and we can decide on whether or not to send stats now.
     $LastSentDate = self::LastSentDate();
     if (empty($LastSentDate) || $LastSentDate < date('Ymd', strtotime('-1 day'))) {
         return $this->Stats();
     }
 }
コード例 #6
0
 protected function _GetForeignCredentials($ForeignIdentityUrl)
 {
     // Get the contents of the Authentication Url (timeout 5 seconds);
     @session_write_close();
     $Response = ProxyRequest($ForeignIdentityUrl, 5);
     if ($Response) {
         $ReadMode = strtolower(C("Garden.Authenticators.proxy.RemoteFormat", "ini"));
         switch ($ReadMode) {
             case 'ini':
                 $Response = trim($Response);
                 $IniResult = array();
                 $RawIni = explode("\n", $Response);
                 foreach ($RawIni as $ResponeLine) {
                     $ResponeLine = trim($ResponeLine);
                     if (stristr($ResponeLine, '=') === FALSE) {
                         continue;
                     }
                     $ResponseParts = explode("=", $ResponeLine);
                     $ResponseKey = array_shift($ResponseParts);
                     $ResponseValue = implode("=", $ResponseParts);
                     $IniResult[$ResponseKey] = $ResponseValue;
                 }
                 if (sizeof($IniResult)) {
                     $Result = $IniResult;
                 }
                 break;
             case 'json':
                 $Result = @json_decode($Response);
                 break;
             default:
                 throw new Exception("Unexpected value '{$ReadMode}' for 'Garden.Authenticators.proxy.RemoteFormat'");
         }
         if ($Result) {
             // Bad page? Get out.
             $UniqueID = GetValue('UniqueID', $Result, NULL);
             $Email = GetValue('Email', $Result, NULL);
             if (is_null($Email) || is_null($UniqueID)) {
                 return FALSE;
             }
             $ReturnArray = array('Email' => $Email, 'UniqueID' => $UniqueID, 'Name' => GetValue('Name', $Result, NULL), 'TransientKey' => GetValue('TransientKey', $Result, NULL));
             if (isset($Result['Roles'])) {
                 $ReturnArray['Roles'] = $Result['Roles'];
             }
             return $ReturnArray;
         }
     }
     return FALSE;
 }
コード例 #7
0
 public function PreviewTheme($ThemeFolder = '')
 {
     $this->Permission('Garden.Themes.Manage');
     $ThemeManager = new Gdn_ThemeManager();
     $this->AvailableThemes = $ThemeManager->AvailableThemes();
     $PreviewThemeName = '';
     $PreviewThemeFolder = $ThemeFolder;
     foreach ($this->AvailableThemes as $ThemeName => $ThemeInfo) {
         if ($ThemeInfo['Folder'] == $ThemeFolder) {
             $PreviewThemeName = $ThemeName;
         }
     }
     // If we failed to get the requested theme, default back to the one currently enabled
     if ($PreviewThemeName == '') {
         $this->ThemeName = $ThemeManager->EnabledTheme();
         foreach ($this->AvailableThemes as $ThemeName => $ThemeInfo) {
             if ($ThemeName == $PreviewThemeName) {
                 $PreviewThemeFolder = $ThemeInfo['Folder'];
             }
         }
     }
     // Check for errors
     $Session = Gdn::Session();
     $Test = ProxyRequest(Url('/dashboard/settings/testaddon/Theme/' . $ThemeName . '/' . $Session->TransientKey() . '?DeliveryType=JSON', TRUE));
     if ($Test != 'Success') {
         $this->Form->AddError(sprintf(T('The theme could not be previewed because it generated a fatal error: <pre>%s</pre>'), strip_tags($Test)));
         $this->View = 'themes';
         $this->Themes();
     } else {
         $Session->SetPreference(array('PreviewThemeName' => $PreviewThemeName, 'PreviewThemeFolder' => $PreviewThemeFolder));
         Redirect('/');
     }
 }
コード例 #8
0
 protected function _GetForeignCredentials($ForeignIdentityUrl)
 {
     $Response = ProxyRequest($ForeignIdentityUrl, 5);
     if ($Response) {
         $Result = @parse_ini_string($Response);
         if ($Result) {
             $ReturnArray = array('Email' => ArrayValue('Email', $Result), 'Name' => ArrayValue('Name', $Result), 'UniqueID' => ArrayValue('UniqueID', $Result));
             return $ReturnArray;
         }
     }
     return FALSE;
 }
コード例 #9
0
 protected function QueryRemote($Provider, $Task, $Arguments = NULL, $Secure = TRUE, $GetBody = FALSE)
 {
     if (!is_array($Arguments)) {
         $Arguments = array();
     }
     $Arguments = array_merge($Arguments, array('ProxyConnectAutoconfigure' => 'configure', 'Task' => $Task));
     if ($Secure) {
         $Arguments = array_merge($Arguments, array('Key' => GetValue('AssociationSecret', $Provider)));
     }
     $RealURL = GetValue('URL', $Provider) . "?" . http_build_query($Arguments);
     if ($GetBody) {
         return ProxyRequest($RealURL, FALSE, TRUE);
     } else {
         return ProxyHead($RealURL, NULL, FALSE, TRUE);
     }
 }
コード例 #10
0
ファイル: class.hooks.php プロジェクト: vanilla/community
 /**
  * Proxy an RSS feed for Dashboard use across our kingdom.
  *
  * @param Gdn_Controller $sender
  * @param $Url
  * @return mixed|string
  * @throws Exception
  */
 public function homeController_proxyFeed_create($sender, $Url)
 {
     $Key = 'Feed|' . $Url;
     $Feed = Gdn::cache()->get($Key);
     if (!$Feed) {
         $Feed = ProxyRequest($Url, 5);
         Gdn::cache()->store($Key, $Feed, array(Gdn_Cache::FEATURE_EXPIRY => 5 * 60));
     }
     return $Feed;
 }