diff --git a/apps/federatedfilesharing/lib/discoverymanager.php b/apps/federatedfilesharing/lib/discoverymanager.php
new file mode 100644
index 0000000000000000000000000000000000000000..51ea71195fa5c570e2052237330d5430ac0cfcdd
--- /dev/null
+++ b/apps/federatedfilesharing/lib/discoverymanager.php
@@ -0,0 +1,136 @@
+<?php
+/**
+ * @author Lukas Reschke <lukas@owncloud.com>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCA\FederatedFileSharing;
+
+use GuzzleHttp\Exception\ClientException;
+use GuzzleHttp\Exception\ConnectException;
+use OCP\Http\Client\IClient;
+use OCP\Http\Client\IClientService;
+use OCP\ICache;
+use OCP\ICacheFactory;
+
+/**
+ * Class DiscoveryManager handles the discovery of endpoints used by Federated
+ * Cloud Sharing.
+ *
+ * @package OCA\FederatedFileSharing
+ */
+class DiscoveryManager {
+	/** @var ICache */
+	private $cache;
+	/** @var IClient */
+	private $client;
+
+	/**
+	 * @param ICacheFactory $cacheFactory
+	 * @param IClientService $clientService
+	 */
+	public function __construct(ICacheFactory $cacheFactory,
+								IClientService $clientService) {
+		$this->cache = $cacheFactory->create('ocs-discovery');
+		$this->client = $clientService->newClient();
+	}
+
+	/**
+	 * Returns whether the specified URL includes only safe characters, if not
+	 * returns false
+	 *
+	 * @param string $url
+	 * @return bool
+	 */
+	private function isSafeUrl($url) {
+		return (bool)preg_match('/^[\/\.A-Za-z0-9]+$/', $url);
+	}
+
+	/**
+	 * Discover the actual data and do some naive caching to ensure that the data
+	 * is not requested multiple times.
+	 *
+	 * If no valid discovery data is found the ownCloud defaults are returned.
+	 *
+	 * @param string $remote
+	 * @return array
+	 */
+	private function discover($remote) {
+		// Check if something is in the cache
+		if($cacheData = $this->cache->get($remote)) {
+			return json_decode($cacheData, true);
+		}
+
+		// Default response body
+		$discoveredServices = [
+			'webdav' => '/public.php/webdav',
+			'share' => '/ocs/v1.php/cloud/shares',
+		];
+
+		// Read the data from the response body
+		try {
+			$response = $this->client->get($remote . '/ocs-provider/');
+			if($response->getStatusCode() === 200) {
+				$decodedService = json_decode($response->getBody(), true);
+				if(is_array($decodedService)) {
+					$endpoints = [
+						'webdav',
+						'share',
+					];
+
+					foreach($endpoints as $endpoint) {
+						if(isset($decodedService['services']['FEDERATED_SHARING']['endpoints'][$endpoint])) {
+							$endpointUrl = (string)$decodedService['services']['FEDERATED_SHARING']['endpoints'][$endpoint];
+							if($this->isSafeUrl($endpointUrl)) {
+								$discoveredServices[$endpoint] = $endpointUrl;
+							}
+						}
+					}
+				}
+			}
+		} catch (ClientException $e) {
+			// Don't throw any exception since exceptions are handled before
+		} catch (ConnectException $e) {
+			// Don't throw any exception since exceptions are handled before
+		}
+
+		// Write into cache
+		$this->cache->set($remote, json_encode($discoveredServices));
+		return $discoveredServices;
+	}
+
+	/**
+	 * Return the public WebDAV endpoint used by the specified remote
+	 *
+	 * @param string $host
+	 * @return string
+	 */
+	public function getWebDavEndpoint($host) {
+		return $this->discover($host)['webdav'];
+	}
+
+	/**
+	 * Return the sharing endpoint used by the specified remote
+	 *
+	 * @param string $host
+	 * @return string
+	 */
+	public function getShareEndpoint($host) {
+		return $this->discover($host)['share'];
+	}
+}
diff --git a/apps/federatedfilesharing/lib/notifications.php b/apps/federatedfilesharing/lib/notifications.php
index d778ac87828eeb63795b6b8d6b20a9484716ebcc..4ec21e81cc7602b35fee5577738c2c2f9044fec6 100644
--- a/apps/federatedfilesharing/lib/notifications.php
+++ b/apps/federatedfilesharing/lib/notifications.php
@@ -1,6 +1,7 @@
 <?php
 /**
  * @author Björn Schießle <schiessle@owncloud.com>
+ * @author Lukas Reschke <lukas@owncloud.com>
  *
  * @copyright Copyright (c) 2016, ownCloud, Inc.
  * @license AGPL-3.0
@@ -22,32 +23,31 @@
 
 namespace OCA\FederatedFileSharing;
 
-
 use OCP\Http\Client\IClientService;
 
 class Notifications {
-
-	const BASE_PATH_TO_SHARE_API = '/ocs/v1.php/cloud/shares';
 	const RESPONSE_FORMAT = 'json'; // default response format for ocs calls
 
 	/** @var AddressHandler */
 	private $addressHandler;
-
 	/** @var IClientService */
 	private $httpClientService;
+	/** @var DiscoveryManager */
+	private $discoveryManager;
 
 	/**
-	 * Notifications constructor.
-	 *
 	 * @param AddressHandler $addressHandler
 	 * @param IClientService $httpClientService
+	 * @param DiscoveryManager $discoveryManager
 	 */
 	public function __construct(
 		AddressHandler $addressHandler,
-		IClientService $httpClientService
+		IClientService $httpClientService,
+		DiscoveryManager $discoveryManager
 	) {
 		$this->addressHandler = $addressHandler;
 		$this->httpClientService = $httpClientService;
+		$this->discoveryManager = $discoveryManager;
 	}
 
 	/**
@@ -65,7 +65,7 @@ class Notifications {
 		list($user, $remote) = $this->addressHandler->splitUserRemote($shareWith);
 
 		if ($user && $remote) {
-			$url = $remote . self::BASE_PATH_TO_SHARE_API . '?format=' . self::RESPONSE_FORMAT;
+			$url = $remote;
 			$local = $this->addressHandler->generateRemoteURL();
 
 			$fields = array(
@@ -78,10 +78,10 @@ class Notifications {
 			);
 
 			$url = $this->addressHandler->removeProtocolFromUrl($url);
-			$result = $this->tryHttpPost($url, $fields);
+			$result = $this->tryHttpPostToShareEndpoint($url, '', $fields);
 			$status = json_decode($result['result'], true);
 
-			if ($result['success'] && $status['ocs']['meta']['statuscode'] === 100) {
+			if ($result['success'] && ($status['ocs']['meta']['statuscode'] === 100 || $status['ocs']['meta']['statuscode'] === 200)) {
 				\OC_Hook::emit('OCP\Share', 'federated_share_added', ['server' => $remote]);
 				return true;
 			}
@@ -100,23 +100,24 @@ class Notifications {
 	 * @return bool
 	 */
 	public function sendRemoteUnShare($remote, $id, $token) {
-		$url = rtrim($remote, '/') . self::BASE_PATH_TO_SHARE_API . '/' . $id . '/unshare?format=' . self::RESPONSE_FORMAT;
+		$url = rtrim($remote, '/');
 		$fields = array('token' => $token, 'format' => 'json');
 		$url = $this->addressHandler->removeProtocolFromUrl($url);
-		$result = $this->tryHttpPost($url, $fields);
+		$result = $this->tryHttpPostToShareEndpoint($url, '/'.$id.'/unshare', $fields);
 		$status = json_decode($result['result'], true);
 
-		return ($result['success'] && $status['ocs']['meta']['statuscode'] === 100);
+		return ($result['success'] && ($status['ocs']['meta']['statuscode'] === 100 || $status['ocs']['meta']['statuscode'] === 200));
 	}
 
 	/**
 	 * try http post first with https and then with http as a fallback
 	 *
-	 * @param string $url
+	 * @param string $remoteDomain
+	 * @param string $urlSuffix
 	 * @param array $fields post parameters
 	 * @return array
 	 */
-	private function tryHttpPost($url, array $fields) {
+	private function tryHttpPostToShareEndpoint($remoteDomain, $urlSuffix, array $fields) {
 		$client = $this->httpClientService->newClient();
 		$protocol = 'https://';
 		$result = [
@@ -124,9 +125,11 @@ class Notifications {
 			'result' => '',
 		];
 		$try = 0;
+
 		while ($result['success'] === false && $try < 2) {
+			$endpoint = $this->discoveryManager->getShareEndpoint($protocol . $remoteDomain);
 			try {
-				$response = $client->post($protocol . $url, [
+				$response = $client->post($protocol . $remoteDomain . $endpoint . $urlSuffix . '?format=' . self::RESPONSE_FORMAT, [
 					'body' => $fields
 				]);
 				$result['result'] = $response->getBody();
@@ -140,5 +143,4 @@ class Notifications {
 
 		return $result;
 	}
-
 }
diff --git a/apps/federatedfilesharing/tests/DiscoveryManagerTest.php b/apps/federatedfilesharing/tests/DiscoveryManagerTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..9ae62b1ae4da374609ffcfffc759a4c9ef4b1a06
--- /dev/null
+++ b/apps/federatedfilesharing/tests/DiscoveryManagerTest.php
@@ -0,0 +1,194 @@
+<?php
+/**
+ * @author Lukas Reschke <lukas@owncloud.com>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCA\FederatedFileSharing\Tests;
+
+use OCA\FederatedFileSharing\DiscoveryManager;
+use OCP\Http\Client\IClient;
+use OCP\Http\Client\IClientService;
+use OCP\ICache;
+use OCP\ICacheFactory;
+use Test\TestCase;
+
+class DiscoveryManagerTest extends TestCase {
+	/** @var ICache */
+	private $cache;
+	/** @var IClient */
+	private $client;
+	/** @var DiscoveryManager */
+	private $discoveryManager;
+
+	public function setUp() {
+		parent::setUp();
+		$this->cache = $this->getMock('\OCP\ICache');
+		/** @var ICacheFactory $cacheFactory */
+		$cacheFactory = $this->getMockBuilder('\OCP\ICacheFactory')
+			->disableOriginalConstructor()->getMock();
+		$cacheFactory
+			->expects($this->once())
+			->method('create')
+			->with('ocs-discovery')
+			->willReturn($this->cache);
+
+		$this->client = $this->getMockBuilder('\OCP\Http\Client\IClient')
+			->disableOriginalConstructor()->getMock();
+		/** @var IClientService $clientService */
+		$clientService = $this->getMockBuilder('\OCP\Http\Client\IClientService')
+			->disableOriginalConstructor()->getMock();
+		$clientService
+			->expects($this->once())
+			->method('newClient')
+			->willReturn($this->client);
+
+		$this->discoveryManager = new DiscoveryManager(
+			$cacheFactory,
+			$clientService
+		);
+	}
+
+	public function testWithMalformedFormattedEndpointCached() {
+		$response = $this->getMock('\OCP\Http\Client\IResponse');
+		$response
+			->expects($this->once())
+			->method('getStatusCode')
+			->willReturn(200);
+		$response
+			->expects($this->once())
+			->method('getBody')
+			->willReturn('CertainlyNotJson');
+		$this->client
+			->expects($this->once())
+			->method('get')
+			->with('https://myhost.com/ocs-provider/', [])
+			->willReturn($response);
+		$this->cache
+			->expects($this->at(0))
+			->method('get')
+			->with('https://myhost.com')
+			->willReturn(null);
+		$this->cache
+			->expects($this->at(1))
+			->method('set')
+			->with('https://myhost.com', '{"webdav":"\/public.php\/webdav","share":"\/ocs\/v1.php\/cloud\/shares"}');
+		$this->cache
+			->expects($this->at(2))
+			->method('get')
+			->with('https://myhost.com')
+			->willReturn('{"webdav":"\/public.php\/webdav","share":"\/ocs\/v1.php\/cloud\/shares"}');
+
+		$this->assertSame('/public.php/webdav', $this->discoveryManager->getWebDavEndpoint('https://myhost.com'));
+		$this->assertSame('/ocs/v1.php/cloud/shares', $this->discoveryManager->getShareEndpoint('https://myhost.com'));
+	}
+
+	public function testGetWebDavEndpointWithValidFormattedEndpointAndNotCached() {
+		$response = $this->getMock('\OCP\Http\Client\IResponse');
+		$response
+			->expects($this->once())
+			->method('getStatusCode')
+			->willReturn(200);
+		$response
+			->expects($this->once())
+			->method('getBody')
+			->willReturn('{"version":2,"services":{"PRIVATE_DATA":{"version":1,"endpoints":{"store":"\/ocs\/v2.php\/privatedata\/setattribute","read":"\/ocs\/v2.php\/privatedata\/getattribute","delete":"\/ocs\/v2.php\/privatedata\/deleteattribute"}},"SHARING":{"version":1,"endpoints":{"share":"\/ocs\/v2.php\/apps\/files_sharing\/api\/v1\/shares"}},"FEDERATED_SHARING":{"version":1,"endpoints":{"share":"\/ocs\/v2.php\/cloud\/shares","webdav":"\/public.php\/MyCustomEndpoint\/"}},"ACTIVITY":{"version":1,"endpoints":{"list":"\/ocs\/v2.php\/cloud\/activity"}},"PROVISIONING":{"version":1,"endpoints":{"user":"\/ocs\/v2.php\/cloud\/users","groups":"\/ocs\/v2.php\/cloud\/groups","apps":"\/ocs\/v2.php\/cloud\/apps"}}}}');
+		$this->client
+			->expects($this->once())
+			->method('get')
+			->with('https://myhost.com/ocs-provider/', [])
+			->willReturn($response);
+
+		$expectedResult = '/public.php/MyCustomEndpoint/';
+		$this->assertSame($expectedResult, $this->discoveryManager->getWebDavEndpoint('https://myhost.com'));
+	}
+
+	public function testGetWebDavEndpointWithValidFormattedEndpointWithoutDataAndNotCached() {
+		$response = $this->getMock('\OCP\Http\Client\IResponse');
+		$response
+			->expects($this->once())
+			->method('getStatusCode')
+			->willReturn(200);
+		$response
+			->expects($this->once())
+			->method('getBody')
+			->willReturn('{"version":2,"PRIVATE_DATA":{"version":1,"endpoints":{"store":"\/ocs\/v2.php\/privatedata\/setattribute","read":"\/ocs\/v2.php\/privatedata\/getattribute","delete":"\/ocs\/v2.php\/privatedata\/deleteattribute"}},"SHARING":{"version":1,"endpoints":{"share":"\/ocs\/v2.php\/apps\/files_sharing\/api\/v1\/shares"}},"FEDERATED_SHARING":{"version":1,"endpoints":{"share":"\/ocs\/v2.php\/cloud\/shares","webdav":"\/public.php\/MyCustomEndpoint\/"}},"ACTIVITY":{"version":1,"endpoints":{"list":"\/ocs\/v2.php\/cloud\/activity"}},"PROVISIONING":{"version":1,"endpoints":{"user":"\/ocs\/v2.php\/cloud\/users","groups":"\/ocs\/v2.php\/cloud\/groups","apps":"\/ocs\/v2.php\/cloud\/apps"}}}');
+		$this->client
+			->expects($this->once())
+			->method('get')
+			->with('https://myhost.com/ocs-provider/', [])
+			->willReturn($response);
+
+		$expectedResult = '/public.php/webdav';
+		$this->assertSame($expectedResult, $this->discoveryManager->getWebDavEndpoint('https://myhost.com'));
+	}
+
+	public function testGetShareEndpointWithValidFormattedEndpointAndNotCached() {
+		$response = $this->getMock('\OCP\Http\Client\IResponse');
+		$response
+			->expects($this->once())
+			->method('getStatusCode')
+			->willReturn(200);
+		$response
+			->expects($this->once())
+			->method('getBody')
+			->willReturn('{"version":2,"services":{"PRIVATE_DATA":{"version":1,"endpoints":{"store":"\/ocs\/v2.php\/privatedata\/setattribute","read":"\/ocs\/v2.php\/privatedata\/getattribute","delete":"\/ocs\/v2.php\/privatedata\/deleteattribute"}},"SHARING":{"version":1,"endpoints":{"share":"\/ocs\/v2.php\/apps\/files_sharing\/api\/v1\/shares"}},"FEDERATED_SHARING":{"version":1,"endpoints":{"share":"\/ocs\/v2.php\/cloud\/MyCustomShareEndpoint","webdav":"\/public.php\/MyCustomEndpoint\/"}},"ACTIVITY":{"version":1,"endpoints":{"list":"\/ocs\/v2.php\/cloud\/activity"}},"PROVISIONING":{"version":1,"endpoints":{"user":"\/ocs\/v2.php\/cloud\/users","groups":"\/ocs\/v2.php\/cloud\/groups","apps":"\/ocs\/v2.php\/cloud\/apps"}}}}');
+		$this->client
+			->expects($this->once())
+			->method('get')
+			->with('https://myhost.com/ocs-provider/', [])
+			->willReturn($response);
+
+		$expectedResult = '/ocs/v2.php/cloud/MyCustomShareEndpoint';
+		$this->assertSame($expectedResult, $this->discoveryManager->getShareEndpoint('https://myhost.com'));
+	}
+
+	public function testWithMaliciousEndpointCached() {
+		$response = $this->getMock('\OCP\Http\Client\IResponse');
+		$response
+			->expects($this->once())
+			->method('getStatusCode')
+			->willReturn(200);
+		$response
+			->expects($this->once())
+			->method('getBody')
+			->willReturn('{"version":2,"services":{"PRIVATE_DATA":{"version":1,"endpoints":{"store":"\/ocs\/v2.php\/privatedata\/setattribute","read":"\/ocs\/v2.php\/privatedata\/getattribute","delete":"\/ocs\/v2.php\/privatedata\/deleteattribute"}},"SHARING":{"version":1,"endpoints":{"share":"\/ocs\/v2.php\/apps\/files_sharing\/api\/v1\/shares"}},"FEDERATED_SHARING":{"version":1,"endpoints":{"share":"\/ocs\/v2.php\/cl@oud\/MyCustomShareEndpoint","webdav":"\/public.php\/MyC:ustomEndpoint\/"}},"ACTIVITY":{"version":1,"endpoints":{"list":"\/ocs\/v2.php\/cloud\/activity"}},"PROVISIONING":{"version":1,"endpoints":{"user":"\/ocs\/v2.php\/cloud\/users","groups":"\/ocs\/v2.php\/cloud\/groups","apps":"\/ocs\/v2.php\/cloud\/apps"}}}}');
+		$this->client
+			->expects($this->once())
+			->method('get')
+			->with('https://myhost.com/ocs-provider/', [])
+			->willReturn($response);
+		$this->cache
+			->expects($this->at(0))
+			->method('get')
+			->with('https://myhost.com')
+			->willReturn(null);
+		$this->cache
+			->expects($this->at(1))
+			->method('set')
+			->with('https://myhost.com', '{"webdav":"\/public.php\/webdav","share":"\/ocs\/v1.php\/cloud\/shares"}');
+		$this->cache
+			->expects($this->at(2))
+			->method('get')
+			->with('https://myhost.com')
+			->willReturn('{"webdav":"\/public.php\/webdav","share":"\/ocs\/v1.php\/cloud\/shares"}');
+
+		$this->assertSame('/public.php/webdav', $this->discoveryManager->getWebDavEndpoint('https://myhost.com'));
+		$this->assertSame('/ocs/v1.php/cloud/shares', $this->discoveryManager->getShareEndpoint('https://myhost.com'));
+	}
+}
diff --git a/apps/files_sharing/ajax/external.php b/apps/files_sharing/ajax/external.php
index 1efe4356b4c7ad28b53f55326b35a0eb60e7ce06..76f9d5d76681afc91d657cb72202c17285092d4b 100644
--- a/apps/files_sharing/ajax/external.php
+++ b/apps/files_sharing/ajax/external.php
@@ -57,13 +57,17 @@ if (\OC\Share\Helper::isSameUserOnSameServer($owner, $remote, $currentUser, $cur
 	exit();
 }
 
-
+$discoveryManager = new \OCA\FederatedFileSharing\DiscoveryManager(
+	\OC::$server->getMemCacheFactory(),
+	\OC::$server->getHTTPClientService()
+);
 $externalManager = new \OCA\Files_Sharing\External\Manager(
 		\OC::$server->getDatabaseConnection(),
 		\OC\Files\Filesystem::getMountManager(),
 		\OC\Files\Filesystem::getLoader(),
 		\OC::$server->getHTTPHelper(),
 		\OC::$server->getNotificationManager(),
+		$discoveryManager,
 		\OC::$server->getUserSession()->getUser()->getUID()
 );
 
diff --git a/apps/files_sharing/api/remote.php b/apps/files_sharing/api/remote.php
index 8b47955b51ec4c36ef682af72c020831c280dfc2..1b5eb28aa86028efd112e92bfc11d1f5d547caed 100644
--- a/apps/files_sharing/api/remote.php
+++ b/apps/files_sharing/api/remote.php
@@ -24,6 +24,7 @@
 namespace OCA\Files_Sharing\API;
 
 use OC\Files\Filesystem;
+use OCA\FederatedFileSharing\DiscoveryManager;
 use OCA\Files_Sharing\External\Manager;
 
 class Remote {
@@ -35,12 +36,17 @@ class Remote {
 	 * @return \OC_OCS_Result
 	 */
 	public static function getOpenShares($params) {
+		$discoveryManager = new DiscoveryManager(
+			\OC::$server->getMemCacheFactory(),
+			\OC::$server->getHTTPClientService()
+		);
 		$externalManager = new Manager(
 			\OC::$server->getDatabaseConnection(),
 			Filesystem::getMountManager(),
 			Filesystem::getLoader(),
 			\OC::$server->getHTTPHelper(),
 			\OC::$server->getNotificationManager(),
+			$discoveryManager,
 			\OC_User::getUser()
 		);
 
@@ -54,12 +60,17 @@ class Remote {
 	 * @return \OC_OCS_Result
 	 */
 	public static function acceptShare($params) {
+		$discoveryManager = new DiscoveryManager(
+			\OC::$server->getMemCacheFactory(),
+			\OC::$server->getHTTPClientService()
+		);
 		$externalManager = new Manager(
 			\OC::$server->getDatabaseConnection(),
 			Filesystem::getMountManager(),
 			Filesystem::getLoader(),
 			\OC::$server->getHTTPHelper(),
 			\OC::$server->getNotificationManager(),
+			$discoveryManager,
 			\OC_User::getUser()
 		);
 
@@ -80,12 +91,17 @@ class Remote {
 	 * @return \OC_OCS_Result
 	 */
 	public static function declineShare($params) {
+		$discoveryManager = new DiscoveryManager(
+			\OC::$server->getMemCacheFactory(),
+			\OC::$server->getHTTPClientService()
+		);
 		$externalManager = new Manager(
 			\OC::$server->getDatabaseConnection(),
 			Filesystem::getMountManager(),
 			Filesystem::getLoader(),
 			\OC::$server->getHTTPHelper(),
 			\OC::$server->getNotificationManager(),
+			$discoveryManager,
 			\OC_User::getUser()
 		);
 
@@ -123,12 +139,17 @@ class Remote {
 	 * @return \OC_OCS_Result
 	 */
 	public static function getShares($params) {
+		$discoveryManager = new DiscoveryManager(
+			\OC::$server->getMemCacheFactory(),
+			\OC::$server->getHTTPClientService()
+		);
 		$externalManager = new Manager(
 			\OC::$server->getDatabaseConnection(),
 			Filesystem::getMountManager(),
 			Filesystem::getLoader(),
 			\OC::$server->getHTTPHelper(),
 			\OC::$server->getNotificationManager(),
+			$discoveryManager,
 			\OC_User::getUser()
 		);
 
@@ -146,12 +167,17 @@ class Remote {
 	 * @return \OC_OCS_Result
 	 */
 	public static function getShare($params) {
+		$discoveryManager = new DiscoveryManager(
+			\OC::$server->getMemCacheFactory(),
+			\OC::$server->getHTTPClientService()
+		);
 		$externalManager = new Manager(
 			\OC::$server->getDatabaseConnection(),
 			Filesystem::getMountManager(),
 			Filesystem::getLoader(),
 			\OC::$server->getHTTPHelper(),
 			\OC::$server->getNotificationManager(),
+			$discoveryManager,
 			\OC_User::getUser()
 		);
 
@@ -172,12 +198,17 @@ class Remote {
 	 * @return \OC_OCS_Result
 	 */
 	public static function unshare($params) {
+		$discoveryManager = new DiscoveryManager(
+			\OC::$server->getMemCacheFactory(),
+			\OC::$server->getHTTPClientService()
+		);
 		$externalManager = new Manager(
 			\OC::$server->getDatabaseConnection(),
 			Filesystem::getMountManager(),
 			Filesystem::getLoader(),
 			\OC::$server->getHTTPHelper(),
 			\OC::$server->getNotificationManager(),
+			$discoveryManager,
 			\OC_User::getUser()
 		);
 
diff --git a/apps/files_sharing/api/server2server.php b/apps/files_sharing/api/server2server.php
index f04ddc81b84c6a8b1c298e7ad41d71ae63d2ac57..6da95ed654908895db111a3427bff5be0d0b0774 100644
--- a/apps/files_sharing/api/server2server.php
+++ b/apps/files_sharing/api/server2server.php
@@ -25,6 +25,7 @@
 
 namespace OCA\Files_Sharing\API;
 
+use OCA\FederatedFileSharing\DiscoveryManager;
 use OCA\Files_Sharing\Activity;
 use OCP\Files\NotFoundException;
 
@@ -70,12 +71,17 @@ class Server2Server {
 
 			\OC_Util::setupFS($shareWith);
 
+			$discoveryManager = new DiscoveryManager(
+				\OC::$server->getMemCacheFactory(),
+				\OC::$server->getHTTPClientService()
+			);
 			$externalManager = new \OCA\Files_Sharing\External\Manager(
 					\OC::$server->getDatabaseConnection(),
 					\OC\Files\Filesystem::getMountManager(),
 					\OC\Files\Filesystem::getLoader(),
 					\OC::$server->getHTTPHelper(),
 					\OC::$server->getNotificationManager(),
+					$discoveryManager,
 					$shareWith
 				);
 
diff --git a/apps/files_sharing/appinfo/application.php b/apps/files_sharing/appinfo/application.php
index e4a2262fece31732e05b3e2e6d079d2dcb5e072c..64c7517456d4e1b86b8f48c1d9db86e7246fc7c8 100644
--- a/apps/files_sharing/appinfo/application.php
+++ b/apps/files_sharing/appinfo/application.php
@@ -24,6 +24,7 @@
 
 namespace OCA\Files_Sharing\AppInfo;
 
+use OCA\FederatedFileSharing\DiscoveryManager;
 use OCA\Files_Sharing\MountProvider;
 use OCP\AppFramework\App;
 use OC\AppFramework\Utility\SimpleContainer;
@@ -76,12 +77,17 @@ class Application extends App {
 		$container->registerService('ExternalManager', function (SimpleContainer $c) use ($server) {
 			$user = $server->getUserSession()->getUser();
 			$uid = $user ? $user->getUID() : null;
+			$discoveryManager = new DiscoveryManager(
+				\OC::$server->getMemCacheFactory(),
+				\OC::$server->getHTTPClientService()
+			);
 			return new \OCA\Files_Sharing\External\Manager(
 				$server->getDatabaseConnection(),
 				\OC\Files\Filesystem::getMountManager(),
 				\OC\Files\Filesystem::getLoader(),
 				$server->getHTTPHelper(),
 				$server->getNotificationManager(),
+				$discoveryManager,
 				$uid
 			);
 		});
diff --git a/apps/files_sharing/lib/external/manager.php b/apps/files_sharing/lib/external/manager.php
index 84de1da69f6bee94ba0b9e69e8951c23991d574f..ec487449625b1de03ccded99aa1913bfb2e3b8c0 100644
--- a/apps/files_sharing/lib/external/manager.php
+++ b/apps/files_sharing/lib/external/manager.php
@@ -27,6 +27,7 @@
 namespace OCA\Files_Sharing\External;
 
 use OC\Files\Filesystem;
+use OCA\FederatedFileSharing\DiscoveryManager;
 use OCP\Files;
 use OCP\Notification\IManager;
 
@@ -62,6 +63,8 @@ class Manager {
 	 * @var IManager
 	 */
 	private $notificationManager;
+	/** @var DiscoveryManager */
+	private $discoveryManager;
 
 	/**
 	 * @param \OCP\IDBConnection $connection
@@ -69,16 +72,23 @@ class Manager {
 	 * @param \OCP\Files\Storage\IStorageFactory $storageLoader
 	 * @param \OC\HTTPHelper $httpHelper
 	 * @param IManager $notificationManager
+	 * @param DiscoveryManager $discoveryManager
 	 * @param string $uid
 	 */
-	public function __construct(\OCP\IDBConnection $connection, \OC\Files\Mount\Manager $mountManager,
-								\OCP\Files\Storage\IStorageFactory $storageLoader, \OC\HTTPHelper $httpHelper, IManager $notificationManager, $uid) {
+	public function __construct(\OCP\IDBConnection $connection,
+								\OC\Files\Mount\Manager $mountManager,
+								\OCP\Files\Storage\IStorageFactory $storageLoader,
+								\OC\HTTPHelper $httpHelper,
+								IManager $notificationManager,
+								DiscoveryManager $discoveryManager,
+								$uid) {
 		$this->connection = $connection;
 		$this->mountManager = $mountManager;
 		$this->storageLoader = $storageLoader;
 		$this->httpHelper = $httpHelper;
 		$this->uid = $uid;
 		$this->notificationManager = $notificationManager;
+		$this->discoveryManager = $discoveryManager;
 	}
 
 	/**
@@ -246,13 +256,13 @@ class Manager {
 	 */
 	private function sendFeedbackToRemote($remote, $token, $remoteId, $feedback) {
 
-		$url = rtrim($remote, '/') . \OCP\Share::BASE_PATH_TO_SHARE_API . '/' . $remoteId . '/' . $feedback . '?format=' . \OCP\Share::RESPONSE_FORMAT;
+		$url = rtrim($remote, '/') . $this->discoveryManager->getShareEndpoint($remote) . '/' . $remoteId . '/' . $feedback . '?format=' . \OCP\Share::RESPONSE_FORMAT;
 		$fields = array('token' => $token);
 
 		$result = $this->httpHelper->post($url, $fields);
 		$status = json_decode($result['result'], true);
 
-		return ($result['success'] && $status['ocs']['meta']['statuscode'] === 100);
+		return ($result['success'] && ($status['ocs']['meta']['statuscode'] === 100 || $status['ocs']['meta']['statuscode'] === 200));
 	}
 
 	/**
diff --git a/apps/files_sharing/lib/external/storage.php b/apps/files_sharing/lib/external/storage.php
index ed391f331ade9fada671d4adc5931ef1b457c381..41f7bef589b3468d2c5def7fec6607767a7e17f4 100644
--- a/apps/files_sharing/lib/external/storage.php
+++ b/apps/files_sharing/lib/external/storage.php
@@ -67,6 +67,11 @@ class Storage extends DAV implements ISharedStorage {
 	private $manager;
 
 	public function __construct($options) {
+		$discoveryManager = new DiscoveryManager(
+			\OC::$server->getMemCacheFactory(),
+			\OC::$server->getHTTPClientService()
+		);
+
 		$this->manager = $options['manager'];
 		$this->certificateManager = $options['certificateManager'];
 		$this->remote = $options['remote'];
@@ -79,7 +84,7 @@ class Storage extends DAV implements ISharedStorage {
 			$root = '';
 		}
 		$secure = $protocol === 'https';
-		$root = rtrim($root, '/') . '/public.php/webdav';
+		$root = rtrim($root, '/') . $discoveryManager->getWebDavEndpoint($this->remote);
 		$this->mountPoint = $options['mountpoint'];
 		$this->token = $options['token'];
 		parent::__construct(array(
diff --git a/apps/files_sharing/lib/hooks.php b/apps/files_sharing/lib/hooks.php
index 166905b9aa487085d946ce834b40f7e6c1204145..e3f24d02268eed302025ad76baf51d1ecf8a5b88 100644
--- a/apps/files_sharing/lib/hooks.php
+++ b/apps/files_sharing/lib/hooks.php
@@ -25,16 +25,22 @@
 namespace OCA\Files_Sharing;
 
 use OC\Files\Filesystem;
+use OCA\FederatedFileSharing\DiscoveryManager;
 
 class Hooks {
 
 	public static function deleteUser($params) {
+		$discoveryManager = new DiscoveryManager(
+			\OC::$server->getMemCacheFactory(),
+			\OC::$server->getHTTPClientService()
+		);
 		$manager = new External\Manager(
 			\OC::$server->getDatabaseConnection(),
 			\OC\Files\Filesystem::getMountManager(),
 			\OC\Files\Filesystem::getLoader(),
 			\OC::$server->getHTTPHelper(),
 			\OC::$server->getNotificationManager(),
+			$discoveryManager,
 			$params['uid']);
 
 		$manager->removeUserShares($params['uid']);
diff --git a/apps/files_sharing/tests/external/managertest.php b/apps/files_sharing/tests/external/managertest.php
index f73fedaf05cb6eaabed57ddac6f7b37ae49a6692..2836a3dc024a44f4d4f2e9314cc58d0c52e2a8f9 100644
--- a/apps/files_sharing/tests/external/managertest.php
+++ b/apps/files_sharing/tests/external/managertest.php
@@ -24,6 +24,7 @@
 namespace OCA\Files_Sharing\Tests\External;
 
 use OC\Files\Storage\StorageFactory;
+use OCA\FederatedFileSharing\DiscoveryManager;
 use OCA\Files_Sharing\External\Manager;
 use OCA\Files_Sharing\External\MountProvider;
 use OCA\Files_Sharing\Tests\TestCase;
@@ -64,6 +65,10 @@ class ManagerTest extends TestCase {
 		$this->user = \OC::$server->getUserManager()->get($this->uid);
 		$this->mountManager = new \OC\Files\Mount\Manager();
 		$this->httpHelper = $httpHelper = $this->getMockBuilder('\OC\HTTPHelper')->disableOriginalConstructor()->getMock();
+		$discoveryManager = new DiscoveryManager(
+			\OC::$server->getMemCacheFactory(),
+			\OC::$server->getHTTPClientService()
+		);
 		/** @var \OC\HTTPHelper $httpHelper */
 		$this->manager = new Manager(
 			\OC::$server->getDatabaseConnection(),
@@ -71,6 +76,7 @@ class ManagerTest extends TestCase {
 			new StorageFactory(),
 			$httpHelper,
 			\OC::$server->getNotificationManager(),
+			$discoveryManager,
 			$this->uid
 		);
 		$this->mountProvider = new MountProvider(\OC::$server->getDatabaseConnection(), function() {
diff --git a/apps/files_sharing/tests/server2server.php b/apps/files_sharing/tests/server2server.php
index a282f92ecb94030418b953342284d089968df40d..298f1008f712a4921b90fdb5d501c6bbfcf4ce8a 100644
--- a/apps/files_sharing/tests/server2server.php
+++ b/apps/files_sharing/tests/server2server.php
@@ -153,14 +153,19 @@ class Test_Files_Sharing_S2S_OCS_API extends TestCase {
 	function testDeleteUser($toDelete, $expected, $remainingUsers) {
 		$this->createDummyS2SShares();
 
+		$discoveryManager = new \OCA\FederatedFileSharing\DiscoveryManager(
+			\OC::$server->getMemCacheFactory(),
+			\OC::$server->getHTTPClientService()
+		);
 		$manager = new OCA\Files_Sharing\External\Manager(
 			\OC::$server->getDatabaseConnection(),
 			\OC\Files\Filesystem::getMountManager(),
 			\OC\Files\Filesystem::getLoader(),
 			\OC::$server->getHTTPHelper(),
 			\OC::$server->getNotificationManager(),
+			$discoveryManager,
 			$toDelete
-			);
+		);
 
 		$manager->removeUserShares($toDelete);
 
diff --git a/lib/private/share/constants.php b/lib/private/share/constants.php
index e2b87d72476e849719d3f131958f89d8a4dff89c..e60eb98832b5389e77a583088fa2710e68dd1bf8 100644
--- a/lib/private/share/constants.php
+++ b/lib/private/share/constants.php
@@ -40,8 +40,6 @@ class Constants {
 
 	const TOKEN_LENGTH = 15; // old (oc7) length is 32, keep token length in db at least that for compatibility
 
-	const BASE_PATH_TO_SHARE_API = '/ocs/v1.php/cloud/shares';
-
 	protected static $shareTypeUserAndGroups = -1;
 	protected static $shareTypeGroupUserUnique = 2;
 	protected static $backends = array();
diff --git a/lib/private/share/share.php b/lib/private/share/share.php
index 149dd082bbcdc913efe44a7a484d8ac43bf4c6f4..4453e3758ba5266bcb850b9afd9717326044fc13 100644
--- a/lib/private/share/share.php
+++ b/lib/private/share/share.php
@@ -38,6 +38,7 @@
 namespace OC\Share;
 
 use OC\Files\Filesystem;
+use OCA\FederatedFileSharing\DiscoveryManager;
 use OCP\DB\QueryBuilder\IQueryBuilder;
 use OCP\IUserSession;
 use OCP\IDBConnection;
@@ -2620,19 +2621,25 @@ class Share extends Constants {
 	/**
 	 * try http post first with https and then with http as a fallback
 	 *
-	 * @param string $url
+	 * @param string $remoteDomain
+	 * @param string $urlSuffix
 	 * @param array $fields post parameters
 	 * @return array
 	 */
-	private static function tryHttpPost($url, $fields) {
+	private static function tryHttpPostToShareEndpoint($remoteDomain, $urlSuffix, array $fields) {
 		$protocol = 'https://';
 		$result = [
 			'success' => false,
 			'result' => '',
 		];
 		$try = 0;
+		$discoveryManager = new DiscoveryManager(
+			\OC::$server->getMemCacheFactory(),
+			\OC::$server->getHTTPClientService()
+		);
 		while ($result['success'] === false && $try < 2) {
-			$result = \OC::$server->getHTTPHelper()->post($protocol . $url, $fields);
+			$endpoint = $discoveryManager->getShareEndpoint($protocol . $remoteDomain);
+			$result = \OC::$server->getHTTPHelper()->post($protocol . $remoteDomain . $endpoint . $urlSuffix . '?format=' . self::RESPONSE_FORMAT, $fields);
 			$try++;
 			$protocol = 'http://';
 		}
@@ -2655,7 +2662,7 @@ class Share extends Constants {
 		list($user, $remote) = Helper::splitUserRemote($shareWith);
 
 		if ($user && $remote) {
-			$url = $remote . self::BASE_PATH_TO_SHARE_API . '?format=' . self::RESPONSE_FORMAT;
+			$url = $remote;
 
 			$local = \OC::$server->getURLGenerator()->getAbsoluteURL('/');
 
@@ -2669,10 +2676,10 @@ class Share extends Constants {
 			);
 
 			$url = self::removeProtocolFromUrl($url);
-			$result = self::tryHttpPost($url, $fields);
+			$result = self::tryHttpPostToShareEndpoint($url, '', $fields);
 			$status = json_decode($result['result'], true);
 
-			if ($result['success'] && $status['ocs']['meta']['statuscode'] === 100) {
+			if ($result['success'] && ($status['ocs']['meta']['statuscode'] === 100 || $status['ocs']['meta']['statuscode'] === 200)) {
 				\OC_Hook::emit('OCP\Share', 'federated_share_added', ['server' => $remote]);
 				return true;
 			}
@@ -2691,13 +2698,13 @@ class Share extends Constants {
 	 * @return bool
 	 */
 	private static function sendRemoteUnshare($remote, $id, $token) {
-		$url = rtrim($remote, '/') . self::BASE_PATH_TO_SHARE_API . '/' . $id . '/unshare?format=' . self::RESPONSE_FORMAT;
+		$url = rtrim($remote, '/');
 		$fields = array('token' => $token, 'format' => 'json');
 		$url = self::removeProtocolFromUrl($url);
-		$result = self::tryHttpPost($url, $fields);
+		$result = self::tryHttpPostToShareEndpoint($url, '/'.$id.'/unshare', $fields);
 		$status = json_decode($result['result'], true);
 
-		return ($result['success'] && $status['ocs']['meta']['statuscode'] === 100);
+		return ($result['success'] && ($status['ocs']['meta']['statuscode'] === 100 || $status['ocs']['meta']['statuscode'] === 200));
 	}
 
 	/**
diff --git a/lib/private/share20/providerfactory.php b/lib/private/share20/providerfactory.php
index bb440d2e01f3ba6750859dc330015542fc2f5db1..c2980b2251573892c3bc0e59cff3fb7dfa1abee3 100644
--- a/lib/private/share20/providerfactory.php
+++ b/lib/private/share20/providerfactory.php
@@ -21,6 +21,7 @@
 namespace OC\Share20;
 
 use OCA\FederatedFileSharing\AddressHandler;
+use OCA\FederatedFileSharing\DiscoveryManager;
 use OCA\FederatedFileSharing\FederatedShareProvider;
 use OCA\FederatedFileSharing\Notifications;
 use OCA\FederatedFileSharing\TokenHandler;
@@ -91,9 +92,14 @@ class ProviderFactory implements IProviderFactory {
 				$this->serverContainer->getURLGenerator(),
 				$l
 			);
+			$discoveryManager = new DiscoveryManager(
+				$this->serverContainer->getMemCacheFactory(),
+				$this->serverContainer->getHTTPClientService()
+			);
 			$notifications = new Notifications(
 				$addressHandler,
-				$this->serverContainer->getHTTPClientService()
+				$this->serverContainer->getHTTPClientService(),
+				$discoveryManager
 			);
 			$tokenHandler = new TokenHandler(
 				$this->serverContainer->getSecureRandom()