Throttling middleware test

This commit is contained in:
Ruben 2016-10-05 21:42:27 +02:00
parent 8d19f0cf57
commit 8dca792ef8
4 changed files with 102 additions and 276 deletions

View file

@ -37,6 +37,16 @@ foreach($queries as $sql){ echo "$sql;\n"; }
// updateSchema // updateSchema
$tool->updateSchema($classes); $tool->updateSchema($classes);
$em->getConnection()->query("
CREATE TABLE IF NOT EXISTS `TokenBucket` (
`name` varchar(128) NOT NULL,
`value` varchar(255) NOT NULL
) ENGINE=MEMORY DEFAULT CHARSET=utf8;
ALTER TABLE `TokenBucket`
ADD PRIMARY KEY (`name`);
");
// ADD EMOTIONS // ADD EMOTIONS
@ -99,7 +109,7 @@ $i++;
$lvl->createTarget($emotions['fear'], 100, $i++); $lvl->createTarget($emotions['fear'], 100, $i++);
$lvl->createTarget($emotions['fear'], 100, $i++); $lvl->createTarget($emotions['fear'], 100, $i++);
$lvl->createTarget($emotions['fear'], 100, $i++); $lvl->createTarget($emotions['fear'], 100, $i++);
$em->persist($lvl);*/ $em->persist($lvl);
$lvl = new EmotionHero\Models\Level(); $lvl = new EmotionHero\Models\Level();
$lvl->setId(6); $lvl->setId(6);
@ -333,228 +343,13 @@ $lvl->createTarget($emotions['surprise'], 1, $a);
$em->persist($lvl); $em->persist($lvl);
*/
$em->flush(); $em->flush();
die();
// ////////////////// new levels:
// case LVL_SMILE:
// int s = 2;
// setTarget(Emotion.JOY, 100, s++);
// setTarget(Emotion.JOY, 100, s++);
// setTarget(Emotion.JOY, 50, s++);
// setTarget(Emotion.JOY, 50, s++);
// setTarget(Emotion.JOY, 30, s++);
// setTarget(Emotion.JOY, 30, s++);
// setTarget(Emotion.JOY, 50, s++);
// setTarget(Emotion.JOY, 50, s++);
// setTarget(Emotion.JOY, 100, s++);
// setTarget(Emotion.JOY, 100, s++);
// $s++;
// $s++;
// setTarget(Emotion.SURPRISE, 100, s++);
// setTarget(Emotion.SURPRISE, 100, s++);
// setTarget(Emotion.SURPRISE, 50, s++);
// setTarget(Emotion.SURPRISE, 50, s++);
// setTarget(Emotion.SURPRISE, 100, s++);
// setTarget(Emotion.SURPRISE, 100, s++);
// $s++;
// $s++;
// $s++;
// setTarget(Emotion.JOY, 100, s++);
// setTarget(Emotion.SURPRISE, 100, s);
// setTarget(Emotion.JOY, 100, s++);
// setTarget(Emotion.SURPRISE, 100, s);
// setTarget(Emotion.JOY, 100, s++);
// setTarget(Emotion.SURPRISE, 50, s);
// setTarget(Emotion.SURPRISE, 30, s);
// $s++;
// $s++;
// setTarget(Emotion.JOY, 100, s++);
// setTarget(Emotion.ANGER, 1, s);
// setTarget(Emotion.CONTEMPT, 1, s);
// setTarget(Emotion.DISGUST, 1, s);
// $s++;
// $s++;
// setTarget(Emotion.DISGUST, 1, s++);
// setTarget(Emotion.ANGER, 1, s);
// setTarget(Emotion.SURPRISE, 100, s);
// setMinimumScoreFromPercentage(40);
// minimumAchievements = 2;
// achievements.add(achievementCollection.get(5));
// achievements.add(achievementCollection.get(6));
// achievements.add(achievementCollection.get(7));
// break;
// case LVL_BUSINESS:
// int b = 2;
// setTarget(Emotion.ANGER, 100, b++);
// setTarget(Emotion.ANGER, 100, b++);
// setTarget(Emotion.ANGER, 50, b++);
// setTarget(Emotion.ANGER, 50, b++);
// setTarget(Emotion.ANGER, 30, b++);
// setTarget(Emotion.ANGER, 30, b++);
// $b++;
// setTarget(Emotion.DISGUST, 100, b++);
// setTarget(Emotion.DISGUST, 50, b++);
// setTarget(Emotion.DISGUST, 50, b++);
// setTarget(Emotion.DISGUST, 30, b++);
// $b++;
// setTarget(Emotion.CONTEMPT, 100, b++);
// setTarget(Emotion.CONTEMPT, 50, b++);
// setTarget(Emotion.CONTEMPT, 50, b++);
// setTarget(Emotion.CONTEMPT, 30, b++);
// $b++;
// setTarget(Emotion.SURPRISE, 100, b++);
// setTarget(Emotion.SURPRISE, 100, b++);
// setTarget(Emotion.SADNESS, 50, b);
// setTarget(Emotion.JOY, 50, b++);
// setTarget(Emotion.DISGUST, 50, b++);
// setTarget(Emotion.CONTEMPT, 30, b++);
// setTarget(Emotion.CONTEMPT, 100, b++);
// setTarget(Emotion.JOY, 100, b++);
// setTarget(Emotion.SURPRISE, 100, b++);
// b++;
// setTarget(Emotion.SADNESS, 100, b++);
// setTarget(Emotion.ANGER, 10, b++);
// setTarget(Emotion.SADNESS, 100, b++);
// setTarget(Emotion.ANGER, 10, b++);
// setTarget(Emotion.SADNESS, 100, b++);
// setTarget(Emotion.ANGER, 10, b++);
// setMinimumScoreFromPercentage(40);
// minimumAchievements = 2;
// achievements.add(achievementCollection.get(8));
// achievements.add(achievementCollection.get(9));
// achievements.add(achievementCollection.get(10));
// break;
// case LVL_REALLY:
// int r = 2;
// setTarget(Emotion.FEAR, 100, r++);
// setTarget(Emotion.FEAR, 50, r++);
// setTarget(Emotion.FEAR, 30, r++);
// r++;
// setTarget(Emotion.SADNESS, 100, r++);
// setTarget(Emotion.SADNESS, 50, r++);
// setTarget(Emotion.SADNESS, 100, r++);
// r++;
// setTarget(Emotion.DISGUST, 100, r++);
// setTarget(Emotion.DISGUST, 100, r++);
// setTarget(Emotion.DISGUST, 50, r++);
// r++;
// setTarget(Emotion.DISGUST, 100, r++);
// setTarget(Emotion.CONTEMPT, 30, r);
// setTarget(Emotion.DISGUST, 50, r++);
// setTarget(Emotion.CONTEMPT, 50, r);
// setTarget(Emotion.DISGUST, 30, r++);
// setTarget(Emotion.CONTEMPT, 100, r);
// r++;
// r++;
// setTarget(Emotion.SADNESS, 100, r++);
// setTarget(Emotion.JOY, 50, r++);
// setTarget(Emotion.SADNESS, 100, r++);
// setTarget(Emotion.JOY, 50, r++);
// setTarget(Emotion.SADNESS, 50, r++);
// setTarget(Emotion.JOY, 100, r++);
// setTarget(Emotion.SADNESS, 50, r++);
// setTarget(Emotion.JOY, 100, r);
// setTarget(Emotion.SADNESS, 100, r++);
// setTarget(Emotion.JOY, 50, r);
// setMinimumScoreFromPercentage(40);
// minimumAchievements = 2;
// achievements.add(achievementCollection.get(8));
// achievements.add(achievementCollection.get(9));
// achievements.add(achievementCollection.get(10));
// achievements.add(achievementCollection.get(11));
// break;
// case LVL_ACTNORMAL:
// float a = 2;
// setTarget(Emotion.ANGER, 100, a++);
// setTarget(Emotion.DISGUST, 100, a++);
// setTarget(Emotion.FEAR, 100, a++);
// setTarget(Emotion.JOY, 100, a++);
// setTarget(Emotion.SADNESS, 100, a++);
// setTarget(Emotion.SURPRISE, 100, a++);
// $a++;
// setTarget(Emotion.ANGER, 30, a++);
// setTarget(Emotion.DISGUST, 30, a+=0.5);
// setTarget(Emotion.FEAR, 30, a+=0.5);
// setTarget(Emotion.JOY, 30, a+=0.5);
// setTarget(Emotion.SADNESS, 30, a+=0.5);
// setTarget(Emotion.SURPRISE, 30, a+=0.5);
// $a++;
// setTarget(Emotion.ANGER, 30, a++);
// setTarget(Emotion.DISGUST, 30, a);
// setTarget(Emotion.ANGER, 30, a++);
// setTarget(Emotion.DISGUST, 30, a);
// setTarget(Emotion.FEAR, 30, a++);
// setTarget(Emotion.JOY, 30, a);
// setTarget(Emotion.FEAR, 30, a++);
// setTarget(Emotion.JOY, 30, a);
// setTarget(Emotion.SADNESS, 30, a++);
// setTarget(Emotion.SURPRISE, 30, a);
// setTarget(Emotion.SADNESS, 30, a++);
// setTarget(Emotion.SURPRISE, 30, a);
// $a++;
// $a++;
// setTarget(Emotion.DISGUST, 20, a++);
// setTarget(Emotion.CONTEMPT, 20, a);
// setTarget(Emotion.SURPRISE, 20, a);
// setTarget(Emotion.DISGUST, 10, a++);
// setTarget(Emotion.CONTEMPT, 10, a);
// setTarget(Emotion.SURPRISE, 10, a);
// setTarget(Emotion.DISGUST, 5, a++);
// setTarget(Emotion.CONTEMPT, 5, a);
// setTarget(Emotion.SURPRISE, 5, a);
// // Kuleshov's target:
// kuleshovTargetIds = new int[3];
// kuleshovTargetIds[0] = setTarget(Emotion.DISGUST, 1, a++);
// kuleshovTargetIds[1] = setTarget(Emotion.CONTEMPT, 1, a);
// kuleshovTargetIds[2] = setTarget(Emotion.SURPRISE, 1, a);
// // END OF KULESHOV
// setTarget(Emotion.DISGUST, 1, a++);
// setTarget(Emotion.CONTEMPT, 1, a);
// setTarget(Emotion.SURPRISE, 1, a);
// setTarget(Emotion.ANGER, 1, a++);
// setTarget(Emotion.CONTEMPT, 1, a);
// setTarget(Emotion.DISGUST, 1, a);
// setTarget(Emotion.FEAR, 1, a);
// setTarget(Emotion.JOY, 1, a);
// setTarget(Emotion.SADNESS, 1, a);
// setTarget(Emotion.SURPRISE, 1, a);
die(); die();
// TEST USER // TEST USER
die();
if(empty($em->getRepository(EmotionHero\Models\User::class)->findOneBy([]))) { if(empty($em->getRepository(EmotionHero\Models\User::class)->findOneBy([]))) {
$user = new EmotionHero\Models\User(); $user = new EmotionHero\Models\User();
$em->persist($user); $em->persist($user);
@ -562,57 +357,3 @@ if(empty($em->getRepository(EmotionHero\Models\User::class)->findOneBy([]))) {
$em->flush(); $em->flush();
} }
// $lvl = new EmotionHero\Models\Level();
// $lvl->setId(1);
// $lvl->setName("I am sooo ANGRY");
// $lvl->createTarget($emotions['anger'], 100, 1);
// $lvl->createTarget($emotions['anger'], 100, 2);
// $lvl->createTarget($emotions['anger'], 10, 3);
// $lvl->createTarget($emotions['anger'], 20, 4);
// $lvl->createTarget($emotions['anger'], 40, 5);
// $lvl->createTarget($emotions['anger'], 70, 6);
// $lvl->createTarget($emotions['anger'], 100, 7);
// $em->persist($lvl);
// $lvl = new EmotionHero\Models\Level();
// $lvl->setId(2);
// $lvl->setName("Let's be joyfull!");
// $lvl->createTarget($emotions['joy'], 100, 1);
// $lvl->createTarget($emotions['joy'], 100, 2);
// $lvl->createTarget($emotions['joy'], 100, 4);
// $lvl->createTarget($emotions['contempt'], 20, 4);
// $lvl->createTarget($emotions['anger'], 100, 5);
// $lvl->createTarget($emotions['joy'], 100, 7);
// $lvl->createTarget($emotions['anger'], 100, 9);
// $lvl->createTarget($emotions['joy'], 100, 11);
// $lvl->createTarget($emotions['joy'], 70, 12);
// $lvl->createTarget($emotions['joy'], 60, 13);
// $lvl->createTarget($emotions['joy'], 30, 14);
// $lvl->createTarget($emotions['joy'], 10, 14.5);
// $lvl->createTarget($emotions['anger'], 100, 16);
// $lvl->createTarget($emotions['joy'], 100, 17);
// $lvl->createTarget($emotions['joy'], 100, 18);
// $lvl->createTarget($emotions['joy'], 100, 19);
// $lvl->createTarget($emotions['joy'], 100, 20);
// $em->persist($lvl);
// $lvl = new EmotionHero\Models\Level();
// $lvl->setId(3);
// $lvl->setName("What a surprise");
// $lvl->createTarget($emotions['surprise'], 20, 1);
// $lvl->createTarget($emotions['surprise'], 50, 2);
// $lvl->createTarget($emotions['surprise'], 80, 3);
// $lvl->createTarget($emotions['surprise'], 100, 4);
// $em->persist($lvl);
// $lvl = new EmotionHero\Models\Level();
// $lvl->setId(4);
// $lvl->setName("Please, don't cry...");
// $lvl->createTarget($emotions['sadness'], 20, 1);
// $lvl->createTarget($emotions['sadness'], 50, 2);
// $lvl->createTarget($emotions['sadness'], 80, 3);
// $lvl->createTarget($emotions['sadness'], 100, 4);
// $em->persist($lvl);
$em->flush();

View file

@ -1,5 +1,11 @@
{ {
"name": "emotionhero/emotionhero_api", "name": "emotionhero/emotionhero_api",
"repositories": [
{
"type": "vcs",
"url": "https://github.com/rubenvandeven/tokenbucket"
}
],
"description": "The API for the Emotion Hero game.", "description": "The API for the Emotion Hero game.",
"require": { "require": {
"silex/silex": "~2.0", "silex/silex": "~2.0",
@ -9,7 +15,8 @@
"symfony/serializer": "^3.1", "symfony/serializer": "^3.1",
"cnam/security-jwt-service-provider": "2.*", "cnam/security-jwt-service-provider": "2.*",
"jms/serializer": "^1.3", "jms/serializer": "^1.3",
"danielstjules/php-pretty-datetime": "dev-master" "danielstjules/php-pretty-datetime": "dev-master",
"fustundag/tokenbucket": "dev-master"
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {

View file

@ -0,0 +1,77 @@
<?php
namespace EmotionHero\Api;
use Exception;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\HttpKernelInterface;
/**
* Description of ThrottleMiddleware
*
* @author ruben
*/
class ThrottleMiddleware implements HttpKernelInterface
{
/** @var HttpKernelInterface The kernel interface of the app */
private $app;
/** @var array Array with options */
private $options;
public function __construct(HttpKernelInterface $app, array $options = [])
{
$this->app = $app;
$this->options = array_merge([
'pdo'=>null,
], $options);
if($this->options['pdo'] === null) {
throw new Exception("Please profide the PDO handle with the 'pdo' option", 1);
}
}
public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
{
$limit_requests = true;
// don't throttle on subrequest (internal)
if($type != HttpKernelInterface::MASTER_REQUEST) {
$limit_requests = false;
} else {
// limited throttling for non-users (at ip level)
$tokens = 15; // max nr of tokens (also start amount)
$rate = 0.5; // tokens per seconds
$name = 'ip_' . $request->getClientIp();
}
if($limit_requests)
{
$storage = new PDOStorage($this->options['pdo']);
// Define the bucket
$bucket_options = array(
'capacity' => $tokens,
'fillRate' => $rate
);
// Create the bucket
$bucket = new TokenBucket($name, $storage, $bucket_options);
if ($bucket->consume()===false) {
return new JsonResponse(['success' => false, 'message' => "Too many requests"], 429);
}
}
// don't return null (which would yield almost the same result), so we can
// add the headers to the response afterwards.
$response = $this->app->handle($request, $type, $catch);
if(isSet($bucket))
{
foreach($bucket->getRateLimitHttpHeaders() as $header_name => $header_value)
{
$response->headers->set($header_name, $header_value);
}
}
return $response;
}
}

View file

@ -166,6 +166,7 @@ $app->get('/api/protected_resource', function() use ($app){
$app->mount('/', new EmotionHero\Api\ScoreControllerProvider()); $app->mount('/', new EmotionHero\Api\ScoreControllerProvider());
// middlewares
$appStack = new EmotionHero\Api\ThrottleMiddleware($app, ['pdo'=>$eh->getEm()->getConnection()] );
$appStack->handle(Request::createFromGlobals())->send();
$app->run();