Tweaks and fixes

This commit is contained in:
Romain Neutron
2013-06-27 23:55:48 +02:00
parent 563d2e2c55
commit e155089cac
21 changed files with 161 additions and 110 deletions

View File

@@ -131,7 +131,7 @@ registration-fields:
name: geonameid
required: true
xsendfile:
enable: false
enabled: false
mapping:
-
directory: ''

View File

@@ -12,7 +12,7 @@
namespace Alchemy\Phrasea\Controller;
use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Response\DeliverDataInterface;
use Alchemy\Phrasea\Http\DeliverDataInterface;
use Silex\ControllerProviderInterface;
use Symfony\Component\HttpFoundation\Request;
@@ -66,7 +66,6 @@ abstract class AbstractDelivery implements ControllerProviderInterface
if ($file->getDataboxSubdef()->get_class() == \databox_subdef::CLASS_THUMBNAIL) {
// default expiration is 5 days
$expiration = 60 * 60 * 24 * 5;
$response->setExpires(new \DateTime(sprintf('+%d seconds', $expiration)));
$response->setMaxAge($expiration);

View File

@@ -11,7 +11,7 @@
namespace Alchemy\Phrasea\Controller\Prod;
use Alchemy\Phrasea\Response\DeliverDataInterface;
use Alchemy\Phrasea\Http\DeliverDataInterface;
use Silex\Application;
use Silex\ControllerProviderInterface;
use Symfony\Component\HttpFoundation\Request;

View File

@@ -14,7 +14,7 @@ namespace Alchemy\Phrasea\Controller\Prod;
use Entities\LazaretFile;
use Alchemy\Phrasea\Border;
use Alchemy\Phrasea\Border\Attribute\AttributeInterface;
use Alchemy\Phrasea\Response\DeliverDataInterface;
use Alchemy\Phrasea\Http\DeliverDataInterface;
use Silex\Application;
use Silex\ControllerProviderInterface;
use Symfony\Component\HttpFoundation\Request;
@@ -522,7 +522,7 @@ class Lazaret implements ControllerProviderInterface
$lazaretThumbFileName = $app['root.path'] . '/tmp/lazaret/' . $lazaretFile->getThumbFilename();
return $app['phraseanet.file-serve']->deliverFile($lazaretThumbFileName, $lazaretFile->getOriginalName(), DeliverDataInterface::DISPOSITION_INLINE, 'image/jpeg');
return $app['phraseanet.file-serve']->deliverFile($lazaretThumbFileName, $lazaretFile->getOriginalName(), DeliverDataInterface::DISPOSITION_INLINE, 'image/jpeg', 3600);
}
/**

View File

@@ -28,13 +28,13 @@ class XSendFileSubscriber implements EventSubscriberInterface
public static function getSubscribedEvents()
{
return array(
KernelEvents::REQUEST => array('applyHeaders', 16),
KernelEvents::REQUEST => array('applyHeaders', 0),
);
}
public function applyHeaders(GetResponseEvent $event)
{
if ($this->app['phraseanet.configuration']['xsendfile']['enable']) {
if ($this->app['phraseanet.configuration']['xsendfile']['enabled']) {
$request = $event->getRequest();
$request->headers->set('X-Sendfile-Type', 'X-Accel-Redirect');
$request->headers->set('X-Accel-Mapping', (string) $this->app['phraseanet.xsendfile-mapping']);

View File

@@ -13,7 +13,8 @@ namespace Alchemy\Phrasea\Core\Provider;
use Silex\Application;
use Silex\ServiceProviderInterface;
use Alchemy\Phrasea\Response\ServeFileResponseFactory;
use Alchemy\Phrasea\Http\ServeFileResponseFactory;
use Alchemy\Phrasea\Http\XsendfileMapping;
use Alchemy\Phrasea\Core\Event\Subscriber\XSendFileSubscriber;
class FileServeServiceProvider implements ServiceProviderInterface
@@ -43,7 +44,7 @@ class FileServeServiceProvider implements ServiceProviderInterface
});
$app['phraseanet.xsendfile-mapping'] = $app->share(function($app) {
return new Mapping($app['xsendfile.mapping']);
return new XsendfileMapping($app['xsendfile.mapping']);
});
$app['phraseanet.file-serve'] = $app->share(function (Application $app) {

View File

@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Response;
namespace Alchemy\Phrasea\Http;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;

View File

@@ -9,9 +9,9 @@
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Response;
namespace Alchemy\Phrasea\Http;
use Alchemy\Phrasea\Response\DeliverDataInterface;
use Alchemy\Phrasea\Http\DeliverDataInterface;
use Alchemy\Phrasea\Application;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
@@ -38,7 +38,7 @@ class ServeFileResponseFactory implements DeliverDataInterface
public static function create(Application $app)
{
return new self(
$app['phraseanet.configuration']['xsendfile']['enable'],
$app['phraseanet.configuration']['xsendfile']['enabled'],
$app['unicode']
);
}
@@ -46,11 +46,12 @@ class ServeFileResponseFactory implements DeliverDataInterface
/**
* {@inheritdoc}
*/
public function deliverFile($file, $filename = '', $disposition = self::DISPOSITION_INLINE, $mimeType = null ,$cacheDuration = 3600)
public function deliverFile($file, $filename = '', $disposition = self::DISPOSITION_INLINE, $mimeType = null ,$cacheDuration = 0)
{
$response = new BinaryFileResponse($file);
$response->setContentDisposition($disposition, $this->sanitizeFilename($filename), $this->sanitizeFilenameFallback($filename));
$response->setMaxAge($cacheDuration);
$response->setPrivate();
if (null !== $mimeType) {
$response->headers->set('Content-Type', $mimeType);
@@ -62,7 +63,7 @@ class ServeFileResponseFactory implements DeliverDataInterface
/**
* {@inheritdoc}
*/
public function deliverData($data, $filename, $mimeType, $disposition = self::DISPOSITION_INLINE, $cacheDuration = 3600)
public function deliverData($data, $filename, $mimeType, $disposition = self::DISPOSITION_INLINE, $cacheDuration = 0)
{
$response = new Response($data);
$response->headers->set('Content-Disposition', $response->headers->makeDisposition(

View File

@@ -9,11 +9,11 @@
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\XSendFile;
namespace Alchemy\Phrasea\Http;
use Alchemy\Phrasea\Exception\InvalidArgumentException;
class Mapping
class XsendfileMapping
{
private $mapping;

View File

@@ -351,7 +351,7 @@ class API_V1_adapter extends API_V1_Abstract
'defaultLanguage' => $app['phraseanet.registry']->get('id_GV_default_lng'),
'allowIndexing' => $app['phraseanet.registry']->get('GV_allow_search_engine'),
'modes' => array(
'XsendFile' => $app['phraseanet.configuration']['xsendfile']['enable'],
'XsendFile' => $app['phraseanet.configuration']['xsendfile']['enabled'],
'XsendFileMapping' => $app['phraseanet.configuration']['xsendfile']['mapping'],
'h264Streaming' => $app['phraseanet.registry']->get('GV_h264_streaming'),
'authTokenDirectory' => $app['phraseanet.registry']->get('GV_mod_auth_token_directory'),

View File

@@ -51,22 +51,24 @@ class patch_3813 implements patchInterface
$xsendfilePath = $app['phraseanet.registry']->get('GV_X_Accel_Redirect');
$xsendfileMountPoint = $app['phraseanet.registry']->get('GV_X_Accel_Redirect_mount_point');
$config = $app['phraseanet.configuration']->setDefault('xsendfile')->getConfig();
$config = $app['phraseanet.configuration']
->setDefault('xsendfile')
->getConfig();
$config['xsendfile']['enable'] = (Boolean) $app['phraseanet.registry']->get('GV_modxsendfile', false);
$config['xsendfile']['enabled'] = (Boolean) $app['phraseanet.registry']->get('GV_modxsendfile', false);
if (null !== $xsendfilePath && null !== $xsendfileMountPoint) {
$config['xsendfile']['mapping'][0] = array(
$config['xsendfile']['mapping'] = array(array(
'directory' => $xsendfilePath,
'mount-point' => $xsendfileMountPoint,
);
));
}
$app['phraseanet.configuration']->setConfig($config);
$toRemove = array('GV_X_Accel_Redirect', 'GV_X_Accel_Redirect_mount_point', 'GV_modxsendfile');
$sql = 'DELETE FROM registry WHERE key = :k';
$sql = 'DELETE FROM registry WHERE `key` = :k';
$stmt = $appbox->get_connection()->prepare($sql);
foreach ($toRemove as $registryKey) {
$stmt->execute(array(

View File

@@ -134,7 +134,7 @@ registration-fields:
name: geonameid
required: true
xsendfile:
enable: false
enabled: false
mapping:
-
directory: ''

View File

@@ -115,7 +115,7 @@ registration-fields:
name: geonameid
required: true
xsendfile:
enable: false
enabled: false
mapping:
-
directory: ''

View File

@@ -115,7 +115,7 @@ registration-fields:
name: geonameid
required: true
xsendfile:
enable: false
enabled: false
mapping:
-
directory: ''

View File

@@ -139,3 +139,9 @@ registration-fields:
-
name: geonameid
required: true
xsendfile:
enabled: false
mapping:
-
directory: ''
mount-point: ''

View File

@@ -139,3 +139,9 @@ registration-fields:
-
name: geonameid
required: true
xsendfile:
enabled: false
mapping:
-
directory: ''
mount-point: ''

View File

@@ -2,6 +2,10 @@
namespace Alchemy\Tests\Phrasea\Core\Provider;
use Alchemy\Phrasea\Core\Provider\ConfigurationServiceProvider;
use Alchemy\Phrasea\Core\Provider\FileServeServiceProvider;
use Silex\Application;
/**
* @covers Alchemy\Phrasea\Core\Provider\FileServeServiceProvider
*/
@@ -10,7 +14,39 @@ class FileServeServiceProviderTest extends ServiceProviderTestCase
public function provideServiceDescription()
{
return array(
array('Alchemy\Phrasea\Core\Provider\FileServeServiceProvider', 'phraseanet.file-serve', 'Alchemy\\Phrasea\\Response\\ServeFileResponseFactory'),
array(
'Alchemy\Phrasea\Core\Provider\FileServeServiceProvider',
'phraseanet.file-serve',
'Alchemy\Phrasea\Http\ServeFileResponseFactory'
),
array(
'Alchemy\Phrasea\Core\Provider\FileServeServiceProvider',
'phraseanet.xsendfile-mapping',
'Alchemy\Phrasea\Http\XsendfileMapping'
),
);
}
public function testMapping()
{
$app = new Application();
$app['root.path'] = __DIR__ . '/../../../../../..';
$app->register(new ConfigurationServiceProvider());
$app->register(new FileServeServiceProvider());
$app['phraseanet.configuration.config-path'] = __DIR__ . '/fixtures/config-mapping.yml';
$app['phraseanet.configuration.config-compiled-path'] = __DIR__ . '/fixtures/config-mapping.php';
$this->assertEquals(array(array(
'directory' => '/tmp',
'mount-point' => 'mount',
),array(
'directory' => __DIR__ . '/../../../../../../tmp/download/',
'mount-point' => '/download/',
),array(
'directory' => __DIR__ . '/../../../../../../tmp/lazaret/',
'mount-point' => '/lazaret/',
)), $app['xsendfile.mapping']);
unlink($app['phraseanet.configuration.config-compiled-path']);
}
}

View File

@@ -1,16 +0,0 @@
<?php
namespace Alchemy\Tests\Phrasea\Core\Provider;
/**
* @covers Alchemy\Phrasea\Core\Provider\FileServeServiceProvider
*/
class XSendFileMappingServiceProviderTest extends ServiceProviderTestCase
{
public function provideServiceDescription()
{
return array(
array('Alchemy\Phrasea\Core\Provider\XSendFileMappingServiceProvider', 'phraseanet.xsendfile-mapping', 'Alchemy\\Phrasea\\XSendFile\\Mapping'),
);
}
}

View File

@@ -1,9 +1,9 @@
<?php
namespace Alchemy\Tests\Phrasea\Response;
namespace Alchemy\Tests\Phrasea\Http;
use Alchemy\Phrasea\Response\ServeFileResponseFactory;
use Alchemy\Phrasea\XSendFile\Mapping;
use Alchemy\Phrasea\Http\ServeFileResponseFactory;
use Alchemy\Phrasea\Http\XsendfileMapping;
use Symfony\Component\HttpFoundation\Request;
class ServeFileResponseFactoryTest extends \PhraseanetWebTestCaseAbstract
@@ -18,6 +18,19 @@ class ServeFileResponseFactoryTest extends \PhraseanetWebTestCaseAbstract
$this->assertInstanceOf("Symfony\Component\HttpFoundation\Response", $response);
$this->assertEquals('inline; filename="cestlafete.jpg"', $response->headers->get('content-disposition'));
$this->assertEquals(0, $response->getMaxAge());
$response->setPrivate();
$this->assertTrue($response->headers->getCacheControlDirective('private'));
}
public function testDeliverFileWithDuration()
{
$this->factory = new ServeFileResponseFactory(false, new \unicode());
$response = $this->factory->deliverFile(__DIR__ . '/../../../../files/cestlafete.jpg', 'hello', 'attachment', 'application/json', 23456);
$this->assertEquals(23456, $response->getMaxAge());
$this->assertTrue($response->headers->getCacheControlDirective('private'));
}
public function testDeliverFileWithFilename()
@@ -45,7 +58,7 @@ class ServeFileResponseFactoryTest extends \PhraseanetWebTestCaseAbstract
$this->factory = new ServeFileResponseFactory(true, new \unicode());
$request = Request::create('/');
$request->headers->set('X-SendFile-Type', 'X-Accel-Redirect');
$request->headers->set('X-Accel-Mapping', (string) new Mapping(array(
$request->headers->set('X-Accel-Mapping', (string) new XsendfileMapping(array(
array(
'directory' => __DIR__ . '/../../../../files/',
'mount-point' => '/protected/'
@@ -65,7 +78,7 @@ class ServeFileResponseFactoryTest extends \PhraseanetWebTestCaseAbstract
$this->factory = new ServeFileResponseFactory(true, new \unicode());
$request = Request::create('/');
$request->headers->set('X-SendFile-Type', 'X-Accel-Redirect');
$request->headers->set('X-Accel-Mapping', (string) new Mapping(array(
$request->headers->set('X-Accel-Mapping', (string) new XsendfileMapping(array(
array(
'directory' => __DIR__ . '/../../../../files/',
'mount-point' => '/protected/'
@@ -95,7 +108,7 @@ class ServeFileResponseFactoryTest extends \PhraseanetWebTestCaseAbstract
$this->factory = new ServeFileResponseFactory(true, new \unicode());
$request = Request::create('/');
$request->headers->set('X-SendFile-Type', 'X-Accel-Redirect');
$request->headers->set('X-Accel-Mapping', (string) new Mapping(array(
$request->headers->set('X-Accel-Mapping', (string) new XsendfileMapping(array(
array(
'directory' => __DIR__ . '/../../../../files/',
'mount-point' => '/protected/'

View File

@@ -0,0 +1,63 @@
<?php
namespace Alchemy\Tests\Phrasea\Http;
use Alchemy\Phrasea\Http\XsendfileMapping;
class XsendfileMappingTest extends \PhraseanetWebTestCaseAbstract
{
public function testOneMapping()
{
$dir = __DIR__ . '/../../../../files/';
$mapping = new XsendfileMapping(array(
array(
'directory' => $dir,
'mount-point' => '/protected/'
)
));
$this->assertEquals('/protected='.realpath($dir), (string) $mapping);
}
public function testMultiMapping()
{
$protected = __DIR__ . '/../../../../files/';
$upload = __DIR__ . '/../../../../';
$mapping = new XsendfileMapping(array(
array(
'directory' => $protected,
'mount-point' => '/protected/'
),
array(
'directory' => $upload,
'mount-point' => '/uploads/'
),
));
$this->assertEquals('/protected='.realpath($protected).',/uploads='.realpath($upload), (string) $mapping);
}
public function testMultiMappingWithANotExsistingDir()
{
$protected = __DIR__ . '/../../../../files/';
$mapping = new XsendfileMapping(array(
array(
'directory' => $protected,
'mount-point' => '/protected/'
),
array(
'directory' => '/path/to/nonexistent/directory',
'mount-point' => '/test/'
),
));
$this->assertEquals('/protected='.realpath($protected), (string) $mapping);
}
public function testEmptyMapping()
{
$mapping = new XsendfileMapping(array());
$this->assertEquals('', (string) $mapping);
}
}

View File

@@ -1,60 +0,0 @@
<?php
namespace Alchemy\Tests\Phrasea\XSendFile;
use Alchemy\Phrasea\XSendFile\Mapping;
class MappingTest extends \PhraseanetWebTestCaseAbstract
{
public function testOneMapping()
{
$mapping = new Mapping(array(
array(
'directory' => __DIR__ . '/../../../../files/',
'mount-point' => '/protected/'
)
));
$this->assertEquals('/protected=/home/nlegoff/workspace/Phraseanet/tests/files', (string) $mapping);
}
public function testMultiMapping()
{
$mapping = new Mapping(array(
array(
'directory' => __DIR__ . '/../../../../files/',
'mount-point' => '/protected/'
),
array(
'directory' => __DIR__ . '/../../../../',
'mount-point' => '/uploads/'
),
));
$this->assertEquals('/protected=/home/nlegoff/workspace/Phraseanet/tests/files,/uploads=/home/nlegoff/workspace/Phraseanet/tests', (string) $mapping);
}
public function testMultiMappingWithANotExsistingDir()
{
$mapping = new Mapping(array(
array(
'directory' => __DIR__ . '/../../../../files/',
'mount-point' => '/protected/'
),
array(
'directory' => __DIR__ . '/../../../../do_not_exists',
'mount-point' => '/test/'
),
));
$this->assertEquals('/protected=/home/nlegoff/workspace/Phraseanet/tests/files', (string) $mapping);
}
public function testEmptyMapping()
{
$mapping = new Mapping(array());
$this->assertEquals('', (string) $mapping);
}
}