2014-06-28 20:28:08 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace Sabre\DAV;
|
|
|
|
|
|
|
|
use Sabre\DAVServerTest;
|
|
|
|
use Sabre\HTTP;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Tests related to the PUT request.
|
|
|
|
*
|
2016-05-11 00:26:44 +00:00
|
|
|
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
|
2014-06-28 20:28:08 +00:00
|
|
|
* @author Evert Pot (http://evertpot.com/)
|
|
|
|
* @license http://sabre.io/license/ Modified BSD License
|
|
|
|
*/
|
|
|
|
class HttpPutTest extends DAVServerTest {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets up the DAV tree.
|
|
|
|
*
|
|
|
|
* @return void
|
|
|
|
*/
|
2016-05-11 00:26:44 +00:00
|
|
|
function setUpTree() {
|
2014-06-28 20:28:08 +00:00
|
|
|
|
2016-05-11 00:26:44 +00:00
|
|
|
$this->tree = new Mock\Collection('root', [
|
2014-06-28 20:28:08 +00:00
|
|
|
'file1' => 'foo',
|
2016-05-11 00:26:44 +00:00
|
|
|
]);
|
2014-06-28 20:28:08 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A successful PUT of a new file.
|
|
|
|
*/
|
2016-05-11 00:26:44 +00:00
|
|
|
function testPut() {
|
2014-06-28 20:28:08 +00:00
|
|
|
|
2016-05-11 00:26:44 +00:00
|
|
|
$request = new HTTP\Request('PUT', '/file2', [], 'hello');
|
2014-06-28 20:28:08 +00:00
|
|
|
|
|
|
|
$response = $this->request($request);
|
|
|
|
|
2016-05-11 00:26:44 +00:00
|
|
|
$this->assertEquals(201, $response->getStatus(), 'Incorrect status code received. Full response body:' . $response->getBodyAsString());
|
2014-06-28 20:28:08 +00:00
|
|
|
|
|
|
|
$this->assertEquals(
|
|
|
|
'hello',
|
|
|
|
$this->server->tree->getNodeForPath('file2')->get()
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertEquals(
|
2016-05-11 00:26:44 +00:00
|
|
|
[
|
|
|
|
'X-Sabre-Version' => [Version::VERSION],
|
2016-05-28 15:46:24 +00:00
|
|
|
'Content-Length' => ['0'],
|
|
|
|
'ETag' => ['"' . md5('hello') . '"']
|
2016-05-11 00:26:44 +00:00
|
|
|
],
|
|
|
|
$response->getHeaders()
|
2014-06-28 20:28:08 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A successful PUT on an existing file.
|
|
|
|
*
|
|
|
|
* @depends testPut
|
|
|
|
*/
|
2016-05-11 00:26:44 +00:00
|
|
|
function testPutExisting() {
|
2014-06-28 20:28:08 +00:00
|
|
|
|
2016-05-11 00:26:44 +00:00
|
|
|
$request = new HTTP\Request('PUT', '/file1', [], 'bar');
|
2014-06-28 20:28:08 +00:00
|
|
|
|
|
|
|
$response = $this->request($request);
|
|
|
|
|
2016-05-11 00:26:44 +00:00
|
|
|
$this->assertEquals(204, $response->getStatus());
|
2014-06-28 20:28:08 +00:00
|
|
|
|
|
|
|
$this->assertEquals(
|
|
|
|
'bar',
|
|
|
|
$this->server->tree->getNodeForPath('file1')->get()
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertEquals(
|
2016-05-11 00:26:44 +00:00
|
|
|
[
|
|
|
|
'X-Sabre-Version' => [Version::VERSION],
|
2016-05-28 15:46:24 +00:00
|
|
|
'Content-Length' => ['0'],
|
|
|
|
'ETag' => ['"' . md5('bar') . '"']
|
2016-05-11 00:26:44 +00:00
|
|
|
],
|
|
|
|
$response->getHeaders()
|
2014-06-28 20:28:08 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* PUT on existing file with If-Match: *
|
|
|
|
*
|
|
|
|
* @depends testPutExisting
|
|
|
|
*/
|
2016-05-11 00:26:44 +00:00
|
|
|
function testPutExistingIfMatchStar() {
|
2014-06-28 20:28:08 +00:00
|
|
|
|
2016-05-11 00:26:44 +00:00
|
|
|
$request = new HTTP\Request(
|
|
|
|
'PUT',
|
|
|
|
'/file1',
|
|
|
|
['If-Match' => '*'],
|
|
|
|
'hello'
|
|
|
|
);
|
2014-06-28 20:28:08 +00:00
|
|
|
|
|
|
|
$response = $this->request($request);
|
|
|
|
|
2016-05-11 00:26:44 +00:00
|
|
|
$this->assertEquals(204, $response->getStatus());
|
2014-06-28 20:28:08 +00:00
|
|
|
|
|
|
|
$this->assertEquals(
|
|
|
|
'hello',
|
|
|
|
$this->server->tree->getNodeForPath('file1')->get()
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertEquals(
|
2016-05-11 00:26:44 +00:00
|
|
|
[
|
|
|
|
'X-Sabre-Version' => [Version::VERSION],
|
2016-05-28 15:46:24 +00:00
|
|
|
'Content-Length' => ['0'],
|
|
|
|
'ETag' => ['"' . md5('hello') . '"']
|
2016-05-11 00:26:44 +00:00
|
|
|
],
|
|
|
|
$response->getHeaders()
|
2014-06-28 20:28:08 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* PUT on existing file with If-Match: with a correct etag
|
|
|
|
*
|
|
|
|
* @depends testPutExisting
|
|
|
|
*/
|
2016-05-11 00:26:44 +00:00
|
|
|
function testPutExistingIfMatchCorrect() {
|
2014-06-28 20:28:08 +00:00
|
|
|
|
2016-05-11 00:26:44 +00:00
|
|
|
$request = new HTTP\Request(
|
|
|
|
'PUT',
|
|
|
|
'/file1',
|
|
|
|
['If-Match' => '"' . md5('foo') . '"'],
|
|
|
|
'hello'
|
|
|
|
);
|
2014-06-28 20:28:08 +00:00
|
|
|
|
|
|
|
$response = $this->request($request);
|
|
|
|
|
2016-05-11 00:26:44 +00:00
|
|
|
$this->assertEquals(204, $response->status);
|
2014-06-28 20:28:08 +00:00
|
|
|
|
|
|
|
$this->assertEquals(
|
|
|
|
'hello',
|
|
|
|
$this->server->tree->getNodeForPath('file1')->get()
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertEquals(
|
2016-05-11 00:26:44 +00:00
|
|
|
[
|
|
|
|
'X-Sabre-Version' => [Version::VERSION],
|
2016-05-28 15:46:24 +00:00
|
|
|
'Content-Length' => ['0'],
|
|
|
|
'ETag' => ['"' . md5('hello') . '"'],
|
2016-05-11 00:26:44 +00:00
|
|
|
],
|
|
|
|
$response->getHeaders()
|
2014-06-28 20:28:08 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* PUT with Content-Range should be rejected.
|
|
|
|
*
|
|
|
|
* @depends testPut
|
|
|
|
*/
|
2016-05-11 00:26:44 +00:00
|
|
|
function testPutContentRange() {
|
2014-06-28 20:28:08 +00:00
|
|
|
|
2016-05-11 00:26:44 +00:00
|
|
|
$request = new HTTP\Request(
|
|
|
|
'PUT',
|
|
|
|
'/file2',
|
|
|
|
['Content-Range' => 'bytes/100-200'],
|
|
|
|
'hello'
|
|
|
|
);
|
2014-06-28 20:28:08 +00:00
|
|
|
|
|
|
|
$response = $this->request($request);
|
2016-05-11 00:26:44 +00:00
|
|
|
$this->assertEquals(400, $response->getStatus());
|
2014-06-28 20:28:08 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* PUT on non-existing file with If-None-Match: * should work.
|
|
|
|
*
|
|
|
|
* @depends testPut
|
|
|
|
*/
|
2016-05-11 00:26:44 +00:00
|
|
|
function testPutIfNoneMatchStar() {
|
2014-06-28 20:28:08 +00:00
|
|
|
|
2016-05-11 00:26:44 +00:00
|
|
|
$request = new HTTP\Request(
|
|
|
|
'PUT',
|
|
|
|
'/file2',
|
|
|
|
['If-None-Match' => '*'],
|
|
|
|
'hello'
|
|
|
|
);
|
2014-06-28 20:28:08 +00:00
|
|
|
|
|
|
|
$response = $this->request($request);
|
|
|
|
|
2016-05-11 00:26:44 +00:00
|
|
|
$this->assertEquals(201, $response->getStatus());
|
2014-06-28 20:28:08 +00:00
|
|
|
|
|
|
|
$this->assertEquals(
|
|
|
|
'hello',
|
|
|
|
$this->server->tree->getNodeForPath('file2')->get()
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertEquals(
|
2016-05-11 00:26:44 +00:00
|
|
|
[
|
|
|
|
'X-Sabre-Version' => [Version::VERSION],
|
2016-05-28 15:46:24 +00:00
|
|
|
'Content-Length' => ['0'],
|
|
|
|
'ETag' => ['"' . md5('hello') . '"']
|
2016-05-11 00:26:44 +00:00
|
|
|
],
|
|
|
|
$response->getHeaders()
|
2014-06-28 20:28:08 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* PUT on non-existing file with If-Match: * should fail.
|
|
|
|
*
|
|
|
|
* @depends testPut
|
|
|
|
*/
|
2016-05-11 00:26:44 +00:00
|
|
|
function testPutIfMatchStar() {
|
2014-06-28 20:28:08 +00:00
|
|
|
|
2016-05-11 00:26:44 +00:00
|
|
|
$request = new HTTP\Request(
|
|
|
|
'PUT',
|
|
|
|
'/file2',
|
|
|
|
['If-Match' => '*'],
|
|
|
|
'hello'
|
|
|
|
);
|
2014-06-28 20:28:08 +00:00
|
|
|
|
|
|
|
$response = $this->request($request);
|
|
|
|
|
2016-05-11 00:26:44 +00:00
|
|
|
$this->assertEquals(412, $response->getStatus());
|
2014-06-28 20:28:08 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* PUT on existing file with If-None-Match: * should fail.
|
|
|
|
*
|
|
|
|
* @depends testPut
|
|
|
|
*/
|
2016-05-11 00:26:44 +00:00
|
|
|
function testPutExistingIfNoneMatchStar() {
|
2014-06-28 20:28:08 +00:00
|
|
|
|
2016-05-11 00:26:44 +00:00
|
|
|
$request = new HTTP\Request(
|
|
|
|
'PUT',
|
|
|
|
'/file1',
|
|
|
|
['If-None-Match' => '*'],
|
|
|
|
'hello'
|
|
|
|
);
|
2014-06-28 20:28:08 +00:00
|
|
|
$request->setBody('hello');
|
|
|
|
|
|
|
|
$response = $this->request($request);
|
|
|
|
|
2016-05-11 00:26:44 +00:00
|
|
|
$this->assertEquals(412, $response->getStatus());
|
2014-06-28 20:28:08 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* PUT thats created in a non-collection should be rejected.
|
|
|
|
*
|
|
|
|
* @depends testPut
|
|
|
|
*/
|
2016-05-11 00:26:44 +00:00
|
|
|
function testPutNoParent() {
|
2014-06-28 20:28:08 +00:00
|
|
|
|
2016-05-11 00:26:44 +00:00
|
|
|
$request = new HTTP\Request(
|
|
|
|
'PUT',
|
|
|
|
'/file1/file2',
|
|
|
|
[],
|
|
|
|
'hello'
|
|
|
|
);
|
2014-06-28 20:28:08 +00:00
|
|
|
|
|
|
|
$response = $this->request($request);
|
2016-05-11 00:26:44 +00:00
|
|
|
$this->assertEquals(409, $response->getStatus());
|
2014-06-28 20:28:08 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Finder may sometimes make a request, which gets its content-body
|
|
|
|
* stripped. We can't always prevent this from happening, but in some cases
|
|
|
|
* we can detected this and return an error instead.
|
|
|
|
*
|
|
|
|
* @depends testPut
|
|
|
|
*/
|
2016-05-11 00:26:44 +00:00
|
|
|
function testFinderPutSuccess() {
|
2014-06-28 20:28:08 +00:00
|
|
|
|
2016-05-11 00:26:44 +00:00
|
|
|
$request = new HTTP\Request(
|
|
|
|
'PUT',
|
|
|
|
'/file2',
|
|
|
|
['X-Expected-Entity-Length' => '5'],
|
|
|
|
'hello'
|
|
|
|
);
|
2014-06-28 20:28:08 +00:00
|
|
|
$response = $this->request($request);
|
|
|
|
|
2016-05-11 00:26:44 +00:00
|
|
|
$this->assertEquals(201, $response->getStatus());
|
2014-06-28 20:28:08 +00:00
|
|
|
|
|
|
|
$this->assertEquals(
|
|
|
|
'hello',
|
|
|
|
$this->server->tree->getNodeForPath('file2')->get()
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertEquals(
|
2016-05-11 00:26:44 +00:00
|
|
|
[
|
|
|
|
'X-Sabre-Version' => [Version::VERSION],
|
2016-05-28 15:46:24 +00:00
|
|
|
'Content-Length' => ['0'],
|
|
|
|
'ETag' => ['"' . md5('hello') . '"'],
|
2016-05-11 00:26:44 +00:00
|
|
|
],
|
|
|
|
$response->getHeaders()
|
2014-06-28 20:28:08 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Same as the last one, but in this case we're mimicing a failed request.
|
|
|
|
*
|
|
|
|
* @depends testFinderPutSuccess
|
|
|
|
*/
|
2016-05-11 00:26:44 +00:00
|
|
|
function testFinderPutFail() {
|
2014-06-28 20:28:08 +00:00
|
|
|
|
2016-05-11 00:26:44 +00:00
|
|
|
$request = new HTTP\Request(
|
|
|
|
'PUT',
|
|
|
|
'/file2',
|
|
|
|
['X-Expected-Entity-Length' => '5'],
|
|
|
|
''
|
|
|
|
);
|
2014-06-28 20:28:08 +00:00
|
|
|
|
|
|
|
$response = $this->request($request);
|
|
|
|
|
2016-05-11 00:26:44 +00:00
|
|
|
$this->assertEquals(403, $response->getStatus());
|
2014-06-28 20:28:08 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Plugins can intercept PUT. We need to make sure that works.
|
2016-05-11 00:26:44 +00:00
|
|
|
*
|
|
|
|
* @depends testPut
|
2014-06-28 20:28:08 +00:00
|
|
|
*/
|
2016-05-11 00:26:44 +00:00
|
|
|
function testPutIntercept() {
|
2014-06-28 20:28:08 +00:00
|
|
|
|
2016-05-11 00:26:44 +00:00
|
|
|
$this->server->on('beforeBind', function($uri) {
|
|
|
|
$this->server->httpResponse->setStatus(418);
|
|
|
|
return false;
|
|
|
|
});
|
2014-06-28 20:28:08 +00:00
|
|
|
|
2016-05-11 00:26:44 +00:00
|
|
|
$request = new HTTP\Request('PUT', '/file2', [], 'hello');
|
2014-06-28 20:28:08 +00:00
|
|
|
$response = $this->request($request);
|
|
|
|
|
2016-05-28 15:46:24 +00:00
|
|
|
$this->assertEquals(418, $response->getStatus(), 'Incorrect status code received. Full response body: ' . $response->getBodyAsString());
|
2014-06-28 20:28:08 +00:00
|
|
|
|
|
|
|
$this->assertFalse(
|
|
|
|
$this->server->tree->nodeExists('file2')
|
|
|
|
);
|
|
|
|
|
2016-05-11 00:26:44 +00:00
|
|
|
$this->assertEquals([
|
|
|
|
'X-Sabre-Version' => [Version::VERSION],
|
|
|
|
], $response->getHeaders());
|
2014-06-28 20:28:08 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|