Support Nextcloud installations in subfolders

This commit is contained in:
ByteHamster 2022-02-24 21:20:40 +01:00
parent 6a366f0ad1
commit 348d366a3a
5 changed files with 69 additions and 15 deletions

View File

@ -12,4 +12,6 @@ dependencies {
implementation "commons-io:commons-io:$commonsioVersion"
implementation "io.reactivex.rxjava2:rxandroid:$rxAndroidVersion"
implementation "io.reactivex.rxjava2:rxjava:$rxJavaVersion"
testImplementation "junit:junit:$junitVersion"
}

View File

@ -1,5 +1,7 @@
package de.danoeh.antennapod.net.sync;
import org.apache.commons.lang3.StringUtils;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -7,9 +9,10 @@ public class HostnameParser {
public String scheme;
public int port;
public String host;
public String subfolder;
// split into schema, host and port - missing parts are null
private static final Pattern URLSPLIT_REGEX = Pattern.compile("(?:(https?)://)?([^:]+)(?::(\\d+))?");
private static final Pattern URLSPLIT_REGEX = Pattern.compile("(?:(https?)://)?([^:/]+)(?::(\\d+))?(.+)?");
public HostnameParser(String hosturl) {
Matcher m = URLSPLIT_REGEX.matcher(hosturl);
@ -21,6 +24,11 @@ public class HostnameParser {
} else {
port = Integer.parseInt(m.group(3)); // regex -> can only be digits
}
if (m.group(4) == null) {
subfolder = "";
} else {
subfolder = StringUtils.stripEnd(m.group(4), "/");
}
} else {
// URL does not match regex: use it anyway -> this will cause an exception on connect
scheme = "https";
@ -28,8 +36,10 @@ public class HostnameParser {
port = 443;
}
if (scheme == null) { // assume https
scheme = "https";
if (scheme == null && port == 80) {
scheme = "http";
} else if (scheme == null) {
scheme = "https"; // assume https
}
if (scheme.equals("https") && port == -1) {

View File

@ -46,7 +46,7 @@ public class NextcloudLoginFlow {
public void start() {
startDisposable = Observable.fromCallable(() -> {
URL url = new URI(hostname.scheme, null, hostname.host, hostname.port,
"/index.php/login/v2", null, null).toURL();
hostname.subfolder + "/index.php/login/v2", null, null).toURL();
JSONObject result = doRequest(url, "");
String loginUrl = result.getString("login");
this.token = result.getJSONObject("poll").getString("token");
@ -93,9 +93,13 @@ public class NextcloudLoginFlow {
Request request = new Request.Builder().url(url).method("POST", requestBody).build();
Response response = httpClient.newCall(request).execute();
if (response.code() != 200) {
response.close();
throw new IOException("Return code " + response.code());
}
ResponseBody body = response.body();
if (body == null) {
throw new IOException("Empty response");
}
return new JSONObject(body.string());
}

View File

@ -28,9 +28,7 @@ import java.util.List;
public class NextcloudSyncService implements ISyncService {
private static final int UPLOAD_BULK_SIZE = 30;
private final OkHttpClient httpClient;
private final String baseScheme;
private final int basePort;
private final String baseHost;
private final HostnameParser hostname;
private final String username;
private final String password;
@ -39,10 +37,7 @@ public class NextcloudSyncService implements ISyncService {
this.httpClient = httpClient;
this.username = username;
this.password = password;
HostnameParser hostname = new HostnameParser(baseHosturl);
this.baseHost = hostname.host;
this.basePort = hostname.port;
this.baseScheme = hostname.scheme;
this.hostname = new HostnameParser(baseHosturl);
}
@Override
@ -150,10 +145,10 @@ public class NextcloudSyncService implements ISyncService {
private HttpUrl.Builder makeUrl(String path) {
return new HttpUrl.Builder()
.scheme(baseScheme)
.host(baseHost)
.port(basePort)
.addPathSegments(path);
.scheme(hostname.scheme)
.host(hostname.host)
.port(hostname.port)
.addPathSegments(hostname.subfolder + path);
}
@Override

View File

@ -0,0 +1,43 @@
package de.danoeh.antennapod.net.sync;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class HostnameParserTest {
@Test
public void testHostOnly() {
assertHostname(new HostnameParser("example.com"), "https", 443, "example.com", "");
assertHostname(new HostnameParser("www.example.com"), "https", 443, "www.example.com", "");
}
@Test
public void testHostAndPort() {
assertHostname(new HostnameParser("example.com:443"), "https", 443, "example.com", "");
assertHostname(new HostnameParser("example.com:80"), "http", 80, "example.com", "");
assertHostname(new HostnameParser("example.com:123"), "https", 123, "example.com", "");
}
@Test
public void testScheme() {
assertHostname(new HostnameParser("https://example.com"), "https", 443, "example.com", "");
assertHostname(new HostnameParser("https://example.com:80"), "https", 80, "example.com", "");
assertHostname(new HostnameParser("http://example.com"), "http", 80, "example.com", "");
assertHostname(new HostnameParser("http://example.com:443"), "http", 443, "example.com", "");
}
@Test
public void testSubfolder() {
assertHostname(new HostnameParser("https://example.com/"), "https", 443, "example.com", "");
assertHostname(new HostnameParser("https://example.com/a"), "https", 443, "example.com", "/a");
assertHostname(new HostnameParser("https://example.com/a/"), "https", 443, "example.com", "/a");
assertHostname(new HostnameParser("https://example.com:42/a"), "https", 42, "example.com", "/a");
}
private void assertHostname(HostnameParser parser, String scheme, int port, String host, String subfolder) {
assertEquals(scheme, parser.scheme);
assertEquals(port, parser.port);
assertEquals(host, parser.host);
assertEquals(subfolder, parser.subfolder);
}
}