Skip to content

Instantly share code, notes, and snippets.

@courville
Created January 18, 2024 14:31
Show Gist options
  • Save courville/93b10246ba2bccb716d5acfe01d83d64 to your computer and use it in GitHub Desktop.
Save courville/93b10246ba2bccb716d5acfe01d83d64 to your computer and use it in GitHub Desktop.
realdebrid sardine webdav
diff --git a/src/com/archos/filecorelibrary/FileEditor.java b/src/com/archos/filecorelibrary/FileEditor.java
index d34a879..76d880b 100644
--- a/src/com/archos/filecorelibrary/FileEditor.java
+++ b/src/com/archos/filecorelibrary/FileEditor.java
@@ -52,6 +52,7 @@ public abstract class FileEditor {
public boolean rename(String newName) { return false; };
public boolean move(Uri uri) { return false; };
public abstract boolean exists();
+ public long length() throws Exception { return -1; }
/**
* Use it for file (and just file) copy
diff --git a/src/com/archos/filecorelibrary/StreamOverHttp.java b/src/com/archos/filecorelibrary/StreamOverHttp.java
index 452da7e..4397107 100644
--- a/src/com/archos/filecorelibrary/StreamOverHttp.java
+++ b/src/com/archos/filecorelibrary/StreamOverHttp.java
@@ -317,7 +317,10 @@ public class StreamOverHttp {
if(metaFile2.length()!=0)
length = metaFile2.length();
try {
- is = FileEditorFactory.getFileEditorForUrl(mUri, ArchosUtils.getGlobalContext()).getInputStream(startFrom);
+ var fe = FileEditorFactory.getFileEditorForUrl(mUri, ArchosUtils.getGlobalContext());
+ is = fe.getInputStream(startFrom);
+ var l = fe.length();
+ if (l > 0) length = l;
} catch (IOException ioexception) {
log.debug("openInputStream: caught IOException ", ioexception);
if (ioexception.getMessage().equals("Illegal seek")){
diff --git a/src/com/archos/filecorelibrary/webdav/WebdavFileEditor.java b/src/com/archos/filecorelibrary/webdav/WebdavFileEditor.java
index 4354364..ab7c015 100644
--- a/src/com/archos/filecorelibrary/webdav/WebdavFileEditor.java
+++ b/src/com/archos/filecorelibrary/webdav/WebdavFileEditor.java
@@ -21,6 +21,7 @@ import android.net.Uri;
import com.archos.filecorelibrary.FileEditor;
import com.archos.filecorelibrary.FileUtils;
import com.thegrizzlylabs.sardineandroid.impl.OkHttpSardine;
+import com.thegrizzlylabs.sardineandroid.impl.SardineException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -31,29 +32,53 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
+import okhttp3.Request;
+import okhttp3.Headers;
+import okhttp3.OkHttpClient;
+
public class WebdavFileEditor extends FileEditor {
private static final Logger log = LoggerFactory.getLogger(WebdavFileEditor.class);
private OkHttpSardine mSardine;
+ private OkHttpClient mHttpClient;
+ private long mLength = -1;
public WebdavFileEditor(Uri uri) {
super(uri);
mSardine = WebdavUtils.peekInstance().getSardine(uri);
+ mHttpClient = WebdavUtils.peekInstance().getHttpClient(uri);
}
@Override
public InputStream getInputStream() throws Exception {
- var u = WebdavFile2.uriToHttp(mUri);
- return mSardine.get(u.toString());
+ return getInputStream(-1);
}
@Override
public InputStream getInputStream(long from) throws Exception {
var u = WebdavFile2.uriToHttp(mUri);
- var headers = new HashMap<String, String>();
- headers.put("Range", "bytes=" + from + "-");
- return mSardine.get(u.toString(), headers);
+ log.trace("getInputStream: requesting length for " + u);
+ var reqBuilder = new Request.Builder()
+ .url(u.toString())
+ .get();
+ if (from >= 0) {
+ var headers = new HashMap<String, String>();
+ headers.put("Range", "bytes=" + from + "-");
+ reqBuilder.headers(Headers.of(headers));
+ }
+ var req = reqBuilder.build();
+ var resp = mHttpClient.newCall(req).execute();
+ var length = resp.header("Content-Length");
+ log.trace("getInputStream: got length " + length);
+ mLength = Long.parseLong(length);
+
+ return resp.body().byteStream();
+ }
+
+ @Override
+ public long length() throws Exception {
+ return mLength;
}
@Override
diff --git a/src/com/archos/filecorelibrary/webdav/WebdavUtils.java b/src/com/archos/filecorelibrary/webdav/WebdavUtils.java
index 5d35ef7..af66b81 100644
--- a/src/com/archos/filecorelibrary/webdav/WebdavUtils.java
+++ b/src/com/archos/filecorelibrary/webdav/WebdavUtils.java
@@ -25,14 +25,21 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.ConcurrentHashMap;
+import java.io.IOException;
import okhttp3.OkHttpClient;
+import okhttp3.Authenticator;
+import okhttp3.Credentials;
+import okhttp3.Request;
+import okhttp3.Route;
+import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
public class WebdavUtils {
private static final Logger log = LoggerFactory.getLogger(WebdavUtils.class);
static private ConcurrentHashMap<NetworkCredentialsDatabase.Credential, OkHttpSardine> sardines = new ConcurrentHashMap<>();
+ static private ConcurrentHashMap<NetworkCredentialsDatabase.Credential, OkHttpClient> httpClients = new ConcurrentHashMap<>();
private static Context mContext;
// singleton, volatile to make double-checked-locking work correctly
private static volatile WebdavUtils sInstance;
@@ -60,33 +67,54 @@ public class WebdavUtils {
}
public synchronized OkHttpSardine getSardine(Uri uri) {
- String username = "anonymous";
- String password = "";
NetworkCredentialsDatabase.Credential cred = NetworkCredentialsDatabase.getInstance().getCredential(uri.toString());
if (cred == null)
cred = new NetworkCredentialsDatabase.Credential("anonymous", "", buildKeyFromUri(uri).toString(), "", true);
- password = cred.getPassword();
- username = cred.getUsername();
+ final String password = cred.getPassword();
+ final String username = cred.getUsername();
OkHttpSardine sardine = sardines.get(cred);
if (sardine == null) {
// configure OkHttpClient to support 302 redirects
OkHttpClient.Builder builder = new OkHttpClient.Builder();
if (log.isTraceEnabled()) {
- HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
+ HttpLoggingInterceptor logging = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
+ @Override
+ public void log(String msg) {
+ log.trace("OkHttpSardine: webdav " + msg);
+ }});
logging.setLevel(HttpLoggingInterceptor.Level.HEADERS);
builder.addInterceptor(logging);
}
+ builder.authenticator(new Authenticator() {
+ @Override
+ public Request authenticate(Route route, Response response) throws IOException {
+ if (response.request().header("Authorization") != null) {
+ return null;
+ }
+ String credential = Credentials.basic(username, password);
+ return response.request().newBuilder().header("Authorization", credential).build();
+ }
+ });
builder.followRedirects(true);
builder.followSslRedirects(true); // Handle SSL redirect
// Set the custom client to the Sardine instance
- sardine = new OkHttpSardine(builder.build());
+ var client = builder.build();
+ sardine = new OkHttpSardine(client);
sardine.setCredentials(username, password);
+ httpClients.put(cred, client);
sardines.put(cred, sardine);
return sardine;
}
return sardine;
}
+ public synchronized OkHttpClient getHttpClient(Uri uri) {
+ NetworkCredentialsDatabase.Credential cred = NetworkCredentialsDatabase.getInstance().getCredential(uri.toString());
+ if (cred == null)
+ cred = new NetworkCredentialsDatabase.Credential("anonymous", "", buildKeyFromUri(uri).toString(), "", true);
+ return httpClients.get(cred);
+ }
+
private Uri buildKeyFromUri(Uri uri) {
// use Uri without the path segment as key: for example, "webdav://blabla.com:5006/toto/titi" gives a "webdav://blabla.com:5006" key
return uri.buildUpon().path("").build();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment