 819b833607
			
		
	
	819b833607
	
	
	
		
			
			Summary: Ref T13008. We haven't hit any issues with this, but I can imagine we might in the future. When one host makes an intracluster request to another host, the `$viewer` ends up as the omnipotent viewer. This viewer isn't logged in, so they'll currently accumulate rate limit points at a high rate. Instead, don't give them any points. These requests are always legitimate, and if they originated from a user request, that request should be the one getting rate limited. Test Plan: Browsed around. Reviewers: amckinley Reviewed By: amckinley Maniphest Tasks: T13008 Differential Revision: https://secure.phabricator.com/D18708
		
			
				
	
	
		
			67 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			67 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| 
 | |
| final class PhabricatorClientRateLimit
 | |
|   extends PhabricatorClientLimit {
 | |
| 
 | |
|   protected function getBucketDuration() {
 | |
|     return 60;
 | |
|   }
 | |
| 
 | |
|   protected function getBucketCount() {
 | |
|     return 5;
 | |
|   }
 | |
| 
 | |
|   protected function shouldRejectConnection($score) {
 | |
|     $limit = $this->getLimit();
 | |
| 
 | |
|     // Reject connections if the average score across all buckets exceeds the
 | |
|     // limit.
 | |
|     $average_score = $score / $this->getBucketCount();
 | |
| 
 | |
|     return ($average_score > $limit);
 | |
|   }
 | |
| 
 | |
|   protected function getConnectScore() {
 | |
|     return 0;
 | |
|   }
 | |
| 
 | |
|   protected function getPenaltyScore() {
 | |
|     return 1;
 | |
|   }
 | |
| 
 | |
|   protected function getDisconnectScore(array $request_state) {
 | |
|     $score = 1;
 | |
| 
 | |
|     // If the user was logged in, let them make more requests.
 | |
|     if (isset($request_state['viewer'])) {
 | |
|       $viewer = $request_state['viewer'];
 | |
|       if ($viewer->isOmnipotent()) {
 | |
|         // If the viewer was omnipotent, this was an intracluster request or
 | |
|         // some other kind of special request, so don't give it any points
 | |
|         // toward rate limiting.
 | |
|         $score = 0;
 | |
|       } else if ($viewer->isLoggedIn()) {
 | |
|         // If the viewer was logged in, give them fewer points than if they
 | |
|         // were logged out, since this traffic is much more likely to be
 | |
|         // legitimate.
 | |
|         $score = 0.25;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     return $score;
 | |
|   }
 | |
| 
 | |
|   protected function getRateLimitReason($score) {
 | |
|     $client_key = $this->getClientKey();
 | |
| 
 | |
|     // NOTE: This happens before we load libraries, so we can not use pht()
 | |
|     // here.
 | |
| 
 | |
|     return
 | |
|       "TOO MANY REQUESTS\n".
 | |
|       "You (\"{$client_key}\") are issuing too many requests ".
 | |
|       "too quickly.\n";
 | |
|   }
 | |
| 
 | |
| }
 |