Merge pull request #20272 from nextcloud/enh/sabre/gzip_propfind
Gzip the propfind responsepull/21311/head
commit
9a196d12a8
@ -0,0 +1,74 @@ |
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
/** |
||||
* @copyright Copyright (c) 2020, Roeland Jago Douma <roeland@famdouma.nl> |
||||
* |
||||
* @author Roeland Jago Douma <roeland@famdouma.nl> |
||||
* |
||||
* @license GNU AGPL version 3 or any later version |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU Affero General Public License as |
||||
* published by the Free Software Foundation, either version 3 of the |
||||
* License, or (at your option) any later version. |
||||
* |
||||
* 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 |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
* |
||||
*/ |
||||
|
||||
namespace OCA\DAV\Connector\Sabre; |
||||
|
||||
use Sabre\DAV\ServerPlugin; |
||||
use Sabre\HTTP\Request; |
||||
use Sabre\HTTP\Response; |
||||
|
||||
class PropfindCompressionPlugin extends ServerPlugin { |
||||
|
||||
/** |
||||
* Reference to main server object |
||||
* |
||||
* @var Server |
||||
*/ |
||||
private $server; |
||||
|
||||
/** |
||||
* This initializes the plugin. |
||||
* |
||||
* This function is called by \Sabre\DAV\Server, after |
||||
* addPlugin is called. |
||||
* |
||||
* This method should set up the required event subscriptions. |
||||
* |
||||
* @param \Sabre\DAV\Server $server |
||||
* @return void |
||||
*/ |
||||
public function initialize(\Sabre\DAV\Server $server) { |
||||
$this->server = $server; |
||||
$this->server->on('afterMethod:PROPFIND', [$this, 'compressResponse'], 100); |
||||
} |
||||
|
||||
public function compressResponse(Request $request, Response $response) { |
||||
$header = $request->getHeader('Accept-Encoding'); |
||||
|
||||
if ($header === null) { |
||||
return $response; |
||||
} |
||||
|
||||
if (strpos($header, 'gzip') !== false) { |
||||
$body = $response->getBody(); |
||||
if (is_string($body)) { |
||||
$response->setHeader('Content-Encoding', 'gzip'); |
||||
$response->setBody(gzencode($body)); |
||||
} |
||||
} |
||||
|
||||
return $response; |
||||
} |
||||
} |
@ -0,0 +1,116 @@ |
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
/** |
||||
* @copyright Copyright (c) 2020, Roeland Jago Douma <roeland@famdouma.nl> |
||||
* |
||||
* @author Roeland Jago Douma <roeland@famdouma.nl> |
||||
* |
||||
* @license GNU AGPL version 3 or any later version |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU Affero General Public License as |
||||
* published by the Free Software Foundation, either version 3 of the |
||||
* License, or (at your option) any later version. |
||||
* |
||||
* 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 |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
* |
||||
*/ |
||||
|
||||
namespace OCA\DAV\Tests\unit\Connector\Sabre; |
||||
|
||||
use OCA\DAV\Connector\Sabre\PropfindCompressionPlugin; |
||||
use Sabre\HTTP\Request; |
||||
use Sabre\HTTP\Response; |
||||
use Test\TestCase; |
||||
|
||||
class PropfindCompressionPluginTest extends TestCase { |
||||
/** @var PropfindCompressionPlugin */ |
||||
private $plugin; |
||||
|
||||
protected function setUp(): void { |
||||
parent::setUp(); |
||||
|
||||
$this->plugin = new PropfindCompressionPlugin(); |
||||
} |
||||
|
||||
public function testNoHeader() { |
||||
$request = $this->createMock(Request::class); |
||||
$response = $this->createMock(Response::class); |
||||
|
||||
$request->method('getHeader') |
||||
->with('Accept-Encoding') |
||||
->willReturn(null); |
||||
|
||||
$response->expects($this->never()) |
||||
->method($this->anything()); |
||||
|
||||
$result = $this->plugin->compressResponse($request, $response); |
||||
$this->assertSame($response, $result); |
||||
} |
||||
|
||||
public function testHeaderButNoGzip() { |
||||
$request = $this->createMock(Request::class); |
||||
$response = $this->createMock(Response::class); |
||||
|
||||
$request->method('getHeader') |
||||
->with('Accept-Encoding') |
||||
->willReturn('deflate'); |
||||
|
||||
$response->expects($this->never()) |
||||
->method($this->anything()); |
||||
|
||||
$result = $this->plugin->compressResponse($request, $response); |
||||
$this->assertSame($response, $result); |
||||
} |
||||
|
||||
public function testHeaderGzipButNoStringBody() { |
||||
$request = $this->createMock(Request::class); |
||||
$response = $this->createMock(Response::class); |
||||
|
||||
$request->method('getHeader') |
||||
->with('Accept-Encoding') |
||||
->willReturn('deflate'); |
||||
|
||||
$response->method('getBody') |
||||
->willReturn(5); |
||||
|
||||
$result = $this->plugin->compressResponse($request, $response); |
||||
$this->assertSame($response, $result); |
||||
} |
||||
|
||||
|
||||
public function testProperGzip() { |
||||
$request = $this->createMock(Request::class); |
||||
$response = $this->createMock(Response::class); |
||||
|
||||
$request->method('getHeader') |
||||
->with('Accept-Encoding') |
||||
->willReturn('gzip, deflate'); |
||||
|
||||
$response->method('getBody') |
||||
->willReturn('my gzip test'); |
||||
|
||||
$response->expects($this->once()) |
||||
->method('setHeader') |
||||
->with( |
||||
$this->equalTo('Content-Encoding'), |
||||
$this->equalTo('gzip') |
||||
); |
||||
$response->expects($this->once()) |
||||
->method('setBody') |
||||
->with($this->callback(function ($data) { |
||||
$orig = gzdecode($data); |
||||
return $orig === 'my gzip test'; |
||||
})); |
||||
|
||||
$result = $this->plugin->compressResponse($request, $response); |
||||
$this->assertSame($response, $result); |
||||
} |
||||
} |
Loading…
Reference in new issue