Skip to content

Commit

Permalink
Merge pull request #29319 from owncloud/preview-via-dav
Browse files Browse the repository at this point in the history
Preview via dav
  • Loading branch information
DeepDiver1975 authored Jan 18, 2018
2 parents 81153de + 52e260e commit 2a67224
Show file tree
Hide file tree
Showing 37 changed files with 760 additions and 517 deletions.
10 changes: 9 additions & 1 deletion apps/dav/lib/Connector/Sabre/File.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
use OCA\DAV\Connector\Sabre\Exception\FileLocked;
use OCA\DAV\Connector\Sabre\Exception\Forbidden as DAVForbiddenException;
use OCA\DAV\Connector\Sabre\Exception\UnsupportedMediaType;
use OCA\DAV\Files\IFileNode;
use OCP\Encryption\Exceptions\GenericEncryptionException;
use OCP\Events\EventEmitterTrait;
use OCP\Files\EntityTooLargeException;
Expand All @@ -60,7 +61,7 @@
use Sabre\DAV\IFile;
use Symfony\Component\EventDispatcher\GenericEvent;

class File extends Node implements IFile {
class File extends Node implements IFile, IFileNode {

use EventEmitterTrait;
protected $request;
Expand Down Expand Up @@ -668,4 +669,11 @@ public function getChecksum($algo = null) {
protected function header($string) {
\header($string);
}

/**
* @return \OCP\Files\Node
*/
public function getNode() {
return \OC::$server->getRootFolder()->get($this->getFileInfo()->getPath());
}
}
4 changes: 2 additions & 2 deletions apps/dav/lib/Connector/Sabre/FilesPlugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -241,9 +241,9 @@ function httpGet(RequestInterface $request, ResponseInterface $response) {
Request::USER_AGENT_ANDROID_MOBILE_CHROME,
Request::USER_AGENT_FREEBOX,
])) {
$response->addHeader('Content-Disposition', 'attachment; filename="' . rawurlencode($filename) . '"');
$response->setHeader('Content-Disposition', 'attachment; filename="' . rawurlencode($filename) . '"');
} else {
$response->addHeader('Content-Disposition', 'attachment; filename*=UTF-8\'\'' . rawurlencode($filename)
$response->setHeader('Content-Disposition', 'attachment; filename*=UTF-8\'\'' . rawurlencode($filename)
. '; filename="' . rawurlencode($filename) . '"');
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
<?php
/**
* @author Björn Schießle <bjoern@schiessle.org>
* @author Jörn Friedrich Dreyer <jfd@butonic.de>
* @author Lukas Reschke <lukas@statuscode.ch>
* @author Morris Jobke <hey@morrisjobke.de>
* @author Roeland Jago Douma <rullzer@owncloud.com>
* @author Thomas Müller <thomas.mueller@tmit.eu>
* @author Tom Needham <tom@owncloud.com>
*
* @copyright Copyright (c) 2018, ownCloud GmbH
* @copyright Copyright (c) 2017, ownCloud GmbH
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
Expand All @@ -25,13 +19,17 @@
*
*/

namespace OCA\Files_Versions\AppInfo;

$application = new Application();
namespace OCA\DAV\Files;

/** @var $this \OCP\Route\IRouter */
$this->create('core_ajax_versions_preview', '/preview')->action(
function() {
require_once __DIR__ . '/../ajax/preview.php';
});

use OCP\Files\Node;

interface IFileNode {

/**
* @return Node
*/
public function getNode();

}
122 changes: 122 additions & 0 deletions apps/dav/lib/Files/PreviewPlugin.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
<?php
/**
* @author Thomas Müller <thomas.mueller@tmit.eu>
*
* @copyright Copyright (c) 2017, ownCloud GmbH
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/

namespace OCA\DAV\Files;

use OCP\Files\IPreviewNode;
use OCP\ILogger;
use Sabre\DAV\Exception\NotFound;
use Sabre\DAV\Server;
use Sabre\DAV\ServerPlugin;
use Sabre\HTTP\RequestInterface;
use Sabre\HTTP\ResponseInterface;

class PreviewPlugin extends ServerPlugin {

/** @var Server */
protected $server;
/** @var ILogger */
private $logger;

public function __construct(ILogger $logger) {
$this->logger = $logger;
}

/**
* Initializes the plugin and registers event handlers
*
* @param Server $server
* @return void
*/
function initialize(Server $server) {

$this->server = $server;
$this->server->on('method:GET', [$this, 'httpGet'], 90);
}

/**
* Intercepts GET requests on node urls ending with ?preview.
* The node has to implement IPreviewNode
*
* @param RequestInterface $request
* @param ResponseInterface $response
* @return bool
* @throws NotFound
* @throws \Sabre\DAVACL\Exception\NeedPrivileges
* @throws \Sabre\DAV\Exception\NotAuthenticated
*/
function httpGet(RequestInterface $request, ResponseInterface $response) {

$queryParams = $request->getQueryParameters();
if (!array_key_exists('preview', $queryParams)) {
return true;
}

$path = $request->getPath();
$node = $this->server->tree->getNodeForPath($path);

if (!$node instanceof IFileNode) {
return false;
}
$fileNode = $node->getNode();
if (!$fileNode instanceof IPreviewNode) {
return false;
}

// Checking ACL, if available.
if ($aclPlugin = $this->server->getPlugin('acl')) {
/** @var \Sabre\DAVACL\Plugin $aclPlugin */
$aclPlugin->checkPrivileges($path, '{DAV:}read');
}

if ($image = $fileNode->getThumbnail($queryParams)) {
if ($image === null || !$image->valid()) {
throw new NotFound();
}
$type = $image->mimeType();
if (!in_array($type, ['image/png', 'image/jpeg', 'image/gif'])) {
$type = 'application/octet-stream';
}

// Enable output buffering
ob_start();
// Capture the output
$image->show();
$imageData = ob_get_contents();
// Clear the output buffer
ob_end_clean();

$response->setHeader('Content-Type', $type);
$response->setHeader('Content-Disposition', 'attachment');
// cache 24h
$response->setHeader('Cache-Control', 'max-age=86400, must-revalidate');
$response->setHeader('Expires', gmdate ("D, d M Y H:i:s", time() + 86400) . " GMT");

$response->setStatus(200);
$response->setBody($imageData);

// Returning false to break the event chain
return false;
}
// TODO: add forceIcon handling .... if still needed
throw new NotFound();
}
}
11 changes: 10 additions & 1 deletion apps/dav/lib/Meta/MetaFile.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
use OC\Files\Meta\MetaFileVersionNode;
use OCA\DAV\Files\ICopySource;
use OCA\DAV\Files\IProvidesAdditionalHeaders;
use OCA\DAV\Files\IFileNode;
use OCP\Files\Node;
use Sabre\DAV\File;

/**
Expand All @@ -34,7 +36,7 @@
*
* @package OCA\DAV\Meta
*/
class MetaFile extends File implements ICopySource, IProvidesAdditionalHeaders {
class MetaFile extends File implements ICopySource, IFileNode, IProvidesAdditionalHeaders {

/** @var \OCP\Files\File */
private $file;
Expand Down Expand Up @@ -119,4 +121,11 @@ public function getContentDispositionFileName() {
}
return $this->getName();
}

/**
* @return Node
*/
public function getNode() {
return $this->file;
}
}
2 changes: 2 additions & 0 deletions apps/dav/lib/Server.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
use OCA\DAV\DAV\MiscCustomPropertiesBackend;
use OCA\DAV\DAV\PublicAuth;
use OCA\DAV\Files\BrowserErrorPagePlugin;
use OCA\DAV\Files\PreviewPlugin;
use OCA\DAV\SystemTag\SystemTagPlugin;
use OCA\DAV\Upload\ChunkingPlugin;
use OCP\IRequest;
Expand Down Expand Up @@ -183,6 +184,7 @@ public function __construct(IRequest $request, $baseUri) {
$this->server->addPlugin(new BrowserErrorPagePlugin());
}

$this->server->addPlugin(new PreviewPlugin($logger));
// wait with registering these until auth is handled and the filesystem is setup
$this->server->on('beforeMethod', function () use ($root) {
// custom properties plugin must be the last one
Expand Down
8 changes: 6 additions & 2 deletions apps/dav/tests/unit/Connector/Sabre/FilesPluginTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -560,14 +560,18 @@ public function testDownloadHeaders($isClumsyAgent, $contentDispositionHeader) {
->will($this->returnValue($isClumsyAgent));

$response
->expects($this->exactly(3))
->expects($this->exactly(2))
->method('addHeader')
->withConsecutive(
['Content-Disposition', $contentDispositionHeader],
['OC-Checksum', 'abcdefghijkl'],
['X-Accel-Buffering', 'no']
);

$response
->expects($this->once())
->method('setHeader')
->with('Content-Disposition', $contentDispositionHeader);

$this->plugin->httpGet($request, $response);
}

Expand Down
13 changes: 11 additions & 2 deletions apps/files/js/filelist.js
Original file line number Diff line number Diff line change
Expand Up @@ -1703,7 +1703,7 @@
* @param {int} urlSpec.x width
* @param {int} urlSpec.y height
* @param {String} urlSpec.file path to the file
* @return preview URL
* @return {String} preview URL
*/
generatePreviewUrl: function(urlSpec) {
urlSpec = urlSpec || {};
Expand All @@ -1718,7 +1718,16 @@
urlSpec.x = Math.ceil(urlSpec.x);
urlSpec.y = Math.ceil(urlSpec.y);
urlSpec.forceIcon = 0;
return OC.generateUrl('/core/preview.png?') + $.param(urlSpec);
var parts = urlSpec.file.split('/');
var encoded = [];
for (var i = 0; i < parts.length; i++) {
encoded.push(encodeURIComponent(parts[i]));
}
var file = encoded.join('/');
delete urlSpec.file;
urlSpec.preview = 1;

return OC.linkToRemoteBase('dav') + '/files/' + OC.getCurrentUser().uid + file + '?' + $.param(urlSpec);
},

/**
Expand Down
4 changes: 2 additions & 2 deletions apps/files_sharing/ajax/publicpreview.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,12 @@
\OCP\Util::writeLog('core-preview', 'Passed filename is not valid, might be malicious (file:"' . $file . '";ip:"' . \OC::$server->getRequest()->getRemoteAddress() . '")', \OCP\Util::WARN);
exit;
}
$sharedFile = \OC\Files\Filesystem::normalizePath($file);
$sharedFile = $node->get($file);
}

if($linkedItem->getNodeType() === 'file') {
$path = $node->getParent()->getPath();
$sharedFile = $node->getName();
$sharedFile = $node;
}

$path = ltrim(\OC\Files\Filesystem::normalizePath($path, false), '/');
Expand Down
65 changes: 0 additions & 65 deletions apps/files_versions/ajax/preview.php

This file was deleted.

2 changes: 2 additions & 0 deletions apps/files_versions/appinfo/app.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,5 @@
\OCP\Util::addStyle('files_versions', 'versions');

\OCA\Files_Versions\Hooks::connectHooks();

$application = new \OCA\Files_Versions\AppInfo\Application();
Loading

0 comments on commit 2a67224

Please sign in to comment.