Completed
Push — stable8.2 ( 6b9b12...4e3ace )
by Thomas
58:11
created

RequestTest::testUndefinedUserAgent()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
dl 0
loc 10
rs 9.4286
c 1
b 1
f 0
cc 1
eloc 6
nc 1
nop 3
1
<?php
2
/**
3
 * @copyright 2013 Thomas Tanghus ([email protected])
4
 * @copyright 2015 Lukas Reschke [email protected]
5
 *
6
 * This file is licensed under the Affero General Public License version 3 or
7
 * later.
8
 * See the COPYING-README file.
9
 */
10
11
namespace OC\AppFramework\Http;
12
13
use OC\Security\Crypto;
14
use OCP\Security\ISecureRandom;
15
use OCP\IConfig;
16
17
/**
18
 * Class RequestTest
19
 *
20
 * @package OC\AppFramework\Http
21
 */
22
class RequestTest extends \Test\TestCase {
23
	/** @var string */
24
	protected $stream = 'fakeinput://data';
25
	/** @var ISecureRandom */
26
	protected $secureRandom;
27
	/** @var IConfig */
28
	protected $config;
29
30
	protected function setUp() {
31
		parent::setUp();
32
33
		require_once __DIR__ . '/requeststream.php';
34
		if (in_array('fakeinput', stream_get_wrappers())) {
35
			stream_wrapper_unregister('fakeinput');
36
		}
37
		stream_wrapper_register('fakeinput', 'RequestStream');
38
39
		$this->secureRandom = $this->getMockBuilder('\OCP\Security\ISecureRandom')->getMock();
40
		$this->config = $this->getMockBuilder('\OCP\IConfig')->getMock();
41
	}
42
43
	protected function tearDown() {
44
		stream_wrapper_unregister('fakeinput');
45
		parent::tearDown();
46
	}
47
48
	public function testRequestAccessors() {
49
		$vars = array(
50
			'get' => array('name' => 'John Q. Public', 'nickname' => 'Joey'),
51
			'method' => 'GET',
52
		);
53
54
		$request = new Request(
55
			$vars,
56
			$this->secureRandom,
57
			$this->config,
58
			$this->stream
59
		);
60
61
		// Countable
62
		$this->assertSame(2, count($request));
63
		// Array access
64
		$this->assertSame('Joey', $request['nickname']);
65
		// "Magic" accessors
66
		$this->assertSame('Joey', $request->{'nickname'});
67
		$this->assertTrue(isset($request['nickname']));
68
		$this->assertTrue(isset($request->{'nickname'}));
69
		$this->assertFalse(isset($request->{'flickname'}));
70
		// Only testing 'get', but same approach for post, files etc.
71
		$this->assertSame('Joey', $request->get['nickname']);
0 ignored issues
show
Documentation introduced by
The property get does not exist on object<OC\AppFramework\Http\Request>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
72
		// Always returns null if variable not set.
73
		$this->assertSame(null, $request->{'flickname'});
74
75
	}
76
77
	// urlParams has precedence over POST which has precedence over GET
78
	public function testPrecedence() {
79
		$vars = array(
80
			'get' => array('name' => 'John Q. Public', 'nickname' => 'Joey'),
81
			'post' => array('name' => 'Jane Doe', 'nickname' => 'Janey'),
82
			'urlParams' => array('user' => 'jw', 'name' => 'Johnny Weissmüller'),
83
			'method' => 'GET'
84
		);
85
86
		$request = new Request(
87
			$vars,
88
			$this->secureRandom,
89
			$this->config,
90
			$this->stream
91
		);
92
93
		$this->assertSame(3, count($request));
94
		$this->assertSame('Janey', $request->{'nickname'});
95
		$this->assertSame('Johnny Weissmüller', $request->{'name'});
96
	}
97
98
99
	/**
100
	 * @expectedException \RuntimeException
101
	 */
102 View Code Duplication
	public function testImmutableArrayAccess() {
103
		$vars = array(
104
			'get' => array('name' => 'John Q. Public', 'nickname' => 'Joey'),
105
			'method' => 'GET'
106
		);
107
108
		$request = new Request(
109
			$vars,
110
			$this->secureRandom,
111
			$this->config,
112
			$this->stream
113
		);
114
115
		$request['nickname'] = 'Janey';
116
	}
117
118
	/**
119
	 * @expectedException \RuntimeException
120
	 */
121 View Code Duplication
	public function testImmutableMagicAccess() {
122
		$vars = array(
123
			'get' => array('name' => 'John Q. Public', 'nickname' => 'Joey'),
124
			'method' => 'GET'
125
		);
126
127
		$request = new Request(
128
			$vars,
129
			$this->secureRandom,
130
			$this->config,
131
			$this->stream
132
		);
133
134
		$request->{'nickname'} = 'Janey';
135
	}
136
137
	/**
138
	 * @expectedException \LogicException
139
	 */
140
	public function testGetTheMethodRight() {
141
		$vars = array(
142
			'get' => array('name' => 'John Q. Public', 'nickname' => 'Joey'),
143
			'method' => 'GET',
144
		);
145
146
		$request = new Request(
147
			$vars,
148
			$this->secureRandom,
149
			$this->config,
150
			$this->stream
151
		);
152
153
		$request->post;
0 ignored issues
show
Documentation introduced by
The property post does not exist on object<OC\AppFramework\Http\Request>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
154
	}
155
156
	public function testTheMethodIsRight() {
157
		$vars = array(
158
			'get' => array('name' => 'John Q. Public', 'nickname' => 'Joey'),
159
			'method' => 'GET',
160
		);
161
162
		$request = new Request(
163
			$vars,
164
			$this->secureRandom,
165
			$this->config,
166
			$this->stream
167
		);
168
169
		$this->assertSame('GET', $request->method);
0 ignored issues
show
Documentation introduced by
The property method does not exist on object<OC\AppFramework\Http\Request>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
170
		$result = $request->get;
0 ignored issues
show
Documentation introduced by
The property get does not exist on object<OC\AppFramework\Http\Request>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
171
		$this->assertSame('John Q. Public', $result['name']);
172
		$this->assertSame('Joey', $result['nickname']);
173
	}
174
175
	public function testJsonPost() {
176
		global $data;
177
		$data = '{"name": "John Q. Public", "nickname": "Joey"}';
178
		$vars = array(
179
			'method' => 'POST',
180
			'server' => array('CONTENT_TYPE' => 'application/json; utf-8')
181
		);
182
183
		$request = new Request(
184
			$vars,
185
			$this->secureRandom,
186
			$this->config,
187
			$this->stream
188
		);
189
190
		$this->assertSame('POST', $request->method);
0 ignored issues
show
Documentation introduced by
The property method does not exist on object<OC\AppFramework\Http\Request>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
191
		$result = $request->post;
0 ignored issues
show
Documentation introduced by
The property post does not exist on object<OC\AppFramework\Http\Request>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
192
		$this->assertSame('John Q. Public', $result['name']);
193
		$this->assertSame('Joey', $result['nickname']);
194
		$this->assertSame('Joey', $request->params['nickname']);
0 ignored issues
show
Documentation introduced by
The property params does not exist on object<OC\AppFramework\Http\Request>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
195
		$this->assertSame('Joey', $request['nickname']);
196
	}
197
198
	public function testNotJsonPost() {
199
		global $data;
200
		$data = 'this is not valid json';
201
		$vars = array(
202
			'method' => 'POST',
203
			'server' => array('CONTENT_TYPE' => 'application/json; utf-8')
204
		);
205
206
		$request = new Request(
207
			$vars,
208
			$this->secureRandom,
209
			$this->config,
210
			$this->stream
211
		);
212
213
		$this->assertEquals('POST', $request->method);
0 ignored issues
show
Documentation introduced by
The property method does not exist on object<OC\AppFramework\Http\Request>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
214
		$result = $request->post;
0 ignored issues
show
Documentation introduced by
The property post does not exist on object<OC\AppFramework\Http\Request>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
Unused Code introduced by
$result is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
215
		// ensure there's no error attempting to decode the content
216
	}
217
218
	public function testPatch() {
219
		global $data;
220
		$data = http_build_query(array('name' => 'John Q. Public', 'nickname' => 'Joey'), '', '&');
221
222
		$vars = array(
223
			'method' => 'PATCH',
224
			'server' => array('CONTENT_TYPE' => 'application/x-www-form-urlencoded'),
225
		);
226
227
		$request = new Request(
228
			$vars,
229
			$this->secureRandom,
230
			$this->config,
231
			$this->stream
232
		);
233
234
		$this->assertSame('PATCH', $request->method);
0 ignored issues
show
Documentation introduced by
The property method does not exist on object<OC\AppFramework\Http\Request>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
235
		$result = $request->patch;
0 ignored issues
show
Documentation introduced by
The property patch does not exist on object<OC\AppFramework\Http\Request>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
236
237
		$this->assertSame('John Q. Public', $result['name']);
238
		$this->assertSame('Joey', $result['nickname']);
239
	}
240
241
	public function testJsonPatchAndPut() {
242
		global $data;
243
244
		// PUT content
245
		$data = '{"name": "John Q. Public", "nickname": "Joey"}';
246
		$vars = array(
247
			'method' => 'PUT',
248
			'server' => array('CONTENT_TYPE' => 'application/json; utf-8'),
249
		);
250
251
		$request = new Request(
252
			$vars,
253
			$this->secureRandom,
254
			$this->config,
255
			$this->stream
256
		);
257
258
		$this->assertSame('PUT', $request->method);
0 ignored issues
show
Documentation introduced by
The property method does not exist on object<OC\AppFramework\Http\Request>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
259
		$result = $request->put;
0 ignored issues
show
Documentation introduced by
The property put does not exist on object<OC\AppFramework\Http\Request>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
260
261
		$this->assertSame('John Q. Public', $result['name']);
262
		$this->assertSame('Joey', $result['nickname']);
263
264
		// PATCH content
265
		$data = '{"name": "John Q. Public", "nickname": null}';
266
		$vars = array(
267
			'method' => 'PATCH',
268
			'server' => array('CONTENT_TYPE' => 'application/json; utf-8'),
269
		);
270
271
		$request = new Request(
272
			$vars,
273
			$this->secureRandom,
274
			$this->config,
275
			$this->stream
276
		);
277
278
		$this->assertSame('PATCH', $request->method);
0 ignored issues
show
Documentation introduced by
The property method does not exist on object<OC\AppFramework\Http\Request>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
279
		$result = $request->patch;
0 ignored issues
show
Documentation introduced by
The property patch does not exist on object<OC\AppFramework\Http\Request>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
280
281
		$this->assertSame('John Q. Public', $result['name']);
282
		$this->assertSame(null, $result['nickname']);
283
	}
284
285
	public function testPutStream() {
286
		global $data;
287
		$data = file_get_contents(__DIR__ . '/../../../data/testimage.png');
288
289
		$vars = array(
290
			'put' => $data,
291
			'method' => 'PUT',
292
			'server' => array('CONTENT_TYPE' => 'image/png'),
293
		);
294
295
		$request = new Request(
296
			$vars,
297
			$this->secureRandom,
298
			$this->config,
299
			$this->stream
300
		);
301
302
		$this->assertSame('PUT', $request->method);
0 ignored issues
show
Documentation introduced by
The property method does not exist on object<OC\AppFramework\Http\Request>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
303
		$resource = $request->put;
0 ignored issues
show
Documentation introduced by
The property put does not exist on object<OC\AppFramework\Http\Request>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
304
		$contents = stream_get_contents($resource);
305
		$this->assertSame($data, $contents);
306
307
		try {
308
			$resource = $request->put;
0 ignored issues
show
Documentation introduced by
The property put does not exist on object<OC\AppFramework\Http\Request>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
Unused Code introduced by
$resource is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
309
		} catch(\LogicException $e) {
0 ignored issues
show
Unused Code introduced by
catch (\LogicException $e) { return; } does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
310
			return;
311
		}
312
		$this->fail('Expected LogicException.');
313
314
	}
315
316
317
	public function testSetUrlParameters() {
318
		$vars = array(
319
			'post' => array(),
320
			'method' => 'POST',
321
			'urlParams' => array('id' => '2'),
322
		);
323
324
		$request = new Request(
325
			$vars,
326
			$this->secureRandom,
327
			$this->config,
328
			$this->stream
329
		);
330
331
		$newParams = array('id' => '3', 'test' => 'test2');
332
		$request->setUrlParameters($newParams);
333
		$this->assertSame('test2', $request->getParam('test'));
334
		$this->assertEquals('3', $request->getParam('id'));
335
		$this->assertEquals('3', $request->getParams()['id']);
336
	}
337
338
	public function testGetIdWithModUnique() {
339
		$vars = [
340
			'server' => [
341
				'UNIQUE_ID' => 'GeneratedUniqueIdByModUnique'
342
			],
343
		];
344
345
		$request = new Request(
346
			$vars,
347
			$this->secureRandom,
348
			$this->config,
349
			$this->stream
350
		);
351
352
		$this->assertSame('GeneratedUniqueIdByModUnique', $request->getId());
353
	}
354
355
	public function testGetIdWithoutModUnique() {
356
		$lowRandomSource = $this->getMockBuilder('\OCP\Security\ISecureRandom')
357
			->disableOriginalConstructor()->getMock();
358
		$lowRandomSource->expects($this->once())
359
			->method('generate')
360
			->with('20')
361
			->will($this->returnValue('GeneratedByOwnCloudItself'));
362
363
		$this->secureRandom
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<OCP\Security\ISecureRandom>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
364
			->expects($this->once())
365
			->method('getLowStrengthGenerator')
366
			->will($this->returnValue($lowRandomSource));
367
368
		$request = new Request(
369
			[],
370
			$this->secureRandom,
371
			$this->config,
372
			$this->stream
373
		);
374
375
		$this->assertSame('GeneratedByOwnCloudItself', $request->getId());
376
	}
377
378
	public function testGetIdWithoutModUniqueStable() {
379
		$request = new Request(
380
			[],
381
			\OC::$server->getSecureRandom(),
382
			$this->config,
383
			$this->stream
384
		);
385
		$firstId = $request->getId();
386
		$secondId = $request->getId();
387
		$this->assertSame($firstId, $secondId);
388
	}
389
390
	public function testGetRemoteAddressWithoutTrustedRemote() {
391
		$this->config
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<OCP\IConfig>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
392
			->expects($this->once())
393
			->method('getSystemValue')
394
			->with('trusted_proxies')
395
			->will($this->returnValue([]));
396
397
		$request = new Request(
398
			[
399
				'server' => [
400
					'REMOTE_ADDR' => '10.0.0.2',
401
					'HTTP_X_FORWARDED' => '10.4.0.5, 10.4.0.4',
402
					'HTTP_X_FORWARDED_FOR' => '192.168.0.233'
403
				],
404
			],
405
			$this->secureRandom,
406
			$this->config,
407
			$this->stream
408
		);
409
410
		$this->assertSame('10.0.0.2', $request->getRemoteAddress());
411
	}
412
413
	public function testGetRemoteAddressWithNoTrustedHeader() {
414
		$this->config
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<OCP\IConfig>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
415
			->expects($this->at(0))
416
			->method('getSystemValue')
417
			->with('trusted_proxies')
418
			->will($this->returnValue(['10.0.0.2']));
419
		$this->config
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<OCP\IConfig>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
420
			->expects($this->at(1))
421
			->method('getSystemValue')
422
			->with('forwarded_for_headers')
423
			->will($this->returnValue([]));
424
425
		$request = new Request(
426
			[
427
				'server' => [
428
					'REMOTE_ADDR' => '10.0.0.2',
429
					'HTTP_X_FORWARDED' => '10.4.0.5, 10.4.0.4',
430
					'HTTP_X_FORWARDED_FOR' => '192.168.0.233'
431
				],
432
			],
433
			$this->secureRandom,
434
			$this->config,
435
			$this->stream
436
		);
437
438
		$this->assertSame('10.0.0.2', $request->getRemoteAddress());
439
	}
440
441 View Code Duplication
	public function testGetRemoteAddressWithSingleTrustedRemote() {
442
		$this->config
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<OCP\IConfig>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
443
			->expects($this->at(0))
444
			->method('getSystemValue')
445
			->with('trusted_proxies')
446
			->will($this->returnValue(['10.0.0.2']));
447
		$this->config
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<OCP\IConfig>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
448
			->expects($this->at(1))
449
			->method('getSystemValue')
450
			->with('forwarded_for_headers')
451
			->will($this->returnValue(['HTTP_X_FORWARDED']));
452
453
		$request = new Request(
454
			[
455
				'server' => [
456
					'REMOTE_ADDR' => '10.0.0.2',
457
					'HTTP_X_FORWARDED' => '10.4.0.5, 10.4.0.4',
458
					'HTTP_X_FORWARDED_FOR' => '192.168.0.233'
459
				],
460
			],
461
			$this->secureRandom,
462
			$this->config,
463
			$this->stream
464
		);
465
466
		$this->assertSame('10.4.0.5', $request->getRemoteAddress());
467
	}
468
469 View Code Duplication
	public function testGetRemoteAddressVerifyPriorityHeader() {
470
		$this->config
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<OCP\IConfig>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
471
			->expects($this->at(0))
472
			->method('getSystemValue')
473
			->with('trusted_proxies')
474
			->will($this->returnValue(['10.0.0.2']));
475
		$this->config
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<OCP\IConfig>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
476
			->expects($this->at(1))
477
			->method('getSystemValue')
478
			->with('forwarded_for_headers')
479
			->will($this->returnValue([
480
				'HTTP_CLIENT_IP',
481
				'HTTP_X_FORWARDED_FOR',
482
				'HTTP_X_FORWARDED'
483
			]));
484
485
		$request = new Request(
486
			[
487
				'server' => [
488
					'REMOTE_ADDR' => '10.0.0.2',
489
					'HTTP_X_FORWARDED' => '10.4.0.5, 10.4.0.4',
490
					'HTTP_X_FORWARDED_FOR' => '192.168.0.233'
491
				],
492
			],
493
			$this->secureRandom,
494
			$this->config,
495
			$this->stream
496
		);
497
498
		$this->assertSame('192.168.0.233', $request->getRemoteAddress());
499
	}
500
501
	/**
502
	 * @return array
503
	 */
504
	public function httpProtocolProvider() {
505
		return [
506
			// Valid HTTP 1.0
507
			['HTTP/1.0', 'HTTP/1.0'],
508
			['http/1.0', 'HTTP/1.0'],
509
			['HTTp/1.0', 'HTTP/1.0'],
510
511
			// Valid HTTP 1.1
512
			['HTTP/1.1', 'HTTP/1.1'],
513
			['http/1.1', 'HTTP/1.1'],
514
			['HTTp/1.1', 'HTTP/1.1'],
515
516
			// Valid HTTP 2.0
517
			['HTTP/2', 'HTTP/2'],
518
			['http/2', 'HTTP/2'],
519
			['HTTp/2', 'HTTP/2'],
520
521
			// Invalid
522
			['HTTp/394', 'HTTP/1.1'],
523
			['InvalidProvider/1.1', 'HTTP/1.1'],
524
			[null, 'HTTP/1.1'],
525
			['', 'HTTP/1.1'],
526
527
		];
528
	}
529
530
	/**
531
	 * @dataProvider httpProtocolProvider
532
	 *
533
	 * @param mixed $input
534
	 * @param string $expected
535
	 */
536
	public function testGetHttpProtocol($input, $expected) {
537
		$request = new Request(
538
			[
539
				'server' => [
540
					'SERVER_PROTOCOL' => $input,
541
				],
542
			],
543
			$this->secureRandom,
544
			$this->config,
545
			$this->stream
546
		);
547
548
		$this->assertSame($expected, $request->getHttpProtocol());
549
	}
550
551 View Code Duplication
	public function testGetServerProtocolWithOverride() {
552
		$this->config
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<OCP\IConfig>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
553
			->expects($this->at(0))
554
			->method('getSystemValue')
555
			->with('overwriteprotocol')
556
			->will($this->returnValue('customProtocol'));
557
		$this->config
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<OCP\IConfig>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
558
			->expects($this->at(1))
559
			->method('getSystemValue')
560
			->with('overwritecondaddr')
561
			->will($this->returnValue(''));
562
		$this->config
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<OCP\IConfig>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
563
			->expects($this->at(2))
564
			->method('getSystemValue')
565
			->with('overwriteprotocol')
566
			->will($this->returnValue('customProtocol'));
567
568
		$request = new Request(
569
			[],
570
			$this->secureRandom,
571
			$this->config,
572
			$this->stream
573
		);
574
575
		$this->assertSame('customProtocol', $request->getServerProtocol());
576
	}
577
578
	public function testGetServerProtocolWithProtoValid() {
579
		$this->config
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<OCP\IConfig>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
580
			->expects($this->exactly(2))
581
			->method('getSystemValue')
582
			->with('overwriteprotocol')
583
			->will($this->returnValue(''));
584
585
		$requestHttps = new Request(
586
			[
587
				'server' => [
588
					'HTTP_X_FORWARDED_PROTO' => 'HtTpS'
589
				],
590
			],
591
			$this->secureRandom,
592
			$this->config,
593
			$this->stream
594
		);
595
		$requestHttp = new Request(
596
			[
597
				'server' => [
598
					'HTTP_X_FORWARDED_PROTO' => 'HTTp'
599
				],
600
			],
601
			$this->secureRandom,
602
			$this->config,
603
			$this->stream
604
		);
605
606
607
		$this->assertSame('https', $requestHttps->getServerProtocol());
608
		$this->assertSame('http', $requestHttp->getServerProtocol());
609
	}
610
611 View Code Duplication
	public function testGetServerProtocolWithHttpsServerValueOn() {
612
		$this->config
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<OCP\IConfig>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
613
			->expects($this->once())
614
			->method('getSystemValue')
615
			->with('overwriteprotocol')
616
			->will($this->returnValue(''));
617
618
		$request = new Request(
619
			[
620
				'server' => [
621
					'HTTPS' => 'on'
622
				],
623
			],
624
			$this->secureRandom,
625
			$this->config,
626
			$this->stream
627
		);
628
		$this->assertSame('https', $request->getServerProtocol());
629
	}
630
631 View Code Duplication
	public function testGetServerProtocolWithHttpsServerValueOff() {
632
		$this->config
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<OCP\IConfig>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
633
			->expects($this->once())
634
			->method('getSystemValue')
635
			->with('overwriteprotocol')
636
			->will($this->returnValue(''));
637
638
		$request = new Request(
639
			[
640
				'server' => [
641
					'HTTPS' => 'off'
642
				],
643
			],
644
			$this->secureRandom,
645
			$this->config,
646
			$this->stream
647
		);
648
		$this->assertSame('http', $request->getServerProtocol());
649
	}
650
651 View Code Duplication
	public function testGetServerProtocolDefault() {
652
		$this->config
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<OCP\IConfig>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
653
			->expects($this->once())
654
			->method('getSystemValue')
655
			->with('overwriteprotocol')
656
			->will($this->returnValue(''));
657
658
		$request = new Request(
659
			[],
660
			$this->secureRandom,
661
			$this->config,
662
			$this->stream
663
		);
664
		$this->assertSame('http', $request->getServerProtocol());
665
	}
666
667 View Code Duplication
	public function testGetServerProtocolBehindLoadBalancers() {
668
		$this->config
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<OCP\IConfig>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
669
			->expects($this->once())
670
			->method('getSystemValue')
671
			->with('overwriteprotocol')
672
			->will($this->returnValue(''));
673
674
		$request = new Request(
675
			[
676
				'server' => [
677
					'HTTP_X_FORWARDED_PROTO' => 'https,http,http'
678
				],
679
			],
680
			$this->secureRandom,
681
			$this->config,
682
			$this->stream
683
		);
684
685
		$this->assertSame('https', $request->getServerProtocol());
686
	}
687
688
	/**
689
	 * @dataProvider userAgentProvider
690
	 * @param string $testAgent
691
	 * @param array $userAgent
692
	 * @param bool $matches
693
	 */
694
	public function testUserAgent($testAgent, $userAgent, $matches) {
695
		$request = new Request(
696
				[
697
						'server' => [
698
								'HTTP_USER_AGENT' => $testAgent,
699
						]
700
				],
701
				$this->secureRandom,
702
				$this->config,
703
				$this->stream
704
		);
705
706
		$this->assertSame($matches, $request->isUserAgent($userAgent));
707
	}
708
709
	/**
710
	 * @dataProvider userAgentProvider
711
	 * @param string $testAgent
712
	 * @param array $userAgent
713
	 * @param bool $matches
714
	 */
715
	public function testUndefinedUserAgent($testAgent, $userAgent, $matches) {
716
		$request = new Request(
717
				[],
718
				$this->secureRandom,
719
				$this->config,
720
				$this->stream
721
		);
722
723
		$this->assertFalse($request->isUserAgent($userAgent));
724
	}
725
726
	/**
727
	 * @return array
728
	 */
729
	function userAgentProvider() {
1 ignored issue
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
730
		return [
731
			[
732
				'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
733
				[
734
					Request::USER_AGENT_IE
735
				],
736
				true,
737
			],
738
			[
739
				'Mozilla/5.0 (X11; Linux i686; rv:24.0) Gecko/20100101 Firefox/24.0',
740
				[
741
					Request::USER_AGENT_IE
742
				],
743
				false,
744
			],
745
			[
746
				'Mozilla/5.0 (Linux; Android 4.4; Nexus 4 Build/KRT16S) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.59 Mobile Safari/537.36',
747
				[
748
					Request::USER_AGENT_ANDROID_MOBILE_CHROME
749
				],
750
				true,
751
			],
752
			[
753
				'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
754
				[
755
					Request::USER_AGENT_ANDROID_MOBILE_CHROME
756
				],
757
				false,
758
			],
759
			[
760
				'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
761
				[
762
					Request::USER_AGENT_IE,
763
					Request::USER_AGENT_ANDROID_MOBILE_CHROME,
764
				],
765
				true,
766
			],
767
			[
768
				'Mozilla/5.0 (Linux; Android 4.4; Nexus 4 Build/KRT16S) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.59 Mobile Safari/537.36',
769
				[
770
					Request::USER_AGENT_IE,
771
					Request::USER_AGENT_ANDROID_MOBILE_CHROME,
772
				],
773
				true,
774
			],
775
			[
776
				'Mozilla/5.0 (X11; Linux i686; rv:24.0) Gecko/20100101 Firefox/24.0',
777
				[
778
					Request::USER_AGENT_FREEBOX
779
				],
780
				false,
781
			],
782
			[
783
				'Mozilla/5.0',
784
				[
785
					Request::USER_AGENT_FREEBOX
786
				],
787
				true,
788
			],
789
			[
790
				'Fake Mozilla/5.0',
791
				[
792
					Request::USER_AGENT_FREEBOX
793
				],
794
				false,
795
			],
796
		];
797
	}
798
799 View Code Duplication
	public function testInsecureServerHostServerNameHeader() {
800
		$request = new Request(
801
			[
802
				'server' => [
803
					'SERVER_NAME' => 'from.server.name:8080',
804
				]
805
			],
806
			$this->secureRandom,
807
			$this->config,
808
			$this->stream
809
		);
810
811
		$this->assertSame('from.server.name:8080',  $request->getInsecureServerHost());
812
	}
813
814 View Code Duplication
	public function testInsecureServerHostHttpHostHeader() {
815
		$request = new Request(
816
			[
817
				'server' => [
818
					'SERVER_NAME' => 'from.server.name:8080',
819
					'HTTP_HOST' => 'from.host.header:8080',
820
				]
821
			],
822
			$this->secureRandom,
823
			$this->config,
824
			$this->stream
825
		);
826
827
		$this->assertSame('from.host.header:8080',  $request->getInsecureServerHost());
828
	}
829
830 View Code Duplication
	public function testInsecureServerHostHttpFromForwardedHeaderSingle() {
831
		$request = new Request(
832
			[
833
				'server' => [
834
					'SERVER_NAME' => 'from.server.name:8080',
835
					'HTTP_HOST' => 'from.host.header:8080',
836
					'HTTP_X_FORWARDED_HOST' => 'from.forwarded.host:8080',
837
				]
838
			],
839
			$this->secureRandom,
840
			$this->config,
841
			$this->stream
842
		);
843
844
		$this->assertSame('from.forwarded.host:8080',  $request->getInsecureServerHost());
845
	}
846
847 View Code Duplication
	public function testInsecureServerHostHttpFromForwardedHeaderStacked() {
848
		$request = new Request(
849
			[
850
				'server' => [
851
					'SERVER_NAME' => 'from.server.name:8080',
852
					'HTTP_HOST' => 'from.host.header:8080',
853
					'HTTP_X_FORWARDED_HOST' => 'from.forwarded.host2:8080,another.one:9000',
854
				]
855
			],
856
			$this->secureRandom,
857
			$this->config,
858
			$this->stream
859
		);
860
861
		$this->assertSame('from.forwarded.host2:8080',  $request->getInsecureServerHost());
862
	}
863
864 View Code Duplication
	public function testGetServerHostWithOverwriteHost() {
865
		$this->config
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<OCP\IConfig>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
866
			->expects($this->at(0))
867
			->method('getSystemValue')
868
			->with('overwritehost')
869
			->will($this->returnValue('my.overwritten.host'));
870
		$this->config
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<OCP\IConfig>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
871
			->expects($this->at(1))
872
			->method('getSystemValue')
873
			->with('overwritecondaddr')
874
			->will($this->returnValue(''));
875
		$this->config
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<OCP\IConfig>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
876
			->expects($this->at(2))
877
			->method('getSystemValue')
878
			->with('overwritehost')
879
			->will($this->returnValue('my.overwritten.host'));
880
881
		$request = new Request(
882
			[],
883
			$this->secureRandom,
884
			$this->config,
885
			$this->stream
886
		);
887
888
		$this->assertSame('my.overwritten.host',  $request->getServerHost());
889
	}
890
891 View Code Duplication
	public function testGetServerHostWithTrustedDomain() {
892
		$this->config
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<OCP\IConfig>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
893
			->expects($this->at(3))
894
			->method('getSystemValue')
895
			->with('trusted_domains')
896
			->will($this->returnValue(['my.trusted.host']));
897
898
		$request = new Request(
899
			[
900
				'server' => [
901
					'HTTP_X_FORWARDED_HOST' => 'my.trusted.host',
902
				],
903
			],
904
			$this->secureRandom,
905
			$this->config,
906
			$this->stream
907
		);
908
909
		$this->assertSame('my.trusted.host',  $request->getServerHost());
910
	}
911
912 View Code Duplication
	public function testGetServerHostWithUntrustedDomain() {
913
		$this->config
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<OCP\IConfig>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
914
			->expects($this->at(3))
915
			->method('getSystemValue')
916
			->with('trusted_domains')
917
			->will($this->returnValue(['my.trusted.host']));
918
		$this->config
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<OCP\IConfig>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
919
			->expects($this->at(4))
920
			->method('getSystemValue')
921
			->with('trusted_domains')
922
			->will($this->returnValue(['my.trusted.host']));
923
924
		$request = new Request(
925
			[
926
				'server' => [
927
					'HTTP_X_FORWARDED_HOST' => 'my.untrusted.host',
928
				],
929
			],
930
			$this->secureRandom,
931
			$this->config,
932
			$this->stream
933
		);
934
935
		$this->assertSame('my.trusted.host',  $request->getServerHost());
936
	}
937
938 View Code Duplication
	public function testGetServerHostWithNoTrustedDomain() {
939
		$this->config
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<OCP\IConfig>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
940
			->expects($this->at(3))
941
			->method('getSystemValue')
942
			->with('trusted_domains')
943
			->will($this->returnValue([]));
944
		$this->config
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<OCP\IConfig>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
945
			->expects($this->at(4))
946
			->method('getSystemValue')
947
			->with('trusted_domains')
948
			->will($this->returnValue([]));
949
950
		$request = new Request(
951
			[
952
				'server' => [
953
					'HTTP_X_FORWARDED_HOST' => 'my.untrusted.host',
954
				],
955
			],
956
			$this->secureRandom,
957
			$this->config,
958
			$this->stream
959
		);
960
961
		$this->assertSame('',  $request->getServerHost());
962
	}
963
964 View Code Duplication
	public function testGetOverwriteHostDefaultNull() {
965
		$this->config
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<OCP\IConfig>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
966
			->expects($this->once())
967
			->method('getSystemValue')
968
			->with('overwritehost')
969
			->will($this->returnValue(''));
970
		$request = new Request(
971
			[],
972
			$this->secureRandom,
973
			$this->config,
974
			$this->stream
975
		);
976
977
		$this->assertNull(self::invokePrivate($request, 'getOverwriteHost'));
978
	}
979
980 View Code Duplication
	public function testGetOverwriteHostWithOverwrite() {
981
		$this->config
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<OCP\IConfig>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
982
			->expects($this->at(0))
983
			->method('getSystemValue')
984
			->with('overwritehost')
985
			->will($this->returnValue('www.owncloud.org'));
986
		$this->config
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<OCP\IConfig>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
987
			->expects($this->at(1))
988
			->method('getSystemValue')
989
			->with('overwritecondaddr')
990
			->will($this->returnValue(''));
991
		$this->config
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<OCP\IConfig>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
992
			->expects($this->at(2))
993
			->method('getSystemValue')
994
			->with('overwritehost')
995
			->will($this->returnValue('www.owncloud.org'));
996
997
		$request = new Request(
998
			[],
999
			$this->secureRandom,
1000
			$this->config,
1001
			$this->stream
1002
		);
1003
1004
		$this->assertSame('www.owncloud.org', self::invokePrivate($request, 'getOverwriteHost'));
1005
	}
1006
1007 View Code Duplication
	public function testGetPathInfoWithSetEnv() {
1008
		$request = new Request(
1009
			[
1010
				'server' => [
1011
					'PATH_INFO' => 'apps/files/',
1012
				]
1013
			],
1014
			$this->secureRandom,
1015
			$this->config,
1016
			$this->stream
1017
		);
1018
1019
		$this->assertSame('apps/files/',  $request->getPathInfo());
1020
	}
1021
1022
	/**
1023
	 * @expectedException \Exception
1024
	 * @expectedExceptionMessage The requested uri(/foo.php) cannot be processed by the script '/var/www/index.php')
1025
	 */
1026 View Code Duplication
	public function testGetPathInfoNotProcessible() {
1027
		$request = new Request(
1028
			[
1029
				'server' => [
1030
					'REQUEST_URI' => '/foo.php',
1031
					'SCRIPT_NAME' => '/var/www/index.php',
1032
				]
1033
			],
1034
			$this->secureRandom,
1035
			$this->config,
1036
			$this->stream
1037
		);
1038
1039
		$request->getPathInfo();
1040
	}
1041
1042
	/**
1043
	 * @expectedException \Exception
1044
	 * @expectedExceptionMessage The requested uri(/foo.php) cannot be processed by the script '/var/www/index.php')
1045
	 */
1046 View Code Duplication
	public function testGetRawPathInfoNotProcessible() {
1047
		$request = new Request(
1048
			[
1049
				'server' => [
1050
					'REQUEST_URI' => '/foo.php',
1051
					'SCRIPT_NAME' => '/var/www/index.php',
1052
				]
1053
			],
1054
			$this->secureRandom,
1055
			$this->config,
1056
			$this->stream
1057
		);
1058
1059
		$request->getRawPathInfo();
1060
	}
1061
1062
	/**
1063
	 * @dataProvider genericPathInfoProvider
1064
	 * @param string $requestUri
1065
	 * @param string $scriptName
1066
	 * @param string $expected
1067
	 */
1068
	public function testGetPathInfoWithoutSetEnvGeneric($requestUri, $scriptName, $expected) {
1069
		$request = new Request(
1070
			[
1071
				'server' => [
1072
					'REQUEST_URI' => $requestUri,
1073
					'SCRIPT_NAME' => $scriptName,
1074
				]
1075
			],
1076
			$this->secureRandom,
1077
			$this->config,
1078
			$this->stream
1079
		);
1080
1081
		$this->assertSame($expected, $request->getPathInfo());
1082
	}
1083
1084
	/**
1085
	 * @dataProvider genericPathInfoProvider
1086
	 * @param string $requestUri
1087
	 * @param string $scriptName
1088
	 * @param string $expected
1089
	 */
1090
	public function testGetRawPathInfoWithoutSetEnvGeneric($requestUri, $scriptName, $expected) {
1091
		$request = new Request(
1092
			[
1093
				'server' => [
1094
					'REQUEST_URI' => $requestUri,
1095
					'SCRIPT_NAME' => $scriptName,
1096
				]
1097
			],
1098
			$this->secureRandom,
1099
			$this->config,
1100
			$this->stream
1101
		);
1102
1103
		$this->assertSame($expected, $request->getRawPathInfo());
1104
	}
1105
1106
	/**
1107
	 * @dataProvider rawPathInfoProvider
1108
	 * @param string $requestUri
1109
	 * @param string $scriptName
1110
	 * @param string $expected
1111
	 */
1112
	public function testGetRawPathInfoWithoutSetEnv($requestUri, $scriptName, $expected) {
1113
		$request = new Request(
1114
			[
1115
				'server' => [
1116
					'REQUEST_URI' => $requestUri,
1117
					'SCRIPT_NAME' => $scriptName,
1118
				]
1119
			],
1120
			$this->secureRandom,
1121
			$this->config,
1122
			$this->stream
1123
		);
1124
1125
		$this->assertSame($expected, $request->getRawPathInfo());
1126
	}
1127
1128
	/**
1129
	 * @dataProvider pathInfoProvider
1130
	 * @param string $requestUri
1131
	 * @param string $scriptName
1132
	 * @param string $expected
1133
	 */
1134
	public function testGetPathInfoWithoutSetEnv($requestUri, $scriptName, $expected) {
1135
		$request = new Request(
1136
			[
1137
				'server' => [
1138
					'REQUEST_URI' => $requestUri,
1139
					'SCRIPT_NAME' => $scriptName,
1140
				]
1141
			],
1142
			$this->secureRandom,
1143
			$this->config,
1144
			$this->stream
1145
		);
1146
1147
		$this->assertSame($expected, $request->getPathInfo());
1148
	}
1149
1150
	/**
1151
	 * @return array
1152
	 */
1153
	public function genericPathInfoProvider() {
1154
		return [
1155
			['/core/index.php?XDEBUG_SESSION_START=14600', '/core/index.php', ''],
1156
			['/index.php/apps/files/', 'index.php', '/apps/files/'],
1157
			['/index.php/apps/files/../&amp;/&?someQueryParameter=QueryParam', 'index.php', '/apps/files/../&amp;/&'],
1158
			['/remote.php/漢字編碼方法 / 汉字编码方法', 'remote.php', '/漢字編碼方法 / 汉字编码方法'],
1159
			['///removeTrailin//gSlashes///', 'remote.php', '/removeTrailin/gSlashes/'],
1160
			['/', '/', ''],
1161
			['', '', ''],
1162
		];
1163
	}
1164
1165
	/**
1166
	 * @return array
1167
	 */
1168
	public function rawPathInfoProvider() {
1169
		return [
1170
			['/foo%2Fbar/subfolder', '', 'foo%2Fbar/subfolder'],
1171
		];
1172
	}
1173
1174
	/**
1175
	 * @return array
1176
	 */
1177
	public function pathInfoProvider() {
1178
		return [
1179
			['/foo%2Fbar/subfolder', '', 'foo/bar/subfolder'],
1180
		];
1181
	}
1182
1183 View Code Duplication
	public function testGetRequestUriWithoutOverwrite() {
1184
		$this->config
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<OCP\IConfig>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
1185
			->expects($this->once())
1186
			->method('getSystemValue')
1187
			->with('overwritewebroot')
1188
			->will($this->returnValue(''));
1189
1190
		$request = new Request(
1191
			[
1192
				'server' => [
1193
					'REQUEST_URI' => '/test.php'
1194
				]
1195
			],
1196
			$this->secureRandom,
1197
			$this->config,
1198
			$this->stream
1199
		);
1200
1201
		$this->assertSame('/test.php', $request->getRequestUri());
1202
	}
1203
1204
	public function providesGetRequestUriWithOverwriteData() {
1205
		return [
1206
			['/scriptname.php/some/PathInfo', '/owncloud/', ''],
1207
			['/scriptname.php/some/PathInfo', '/owncloud/', '123'],
1208
		];
1209
	}
1210
1211
	/**
1212
	 * @dataProvider providesGetRequestUriWithOverwriteData
1213
	 */
1214
	public function testGetRequestUriWithOverwrite($expectedUri, $overwriteWebRoot, $overwriteCondAddr) {
1215
		$this->config
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<OCP\IConfig>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
1216
			->expects($this->at(0))
1217
			->method('getSystemValue')
1218
			->with('overwritewebroot')
1219
			->will($this->returnValue($overwriteWebRoot));
1220
		$this->config
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<OCP\IConfig>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
1221
			->expects($this->at(1))
1222
			->method('getSystemValue')
1223
			->with('overwritecondaddr')
1224
			->will($this->returnValue($overwriteCondAddr));
1225
1226
		$request = $this->getMockBuilder('\OC\AppFramework\Http\Request')
1227
			->setMethods(['getScriptName'])
1228
			->setConstructorArgs([
1229
				[
1230
					'server' => [
1231
						'REQUEST_URI' => '/test.php/some/PathInfo',
1232
						'SCRIPT_NAME' => '/test.php',
1233
					]
1234
				],
1235
				$this->secureRandom,
1236
				$this->config,
1237
				$this->stream
1238
			])
1239
			->getMock();
1240
		$request
1241
			->expects($this->once())
1242
			->method('getScriptName')
1243
			->will($this->returnValue('/scriptname.php'));
1244
1245
		$this->assertSame($expectedUri, $request->getRequestUri());
1246
	}
1247
1248 View Code Duplication
	public function testPassesCSRFCheckWithGet() {
1249
		/** @var Request $request */
1250
		$request = $this->getMockBuilder('\OC\AppFramework\Http\Request')
1251
			->setMethods(['getScriptName'])
1252
			->setConstructorArgs([
1253
				[
1254
					'get' => [
1255
						'requesttoken' => 'AAAHGxsTCTc3BgMQESAcNR0OAR0=:MyTotalSecretShareds',
1256
					],
1257
					'requesttoken' => 'MyStoredRequestToken',
1258
				],
1259
				$this->secureRandom,
1260
				$this->config,
1261
				$this->stream
1262
			])
1263
			->getMock();
1264
1265
		$this->assertTrue($request->passesCSRFCheck());
1266
	}
1267
1268 View Code Duplication
	public function testPassesCSRFCheckWithPost() {
1269
		/** @var Request $request */
1270
		$request = $this->getMockBuilder('\OC\AppFramework\Http\Request')
1271
			->setMethods(['getScriptName'])
1272
			->setConstructorArgs([
1273
				[
1274
					'post' => [
1275
						'requesttoken' => 'AAAHGxsTCTc3BgMQESAcNR0OAR0=:MyTotalSecretShareds',
1276
					],
1277
					'requesttoken' => 'MyStoredRequestToken',
1278
				],
1279
				$this->secureRandom,
1280
				$this->config,
1281
				$this->stream
1282
			])
1283
			->getMock();
1284
1285
		$this->assertTrue($request->passesCSRFCheck());
1286
	}
1287
1288 View Code Duplication
	public function testPassesCSRFCheckWithHeader() {
1289
		/** @var Request $request */
1290
		$request = $this->getMockBuilder('\OC\AppFramework\Http\Request')
1291
			->setMethods(['getScriptName'])
1292
			->setConstructorArgs([
1293
				[
1294
					'server' => [
1295
						'HTTP_REQUESTTOKEN' => 'AAAHGxsTCTc3BgMQESAcNR0OAR0=:MyTotalSecretShareds',
1296
					],
1297
					'requesttoken' => 'MyStoredRequestToken',
1298
				],
1299
				$this->secureRandom,
1300
				$this->config,
1301
				$this->stream
1302
			])
1303
			->getMock();
1304
1305
		$this->assertTrue($request->passesCSRFCheck());
1306
	}
1307
1308
	/**
1309
	 * @return array
1310
	 */
1311
	public function invalidTokenDataProvider() {
1312
		return [
1313
			['InvalidSentToken'],
1314
			['InvalidSentToken:InvalidSecret'],
1315
			[null],
1316
			[''],
1317
		];
1318
	}
1319
1320
	/**
1321
	 * @dataProvider invalidTokenDataProvider
1322
	 * @param string $invalidToken
1323
	 */
1324 View Code Duplication
	public function testPassesCSRFCheckWithInvalidToken($invalidToken) {
1325
		/** @var Request $request */
1326
		$request = $this->getMockBuilder('\OC\AppFramework\Http\Request')
1327
			->setMethods(['getScriptName'])
1328
			->setConstructorArgs([
1329
				[
1330
					'server' => [
1331
						'HTTP_REQUESTTOKEN' => $invalidToken,
1332
					],
1333
					'requesttoken' => 'MyStoredRequestToken',
1334
				],
1335
				$this->secureRandom,
1336
				$this->config,
1337
				$this->stream
1338
			])
1339
			->getMock();
1340
1341
		$this->assertFalse($request->passesCSRFCheck());
1342
	}
1343
1344
	public function testPassesCSRFCheckWithoutTokenFail() {
1345
		/** @var Request $request */
1346
		$request = $this->getMockBuilder('\OC\AppFramework\Http\Request')
1347
			->setMethods(['getScriptName'])
1348
			->setConstructorArgs([
1349
				[],
1350
				$this->secureRandom,
1351
				$this->config,
1352
				$this->stream
1353
			])
1354
			->getMock();
1355
1356
		$this->assertFalse($request->passesCSRFCheck());
1357
	}
1358
1359
}
1360