diff --git a/lib/base.php b/lib/base.php
index db758958577dfe48344c84235f3895b5590179c9..51d59d130aa71bda2632dcad7e0db5e5c4fda3dd 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -100,7 +100,11 @@ class OC {
 		OC_Config::$object = new \OC\Config(self::$configDir);
 
 		OC::$SUBURI = str_replace("\\", "/", substr(realpath($_SERVER["SCRIPT_FILENAME"]), strlen(OC::$SERVERROOT)));
-		$scriptName = OC_Request::scriptName();
+		/**
+		 * FIXME: The following line is required because of a cyclic dependency
+		 *        on IRequest.
+		 */
+		$scriptName = $_SERVER['SCRIPT_NAME'];
 		if (substr($scriptName, -1) == '/') {
 			$scriptName .= 'index.php';
 			//make sure suburi follows the same rules as scriptName
@@ -230,6 +234,8 @@ class OC {
 	}
 
 	public static function checkSSL() {
+		$request = \OC::$server->getRequest();
+
 		// redirect to https site if configured
 		if (\OC::$server->getSystemConfig()->getValue('forcessl', false)) {
 			// Default HSTS policy
@@ -241,14 +247,15 @@ class OC {
 			}
 			header($header);
 			ini_set('session.cookie_secure', 'on');
-			if (OC_Request::serverProtocol() <> 'https' and !OC::$CLI) {
-				$url = 'https://' . OC_Request::serverHost() . OC_Request::requestUri();
+
+			if ($request->getServerProtocol() <> 'https' && !OC::$CLI) {
+				$url = 'https://' . $request->getServerHost() . $request->getRequestUri();
 				header("Location: $url");
 				exit();
 			}
 		} else {
 			// Invalidate HSTS headers
-			if (OC_Request::serverProtocol() === 'https') {
+			if ($request->getServerProtocol() === 'https') {
 				header('Strict-Transport-Security: max-age=0');
 			}
 		}
@@ -612,18 +619,24 @@ class OC {
 			return;
 		}
 
-		$host = OC_Request::insecureServerHost();
-		// if the host passed in headers isn't trusted
+		$trustedDomainHelper = new \OC\Security\TrustedDomainHelper(\OC::$server->getConfig());
+		$request = \OC::$server->getRequest();
+		$host = $request->getInsecureServerHost();
+		/**
+		 * if the host passed in headers isn't trusted
+		 * FIXME: Should not be in here at all :see_no_evil:
+		 */
 		if (!OC::$CLI
-			// overwritehost is always trusted
-			&& OC_Request::getOverwriteHost() === null
-			&& !OC_Request::isTrustedDomain($host)
+			// overwritehost is always trusted, workaround to not have to make
+			// \OC\AppFramework\Http\Request::getOverwriteHost public
+			&& self::$server->getConfig()->getSystemValue('overwritehost') === ''
+			&& !$trustedDomainHelper->isTrustedDomain($host)
 		) {
 			header('HTTP/1.1 400 Bad Request');
 			header('Status: 400 Bad Request');
 
 			$tmpl = new OCP\Template('core', 'untrustedDomain', 'guest');
-			$tmpl->assign('domain', $_SERVER['SERVER_NAME']);
+			$tmpl->assign('domain', $request->server['SERVER_NAME']);
 			$tmpl->printPage();
 
 			exit();
@@ -720,6 +733,7 @@ class OC {
 	 * Handle the request
 	 */
 	public static function handleRequest() {
+
 		\OC::$server->getEventLogger()->start('handle_request', 'Handle request');
 		$systemConfig = \OC::$server->getSystemConfig();
 		// load all the classpaths from the enabled apps so they are available
@@ -734,7 +748,7 @@ class OC {
 			exit();
 		}
 
-		$request = OC_Request::getPathInfo();
+		$request = \OC::$server->getRequest()->getPathInfo();
 		if (substr($request, -3) !== '.js') { // we need these files during the upgrade
 			self::checkMaintenanceMode();
 			self::checkUpgrade();
@@ -764,7 +778,7 @@ class OC {
 				}
 				self::checkSingleUserMode();
 				OC_Util::setupFS();
-				OC::$server->getRouter()->match(OC_Request::getRawPathInfo());
+				OC::$server->getRouter()->match(\OC::$server->getRequest()->getRawPathInfo());
 				return;
 			} catch (Symfony\Component\Routing\Exception\ResourceNotFoundException $e) {
 				//header('HTTP/1.0 404 Not Found');
@@ -895,7 +909,7 @@ class OC {
 
 		// if return is true we are logged in -> redirect to the default page
 		if ($return === true) {
-			$_REQUEST['redirect_url'] = \OC_Request::requestUri();
+			$_REQUEST['redirect_url'] = \OC::$server->getRequest()->getRequestUri();
 			OC_Util::redirectToDefaultPage();
 			exit;
 		}
diff --git a/lib/private/app.php b/lib/private/app.php
index f41cb82c36bd7236b8122b2b1b481a65d111ec71..1af2c36e19f14a5e10fcf500f067df1872f10732 100644
--- a/lib/private/app.php
+++ b/lib/private/app.php
@@ -665,10 +665,11 @@ class OC_App {
 	 * @return string
 	 */
 	public static function getCurrentApp() {
-		$script = substr(OC_Request::scriptName(), strlen(OC::$WEBROOT) + 1);
+		$request = \OC::$server->getRequest();
+		$script = substr($request->getScriptName(), strlen(OC::$WEBROOT) + 1);
 		$topFolder = substr($script, 0, strpos($script, '/'));
 		if (empty($topFolder)) {
-			$path_info = OC_Request::getPathInfo();
+			$path_info = $request->getPathInfo();
 			if ($path_info) {
 				$topFolder = substr($path_info, 1, strpos($path_info, '/', 1) - 1);
 			}
diff --git a/lib/private/appframework/http/request.php b/lib/private/appframework/http/request.php
index 4902671d4b857c6985d3ea28587a446e9a15e93e..f11d189962da0fb917ba78b0ef2335f677432b31 100644
--- a/lib/private/appframework/http/request.php
+++ b/lib/private/appframework/http/request.php
@@ -24,6 +24,8 @@
 
 namespace OC\AppFramework\Http;
 
+use OC\Security\TrustedDomainHelper;
+use OCP\IConfig;
 use OCP\IRequest;
 use OCP\Security\ISecureRandom;
 
@@ -31,9 +33,14 @@ use OCP\Security\ISecureRandom;
  * Class for accessing variables in the request.
  * This class provides an immutable object with request variables.
  */
-
 class Request implements \ArrayAccess, \Countable, IRequest {
 
+	const USER_AGENT_IE = '/MSIE/';
+	// Android Chrome user agent: https://developers.google.com/chrome/mobile/docs/user-agent
+	const USER_AGENT_ANDROID_MOBILE_CHROME = '#Android.*Chrome/[.0-9]*#';
+	const USER_AGENT_FREEBOX = '#^Mozilla/5\.0$#';
+	const REGEX_LOCALHOST = '/^(127\.0\.0\.1|localhost)$/';
+
 	protected $inputStream;
 	protected $content;
 	protected $items = array();
@@ -51,6 +58,8 @@ class Request implements \ArrayAccess, \Countable, IRequest {
 	);
 	/** @var ISecureRandom */
 	protected $secureRandom;
+	/** @var IConfig */
+	protected $config;
 	/** @var string */
 	protected $requestId = '';
 
@@ -66,15 +75,18 @@ class Request implements \ArrayAccess, \Countable, IRequest {
 	 *        - string 'method' the request method (GET, POST etc)
 	 *        - string|false 'requesttoken' the requesttoken or false when not available
 	 * @param ISecureRandom $secureRandom
+	 * @param IConfig $config
 	 * @param string $stream
 	 * @see http://www.php.net/manual/en/reserved.variables.php
 	 */
 	public function __construct(array $vars=array(),
 								ISecureRandom $secureRandom,
+								IConfig $config,
 								$stream='php://input') {
 		$this->inputStream = $stream;
 		$this->items['params'] = array();
 		$this->secureRandom = $secureRandom;
+		$this->config = $config;
 
 		if(!array_key_exists('method', $vars)) {
 			$vars['method'] = 'GET';
@@ -115,7 +127,9 @@ class Request implements \ArrayAccess, \Countable, IRequest {
 		);
 
 	}
-
+	/**
+	 * @param $parameters
+	 */
 	public function setUrlParameters($parameters) {
 		$this->items['urlParams'] = $parameters;
 		$this->items['parameters'] = array_merge(
@@ -124,7 +138,10 @@ class Request implements \ArrayAccess, \Countable, IRequest {
 		);
 	}
 
-	// Countable method.
+	/**
+	 * Countable method
+	 * @return int
+	 */
 	public function count() {
 		return count(array_keys($this->items['parameters']));
 	}
@@ -176,7 +193,11 @@ class Request implements \ArrayAccess, \Countable, IRequest {
 		throw new \RuntimeException('You cannot change the contents of the request object');
 	}
 
-	// Magic property accessors
+	/**
+	 * Magic property accessors
+	 * @param $name
+	 * @param $value
+	 */
 	public function __set($name, $value) {
 		throw new \RuntimeException('You cannot change the contents of the request object');
 	}
@@ -231,12 +252,17 @@ class Request implements \ArrayAccess, \Countable, IRequest {
 		}
 	}
 
-
+	/**
+	 * @param $name
+	 * @return bool
+	 */
 	public function __isset($name) {
 		return isset($this->items['parameters'][$name]);
 	}
 
-
+	/**
+	 * @param $id
+	 */
 	public function __unset($id) {
 		throw new \RunTimeException('You cannot change the contents of the request object');
 	}
@@ -412,4 +438,254 @@ class Request implements \ArrayAccess, \Countable, IRequest {
 		return $this->requestId;
 	}
 
+	/**
+	 * Returns the remote address, if the connection came from a trusted proxy
+	 * and `forwarded_for_headers` has been configured then the IP address
+	 * specified in this header will be returned instead.
+	 * Do always use this instead of $_SERVER['REMOTE_ADDR']
+	 * @return string IP address
+	 */
+	public function getRemoteAddress() {
+		$remoteAddress = isset($this->server['REMOTE_ADDR']) ? $this->server['REMOTE_ADDR'] : '';
+		$trustedProxies = $this->config->getSystemValue('trusted_proxies', []);
+
+		if(is_array($trustedProxies) && in_array($remoteAddress, $trustedProxies)) {
+			$forwardedForHeaders = $this->config->getSystemValue('forwarded_for_headers', []);
+
+			foreach($forwardedForHeaders as $header) {
+				if(isset($this->server[$header])) {
+					foreach(explode(',', $this->server[$header]) as $IP) {
+						$IP = trim($IP);
+						if (filter_var($IP, FILTER_VALIDATE_IP) !== false) {
+							return $IP;
+						}
+					}
+				}
+			}
+		}
+
+		return $remoteAddress;
+	}
+
+	/**
+	 * Check overwrite condition
+	 * @param string $type
+	 * @return bool
+	 */
+	private function isOverwriteCondition($type = '') {
+		$regex = '/' . $this->config->getSystemValue('overwritecondaddr', '')  . '/';
+		return $regex === '//' || preg_match($regex, $this->server['REMOTE_ADDR']) === 1
+		|| ($type !== 'protocol' && $this->config->getSystemValue('forcessl', false));
+	}
+
+	/**
+	 * Returns the server protocol. It respects reverse proxy servers and load
+	 * balancers.
+	 * @return string Server protocol (http or https)
+	 */
+	public function getServerProtocol() {
+		if($this->config->getSystemValue('overwriteprotocol') !== ''
+			&& $this->isOverwriteCondition('protocol')) {
+			return $this->config->getSystemValue('overwriteprotocol');
+		}
+
+		if (isset($this->server['HTTP_X_FORWARDED_PROTO'])) {
+			$proto = strtolower($this->server['HTTP_X_FORWARDED_PROTO']);
+			// Verify that the protocol is always HTTP or HTTPS
+			// default to http if an invalid value is provided
+			return $proto === 'https' ? 'https' : 'http';
+		}
+
+		if (isset($this->server['HTTPS'])
+			&& $this->server['HTTPS'] !== null
+			&& $this->server['HTTPS'] !== 'off') {
+			return 'https';
+		}
+
+		return 'http';
+	}
+
+	/**
+	 * Returns the request uri, even if the website uses one or more
+	 * reverse proxies
+	 * @return string
+	 */
+	public function getRequestUri() {
+		$uri = isset($this->server['REQUEST_URI']) ? $this->server['REQUEST_URI'] : '';
+		if($this->config->getSystemValue('overwritewebroot') !== '' && $this->isOverwriteCondition()) {
+			$uri = $this->getScriptName() . substr($uri, strlen($this->server['SCRIPT_NAME']));
+		}
+		return $uri;
+	}
+
+	/**
+	 * Get raw PathInfo from request (not urldecoded)
+	 * @throws \Exception
+	 * @return string|false Path info or false when not found
+	 */
+	public function getRawPathInfo() {
+		$requestUri = isset($this->server['REQUEST_URI']) ? $this->server['REQUEST_URI'] : '';
+		// remove too many leading slashes - can be caused by reverse proxy configuration
+		if (strpos($requestUri, '/') === 0) {
+			$requestUri = '/' . ltrim($requestUri, '/');
+		}
+
+		$requestUri = preg_replace('%/{2,}%', '/', $requestUri);
+
+		// Remove the query string from REQUEST_URI
+		if ($pos = strpos($requestUri, '?')) {
+			$requestUri = substr($requestUri, 0, $pos);
+		}
+
+		$scriptName = $this->server['SCRIPT_NAME'];
+		$pathInfo = $requestUri;
+
+		// strip off the script name's dir and file name
+		// FIXME: Sabre does not really belong here
+		list($path, $name) = \Sabre\DAV\URLUtil::splitPath($scriptName);
+		if (!empty($path)) {
+			if($path === $pathInfo || strpos($pathInfo, $path.'/') === 0) {
+				$pathInfo = substr($pathInfo, strlen($path));
+			} else {
+				throw new \Exception("The requested uri($requestUri) cannot be processed by the script '$scriptName')");
+			}
+		}
+		if (strpos($pathInfo, '/'.$name) === 0) {
+			$pathInfo = substr($pathInfo, strlen($name) + 1);
+		}
+		if (strpos($pathInfo, $name) === 0) {
+			$pathInfo = substr($pathInfo, strlen($name));
+		}
+		if($pathInfo === '/'){
+			return '';
+		} else {
+			return $pathInfo;
+		}
+	}
+
+	/**
+	 * Get PathInfo from request
+	 * @throws \Exception
+	 * @return string|false Path info or false when not found
+	 */
+	public function getPathInfo() {
+		if(isset($this->server['PATH_INFO'])) {
+			return $this->server['PATH_INFO'];
+		}
+
+		$pathInfo = $this->getRawPathInfo();
+		// following is taken from \Sabre\DAV\URLUtil::decodePathSegment
+		$pathInfo = rawurldecode($pathInfo);
+		$encoding = mb_detect_encoding($pathInfo, ['UTF-8', 'ISO-8859-1']);
+
+		switch($encoding) {
+			case 'ISO-8859-1' :
+				$pathInfo = utf8_encode($pathInfo);
+		}
+		// end copy
+
+		return $pathInfo;
+	}
+
+	/**
+	 * Returns the script name, even if the website uses one or more
+	 * reverse proxies
+	 * @return string the script name
+	 */
+	public function getScriptName() {
+		$name = $this->server['SCRIPT_NAME'];
+		$overwriteWebRoot =  $this->config->getSystemValue('overwritewebroot');
+		if ($overwriteWebRoot !== '' && $this->isOverwriteCondition()) {
+			// FIXME: This code is untestable due to ___DIR__
+			$serverRoot = str_replace('\\', '/', substr(__DIR__, 0, -strlen('lib/private/')));
+			$suburi = str_replace('\\', '/', substr(realpath($this->server['SCRIPT_FILENAME']), strlen($serverRoot)));
+			$name = '/' . ltrim($overwriteWebRoot . $suburi, '/');
+		}
+		return $name;
+	}
+
+	/**
+	 * Checks whether the user agent matches a given regex
+	 * @param array $agent array of agent names
+	 * @return bool true if at least one of the given agent matches, false otherwise
+	 */
+	public function isUserAgent(array $agent) {
+		foreach ($agent as $regex) {
+			if (preg_match($regex, $this->server['HTTP_USER_AGENT'])) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Returns the unverified server host from the headers without checking
+	 * whether it is a trusted domain
+	 * @return string Server host
+	 */
+	public function getInsecureServerHost() {
+		$host = null;
+		if (isset($this->server['HTTP_X_FORWARDED_HOST'])) {
+			if (strpos($this->server['HTTP_X_FORWARDED_HOST'], ',') !== false) {
+				$parts = explode(',', $this->server['HTTP_X_FORWARDED_HOST']);
+				$host = trim(current($parts));
+			} else {
+				$host = $this->server['HTTP_X_FORWARDED_HOST'];
+			}
+		} else {
+			if (isset($this->server['HTTP_HOST'])) {
+				$host = $this->server['HTTP_HOST'];
+			} else if (isset($this->server['SERVER_NAME'])) {
+				$host = $this->server['SERVER_NAME'];
+			}
+		}
+		return $host;
+	}
+
+
+	/**
+	 * Returns the server host from the headers, or the first configured
+	 * trusted domain if the host isn't in the trusted list
+	 * @return string Server host
+	 */
+	public function getServerHost() {
+		// FIXME: Ugly workaround that we need to get rid of
+		if (\OC::$CLI && defined('PHPUNIT_RUN')) {
+			return 'localhost';
+		}
+
+		// overwritehost is always trusted
+		$host = $this->getOverwriteHost();
+		if ($host !== null) {
+			return $host;
+		}
+
+		// get the host from the headers
+		$host = $this->getInsecureServerHost();
+
+		// Verify that the host is a trusted domain if the trusted domains
+		// are defined
+		// If no trusted domain is provided the first trusted domain is returned
+		$trustedDomainHelper = new TrustedDomainHelper($this->config);
+		if ($trustedDomainHelper->isTrustedDomain($host)) {
+			return $host;
+		} else {
+			$trustedList = $this->config->getSystemValue('trusted_domains', []);
+			return $trustedList[0];
+		}
+	}
+
+	/**
+	 * Returns the overwritehost setting from the config if set and
+	 * if the overwrite condition is met
+	 * @return string|null overwritehost value or null if not defined or the defined condition
+	 * isn't met
+	 */
+	private function getOverwriteHost() {
+		if($this->config->getSystemValue('overwritehost') !== '' && $this->isOverwriteCondition()) {
+			return $this->config->getSystemValue('overwritehost');
+		}
+		return null;
+	}
+
 }
diff --git a/lib/private/connector/sabre/file.php b/lib/private/connector/sabre/file.php
index e57d04f9a6e8bc7fc4e1b0796a3ec635e7a6d2c9..bb672696f2bba70d4c0a625786bd47b1be790a69 100644
--- a/lib/private/connector/sabre/file.php
+++ b/lib/private/connector/sabre/file.php
@@ -149,9 +149,9 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements \Sabre\
 			}
 
 			// allow sync clients to send the mtime along in a header
-			$mtime = OC_Request::hasModificationTime();
-			if ($mtime !== false) {
-				if($this->fileView->touch($this->path, $mtime)) {
+			$request = \OC::$server->getRequest();
+			if (isset($request->server['HTTP_X_OC_MTIME'])) {
+				if($this->fileView->touch($this->path, $request->server['HTTP_X_OC_MTIME'])) {
 					header('X-OC-MTime: accepted');
 				}
 			}
@@ -165,8 +165,9 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements \Sabre\
 
 	/**
 	 * Returns the data
-	 *
 	 * @return string|resource
+	 * @throws \Sabre\DAV\Exception\Forbidden
+	 * @throws \Sabre\DAV\Exception\ServiceUnavailable
 	 */
 	public function get() {
 
@@ -187,9 +188,8 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements \Sabre\
 
 	/**
 	 * Delete the current file
-	 *
-	 * @return void
 	 * @throws \Sabre\DAV\Exception\Forbidden
+	 * @throws \Sabre\DAV\Exception\ServiceUnavailable
 	 */
 	public function delete() {
 		if (!$this->info->isDeletable()) {
@@ -251,6 +251,9 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements \Sabre\
 		return \OC_Helper::getSecureMimeType($mimeType);
 	}
 
+	/**
+	 * @return array|false
+	 */
 	public function getDirectDownload() {
 		if (\OCP\App::isEnabled('encryption')) {
 			return [];
@@ -267,6 +270,10 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements \Sabre\
 	/**
 	 * @param resource $data
 	 * @return null|string
+	 * @throws \Sabre\DAV\Exception
+	 * @throws \Sabre\DAV\Exception\BadRequest
+	 * @throws \Sabre\DAV\Exception\NotImplemented
+	 * @throws \Sabre\DAV\Exception\ServiceUnavailable
 	 */
 	private function createFileChunked($data)
 	{
@@ -319,9 +326,9 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements \Sabre\
 				}
 
 				// allow sync clients to send the mtime along in a header
-				$mtime = OC_Request::hasModificationTime();
-				if ($mtime !== false) {
-					if($this->fileView->touch($targetPath, $mtime)) {
+				$request = \OC::$server->getRequest();
+				if (isset($request->server['HTTP_X_OC_MTIME'])) {
+					if($this->fileView->touch($targetPath, $request->server['HTTP_X_OC_MTIME'])) {
 						header('X-OC-MTime: accepted');
 					}
 				}
@@ -340,9 +347,8 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements \Sabre\
 	 * Returns whether a part file is needed for the given storage
 	 * or whether the file can be assembled/uploaded directly on the
 	 * target storage.
-	 *
-	 * @param \OCP\Files\Storage $storage storage to check
-	 * @param bool true if the storage needs part file handling
+	 * @param \OCP\Files\Storage $storage
+	 * @return bool true if the storage needs part file handling
 	 */
 	private function needsPartFile($storage) {
 		// TODO: in the future use ChunkHandler provided by storage
diff --git a/lib/private/connector/sabre/request.php b/lib/private/connector/sabre/request.php
index c98b28c4d74d5e5614e63fd027af1fc12f3fa6b1..2ce753d916f19edcbd367ce8596eb3612ae82eaf 100644
--- a/lib/private/connector/sabre/request.php
+++ b/lib/private/connector/sabre/request.php
@@ -28,7 +28,7 @@ class OC_Connector_Sabre_Request extends \Sabre\HTTP\Request {
 	 * @return string
 	 */
 	public function getUri() {
-		return OC_Request::requestUri();
+		return \OC::$server->getRequest()->getRequestUri();
 	}
 
 	/**
diff --git a/lib/private/installer.php b/lib/private/installer.php
index aeac3497fd758e8fe7c918771737b4a808deb01e..8ed15a3a5d8f5d3b06e12da873ea18d547cce2f2 100644
--- a/lib/private/installer.php
+++ b/lib/private/installer.php
@@ -529,7 +529,6 @@ class OC_Installer{
 	 * @param string $folder the folder of the app to check
 	 * @return boolean true for app is o.k. and false for app is not o.k.
 	 */
-
 	public static function checkCode($folder) {
 		// is the code checker enabled?
 		if(!OC_Config::getValue('appcodechecker', false)) {
diff --git a/lib/private/log/owncloud.php b/lib/private/log/owncloud.php
index 8e55bf1c6953a17221d9c0f93ab2b43f4e58cb56..62c2da6febec6f2527dee5e1a156df0c3278a3a4 100644
--- a/lib/private/log/owncloud.php
+++ b/lib/private/log/owncloud.php
@@ -68,8 +68,9 @@ class OC_Log_Owncloud {
 				$timezone = new DateTimeZone('UTC');
 			}
 			$time = new DateTime(null, $timezone);
-			$reqId = \OC::$server->getRequest()->getId();
-			$remoteAddr = \OC_Request::getRemoteAddress();
+			$request = \OC::$server->getRequest();
+			$reqId = $request->getId();
+			$remoteAddr = $request->getRemoteAddress();
 			// remove username/passwords from URLs before writing the to the log file
 			$time = $time->format($format);
 			if($minLevel == OC_Log::DEBUG) {
diff --git a/lib/private/request.php b/lib/private/request.php
deleted file mode 100644
index ab011c913d92f3365bb61a6f076b8d9f1b905747..0000000000000000000000000000000000000000
--- a/lib/private/request.php
+++ /dev/null
@@ -1,330 +0,0 @@
-<?php
-/**
- * Copyright (c) 2012 Bart Visscher <bartv@thisnet.nl>
- * This file is licensed under the Affero General Public License version 3 or
- * later.
- * See the COPYING-README file.
- */
-
-class OC_Request {
-
-	const USER_AGENT_IE = '/MSIE/';
-	// Android Chrome user agent: https://developers.google.com/chrome/mobile/docs/user-agent
-	const USER_AGENT_ANDROID_MOBILE_CHROME = '#Android.*Chrome/[.0-9]*#';
-	const USER_AGENT_FREEBOX = '#^Mozilla/5\.0$#';
-	const REGEX_LOCALHOST = '/^(127\.0\.0\.1|localhost)$/';
-
-	/**
-	 * Returns the remote address, if the connection came from a trusted proxy and `forwarded_for_headers` has been configured
-	 * then the IP address specified in this header will be returned instead.
-	 * Do always use this instead of $_SERVER['REMOTE_ADDR']
-	 * @return string IP address
-	 */
-	public static function getRemoteAddress() {
-		$remoteAddress = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '';
-		$trustedProxies = \OC::$server->getConfig()->getSystemValue('trusted_proxies', array());
-
-		if(is_array($trustedProxies) && in_array($remoteAddress, $trustedProxies)) {
-			$forwardedForHeaders = \OC::$server->getConfig()->getSystemValue('forwarded_for_headers', array());
-
-			foreach($forwardedForHeaders as $header) {
-				if (array_key_exists($header, $_SERVER) === true) {
-					foreach (explode(',', $_SERVER[$header]) as $IP) {
-						$IP = trim($IP);
-						if (filter_var($IP, FILTER_VALIDATE_IP) !== false) {
-							return $IP;
-						}
-					}
-				}
-			}
-		}
-
-		return $remoteAddress;
-	}
-
-	/**
-	 * Check overwrite condition
-	 * @param string $type
-	 * @return bool
-	 */
-	private static function isOverwriteCondition($type = '') {
-		$regex = '/' . OC_Config::getValue('overwritecondaddr', '')  . '/';
-		return $regex === '//' or preg_match($regex, $_SERVER['REMOTE_ADDR']) === 1
-			or ($type !== 'protocol' and OC_Config::getValue('forcessl', false));
-	}
-
-	/**
-	 * Strips a potential port from a domain (in format domain:port)
-	 * @param $host
-	 * @return string $host without appended port
-	 */
-	public static function getDomainWithoutPort($host) {
-		$pos = strrpos($host, ':');
-		if ($pos !== false) {
-			$port = substr($host, $pos + 1);
-			if (is_numeric($port)) {
-				$host = substr($host, 0, $pos);
-			}
-		}
-		return $host;
-	}
-
-	/**
-	 * Checks whether a domain is considered as trusted from the list
-	 * of trusted domains. If no trusted domains have been configured, returns
-	 * true.
-	 * This is used to prevent Host Header Poisoning.
-	 * @param string $domainWithPort
-	 * @return bool true if the given domain is trusted or if no trusted domains
-	 * have been configured
-	 */
-	public static function isTrustedDomain($domainWithPort) {
-		// Extract port from domain if needed
-		$domain = self::getDomainWithoutPort($domainWithPort);
-
-		// FIXME: Empty config array defaults to true for now. - Deprecate this behaviour with ownCloud 8.
-		$trustedList = \OC::$server->getConfig()->getSystemValue('trusted_domains', array());
-		if (empty($trustedList)) {
-			return true;
-		}
-
-		// FIXME: Workaround for older instances still with port applied. Remove for ownCloud 9.
-		if(in_array($domainWithPort, $trustedList)) {
-			return true;
-		}
-
-		// Always allow access from localhost
-		if (preg_match(self::REGEX_LOCALHOST, $domain) === 1) {
-			return true;
-		}
-
-		return in_array($domain, $trustedList);
-	}
-
-	/**
-	 * Returns the unverified server host from the headers without checking
-	 * whether it is a trusted domain
-	 * @return string the server host
-	 *
-	 * Returns the server host, even if the website uses one or more
-	 * reverse proxies
-	 */
-	public static function insecureServerHost() {
-		$host = null;
-		if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
-			if (strpos($_SERVER['HTTP_X_FORWARDED_HOST'], ",") !== false) {
-				$parts = explode(',', $_SERVER['HTTP_X_FORWARDED_HOST']);
-				$host = trim(current($parts));
-			} else {
-				$host = $_SERVER['HTTP_X_FORWARDED_HOST'];
-			}
-		} else {
-			if (isset($_SERVER['HTTP_HOST'])) {
-				$host = $_SERVER['HTTP_HOST'];
-			} else if (isset($_SERVER['SERVER_NAME'])) {
-				$host = $_SERVER['SERVER_NAME'];
-			}
-		}
-		return $host;
-	}
-
-	/**
-	 * Returns the overwritehost setting from the config if set and
-	 * if the overwrite condition is met
-	 * @return string|null overwritehost value or null if not defined or the defined condition
-	 * isn't met
-	 */
-	public static function getOverwriteHost() {
-		if(OC_Config::getValue('overwritehost', '') !== '' and self::isOverwriteCondition()) {
-			return OC_Config::getValue('overwritehost');
-		}
-		return null;
-	}
-
-	/**
-	 * Returns the server host from the headers, or the first configured
-	 * trusted domain if the host isn't in the trusted list
-	 * @return string the server host
-	 *
-	 * Returns the server host, even if the website uses one or more
-	 * reverse proxies
-	 */
-	public static function serverHost() {
-		if (OC::$CLI && defined('PHPUNIT_RUN')) {
-			return 'localhost';
-		}
-
-		// overwritehost is always trusted
-		$host = self::getOverwriteHost();
-		if ($host !== null) {
-			return $host;
-		}
-
-		// get the host from the headers
-		$host = self::insecureServerHost();
-
-		// Verify that the host is a trusted domain if the trusted domains
-		// are defined
-		// If no trusted domain is provided the first trusted domain is returned
-		if (self::isTrustedDomain($host)) {
-			return $host;
-		} else {
-			$trustedList = \OC_Config::getValue('trusted_domains', array(''));
-			return $trustedList[0];
-		}
-	}
-
-	/**
-	* Returns the server protocol
-	* @return string the server protocol
-	*
-	* Returns the server protocol. It respects reverse proxy servers and load balancers
-	*/
-	public static function serverProtocol() {
-		if(OC_Config::getValue('overwriteprotocol', '') !== '' and self::isOverwriteCondition('protocol')) {
-			return OC_Config::getValue('overwriteprotocol');
-		}
-		if (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) {
-			$proto = strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']);
-			// Verify that the protocol is always HTTP or HTTPS
-			// default to http if an invalid value is provided
-			return $proto === 'https' ? 'https' : 'http';
-		}
-		if (isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') {
-			return 'https';
-		}
-		return 'http';
-	}
-
-	/**
-	 * Returns the request uri
-	 * @return string the request uri
-	 *
-	 * Returns the request uri, even if the website uses one or more
-	 * reverse proxies
-	 * @return string
-	 */
-	public static function requestUri() {
-		$uri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '';
-		if (OC_Config::getValue('overwritewebroot', '') !== '' and self::isOverwriteCondition()) {
-			$uri = self::scriptName() . substr($uri, strlen($_SERVER['SCRIPT_NAME']));
-		}
-		return $uri;
-	}
-
-	/**
-	 * Returns the script name
-	 * @return string the script name
-	 *
-	 * Returns the script name, even if the website uses one or more
-	 * reverse proxies
-	 */
-	public static function scriptName() {
-		$name = $_SERVER['SCRIPT_NAME'];
-		$overwriteWebRoot = OC_Config::getValue('overwritewebroot', '');
-		if ($overwriteWebRoot !== '' and self::isOverwriteCondition()) {
-			$serverroot = str_replace("\\", '/', substr(__DIR__, 0, -strlen('lib/private/')));
-			$suburi = str_replace("\\", "/", substr(realpath($_SERVER["SCRIPT_FILENAME"]), strlen($serverroot)));
-			$name = '/' . ltrim($overwriteWebRoot . $suburi, '/');
-		}
-		return $name;
-	}
-
-	/**
-	 * get Path info from request
-	 * @return string Path info or false when not found
-	 */
-	public static function getPathInfo() {
-		if (array_key_exists('PATH_INFO', $_SERVER)) {
-			$path_info = $_SERVER['PATH_INFO'];
-		}else{
-			$path_info = self::getRawPathInfo();
-			// following is taken from \Sabre\DAV\URLUtil::decodePathSegment
-			$path_info = rawurldecode($path_info);
-			$encoding = mb_detect_encoding($path_info, array('UTF-8', 'ISO-8859-1'));
-
-			switch($encoding) {
-
-				case 'ISO-8859-1' :
-					$path_info = utf8_encode($path_info);
-
-			}
-			// end copy
-		}
-		return $path_info;
-	}
-
-	/**
-	 * get Path info from request, not urldecoded
-	 * @throws Exception
-	 * @return string Path info or false when not found
-	 */
-	public static function getRawPathInfo() {
-		$requestUri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '';
-		// remove too many leading slashes - can be caused by reverse proxy configuration
-		if (strpos($requestUri, '/') === 0) {
-			$requestUri = '/' . ltrim($requestUri, '/');
-		}
-
-		$requestUri = preg_replace('%/{2,}%', '/', $requestUri);
-
-		// Remove the query string from REQUEST_URI
-		if ($pos = strpos($requestUri, '?')) {
-			$requestUri = substr($requestUri, 0, $pos);
-		}
-
-		$scriptName = $_SERVER['SCRIPT_NAME'];
-		$path_info = $requestUri;
-
-		// strip off the script name's dir and file name
-		list($path, $name) = \Sabre\DAV\URLUtil::splitPath($scriptName);
-		if (!empty($path)) {
-			if( $path === $path_info || strpos($path_info, $path.'/') === 0) {
-				$path_info = substr($path_info, strlen($path));
-			} else {
-				throw new Exception("The requested uri($requestUri) cannot be processed by the script '$scriptName')");
-			}
-		}
-		if (strpos($path_info, '/'.$name) === 0) {
-			$path_info = substr($path_info, strlen($name) + 1);
-		}
-		if (strpos($path_info, $name) === 0) {
-			$path_info = substr($path_info, strlen($name));
-		}
-		if($path_info === '/'){
-			return '';
-		} else {
-			return $path_info;
-		}
-	}
-
-	/**
-	 * Check if the requester sent along an mtime
-	 * @return false or an mtime
-	 */
-	static public function hasModificationTime () {
-		if (isset($_SERVER['HTTP_X_OC_MTIME'])) {
-			return $_SERVER['HTTP_X_OC_MTIME'];
-		} else {
-			return false;
-		}
-	}
-
-	/**
-	 * Checks whether the user agent matches a given regex
-	 * @param string|array $agent agent name or array of agent names
-	 * @return boolean true if at least one of the given agent matches,
-	 * false otherwise
-	 */
-	static public function isUserAgent($agent) {
-		if (!is_array($agent)) {
-			$agent = array($agent);
-		}
-		foreach ($agent as $regex) {
-			if (preg_match($regex, $_SERVER['HTTP_USER_AGENT'])) {
-				return true;
-			}
-		}
-		return false;
-	}
-}
diff --git a/lib/private/response.php b/lib/private/response.php
index cf18115111a016bd41f8bef00c2968295201d3e7..9be5d75c314dd6570c6c8cc72b0b0f4181af464e 100644
--- a/lib/private/response.php
+++ b/lib/private/response.php
@@ -158,11 +158,12 @@ class OC_Response {
 	 * @param string $type disposition type, either 'attachment' or 'inline'
 	 */
 	static public function setContentDispositionHeader( $filename, $type = 'attachment' ) {
-		if (OC_Request::isUserAgent(array(
-				OC_Request::USER_AGENT_IE,
-				OC_Request::USER_AGENT_ANDROID_MOBILE_CHROME,
-				OC_Request::USER_AGENT_FREEBOX
-			))) {
+		if (\OC::$server->getRequest()->isUserAgent(
+			[
+				\OC\AppFramework\Http\Request::USER_AGENT_IE,
+				\OC\AppFramework\Http\Request::USER_AGENT_ANDROID_MOBILE_CHROME,
+				\OC\AppFramework\Http\Request::USER_AGENT_FREEBOX,
+			])) {
 			header( 'Content-Disposition: ' . rawurlencode($type) . '; filename="' . rawurlencode( $filename ) . '"' );
 		} else {
 			header( 'Content-Disposition: ' . rawurlencode($type) . '; filename*=UTF-8\'\'' . rawurlencode( $filename )
diff --git a/lib/private/route/router.php b/lib/private/route/router.php
index 3559b841926f7848fc53e1e7ed53fb1be05e2559..25e897123d1045e9347e6d0b1e042ae227e8b78b 100644
--- a/lib/private/route/router.php
+++ b/lib/private/route/router.php
@@ -63,8 +63,9 @@ class Router implements IRouter {
 		} else {
 			$method = 'GET';
 		}
-		$host = \OC_Request::serverHost();
-		$schema = \OC_Request::serverProtocol();
+		$request = \OC::$server->getRequest();
+		$host = $request->getServerHost();
+		$schema = $request->getServerProtocol();
 		$this->context = new RequestContext($baseUrl, $method, $host, $schema);
 		// TODO cache
 		$this->root = $this->getCollection('root');
diff --git a/lib/private/security/trusteddomainhelper.php b/lib/private/security/trusteddomainhelper.php
new file mode 100644
index 0000000000000000000000000000000000000000..593263897be339e106688a1fd53340f0be94149c
--- /dev/null
+++ b/lib/private/security/trusteddomainhelper.php
@@ -0,0 +1,75 @@
+<?php
+/**
+ * Copyright (c) 2015 Lukas Reschke <lukas@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC\Security;
+use OC\AppFramework\Http\Request;
+use OCP\IConfig;
+
+/**
+ * Class TrustedDomain
+ *
+ * @package OC\Security
+ */
+class TrustedDomainHelper {
+	/** @var IConfig */
+	private $config;
+
+	/**
+	 * @param IConfig $config
+	 */
+	function __construct(IConfig $config) {
+		$this->config = $config;
+	}
+
+	/**
+	 * Strips a potential port from a domain (in format domain:port)
+	 * @param $host
+	 * @return string $host without appended port
+	 */
+	private function getDomainWithoutPort($host) {
+		$pos = strrpos($host, ':');
+		if ($pos !== false) {
+			$port = substr($host, $pos + 1);
+			if (is_numeric($port)) {
+				$host = substr($host, 0, $pos);
+			}
+		}
+		return $host;
+	}
+
+	/**
+	 * Checks whether a domain is considered as trusted from the list
+	 * of trusted domains. If no trusted domains have been configured, returns
+	 * true.
+	 * This is used to prevent Host Header Poisoning.
+	 * @param string $domainWithPort
+	 * @return bool true if the given domain is trusted or if no trusted domains
+	 * have been configured
+	 */
+	public function isTrustedDomain($domainWithPort) {
+		$domain = $this->getDomainWithoutPort($domainWithPort);
+
+		// Read trusted domains from config
+		$trustedList = $this->config->getSystemValue('trusted_domains', []);
+		if(!is_array($trustedList)) {
+			return false;
+		}
+
+		// TODO: Workaround for older instances still with port applied. Remove for ownCloud 9.
+		if(in_array($domainWithPort, $trustedList)) {
+			return true;
+		}
+
+		// Always allow access from localhost
+		if (preg_match(Request::REGEX_LOCALHOST, $domain) === 1) {
+			return true;
+		}
+		return in_array($domain, $trustedList);
+	}
+
+}
diff --git a/lib/private/server.php b/lib/private/server.php
index 9660597b39dd3ad2967ad7533511d065b2cf0141..9422f332eb1a364e2dd72cda1b0b233a59687e39 100644
--- a/lib/private/server.php
+++ b/lib/private/server.php
@@ -41,45 +41,6 @@ class Server extends SimpleContainer implements IServerContainer {
 		$this->registerService('ContactsManager', function ($c) {
 			return new ContactsManager();
 		});
-		$this->registerService('Request', function (Server $c) {
-			if (isset($c['urlParams'])) {
-				$urlParams = $c['urlParams'];
-			} else {
-				$urlParams = array();
-			}
-
-			if ($c->getSession()->exists('requesttoken')) {
-				$requestToken = $c->getSession()->get('requesttoken');
-			} else {
-				$requestToken = false;
-			}
-
-			if (defined('PHPUNIT_RUN') && PHPUNIT_RUN
-				&& in_array('fakeinput', stream_get_wrappers())
-			) {
-				$stream = 'fakeinput://data';
-			} else {
-				$stream = 'php://input';
-			}
-
-			return new Request(
-				[
-					'get' => $_GET,
-					'post' => $_POST,
-					'files' => $_FILES,
-					'server' => $_SERVER,
-					'env' => $_ENV,
-					'cookies' => $_COOKIE,
-					'method' => (isset($_SERVER) && isset($_SERVER['REQUEST_METHOD']))
-						? $_SERVER['REQUEST_METHOD']
-						: null,
-					'urlParams' => $urlParams,
-					'requesttoken' => $requestToken,
-				],
-				$this->getSecureRandom(),
-				$stream
-			);
-		});
 		$this->registerService('PreviewManager', function ($c) {
 			return new PreviewManager();
 		});
@@ -313,12 +274,57 @@ class Server extends SimpleContainer implements IServerContainer {
 	 * currently being processed is returned from this method.
 	 * In case the current execution was not initiated by a web request null is returned
 	 *
+	 * FIXME: This should be queried as well. However, due to our totally awesome
+	 * static code a lot of tests do stuff like $_SERVER['foo'] which obviously
+	 * will not work with that approach. We even have some integration tests in our
+	 * unit tests which setup a complete webserver. Once the code is all non-static
+	 * or we don't have such mixed integration/unit tests setup anymore this can
+	 * get moved out again.
+	 *
 	 * @return \OCP\IRequest|null
 	 */
 	function getRequest() {
-		return $this->query('Request');
+		if (isset($this['urlParams'])) {
+			$urlParams = $this['urlParams'];
+		} else {
+			$urlParams = array();
+		}
+
+		if ($this->getSession()->exists('requesttoken')) {
+			$requestToken = $this->getSession()->get('requesttoken');
+		} else {
+			$requestToken = false;
+		}
+
+		if (defined('PHPUNIT_RUN') && PHPUNIT_RUN
+			&& in_array('fakeinput', stream_get_wrappers())
+		) {
+			$stream = 'fakeinput://data';
+		} else {
+			$stream = 'php://input';
+		}
+
+		return new Request(
+			[
+				'get' => $_GET,
+				'post' => $_POST,
+				'files' => $_FILES,
+				'server' => $_SERVER,
+				'env' => $_ENV,
+				'cookies' => $_COOKIE,
+				'method' => (isset($_SERVER) && isset($_SERVER['REQUEST_METHOD']))
+					? $_SERVER['REQUEST_METHOD']
+					: null,
+				'urlParams' => $urlParams,
+				'requesttoken' => $requestToken,
+			],
+			$this->getSecureRandom(),
+			$this->getConfig(),
+			$stream
+		);
 	}
 
+
 	/**
 	 * Returns the preview manager which can create preview images for a given file
 	 *
diff --git a/lib/private/setup.php b/lib/private/setup.php
index e3a29b6469d03739282c469064ce96df4524187e..a3b46c1eb4f8087843ff1fb3b8c6da0645373465 100644
--- a/lib/private/setup.php
+++ b/lib/private/setup.php
@@ -157,12 +157,14 @@ class OC_Setup {
 			return $error;
 		}
 
+		$request = \OC::$server->getRequest();
+
 		//no errors, good
 		if(isset($options['trusted_domains'])
 		    && is_array($options['trusted_domains'])) {
 			$trustedDomains = $options['trusted_domains'];
 		} else {
-			$trustedDomains = array(\OC_Request::getDomainWithoutPort(\OC_Request::serverHost()));
+			$trustedDomains = [\OCP\Util::getServerHostName()];
 		}
 
 		if (OC_Util::runningOnWindows()) {
@@ -185,7 +187,7 @@ class OC_Setup {
 			'secret'			=> $secret,
 			'trusted_domains'	=> $trustedDomains,
 			'datadirectory'		=> $dataDir,
-			'overwrite.cli.url'	=> \OC_Request::serverProtocol() . '://' . \OC_Request::serverHost() . OC::$WEBROOT,
+			'overwrite.cli.url'	=> $request->getServerProtocol() . '://' . $request->getServerHost() . OC::$WEBROOT,
 			'dbtype'			=> $dbType,
 			'version'			=> implode('.', OC_Util::getVersion()),
 		]);
diff --git a/lib/private/template.php b/lib/private/template.php
index 4fa1c867d5496c0e58859f624ba078bcd92ff50f..b0d212c6f534cbb961dd3d6c344ab344004714ba 100644
--- a/lib/private/template.php
+++ b/lib/private/template.php
@@ -215,6 +215,7 @@ class OC_Template extends \OC\Template\Base {
 	 * @param Exception $exception
 	 */
 	public static function printExceptionErrorPage(Exception $exception) {
+		$request = \OC::$server->getRequest();
 		$content = new \OC_Template('', 'exception', 'error', false);
 		$content->assign('errorMsg', $exception->getMessage());
 		$content->assign('errorCode', $exception->getCode());
@@ -222,8 +223,8 @@ class OC_Template extends \OC\Template\Base {
 		$content->assign('line', $exception->getLine());
 		$content->assign('trace', $exception->getTraceAsString());
 		$content->assign('debugMode', defined('DEBUG') && DEBUG === true);
-		$content->assign('remoteAddr', OC_Request::getRemoteAddress());
-		$content->assign('requestID', \OC::$server->getRequest()->getId());
+		$content->assign('remoteAddr', $request->getRemoteAddress());
+		$content->assign('requestID', $request->getId());
 		$content->printPage();
 		die();
 	}
diff --git a/lib/private/templatelayout.php b/lib/private/templatelayout.php
index 1a97eb26347af704f373a98065612cef1935da76..1678795f524b41e20a08ce8a3fc8d8f03573246f 100644
--- a/lib/private/templatelayout.php
+++ b/lib/private/templatelayout.php
@@ -34,9 +34,9 @@ class OC_TemplateLayout extends OC_Template {
 		$this->config = \OC::$server->getConfig();
 
 		// Decide which page we show
-		if( $renderAs == 'user' ) {
+		if($renderAs == 'user') {
 			parent::__construct( 'core', 'layout.user' );
-			if(in_array(OC_APP::getCurrentApp(), array('settings','admin', 'help'))!==false) {
+			if(in_array(OC_App::getCurrentApp(), ['settings','admin', 'help']) !== false) {
 				$this->assign('bodyid', 'body-settings');
 			}else{
 				$this->assign('bodyid', 'body-user');
@@ -72,9 +72,9 @@ class OC_TemplateLayout extends OC_Template {
 				}
 			}
 			$userDisplayName = OC_User::getDisplayName();
-			$this->assign( 'user_displayname', $userDisplayName );
-			$this->assign( 'user_uid', OC_User::getUser() );
-			$this->assign( 'appsmanagement_active', strpos(OC_Request::requestUri(), OC_Helper::linkToRoute('settings_apps')) === 0 );
+			$this->assign('user_displayname', $userDisplayName);
+			$this->assign('user_uid', OC_User::getUser());
+			$this->assign('appsmanagement_active', strpos(\OC::$server->getRequest()->getRequestUri(), OC_Helper::linkToRoute('settings_apps')) === 0 );
 			$this->assign('enableAvatars', $this->config->getSystemValue('enable_avatars', true));
 			$this->assign('userAvatarSet', \OC_Helper::userAvatarSet(OC_User::getUser()));
 		} else if ($renderAs == 'error') {
diff --git a/lib/private/urlgenerator.php b/lib/private/urlgenerator.php
index 0bf8ce22998301d0e7590d86928ee46ef867e1b7..e87a6c354fb518f04e66243cc2de7bfcde08cf61 100644
--- a/lib/private/urlgenerator.php
+++ b/lib/private/urlgenerator.php
@@ -170,7 +170,8 @@ class URLGenerator implements IURLGenerator {
 			? ''
 			: \OC::$WEBROOT;
 
-		return \OC_Request::serverProtocol() . '://' . \OC_Request::serverHost(). $webRoot . $separator . $url;
+		$request = \OC::$server->getRequest();
+		return $request->getServerProtocol() . '://' . $request->getServerHost() . $webRoot . $separator . $url;
 	}
 
 	/**
diff --git a/lib/private/util.php b/lib/private/util.php
index 2be7e8eb293b3447c7ba0aac8021f12deee7392e..1993a7c9a98a282229a1e85c79e69f5c2f8c193e 100644
--- a/lib/private/util.php
+++ b/lib/private/util.php
@@ -849,8 +849,11 @@ class OC_Util {
 		// Check if we are a user
 		if (!OC_User::isLoggedIn()) {
 			header('Location: ' . OC_Helper::linkToAbsolute('', 'index.php',
-					array('redirect_url' => OC_Request::requestUri())
-				));
+					[
+						'redirect_url' => \OC::$server->getRequest()->getRequestUri()
+					]
+				)
+			);
 			exit();
 		}
 	}
diff --git a/lib/public/irequest.php b/lib/public/irequest.php
index b5ea1fa95dafe6ce28d4879ec81c5c9b3e771cb2..814fc0251cf968aa8787c2a653b24e4f234d44f8 100644
--- a/lib/public/irequest.php
+++ b/lib/public/irequest.php
@@ -134,4 +134,69 @@ interface IRequest {
 	 * @return string
 	 */
 	public function getId();
+
+	/**
+	 * Returns the remote address, if the connection came from a trusted proxy
+	 * and `forwarded_for_headers` has been configured then the IP address
+	 * specified in this header will be returned instead.
+	 * Do always use this instead of $_SERVER['REMOTE_ADDR']
+	 * @return string IP address
+	 */
+	public function getRemoteAddress();
+
+	/**
+	 * Returns the server protocol. It respects reverse proxy servers and load
+	 * balancers.
+	 * @return string Server protocol (http or https)
+	 */
+	public function getServerProtocol();
+
+	/**
+	* Returns the request uri, even if the website uses one or more
+	* reverse proxies
+	* @return string
+	*/
+	public function getRequestUri();
+
+	/**
+	 * Get raw PathInfo from request (not urldecoded)
+	 * @throws \Exception
+	 * @return string|false Path info or false when not found
+	 */
+	public function getRawPathInfo();
+
+	/**
+	 * Get PathInfo from request
+	 * @throws \Exception
+	 * @return string|false Path info or false when not found
+	 */
+	public function getPathInfo();
+
+	/**
+	 * Returns the script name, even if the website uses one or more
+	 * reverse proxies
+	 * @return string the script name
+	 */
+	public function getScriptName();
+
+	/**
+	 * Checks whether the user agent matches a given regex
+	 * @param array $agent array of agent names
+	 * @return bool true if at least one of the given agent matches, false otherwise
+	 */
+	public function isUserAgent(array $agent);
+
+	/**
+	 * Returns the unverified server host from the headers without checking
+	 * whether it is a trusted domain
+	 * @return string Server host
+	 */
+	public function getInsecureServerHost();
+
+	/**
+	 * Returns the server host from the headers, or the first configured
+	 * trusted domain if the host isn't in the trusted list
+	 * @return string Server host
+	 */
+	public function getServerHost();
 }
diff --git a/lib/public/util.php b/lib/public/util.php
index 7f1974a421d108c01f65da951ee64df8b41f5b7c..e6e14a26e01e08bbdbcd15a81f6d9b2060ee4d05 100644
--- a/lib/public/util.php
+++ b/lib/public/util.php
@@ -234,9 +234,10 @@ class Util {
 	/**
 	 * Returns the server host, even if the website uses one or more reverse proxy
 	 * @return string the server host
+	 * @deprecated Use \OCP\IRequest::getServerHost
 	 */
 	public static function getServerHost() {
-		return(\OC_Request::serverHost());
+		return \OC::$server->getRequest()->getServerHost();
 	}
 
 	/**
@@ -285,25 +286,28 @@ class Util {
 	/**
 	 * Returns the server protocol. It respects reverse proxy servers and load balancers
 	 * @return string the server protocol
+	 * @deprecated Use \OCP\IRequest::getServerProtocol
 	 */
 	public static function getServerProtocol() {
-		return(\OC_Request::serverProtocol());
+		return \OC::$server->getRequest()->getServerProtocol();
 	}
 
 	/**
 	 * Returns the request uri, even if the website uses one or more reverse proxies
 	 * @return string the request uri
+	 * @deprecated Use \OCP\IRequest::getRequestUri
 	 */
 	public static function getRequestUri() {
-		return(\OC_Request::requestUri());
+		return \OC::$server->getRequest()->getRequestUri();
 	}
 
 	/**
 	 * Returns the script name, even if the website uses one or more reverse proxies
 	 * @return string the script name
+	 * @deprecated Use \OCP\IRequest::getScriptName
 	 */
 	public static function getScriptName() {
-		return(\OC_Request::scriptName());
+		return \OC::$server->getRequest()->getScriptName();
 	}
 
 	/**
diff --git a/ocs/v1.php b/ocs/v1.php
index 0a86fb064117c2d45fe6c492714c3dd27d1ae46f..b0f3e5e2b9025651f18aa8fed130dcf312736922 100644
--- a/ocs/v1.php
+++ b/ocs/v1.php
@@ -42,7 +42,7 @@ try {
 	// api calls always will return English
 	\OC_L10N::forceLanguage('en');
 
-	OC::$server->getRouter()->match('/ocs'.OC_Request::getRawPathInfo());
+	OC::$server->getRouter()->match('/ocs'.\OC::$server->getRequest()->getRawPathInfo());
 } catch (ResourceNotFoundException $e) {
 	OC_API::setContentType();
 	OC_OCS::notFound();
diff --git a/public.php b/public.php
index c5c227ef46042e3b46b5bca11200e45c5ead80be..f17052a6c874ee86379b7d0449e7d4e0c7fa0e4d 100644
--- a/public.php
+++ b/public.php
@@ -13,12 +13,13 @@ try {
 
 	OC::checkMaintenanceMode();
 	OC::checkSingleUserMode();
-	$pathInfo = OC_Request::getPathInfo();
-	if (!$pathInfo && !isset($_GET['service'])) {
+	$request = \OC::$server->getRequest();
+	$pathInfo = $request->getPathInfo();
+	if (!$pathInfo && !isset($request->server['service'])) {
 		header('HTTP/1.0 404 Not Found');
 		exit;
-	} elseif (isset($_GET['service'])) {
-		$service = $_GET['service'];
+	} elseif (isset($request->server['service'])) {
+		$service = $request->server['service'];
 	} else {
 		$pathInfo = trim($pathInfo, '/');
 		list($service) = explode('/', $pathInfo);
diff --git a/remote.php b/remote.php
index 7993566afec0b6bf35011eb23e1782f062c4d75f..80173441e90a11b11392f7d9bfb7ec9e448f24f0 100644
--- a/remote.php
+++ b/remote.php
@@ -11,17 +11,18 @@ try {
 		exit;
 	}
 
-	$path_info = OC_Request::getPathInfo();
-	if ($path_info === false || $path_info === '') {
+	$request = \OC::$server->getRequest();
+	$pathInfo = $request->getPathInfo();
+	if ($pathInfo === false || $pathInfo === '') {
 		OC_Response::setStatus(OC_Response::STATUS_NOT_FOUND);
 		exit;
 	}
-	if (!$pos = strpos($path_info, '/', 1)) {
-		$pos = strlen($path_info);
+	if (!$pos = strpos($pathInfo, '/', 1)) {
+		$pos = strlen($pathInfo);
 	}
-	$service=substr($path_info, 1, $pos-1);
+	$service=substr($pathInfo, 1, $pos-1);
 
-	$file = \OC::$server->getAppConfig()->getValue('core', 'remote_' . $service);
+	$file = \OC::$server->getConfig()->getAppValue('core', 'remote_' . $service);
 
 	if(is_null($file)) {
 		OC_Response::setStatus(OC_Response::STATUS_NOT_FOUND);
diff --git a/settings/admin.php b/settings/admin.php
index bb20c665f560cbc3e193fab4f099d0812df51606..cdbc2700a8dd05f292d30e23fd706df8a36ead08 100644
--- a/settings/admin.php
+++ b/settings/admin.php
@@ -20,6 +20,7 @@ $doesLogFileExist = file_exists($logFilePath);
 $logFileSize = filesize($logFilePath);
 $config = \OC::$server->getConfig();
 $appConfig = \OC::$server->getAppConfig();
+$request = \OC::$server->getRequest();
 
 // Should we display sendmail as an option?
 $template->assign('sendmail_is_available', (bool) \OC_Helper::findBinaryPath('sendmail'));
@@ -59,7 +60,7 @@ $excludedGroupsList = explode(',', $excludedGroupsList); // FIXME: this should b
 $template->assign('shareExcludedGroupsList', implode('|', $excludedGroupsList));
 
 // Check if connected using HTTPS
-$template->assign('isConnectedViaHTTPS', OC_Request::serverProtocol() === 'https');
+$template->assign('isConnectedViaHTTPS', $request->getServerProtocol() === 'https');
 $template->assign('enforceHTTPSEnabled', $config->getSystemValue('forcessl', false));
 $template->assign('forceSSLforSubdomainsEnabled', $config->getSystemValue('forceSSLforSubdomains', false));
 
@@ -88,7 +89,7 @@ $template->assign('WindowsWarning', OC_Util::runningOnWindows());
 $forms = OC_App::getForms('admin');
 $l = OC_L10N::get('settings');
 $formsAndMore = array();
-if (OC_Request::serverProtocol() !== 'https' || !OC_Util::isAnnotationsWorking() ||
+if ($request->getServerProtocol()  !== 'https' || !OC_Util::isAnnotationsWorking() ||
 	$suggestedOverwriteCliUrl || !OC_Util::isSetLocaleWorking() || !OC_Util::isPhpCharSetUtf8() ||
 	!OC_Util::fileInfoLoaded() || $databaseOverload
 ) {
diff --git a/tests/lib/appframework/controller/ApiControllerTest.php b/tests/lib/appframework/controller/ApiControllerTest.php
index b2e52cc0b5cae93130e05861e71e854154474734..137e5950f6743301c44bf1df410d018fd41de25f 100644
--- a/tests/lib/appframework/controller/ApiControllerTest.php
+++ b/tests/lib/appframework/controller/ApiControllerTest.php
@@ -37,7 +37,8 @@ class ApiControllerTest extends \Test\TestCase {
     public function testCors() {
         $request = new Request(
             ['server' => ['HTTP_ORIGIN' => 'test']],
-            $this->getMockBuilder('\OCP\Security\ISecureRandom')->getMock()
+            $this->getMock('\OCP\Security\ISecureRandom'),
+            $this->getMock('\OCP\IConfig')
         );
         $this->controller = new ChildApiController('app', $request, 'verbs',
             'headers', 100);
diff --git a/tests/lib/appframework/controller/ControllerTest.php b/tests/lib/appframework/controller/ControllerTest.php
index 58395d05914c2dea48a34875469fc8d475eb5b2d..78c0d9d15a185155008283f315e700909528de86 100644
--- a/tests/lib/appframework/controller/ControllerTest.php
+++ b/tests/lib/appframework/controller/ControllerTest.php
@@ -75,7 +75,8 @@ class ControllerTest extends \Test\TestCase {
 				'session' => ['sezession' => 'kein'],
 				'method' => 'hi',
 			],
-			$this->getMockBuilder('\OCP\Security\ISecureRandom')->getMock()
+			$this->getMock('\OCP\Security\ISecureRandom'),
+			$this->getMock('\OCP\IConfig')
 		);
 
 		$this->app = $this->getMock('OC\AppFramework\DependencyInjection\DIContainer',
diff --git a/tests/lib/appframework/controller/OCSControllerTest.php b/tests/lib/appframework/controller/OCSControllerTest.php
index 3b4de1d7a056f5acb8dfa63c451152a8f26bd416..11a9d45eb925ef22a9b96638037b7a317980a714 100644
--- a/tests/lib/appframework/controller/OCSControllerTest.php
+++ b/tests/lib/appframework/controller/OCSControllerTest.php
@@ -33,11 +33,17 @@ class ChildOCSController extends OCSController {}
 
 class OCSControllerTest extends \Test\TestCase {
 
+	private $controller;
 
 	public function testCors() {
 		$request = new Request(
-			array('server' => array('HTTP_ORIGIN' => 'test')),
-			$this->getMock('\OCP\Security\ISecureRandom')
+			[
+				'server' => [
+					'HTTP_ORIGIN' => 'test',
+				],
+			],
+			$this->getMock('\OCP\Security\ISecureRandom'),
+			$this->getMock('\OCP\IConfig')
 		);
 		$controller = new ChildOCSController('app', $request, 'verbs',
 			'headers', 100);
@@ -57,7 +63,8 @@ class OCSControllerTest extends \Test\TestCase {
 	public function testXML() {
 		$controller = new ChildOCSController('app', new Request(
 			[],
-			$this->getMock('\OCP\Security\ISecureRandom')
+			$this->getMock('\OCP\Security\ISecureRandom'),
+			$this->getMock('\OCP\IConfig')
 		));
 		$expected = "<?xml version=\"1.0\"?>\n" .
 		"<ocs>\n" .
@@ -86,7 +93,8 @@ class OCSControllerTest extends \Test\TestCase {
 	public function testXMLDataResponse() {
 		$controller = new ChildOCSController('app', new Request(
 			[],
-			$this->getMock('\OCP\Security\ISecureRandom')
+			$this->getMock('\OCP\Security\ISecureRandom'),
+			$this->getMock('\OCP\IConfig')
 		));
 		$expected = "<?xml version=\"1.0\"?>\n" .
 		"<ocs>\n" .
@@ -115,7 +123,8 @@ class OCSControllerTest extends \Test\TestCase {
 	public function testJSON() {
 		$controller = new ChildOCSController('app', new Request(
 			[],
-			$this->getMock('\OCP\Security\ISecureRandom')
+			$this->getMock('\OCP\Security\ISecureRandom'),
+			$this->getMock('\OCP\IConfig')
 		));
 		$expected = '{"status":"OK","statuscode":400,"message":"OK",' .
 		            '"totalitems":"","itemsperpage":"","data":{"test":"hi"}}';
diff --git a/tests/lib/appframework/dependencyinjection/DIContainerTest.php b/tests/lib/appframework/dependencyinjection/DIContainerTest.php
index 43309f64e63816b59f3dbadcb6d78ac2ead1565a..0cbdddbb2051e2030d5eaedffda3dd642691be79 100644
--- a/tests/lib/appframework/dependencyinjection/DIContainerTest.php
+++ b/tests/lib/appframework/dependencyinjection/DIContainerTest.php
@@ -73,7 +73,8 @@ class DIContainerTest extends \Test\TestCase {
 	public function testMiddlewareDispatcherIncludesSecurityMiddleware(){
 		$this->container['Request'] = new Request(
 			['method' => 'GET'],
-			$this->getMockBuilder('\OCP\Security\ISecureRandom')->getMock()
+			$this->getMock('\OCP\Security\ISecureRandom'),
+			$this->getMock('\OCP\IConfig')
 		);
 		$security = $this->container['SecurityMiddleware'];
 		$dispatcher = $this->container['MiddlewareDispatcher'];
diff --git a/tests/lib/appframework/http/DispatcherTest.php b/tests/lib/appframework/http/DispatcherTest.php
index 832cd80e60af776dd54d60265698a4a40eff94c8..02c86df8e72113aa8ab021d76bb0890fe62af286 100644
--- a/tests/lib/appframework/http/DispatcherTest.php
+++ b/tests/lib/appframework/http/DispatcherTest.php
@@ -24,7 +24,6 @@
 
 namespace OC\AppFramework\Http;
 
-use OC\AppFramework\Middleware\MiddlewareDispatcher;
 use OC\AppFramework\Utility\ControllerMethodReflector;
 use OCP\AppFramework\Http;
 use OCP\AppFramework\Http\JSONResponse;
@@ -33,6 +32,10 @@ use OCP\AppFramework\Controller;
 
 
 class TestController extends Controller {
+	/**
+	 * @param string $appName
+	 * @param \OCP\IRequest $request
+	 */
 	public function __construct($appName, $request) {
 		parent::__construct($appName, $request);
 	}
@@ -40,6 +43,9 @@ class TestController extends Controller {
 	/**
 	 * @param int $int
 	 * @param bool $bool
+	 * @param int $test
+	 * @param int $test2
+	 * @return array
 	 */
 	public function exec($int, $bool, $test=4, $test2=1) {
 		$this->registerResponder('text', function($in) {
@@ -52,6 +58,9 @@ class TestController extends Controller {
 	/**
 	 * @param int $int
 	 * @param bool $bool
+	 * @param int $test
+	 * @param int $test2
+	 * @return DataResponse
 	 */
 	public function execDataResponse($int, $bool, $test=4, $test2=1) {
 		return new DataResponse(array(
@@ -67,6 +76,7 @@ class DispatcherTest extends \Test\TestCase {
 	private $dispatcher;
 	private $controllerMethod;
 	private $response;
+	private $request;
 	private $lastModified;
 	private $etag;
 	private $http;
@@ -284,7 +294,8 @@ class DispatcherTest extends \Test\TestCase {
 				],
 				'method' => 'POST'
 			],
-			$this->getMockBuilder('\OCP\Security\ISecureRandom')->getMock()
+			$this->getMock('\OCP\Security\ISecureRandom'),
+			$this->getMock('\OCP\IConfig')
 		);
 		$this->dispatcher = new Dispatcher(
 			$this->http, $this->middlewareDispatcher, $this->reflector,
@@ -310,7 +321,8 @@ class DispatcherTest extends \Test\TestCase {
 				],
 				'method' => 'POST',
 			],
-			$this->getMockBuilder('\OCP\Security\ISecureRandom')->getMock()
+			$this->getMock('\OCP\Security\ISecureRandom'),
+			$this->getMock('\OCP\IConfig')
 		);
 		$this->dispatcher = new Dispatcher(
 			$this->http, $this->middlewareDispatcher, $this->reflector,
@@ -339,7 +351,8 @@ class DispatcherTest extends \Test\TestCase {
 				],
 				'method' => 'GET'
 			],
-			$this->getMockBuilder('\OCP\Security\ISecureRandom')->getMock()
+			$this->getMock('\OCP\Security\ISecureRandom'),
+			$this->getMock('\OCP\IConfig')
 		);
 		$this->dispatcher = new Dispatcher(
 			$this->http, $this->middlewareDispatcher, $this->reflector,
@@ -367,7 +380,8 @@ class DispatcherTest extends \Test\TestCase {
 				],
 				'method' => 'GET'
 			],
-			$this->getMockBuilder('\OCP\Security\ISecureRandom')->getMock()
+			$this->getMock('\OCP\Security\ISecureRandom'),
+			$this->getMock('\OCP\IConfig')
 		);
 		$this->dispatcher = new Dispatcher(
 			$this->http, $this->middlewareDispatcher, $this->reflector,
@@ -396,7 +410,8 @@ class DispatcherTest extends \Test\TestCase {
 				],
 				'method' => 'PUT'
 			],
-			$this->getMockBuilder('\OCP\Security\ISecureRandom')->getMock()
+			$this->getMock('\OCP\Security\ISecureRandom'),
+			$this->getMock('\OCP\IConfig')
 		);
 		$this->dispatcher = new Dispatcher(
 			$this->http, $this->middlewareDispatcher, $this->reflector,
@@ -427,7 +442,8 @@ class DispatcherTest extends \Test\TestCase {
 				],
 				'method' => 'POST'
 			],
-			$this->getMockBuilder('\OCP\Security\ISecureRandom')->getMock()
+			$this->getMock('\OCP\Security\ISecureRandom'),
+			$this->getMock('\OCP\IConfig')
 		);
 		$this->dispatcher = new Dispatcher(
 			$this->http, $this->middlewareDispatcher, $this->reflector,
diff --git a/tests/lib/appframework/http/RequestTest.php b/tests/lib/appframework/http/RequestTest.php
index eeba64b7f690372524e0d51c2601f483ee0cbfb6..3185a0093c48a4962c55eff4a72d44dff4e8b78f 100644
--- a/tests/lib/appframework/http/RequestTest.php
+++ b/tests/lib/appframework/http/RequestTest.php
@@ -1,6 +1,8 @@
 <?php
 /**
- * Copyright (c) 2013 Thomas Tanghus (thomas@tanghus.net)
+ * @copyright 2013 Thomas Tanghus (thomas@tanghus.net)
+ * @copyright 2015 Lukas Reschke lukas@owncloud.com
+ *
  * This file is licensed under the Affero General Public License version 3 or
  * later.
  * See the COPYING-README file.
@@ -9,12 +11,20 @@
 namespace OC\AppFramework\Http;
 
 use OCP\Security\ISecureRandom;
+use OCP\IConfig;
 
+/**
+ * Class RequestTest
+ *
+ * @package OC\AppFramework\Http
+ */
 class RequestTest extends \Test\TestCase {
 	/** @var string */
 	protected $stream = 'fakeinput://data';
 	/** @var ISecureRandom */
 	protected $secureRandom;
+	/** @var IConfig */
+	protected $config;
 
 	protected function setUp() {
 		parent::setUp();
@@ -26,6 +36,7 @@ class RequestTest extends \Test\TestCase {
 		stream_wrapper_register('fakeinput', 'RequestStream');
 
 		$this->secureRandom = $this->getMockBuilder('\OCP\Security\ISecureRandom')->getMock();
+		$this->config = $this->getMockBuilder('\OCP\IConfig')->getMock();
 	}
 
 	protected function tearDown() {
@@ -39,7 +50,12 @@ class RequestTest extends \Test\TestCase {
 			'method' => 'GET',
 		);
 
-		$request = new Request($vars, $this->secureRandom, $this->stream);
+		$request = new Request(
+			$vars,
+			$this->secureRandom,
+			$this->config,
+			$this->stream
+		);
 
 		// Countable
 		$this->assertEquals(2, count($request));
@@ -66,7 +82,12 @@ class RequestTest extends \Test\TestCase {
 			'method' => 'GET'
 		);
 
-		$request = new Request($vars, $this->secureRandom, $this->stream);
+		$request = new Request(
+			$vars,
+			$this->secureRandom,
+			$this->config,
+			$this->stream
+		);
 
 		$this->assertEquals(3, count($request));
 		$this->assertEquals('Janey', $request->{'nickname'});
@@ -75,7 +96,7 @@ class RequestTest extends \Test\TestCase {
 
 
 	/**
-	* @expectedException RuntimeException
+	* @expectedException \RuntimeException
 	*/
 	public function testImmutableArrayAccess() {
 		$vars = array(
@@ -83,12 +104,18 @@ class RequestTest extends \Test\TestCase {
 			'method' => 'GET'
 		);
 
-		$request = new Request($vars, $this->secureRandom, $this->stream);
+		$request = new Request(
+			$vars,
+			$this->secureRandom,
+			$this->config,
+			$this->stream
+		);
+
 		$request['nickname'] = 'Janey';
 	}
 
 	/**
-	* @expectedException RuntimeException
+	* @expectedException \RuntimeException
 	*/
 	public function testImmutableMagicAccess() {
 		$vars = array(
@@ -96,12 +123,18 @@ class RequestTest extends \Test\TestCase {
 			'method' => 'GET'
 		);
 
-		$request = new Request($vars, $this->secureRandom, $this->stream);
+		$request = new Request(
+			$vars,
+			$this->secureRandom,
+			$this->config,
+			$this->stream
+		);
+
 		$request->{'nickname'} = 'Janey';
 	}
 
 	/**
-	* @expectedException LogicException
+	* @expectedException \LogicException
 	*/
 	public function testGetTheMethodRight() {
 		$vars = array(
@@ -109,8 +142,14 @@ class RequestTest extends \Test\TestCase {
 			'method' => 'GET',
 		);
 
-		$request = new Request($vars, $this->secureRandom, $this->stream);
-		$result = $request->post;
+		$request = new Request(
+			$vars,
+			$this->secureRandom,
+			$this->config,
+			$this->stream
+		);
+
+		$request->post;
 	}
 
 	public function testTheMethodIsRight() {
@@ -119,7 +158,13 @@ class RequestTest extends \Test\TestCase {
 			'method' => 'GET',
 		);
 
-		$request = new Request($vars, $this->secureRandom, $this->stream);
+		$request = new Request(
+			$vars,
+			$this->secureRandom,
+			$this->config,
+			$this->stream
+		);
+
 		$this->assertEquals('GET', $request->method);
 		$result = $request->get;
 		$this->assertEquals('John Q. Public', $result['name']);
@@ -134,7 +179,13 @@ class RequestTest extends \Test\TestCase {
 			'server' => array('CONTENT_TYPE' => 'application/json; utf-8')
 		);
 
-		$request = new Request($vars, $this->secureRandom, $this->stream);
+		$request = new Request(
+			$vars,
+			$this->secureRandom,
+			$this->config,
+			$this->stream
+		);
+
 		$this->assertEquals('POST', $request->method);
 		$result = $request->post;
 		$this->assertEquals('John Q. Public', $result['name']);
@@ -152,7 +203,12 @@ class RequestTest extends \Test\TestCase {
 			'server' => array('CONTENT_TYPE' => 'application/x-www-form-urlencoded'),
 		);
 
-		$request = new Request($vars, $this->secureRandom, $this->stream);
+		$request = new Request(
+			$vars,
+			$this->secureRandom,
+			$this->config,
+			$this->stream
+		);
 
 		$this->assertEquals('PATCH', $request->method);
 		$result = $request->patch;
@@ -171,7 +227,12 @@ class RequestTest extends \Test\TestCase {
 			'server' => array('CONTENT_TYPE' => 'application/json; utf-8'),
 		);
 
-		$request = new Request($vars, $this->secureRandom, $this->stream);
+		$request = new Request(
+			$vars,
+			$this->secureRandom,
+			$this->config,
+			$this->stream
+		);
 
 		$this->assertEquals('PUT', $request->method);
 		$result = $request->put;
@@ -186,7 +247,12 @@ class RequestTest extends \Test\TestCase {
 			'server' => array('CONTENT_TYPE' => 'application/json; utf-8'),
 		);
 
-		$request = new Request($vars, $this->secureRandom, $this->stream);
+		$request = new Request(
+			$vars,
+			$this->secureRandom,
+			$this->config,
+			$this->stream
+		);
 
 		$this->assertEquals('PATCH', $request->method);
 		$result = $request->patch;
@@ -205,7 +271,13 @@ class RequestTest extends \Test\TestCase {
 			'server' => array('CONTENT_TYPE' => 'image/png'),
 		);
 
-		$request = new Request($vars, $this->secureRandom, $this->stream);
+		$request = new Request(
+			$vars,
+			$this->secureRandom,
+			$this->config,
+			$this->stream
+		);
+
 		$this->assertEquals('PUT', $request->method);
 		$resource = $request->put;
 		$contents = stream_get_contents($resource);
@@ -228,7 +300,12 @@ class RequestTest extends \Test\TestCase {
 			'urlParams' => array('id' => '2'),
 		);
 
-		$request = new Request($vars, $this->secureRandom, $this->stream);
+		$request = new Request(
+			$vars,
+			$this->secureRandom,
+			$this->config,
+			$this->stream
+		);
 
 		$newParams = array('id' => '3', 'test' => 'test2');
 		$request->setUrlParameters($newParams);
@@ -244,7 +321,13 @@ class RequestTest extends \Test\TestCase {
 			],
 		];
 
-		$request = new Request($vars, $this->secureRandom, $this->stream);
+		$request = new Request(
+			$vars,
+			$this->secureRandom,
+			$this->config,
+			$this->stream
+		);
+
 		$this->assertSame('GeneratedUniqueIdByModUnique', $request->getId());
 	}
 
@@ -261,14 +344,695 @@ class RequestTest extends \Test\TestCase {
 			->method('getLowStrengthGenerator')
 			->will($this->returnValue($lowRandomSource));
 
-		$request = new Request([], $this->secureRandom, $this->stream);
+		$request = new Request(
+			[],
+			$this->secureRandom,
+			$this->config,
+			$this->stream
+		);
+
 		$this->assertSame('GeneratedByOwnCloudItself', $request->getId());
 	}
 
 	public function testGetIdWithoutModUniqueStable() {
-		$request = new Request([], \OC::$server->getSecureRandom(), $this->stream);
+		$request = new Request(
+			[],
+			\OC::$server->getSecureRandom(),
+			$this->config,
+			$this->stream
+		);
 		$firstId = $request->getId();
 		$secondId = $request->getId();
 		$this->assertSame($firstId, $secondId);
 	}
+
+	public function testGetRemoteAddressWithoutTrustedRemote() {
+		$this->config
+			->expects($this->once())
+			->method('getSystemValue')
+			->with('trusted_proxies')
+			->will($this->returnValue([]));
+
+		$request = new Request(
+			[
+				'server' => [
+					'REMOTE_ADDR' => '10.0.0.2',
+					'HTTP_X_FORWARDED' => '10.4.0.5, 10.4.0.4',
+					'HTTP_X_FORWARDED_FOR' => '192.168.0.233'
+				],
+			],
+			$this->secureRandom,
+			$this->config,
+			$this->stream
+		);
+
+		$this->assertSame('10.0.0.2', $request->getRemoteAddress());
+	}
+
+	public function testGetRemoteAddressWithNoTrustedHeader() {
+		$this->config
+			->expects($this->at(0))
+			->method('getSystemValue')
+			->with('trusted_proxies')
+			->will($this->returnValue(['10.0.0.2']));
+		$this->config
+			->expects($this->at(1))
+			->method('getSystemValue')
+			->with('forwarded_for_headers')
+			->will($this->returnValue([]));
+
+		$request = new Request(
+			[
+				'server' => [
+					'REMOTE_ADDR' => '10.0.0.2',
+					'HTTP_X_FORWARDED' => '10.4.0.5, 10.4.0.4',
+					'HTTP_X_FORWARDED_FOR' => '192.168.0.233'
+				],
+			],
+			$this->secureRandom,
+			$this->config,
+			$this->stream
+		);
+
+		$this->assertSame('10.0.0.2', $request->getRemoteAddress());
+	}
+
+	public function testGetRemoteAddressWithSingleTrustedRemote() {
+		$this->config
+			->expects($this->at(0))
+			->method('getSystemValue')
+			->with('trusted_proxies')
+			->will($this->returnValue(['10.0.0.2']));
+		$this->config
+			->expects($this->at(1))
+			->method('getSystemValue')
+			->with('forwarded_for_headers')
+			->will($this->returnValue(['HTTP_X_FORWARDED']));
+
+		$request = new Request(
+			[
+				'server' => [
+					'REMOTE_ADDR' => '10.0.0.2',
+					'HTTP_X_FORWARDED' => '10.4.0.5, 10.4.0.4',
+					'HTTP_X_FORWARDED_FOR' => '192.168.0.233'
+				],
+			],
+			$this->secureRandom,
+			$this->config,
+			$this->stream
+		);
+
+		$this->assertSame('10.4.0.5', $request->getRemoteAddress());
+	}
+
+	public function testGetRemoteAddressVerifyPriorityHeader() {
+		$this->config
+			->expects($this->at(0))
+			->method('getSystemValue')
+			->with('trusted_proxies')
+			->will($this->returnValue(['10.0.0.2']));
+		$this->config
+			->expects($this->at(1))
+			->method('getSystemValue')
+			->with('forwarded_for_headers')
+			->will($this->returnValue([
+				'HTTP_CLIENT_IP',
+				'HTTP_X_FORWARDED_FOR',
+				'HTTP_X_FORWARDED'
+			]));
+
+		$request = new Request(
+			[
+				'server' => [
+					'REMOTE_ADDR' => '10.0.0.2',
+					'HTTP_X_FORWARDED' => '10.4.0.5, 10.4.0.4',
+					'HTTP_X_FORWARDED_FOR' => '192.168.0.233'
+				],
+			],
+			$this->secureRandom,
+			$this->config,
+			$this->stream
+		);
+
+		$this->assertSame('192.168.0.233', $request->getRemoteAddress());
+	}
+
+	public function testGetServerProtocolWithOverride() {
+		$this->config
+			->expects($this->at(0))
+			->method('getSystemValue')
+			->with('overwriteprotocol')
+			->will($this->returnValue('customProtocol'));
+		$this->config
+			->expects($this->at(1))
+			->method('getSystemValue')
+			->with('overwritecondaddr')
+			->will($this->returnValue(''));
+		$this->config
+			->expects($this->at(2))
+			->method('getSystemValue')
+			->with('overwriteprotocol')
+			->will($this->returnValue('customProtocol'));
+
+		$request = new Request(
+			[],
+			$this->secureRandom,
+			$this->config,
+			$this->stream
+		);
+
+		$this->assertSame('customProtocol', $request->getServerProtocol());
+	}
+
+	public function testGetServerProtocolWithProtoValid() {
+		$this->config
+				->expects($this->exactly(2))
+				->method('getSystemValue')
+				->with('overwriteprotocol')
+				->will($this->returnValue(''));
+
+		$requestHttps = new Request(
+			[
+				'server' => [
+					'HTTP_X_FORWARDED_PROTO' => 'HtTpS'
+				],
+			],
+			$this->secureRandom,
+			$this->config,
+			$this->stream
+		);
+		$requestHttp = new Request(
+			[
+				'server' => [
+					'HTTP_X_FORWARDED_PROTO' => 'HTTp'
+				],
+			],
+			$this->secureRandom,
+			$this->config,
+			$this->stream
+		);
+
+
+		$this->assertSame('https', $requestHttps->getServerProtocol());
+		$this->assertSame('http', $requestHttp->getServerProtocol());
+	}
+
+	public function testGetServerProtocolWithHttpsServerValueOn() {
+		$this->config
+			->expects($this->once())
+			->method('getSystemValue')
+			->with('overwriteprotocol')
+			->will($this->returnValue(''));
+
+		$request = new Request(
+			[
+				'server' => [
+					'HTTPS' => 'on'
+				],
+			],
+			$this->secureRandom,
+			$this->config,
+			$this->stream
+		);
+		$this->assertSame('https', $request->getServerProtocol());
+	}
+
+	public function testGetServerProtocolWithHttpsServerValueOff() {
+		$this->config
+			->expects($this->once())
+			->method('getSystemValue')
+			->with('overwriteprotocol')
+			->will($this->returnValue(''));
+
+		$request = new Request(
+			[
+				'server' => [
+					'HTTPS' => 'off'
+				],
+			],
+			$this->secureRandom,
+			$this->config,
+			$this->stream
+		);
+		$this->assertSame('http', $request->getServerProtocol());
+	}
+
+	public function testGetServerProtocolDefault() {
+		$this->config
+			->expects($this->once())
+			->method('getSystemValue')
+			->with('overwriteprotocol')
+			->will($this->returnValue(''));
+
+		$request = new Request(
+			[],
+			$this->secureRandom,
+			$this->config,
+			$this->stream
+		);
+		$this->assertSame('http', $request->getServerProtocol());
+	}
+
+	/**
+	 * @dataProvider userAgentProvider
+	 * @param string $testAgent
+	 * @param array $userAgent
+	 * @param bool $matches
+	 */
+	public function testUserAgent($testAgent, $userAgent, $matches) {
+		$request = new Request(
+			[
+				'server' => [
+					'HTTP_USER_AGENT' => $testAgent,
+				]
+			],
+			$this->secureRandom,
+			$this->config,
+			$this->stream
+		);
+
+		$this->assertEquals($matches, $request->isUserAgent($userAgent));
+	}
+
+	/**
+	 * @return array
+	 */
+	function userAgentProvider() {
+		return [
+			[
+				'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
+				[
+					Request::USER_AGENT_IE
+				],
+				true,
+			],
+			[
+				'Mozilla/5.0 (X11; Linux i686; rv:24.0) Gecko/20100101 Firefox/24.0',
+				[
+					Request::USER_AGENT_IE
+				],
+				false,
+			],
+			[
+				'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',
+				[
+					Request::USER_AGENT_ANDROID_MOBILE_CHROME
+				],
+				true,
+			],
+			[
+				'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
+				[
+					Request::USER_AGENT_ANDROID_MOBILE_CHROME
+				],
+				false,
+			],
+			[
+				'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
+				[
+					Request::USER_AGENT_IE,
+					Request::USER_AGENT_ANDROID_MOBILE_CHROME,
+				],
+				true,
+			],
+			[
+				'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',
+				[
+					Request::USER_AGENT_IE,
+					Request::USER_AGENT_ANDROID_MOBILE_CHROME,
+				],
+				true,
+			],
+			[
+				'Mozilla/5.0 (X11; Linux i686; rv:24.0) Gecko/20100101 Firefox/24.0',
+				[
+					Request::USER_AGENT_FREEBOX
+				],
+				false,
+			],
+			[
+				'Mozilla/5.0',
+				[
+					Request::USER_AGENT_FREEBOX
+				],
+				true,
+			],
+			[
+				'Fake Mozilla/5.0',
+				[
+					Request::USER_AGENT_FREEBOX
+				],
+				false,
+			],
+		];
+	}
+
+	public function testInsecureServerHostServerNameHeader() {
+		$request = new Request(
+			[
+				'server' => [
+					'SERVER_NAME' => 'from.server.name:8080',
+				]
+			],
+			$this->secureRandom,
+			$this->config,
+			$this->stream
+		);
+
+		$this->assertEquals('from.server.name:8080',  $request->getInsecureServerHost());
+	}
+
+	public function testInsecureServerHostHttpHostHeader() {
+		$request = new Request(
+			[
+				'server' => [
+					'SERVER_NAME' => 'from.server.name:8080',
+					'HTTP_HOST' => 'from.host.header:8080',
+				]
+			],
+			$this->secureRandom,
+			$this->config,
+			$this->stream
+		);
+
+		$this->assertEquals('from.host.header:8080',  $request->getInsecureServerHost());
+	}
+
+	public function testInsecureServerHostHttpFromForwardedHeaderSingle() {
+		$request = new Request(
+			[
+				'server' => [
+					'SERVER_NAME' => 'from.server.name:8080',
+					'HTTP_HOST' => 'from.host.header:8080',
+					'HTTP_X_FORWARDED_HOST' => 'from.forwarded.host:8080',
+				]
+			],
+			$this->secureRandom,
+			$this->config,
+			$this->stream
+		);
+
+		$this->assertEquals('from.forwarded.host:8080',  $request->getInsecureServerHost());
+	}
+
+	public function testInsecureServerHostHttpFromForwardedHeaderStacked() {
+		$request = new Request(
+			[
+				'server' => [
+					'SERVER_NAME' => 'from.server.name:8080',
+					'HTTP_HOST' => 'from.host.header:8080',
+					'HTTP_X_FORWARDED_HOST' => 'from.forwarded.host2:8080,another.one:9000',
+				]
+			],
+			$this->secureRandom,
+			$this->config,
+			$this->stream
+		);
+
+		$this->assertEquals('from.forwarded.host2:8080',  $request->getInsecureServerHost());
+	}
+
+	public function testGetServerHost() {
+		$request = new Request(
+			[],
+			$this->secureRandom,
+			$this->config,
+			$this->stream
+		);
+
+		$this->assertEquals('localhost',  $request->getServerHost());
+	}
+
+	public function testGetOverwriteHostDefaultNull() {
+		$this->config
+			->expects($this->once())
+			->method('getSystemValue')
+			->with('overwritehost')
+			->will($this->returnValue(''));
+		$request = new Request(
+			[],
+			$this->secureRandom,
+			$this->config,
+			$this->stream
+		);
+
+		$this->assertNull(\Test_Helper::invokePrivate($request, 'getOverwriteHost'));
+	}
+
+	public function testGetOverwriteHostWithOverwrite() {
+		$this->config
+			->expects($this->at(0))
+			->method('getSystemValue')
+			->with('overwritehost')
+			->will($this->returnValue('www.owncloud.org'));
+		$this->config
+			->expects($this->at(1))
+			->method('getSystemValue')
+			->with('overwritecondaddr')
+			->will($this->returnValue(''));
+		$this->config
+			->expects($this->at(2))
+			->method('getSystemValue')
+			->with('overwritehost')
+			->will($this->returnValue('www.owncloud.org'));
+
+		$request = new Request(
+			[],
+			$this->secureRandom,
+			$this->config,
+			$this->stream
+		);
+
+		$this->assertSame('www.owncloud.org', \Test_Helper::invokePrivate($request, 'getOverwriteHost'));
+	}
+
+	public function testGetPathInfoWithSetEnv() {
+		$request = new Request(
+			[
+				'server' => [
+					'PATH_INFO' => 'apps/files/',
+				]
+			],
+			$this->secureRandom,
+			$this->config,
+			$this->stream
+		);
+
+		$this->assertEquals('apps/files/',  $request->getPathInfo());
+	}
+
+	/**
+	 * @expectedException \Exception
+	 * @expectedExceptionMessage The requested uri(/foo.php) cannot be processed by the script '/var/www/index.php')
+	 */
+	public function testGetPathInfoNotProcessible() {
+		$request = new Request(
+			[
+				'server' => [
+					'REQUEST_URI' => '/foo.php',
+					'SCRIPT_NAME' => '/var/www/index.php',
+				]
+			],
+			$this->secureRandom,
+			$this->config,
+			$this->stream
+		);
+
+		$request->getPathInfo();
+	}
+
+	/**
+	 * @expectedException \Exception
+	 * @expectedExceptionMessage The requested uri(/foo.php) cannot be processed by the script '/var/www/index.php')
+	 */
+	public function testGetRawPathInfoNotProcessible() {
+		$request = new Request(
+			[
+				'server' => [
+					'REQUEST_URI' => '/foo.php',
+					'SCRIPT_NAME' => '/var/www/index.php',
+				]
+			],
+			$this->secureRandom,
+			$this->config,
+			$this->stream
+		);
+
+		$request->getRawPathInfo();
+	}
+
+	/**
+	 * @dataProvider genericPathInfoProvider
+	 * @param string $requestUri
+	 * @param string $scriptName
+	 * @param string $expected
+	 */
+	public function testGetPathInfoWithoutSetEnvGeneric($requestUri, $scriptName, $expected) {
+		$request = new Request(
+			[
+				'server' => [
+					'REQUEST_URI' => $requestUri,
+					'SCRIPT_NAME' => $scriptName,
+				]
+			],
+			$this->secureRandom,
+			$this->config,
+			$this->stream
+		);
+
+		$this->assertEquals($expected, $request->getPathInfo());
+	}
+
+	/**
+	 * @dataProvider genericPathInfoProvider
+	 * @param string $requestUri
+	 * @param string $scriptName
+	 * @param string $expected
+	 */
+	public function testGetRawPathInfoWithoutSetEnvGeneric($requestUri, $scriptName, $expected) {
+		$request = new Request(
+			[
+				'server' => [
+					'REQUEST_URI' => $requestUri,
+					'SCRIPT_NAME' => $scriptName,
+				]
+			],
+			$this->secureRandom,
+			$this->config,
+			$this->stream
+		);
+
+		$this->assertEquals($expected, $request->getRawPathInfo());
+	}
+
+	/**
+	 * @dataProvider rawPathInfoProvider
+	 * @param string $requestUri
+	 * @param string $scriptName
+	 * @param string $expected
+	 */
+	public function testGetRawPathInfoWithoutSetEnv($requestUri, $scriptName, $expected) {
+		$request = new Request(
+			[
+				'server' => [
+					'REQUEST_URI' => $requestUri,
+					'SCRIPT_NAME' => $scriptName,
+				]
+			],
+			$this->secureRandom,
+			$this->config,
+			$this->stream
+		);
+
+		$this->assertEquals($expected, $request->getRawPathInfo());
+	}
+
+	/**
+	 * @dataProvider pathInfoProvider
+	 * @param string $requestUri
+	 * @param string $scriptName
+	 * @param string $expected
+	 */
+	public function testGetPathInfoWithoutSetEnv($requestUri, $scriptName, $expected) {
+		$request = new Request(
+			[
+				'server' => [
+					'REQUEST_URI' => $requestUri,
+					'SCRIPT_NAME' => $scriptName,
+				]
+			],
+			$this->secureRandom,
+			$this->config,
+			$this->stream
+		);
+
+		$this->assertEquals($expected, $request->getPathInfo());
+	}
+
+	/**
+	 * @return array
+	 */
+	public function genericPathInfoProvider() {
+		return [
+			['/index.php/apps/files/', 'index.php', '/apps/files/'],
+			['/index.php/apps/files/../&amp;/&?someQueryParameter=QueryParam', 'index.php', '/apps/files/../&amp;/&'],
+			['/remote.php/漢字編碼方法 / 汉字编码方法', 'remote.php', '/漢字編碼方法 / 汉字编码方法'],
+			['///removeTrailin//gSlashes///', 'remote.php', '/removeTrailin/gSlashes/'],
+			['/', '/', ''],
+			['', '', ''],
+		];
+	}
+
+	/**
+	 * @return array
+	 */
+	public function rawPathInfoProvider() {
+		return [
+			['/foo%2Fbar/subfolder', '', 'foo%2Fbar/subfolder'],
+		];
+	}
+
+	/**
+	 * @return array
+	 */
+	public function pathInfoProvider() {
+		return [
+			['/foo%2Fbar/subfolder', '', 'foo/bar/subfolder'],
+		];
+	}
+
+	public function testGetRequestUriWithoutOverwrite() {
+		$this->config
+			->expects($this->once())
+			->method('getSystemValue')
+			->with('overwritewebroot')
+			->will($this->returnValue(''));
+
+		$request = new Request(
+			[
+				'server' => [
+					'REQUEST_URI' => '/test.php'
+				]
+			],
+			$this->secureRandom,
+			$this->config,
+			$this->stream
+		);
+
+		$this->assertSame('/test.php', $request->getRequestUri());
+	}
+
+	public function testGetRequestUriWithOverwrite() {
+		$this->config
+			->expects($this->at(0))
+			->method('getSystemValue')
+			->with('overwritewebroot')
+			->will($this->returnValue('/owncloud/'));
+		$this->config
+			->expects($this->at(1))
+			->method('getSystemValue')
+			->with('overwritecondaddr')
+			->will($this->returnValue(''));
+
+		$request = $this->getMockBuilder('\OC\AppFramework\Http\Request')
+			->setMethods(['getScriptName'])
+			->setConstructorArgs([
+				[
+					'server' => [
+						'REQUEST_URI' => '/test.php/some/PathInfo',
+						'SCRIPT_NAME' => '/test.php',
+					]
+				],
+				$this->secureRandom,
+				$this->config,
+				$this->stream
+			])
+			->getMock();
+		$request
+			->expects($this->once())
+			->method('getScriptName')
+			->will($this->returnValue('/scriptname.php'));
+
+		$this->assertSame('/scriptname.php/some/PathInfo', $request->getRequestUri());
+	}
 }
diff --git a/tests/lib/appframework/middleware/MiddlewareDispatcherTest.php b/tests/lib/appframework/middleware/MiddlewareDispatcherTest.php
index 078543c7b5902eff5fc3d4310d31d8741ce9650d..a873152579899aa9b3cee9f9d3235e77d679f24b 100644
--- a/tests/lib/appframework/middleware/MiddlewareDispatcherTest.php
+++ b/tests/lib/appframework/middleware/MiddlewareDispatcherTest.php
@@ -132,7 +132,8 @@ class MiddlewareDispatcherTest extends \Test\TestCase {
 			['app',
 				new Request(
 					['method' => 'GET'],
-					$this->getMockBuilder('\OCP\Security\ISecureRandom')->getMock()
+					$this->getMock('\OCP\Security\ISecureRandom'),
+					$this->getMock('\OCP\IConfig')
 				)
 			]
 		);
diff --git a/tests/lib/appframework/middleware/MiddlewareTest.php b/tests/lib/appframework/middleware/MiddlewareTest.php
index fcc0c300a8a4339098026ca08da1806001582a24..33f04e1383d0b177c6e1fcb21ae10e47fee87560 100644
--- a/tests/lib/appframework/middleware/MiddlewareTest.php
+++ b/tests/lib/appframework/middleware/MiddlewareTest.php
@@ -26,7 +26,7 @@ namespace OC\AppFramework;
 
 use OC\AppFramework\Http\Request;
 use OCP\AppFramework\Middleware;
-
+use OCP\AppFramework\Http\Response;
 
 class ChildMiddleware extends Middleware {};
 
@@ -40,6 +40,8 @@ class MiddlewareTest extends \Test\TestCase {
 	private $controller;
 	private $exception;
 	private $api;
+	/** @var Response */
+	private $response;
 
 	protected function setUp(){
 		parent::setUp();
@@ -56,7 +58,11 @@ class MiddlewareTest extends \Test\TestCase {
 			[],
 			[
 				$this->api,
-				new Request([], $this->getMockBuilder('\OCP\Security\ISecureRandom')->getMock())
+				new Request(
+					[],
+					$this->getMock('\OCP\Security\ISecureRandom'),
+					$this->getMock('\OCP\IConfig')
+				)
 			]
 		);
 		$this->exception = new \Exception();
diff --git a/tests/lib/appframework/middleware/security/CORSMiddlewareTest.php b/tests/lib/appframework/middleware/security/CORSMiddlewareTest.php
index 57a7c524abe4418745467b88fe42b2ce4bed2471..a4f3137cb11ea935daeca4b4e9413e4983e72cff 100644
--- a/tests/lib/appframework/middleware/security/CORSMiddlewareTest.php
+++ b/tests/lib/appframework/middleware/security/CORSMiddlewareTest.php
@@ -37,7 +37,8 @@ class CORSMiddlewareTest extends \Test\TestCase {
 					'HTTP_ORIGIN' => 'test'
 				]
 			],
-			$this->getMockBuilder('\OCP\Security\ISecureRandom')->getMock()
+			$this->getMock('\OCP\Security\ISecureRandom'),
+			$this->getMock('\OCP\IConfig')
 		);
 		$this->reflector->reflect($this, __FUNCTION__);
 		$middleware = new CORSMiddleware($request, $this->reflector);
@@ -55,7 +56,8 @@ class CORSMiddlewareTest extends \Test\TestCase {
 					'HTTP_ORIGIN' => 'test'
 				]
 			],
-			$this->getMockBuilder('\OCP\Security\ISecureRandom')->getMock()
+			$this->getMock('\OCP\Security\ISecureRandom'),
+			$this->getMock('\OCP\IConfig')
 		);
 		$middleware = new CORSMiddleware($request, $this->reflector);
 
@@ -69,7 +71,11 @@ class CORSMiddlewareTest extends \Test\TestCase {
 	 * @CORS
 	 */
 	public function testNoOriginHeaderNoCORSHEADER() {
-		$request = new Request([], $this->getMockBuilder('\OCP\Security\ISecureRandom')->getMock());
+		$request = new Request(
+			[],
+			$this->getMock('\OCP\Security\ISecureRandom'),
+			$this->getMock('\OCP\IConfig')
+		);
 		$this->reflector->reflect($this, __FUNCTION__);
 		$middleware = new CORSMiddleware($request, $this->reflector);
 
@@ -90,14 +96,15 @@ class CORSMiddlewareTest extends \Test\TestCase {
 					'HTTP_ORIGIN' => 'test'
 				]
 			],
-			$this->getMockBuilder('\OCP\Security\ISecureRandom')->getMock()
+			$this->getMock('\OCP\Security\ISecureRandom'),
+			$this->getMock('\OCP\IConfig')
 		);
 		$this->reflector->reflect($this, __FUNCTION__);
 		$middleware = new CORSMiddleware($request, $this->reflector);
 
 		$response = new Response();
 		$response->addHeader('AcCess-control-Allow-Credentials ', 'TRUE');
-		$response = $middleware->afterController($this, __FUNCTION__, $response);
+		$middleware->afterController($this, __FUNCTION__, $response);
 	}
 
 }
diff --git a/tests/lib/appframework/middleware/security/SecurityMiddlewareTest.php b/tests/lib/appframework/middleware/security/SecurityMiddlewareTest.php
index 3acba7ce1d87cb8ba2c1558868b3ca5b423dbc6d..347a0423ea6e65c0604fe4436893008b5e750756 100644
--- a/tests/lib/appframework/middleware/security/SecurityMiddlewareTest.php
+++ b/tests/lib/appframework/middleware/security/SecurityMiddlewareTest.php
@@ -321,7 +321,8 @@ class SecurityMiddlewareTest extends \Test\TestCase {
 					'REQUEST_URI' => 'owncloud/index.php/apps/specialapp'
 				]
 			],
-			$this->getMockBuilder('\OCP\Security\ISecureRandom')->getMock()
+			$this->getMock('\OCP\Security\ISecureRandom'),
+			$this->getMock('\OCP\IConfig')
 		);
 		$this->middleware = $this->getMiddleware(true, true);
 		$response = $this->middleware->afterException($this->controller, 'test',
diff --git a/tests/lib/appframework/middleware/sessionmiddlewaretest.php b/tests/lib/appframework/middleware/sessionmiddlewaretest.php
index c417225d9087c70aa644e5ba3cf93fc624cfd1bc..11c1600f515edbbb56097fb1cc601d4c281602e5 100644
--- a/tests/lib/appframework/middleware/sessionmiddlewaretest.php
+++ b/tests/lib/appframework/middleware/sessionmiddlewaretest.php
@@ -35,7 +35,8 @@ class SessionMiddlewareTest extends \Test\TestCase {
 
 		$this->request = new Request(
 			[],
-			$this->getMockBuilder('\OCP\Security\ISecureRandom')->getMock()
+			$this->getMockBuilder('\OCP\Security\ISecureRandom')->getMock(),
+			$this->getMock('\OCP\IConfig')
 		);
 		$this->reflector = new ControllerMethodReflector();
 	}
diff --git a/tests/lib/request.php b/tests/lib/request.php
deleted file mode 100644
index dd6d1e47cd5eb15aac22951951abe0fd4505f494..0000000000000000000000000000000000000000
--- a/tests/lib/request.php
+++ /dev/null
@@ -1,333 +0,0 @@
-<?php
-/**
- * Copyright (c) 2013 Thomas Müller <thomas.mueller@tmit.eu>
- * This file is licensed under the Affero General Public License version 3 or
- * later.
- * See the COPYING-README file.
- */
-
-class Test_Request extends \Test\TestCase {
-
-	protected function setUp() {
-		parent::setUp();
-
-		OC::$server->getConfig()->setSystemValue('overwritewebroot', '/domain.tld/ownCloud');
-
-		OC::$server->getConfig()->setSystemValue('trusted_proxies', array());
-		OC::$server->getConfig()->setSystemValue('forwarded_for_headers', array());
-	}
-
-	protected function tearDown() {
-		OC::$server->getConfig()->setSystemValue('overwritewebroot', '');
-		OC::$server->getConfig()->setSystemValue('trusted_proxies', array());
-		OC::$server->getConfig()->setSystemValue('forwarded_for_headers', array());
-
-		parent::tearDown();
-	}
-
-	public function testScriptNameOverWrite() {
-		$_SERVER['REMOTE_ADDR'] = '10.0.0.1';
-		$_SERVER['SCRIPT_FILENAME'] = __FILE__;
-
-		$scriptName = OC_Request::scriptName();
-		$this->assertEquals('/domain.tld/ownCloud/tests/lib/request.php', $scriptName);
-	}
-
-	public function testGetRemoteAddress() {
-		$_SERVER['REMOTE_ADDR'] = '10.0.0.2';
-		$_SERVER['HTTP_X_FORWARDED'] = '10.4.0.5, 10.4.0.4';
-		$_SERVER['HTTP_X_FORWARDED_FOR'] = '192.168.0.233';
-
-		// Without having specified a trusted remote address
-		$this->assertEquals('10.0.0.2', OC_Request::getRemoteAddress());
-
-		// With specifying a trusted remote address but no trusted header
-		OC::$server->getConfig()->setSystemValue('trusted_proxies', array('10.0.0.2'));
-		$this->assertEquals('10.0.0.2', OC_Request::getRemoteAddress());
-
-		// With specifying a trusted remote address and trusted headers
-		OC::$server->getConfig()->setSystemValue('trusted_proxies', array('10.0.0.2'));
-		OC::$server->getConfig()->setSystemValue('forwarded_for_headers', array('HTTP_X_FORWARDED'));
-		$this->assertEquals('10.4.0.5', OC_Request::getRemoteAddress());
-		OC::$server->getConfig()->setSystemValue('forwarded_for_headers', array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED'));
-		$this->assertEquals('192.168.0.233', OC_Request::getRemoteAddress());
-
-		// With specifying multiple trusted remote addresses and trusted headers
-		OC::$server->getConfig()->setSystemValue('trusted_proxies', array('10.3.4.2', '10.0.0.2', '127.0.3.3'));
-		OC::$server->getConfig()->setSystemValue('forwarded_for_headers', array('HTTP_X_FORWARDED'));
-		$this->assertEquals('10.4.0.5', OC_Request::getRemoteAddress());
-		OC::$server->getConfig()->setSystemValue('forwarded_for_headers', array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED'));
-		$this->assertEquals('192.168.0.233', OC_Request::getRemoteAddress());
-	}
-
-	/**
-	 * @dataProvider rawPathInfoProvider
-	 * @param $expected
-	 * @param $requestUri
-	 * @param $scriptName
-	 */
-	public function testRawPathInfo($expected, $requestUri, $scriptName) {
-		$_SERVER['REQUEST_URI'] = $requestUri;
-		$_SERVER['SCRIPT_NAME'] = $scriptName;
-		$rawPathInfo = OC_Request::getRawPathInfo();
-		$this->assertEquals($expected, $rawPathInfo);
-	}
-
-	function rawPathInfoProvider() {
-		return array(
-			array('/core/ajax/translations.php', 'index.php/core/ajax/translations.php', 'index.php'),
-			array('/core/ajax/translations.php', '/index.php/core/ajax/translations.php', '/index.php'),
-			array('/core/ajax/translations.php', '//index.php/core/ajax/translations.php', '/index.php'),
-			array('', '/oc/core', '/oc/core/index.php'),
-			array('', '/oc/core/', '/oc/core/index.php'),
-			array('', '/oc/core/index.php', '/oc/core/index.php'),
-			array('/core/ajax/translations.php', '/core/ajax/translations.php', 'index.php'),
-			array('/core/ajax/translations.php', '//core/ajax/translations.php', '/index.php'),
-			array('/core/ajax/translations.php', '/oc/core/ajax/translations.php', '/oc/index.php'),
-			array('/core/ajax/translations.php', '/oc//index.php/core/ajax/translations.php', '/oc/index.php'),
-			array('/1', '/oc/core/1', '/oc/core/index.php'),
-		);
-	}
-
-	/**
-	 * @dataProvider rawPathInfoThrowsExceptionProvider
-	 * @expectedException Exception
-	 *
-	 * @param $requestUri
-	 * @param $scriptName
-	 */
-	public function testRawPathInfoThrowsException($requestUri, $scriptName) {
-		$_SERVER['REQUEST_URI'] = $requestUri;
-		$_SERVER['SCRIPT_NAME'] = $scriptName;
-		OC_Request::getRawPathInfo();
-	}
-
-	function rawPathInfoThrowsExceptionProvider() {
-		return array(
-			array('/oc/core1', '/oc/core/index.php'),
-		);
-	}
-
-	/**
-	 * @dataProvider userAgentProvider
-	 */
-	public function testUserAgent($testAgent, $userAgent, $matches) {
-		$_SERVER['HTTP_USER_AGENT'] = $testAgent;
-		$this->assertEquals($matches, OC_Request::isUserAgent($userAgent));
-	}
-
-	function userAgentProvider() {
-		return array(
-			array(
-				'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
-				OC_Request::USER_AGENT_IE,
-				true
-			),
-			array(
-				'Mozilla/5.0 (X11; Linux i686; rv:24.0) Gecko/20100101 Firefox/24.0',
-				OC_Request::USER_AGENT_IE,
-				false
-			),
-			array(
-				'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',
-				OC_Request::USER_AGENT_ANDROID_MOBILE_CHROME,
-				true
-			),
-			array(
-				'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
-				OC_Request::USER_AGENT_ANDROID_MOBILE_CHROME,
-				false
-			),
-			// test two values
-			array(
-				'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
-				array(
-					OC_Request::USER_AGENT_IE,
-					OC_Request::USER_AGENT_ANDROID_MOBILE_CHROME,
-				),
-				true
-			),
-			array(
-				'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',
-				array(
-					OC_Request::USER_AGENT_IE,
-					OC_Request::USER_AGENT_ANDROID_MOBILE_CHROME,
-				),
-				true
-			),
-			array(
-				'Mozilla/5.0 (X11; Linux i686; rv:24.0) Gecko/20100101 Firefox/24.0',
-				OC_Request::USER_AGENT_FREEBOX,
-				false
-			),
-			array(
-				'Mozilla/5.0',
-				OC_Request::USER_AGENT_FREEBOX,
-				true
-			),
-			array(
-				'Fake Mozilla/5.0',
-				OC_Request::USER_AGENT_FREEBOX,
-				false
-			),
-		);
-	}
-
-	public function testInsecureServerHost() {
-		unset($_SERVER['HTTP_X_FORWARDED_HOST']);
-		unset($_SERVER['HTTP_HOST']);
-		unset($_SERVER['SERVER_NAME']);
-		$_SERVER['SERVER_NAME'] = 'from.server.name:8080';
-		$host = OC_Request::insecureServerHost();
-		$this->assertEquals('from.server.name:8080', $host);
-
-		$_SERVER['HTTP_HOST'] = 'from.host.header:8080';
-		$host = OC_Request::insecureServerHost();
-		$this->assertEquals('from.host.header:8080', $host);
-
-		$_SERVER['HTTP_X_FORWARDED_HOST'] = 'from.forwarded.host:8080';
-		$host = OC_Request::insecureServerHost();
-		$this->assertEquals('from.forwarded.host:8080', $host);
-
-		$_SERVER['HTTP_X_FORWARDED_HOST'] = 'from.forwarded.host2:8080,another.one:9000';
-		$host = OC_Request::insecureServerHost();
-		$this->assertEquals('from.forwarded.host2:8080', $host);
-
-		// clean up
-		unset($_SERVER['HTTP_X_FORWARDED_HOST']);
-		unset($_SERVER['HTTP_HOST']);
-		unset($_SERVER['SERVER_NAME']);
-	}
-
-	public function testGetOverwriteHost() {
-		unset($_SERVER['REMOTE_ADDR']);
-		OC_Config::deleteKey('overwritecondaddr');
-		OC_Config::deleteKey('overwritehost');
-		$host = OC_Request::getOverwriteHost();
-		$this->assertNull($host);
-
-		OC_Config::setValue('overwritehost', '');
-		$host = OC_Request::getOverwriteHost();
-		$this->assertNull($host);
-
-		OC_Config::setValue('overwritehost', 'host.one.test:8080');
-		$host = OC_Request::getOverwriteHost();
-		$this->assertEquals('host.one.test:8080', $host);
-
-		$_SERVER['REMOTE_ADDR'] = 'somehost.test:8080';
-		OC_Config::setValue('overwritecondaddr', '^somehost\..*$');
-		$host = OC_Request::getOverwriteHost();
-		$this->assertEquals('host.one.test:8080', $host);
-
-		OC_Config::setValue('overwritecondaddr', '^somethingelse.*$');
-		$host = OC_Request::getOverwriteHost();
-		$this->assertNull($host);
-
-		// clean up
-		unset($_SERVER['REMOTE_ADDR']);
-		OC_Config::deleteKey('overwritecondaddr');
-		OC_Config::deleteKey('overwritehost');
-	}
-
-	public function hostWithPortProvider() {
-		return array(
-			array('localhost:500', 'localhost'),
-			array('foo.com', 'foo.com'),
-			array('[1fff:0:a88:85a3::ac1f]:801', '[1fff:0:a88:85a3::ac1f]'),
-			array('[1fff:0:a88:85a3::ac1f]', '[1fff:0:a88:85a3::ac1f]')
-		);
-	}
-
-	/**
-	 * @dataProvider hostWithPortProvider
-	 */
-	public function testGetDomainWithoutPort($hostWithPort, $host) {
-		$this->assertEquals($host, OC_Request::getDomainWithoutPort($hostWithPort));
-
-	}
-
-	/**
-	 * @dataProvider trustedDomainDataProvider
-	 */
-	public function testIsTrustedDomain($trustedDomains, $testDomain, $result) {
-		OC_Config::deleteKey('trusted_domains');
-		if ($trustedDomains !== null) {
-			OC_Config::setValue('trusted_domains', $trustedDomains);
-		}
-
-		$this->assertEquals($result, OC_Request::isTrustedDomain($testDomain));
-
-		// clean up
-		OC_Config::deleteKey('trusted_domains');
-	}
-
-	public function trustedDomainDataProvider() {
-		$trustedHostTestList = array('host.one.test', 'host.two.test', '[1fff:0:a88:85a3::ac1f]');
-		return array(
-			// empty defaults to true
-			array(null, 'host.one.test:8080', true),
-			array('', 'host.one.test:8080', true),
-			array(array(), 'host.one.test:8080', true),
-
-			// trust list when defined
-			array($trustedHostTestList, 'host.two.test:8080', true),
-			array($trustedHostTestList, 'host.two.test:9999', true),
-			array($trustedHostTestList, 'host.three.test:8080', false),
-			array($trustedHostTestList, 'host.two.test:8080:aa:222', false),
-			array($trustedHostTestList, '[1fff:0:a88:85a3::ac1f]', true),
-			array($trustedHostTestList, '[1fff:0:a88:85a3::ac1f]:801', true),
-			array($trustedHostTestList, '[1fff:0:a88:85a3::ac1f]:801:34', false),
-
-			// trust localhost regardless of trust list
-			array($trustedHostTestList, 'localhost', true),
-			array($trustedHostTestList, 'localhost:8080', true),
-			array($trustedHostTestList, '127.0.0.1', true),
-			array($trustedHostTestList, '127.0.0.1:8080', true),
-
-			// do not trust invalid localhosts
-			array($trustedHostTestList, 'localhost:1:2', false),
-			array($trustedHostTestList, 'localhost: evil.host', false),
-		);
-	}
-
-	public function testServerHost() {
-		OC_Config::deleteKey('overwritecondaddr');
-		OC_Config::setValue('overwritehost', 'overwritten.host:8080');
-		OC_Config::setValue(
-			'trusted_domains',
-			array(
-				'trusted.host:8080',
-				'second.trusted.host:8080'
-			)
-		);
-		$_SERVER['HTTP_HOST'] = 'trusted.host:8080';
-
-		// CLI always gives localhost
-		$oldCLI = OC::$CLI;
-		OC::$CLI = true;
-		$host = OC_Request::serverHost();
-		$this->assertEquals('localhost', $host);
-		OC::$CLI = false;
-
-		// overwritehost overrides trusted domain
-		$host = OC_Request::serverHost();
-		$this->assertEquals('overwritten.host:8080', $host);
-
-		// trusted domain returned when used
-		OC_Config::deleteKey('overwritehost');
-		$host = OC_Request::serverHost();
-		$this->assertEquals('trusted.host:8080', $host);
-
-		// trusted domain returned when untrusted one in header
-		$_SERVER['HTTP_HOST'] = 'untrusted.host:8080';
-		OC_Config::deleteKey('overwritehost');
-		$host = OC_Request::serverHost();
-		$this->assertEquals('trusted.host:8080', $host);
-
-		// clean up
-		OC_Config::deleteKey('overwritecondaddr');
-		OC_Config::deleteKey('overwritehost');
-		unset($_SERVER['HTTP_HOST']);
-		OC::$CLI = $oldCLI;
-	}
-}
diff --git a/tests/lib/security/trusteddomainhelper.php b/tests/lib/security/trusteddomainhelper.php
new file mode 100644
index 0000000000000000000000000000000000000000..c8d5ffa587bbd2390fabe21c4ac67207c86d607e
--- /dev/null
+++ b/tests/lib/security/trusteddomainhelper.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ * Copyright (c) 2015 Lukas Reschke <lukas@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+use \OC\Security\TrustedDomainHelper;
+use OCP\IConfig;
+
+/**
+ * Class TrustedDomainHelperTest
+ */
+class TrustedDomainHelperTest extends \Test\TestCase {
+	/** @var IConfig */
+	protected $config;
+
+	protected function setUp() {
+		parent::setUp();
+
+		$this->config = $this->getMockBuilder('\OCP\IConfig')->getMock();
+	}
+
+	/**
+	 * @dataProvider trustedDomainDataProvider
+	 * @param string $trustedDomains
+	 * @param string $testDomain
+	 * @param bool $result
+	 */
+	public function testIsTrustedDomain($trustedDomains, $testDomain, $result) {
+		$this->config->expects($this->once())
+			->method('getSystemValue')
+			->with('trusted_domains')
+			->will($this->returnValue($trustedDomains));
+
+		$trustedDomainHelper = new TrustedDomainHelper($this->config);
+		$this->assertEquals($result, $trustedDomainHelper->isTrustedDomain($testDomain));
+	}
+
+	/**
+	 * @return array
+	 */
+	public function trustedDomainDataProvider() {
+		$trustedHostTestList = ['host.one.test', 'host.two.test', '[1fff:0:a88:85a3::ac1f]'];
+		return [
+			// empty defaults to false with 8.1
+			[null, 'host.one.test:8080', false],
+			['', 'host.one.test:8080', false],
+			[[], 'host.one.test:8080', false],
+			// trust list when defined
+			[$trustedHostTestList, 'host.two.test:8080', true],
+			[$trustedHostTestList, 'host.two.test:9999', true],
+			[$trustedHostTestList, 'host.three.test:8080', false],
+			[$trustedHostTestList, 'host.two.test:8080:aa:222', false],
+			[$trustedHostTestList, '[1fff:0:a88:85a3::ac1f]', true],
+			[$trustedHostTestList, '[1fff:0:a88:85a3::ac1f]:801', true],
+			[$trustedHostTestList, '[1fff:0:a88:85a3::ac1f]:801:34', false],
+			// trust localhost regardless of trust list
+			[$trustedHostTestList, 'localhost', true],
+			[$trustedHostTestList, 'localhost:8080', true],
+			[$trustedHostTestList, '127.0.0.1', true],
+			[$trustedHostTestList, '127.0.0.1:8080', true],
+			// do not trust invalid localhosts
+			[$trustedHostTestList, 'localhost:1:2', false],
+			[$trustedHostTestList, 'localhost: evil.host', false],
+		];
+	}
+
+}
diff --git a/tests/lib/templatelayout.php b/tests/lib/templatelayout.php
index 1035dae122d90b966e5706c5d550c1ea2ab89411..c23aaa9b7626400af9aa78ee366098553eefe3c9 100644
--- a/tests/lib/templatelayout.php
+++ b/tests/lib/templatelayout.php
@@ -52,7 +52,7 @@ class OC_TemplateLayout extends \Test\TestCase {
 	 */
 	public function testConvertToRelativePath($absolutePath, $expected) {
 		$_SERVER['REQUEST_URI'] = $expected;
-		$_SERVER['SCRIPT_NAME'] = '/';
+		$_SERVER['SCRIPT_NAME'] = $expected;
 
 		$relativePath = \Test_Helper::invokePrivate(new \OC_TemplateLayout('user'), 'convertToRelativePath', array($absolutePath));
 		$this->assertEquals($expected, $relativePath);