Commit 5bb95737d5b40c5c074470966def8a5d589670fa
1 parent
b2c5ec48
Exists in
master
and in
111 other branches
Add a query limit for getParameters webservice
Showing
1 changed file
with
49 additions
and
1 deletions
Show diff stats
php/classes/WebServer.php
... | ... | @@ -83,6 +83,9 @@ class WebServer |
83 | 83 | private $wsUserMgr; |
84 | 84 | private $resultMgr, $myParamsInfoMgr; |
85 | 85 | private $dataFileName; |
86 | + private $QUERY_TIME_INTERVAL; | |
87 | + private $MAX_QUERIES; | |
88 | + private $CLIENTS_ACCESS_PATH; | |
86 | 89 | |
87 | 90 | function __construct() { |
88 | 91 | $this->userID = 'impex'; |
... | ... | @@ -90,6 +93,9 @@ class WebServer |
90 | 93 | $this->sessionID = $this->userID; |
91 | 94 | $this->myParamsInfoMgr = new ParamsInfoMgr(); |
92 | 95 | $this->resultMgr = new WebResultMgr(); |
96 | + $this->QUERY_TIME_INTERVAL = 30; // Time interval to limit access, in seconds. | |
97 | + $this->MAX_QUERIES = 3; // Number of queries allowed in one time interval, per IP. | |
98 | + $this->CLIENTS_ACCESS_PATH = './clients'; // Path of the file containing clients access counters. | |
93 | 99 | } |
94 | 100 | |
95 | 101 | protected function init($data) { |
... | ... | @@ -117,6 +123,44 @@ class WebServer |
117 | 123 | return array('success' => true, 'vars' => $vars); |
118 | 124 | } |
119 | 125 | |
126 | + // Returns true if the user reached its query limit. | |
127 | + private function isRateLimitReached() { | |
128 | + $currentTime = (int)(((new DateTime())->getTimestamp())/$this->QUERY_TIME_INTERVAL); | |
129 | + $ip = $_SERVER['REMOTE_ADDR']; | |
130 | + error_log("Client IP: $ip ; Current time: $currentTime\n"); | |
131 | + | |
132 | + if(file_exists($this->CLIENTS_ACCESS_PATH)) { | |
133 | + $clients = file_get_contents($this->CLIENTS_ACCESS_PATH); | |
134 | + $matches = array(); | |
135 | + if(preg_match("/($ip) (\d*) (\d*)/", $clients, $matches, PREG_OFFSET_CAPTURE)) { | |
136 | + error_log("Found an entry for this IP (". $matches[0][0] . ")\n"); | |
137 | + $lastTime = (int)($matches[2][0]); | |
138 | + if($currentTime == $lastTime) { | |
139 | + $count = (int)($matches[3][0]); | |
140 | + if($count >= $this->MAX_QUERIES) { | |
141 | + error_log("Same time range and max count value reached: please wait a moment and try again.\n"); | |
142 | + return true; | |
143 | + } else { | |
144 | + $count++; | |
145 | + error_log("Same time range, but max count value not reached yet: incrementing counter (" . ($this->MAX_QUERIES-$count) . "/$this->MAX_QUERIES).\n"); | |
146 | + $clients = substr_replace($clients, $count, $matches[3][1], strlen($matches[3][0])); | |
147 | + } | |
148 | + } else { | |
149 | + error_log("New time range: resetting time entry."); | |
150 | + $clients = substr_replace($clients, "$ip $currentTime 1", $matches[0][1], strlen($matches[0][0])); | |
151 | + } | |
152 | + } else { | |
153 | + error_log("IP $ip not found: creating new time entry\n"); | |
154 | + $clients = "$clients$ip $currentTime 1\n"; | |
155 | + } | |
156 | + } else { | |
157 | + error_log("File not created yet: creating file and new time entry\n"); | |
158 | + $clients = "$ip $currentTime 1\n"; | |
159 | + } | |
160 | + file_put_contents($this->CLIENTS_ACCESS_PATH, $clients); | |
161 | + return false; | |
162 | + } | |
163 | + | |
120 | 164 | private function setID(){ |
121 | 165 | |
122 | 166 | $nb_min = 10000; |
... | ... | @@ -549,7 +593,11 @@ class WebServer |
549 | 593 | ///////////////////////////////////////START GET DATASET /////////////////////////////// |
550 | 594 | public function getParameter($data) { |
551 | 595 | |
552 | - $multiParam = false; | |
596 | + if($this->isRateLimitReached()) { | |
597 | + return array('success' => false, 'message' => 'Rate limit reached. Please try again later.'); | |
598 | + } | |
599 | + | |
600 | + $multiParam = false; | |
553 | 601 | |
554 | 602 | $res = $this->init($data); |
555 | 603 | |
... | ... |