Session v1.18.2版本的 MD5 值为:92ce129e957021e1a845dcaca5ce957d
以下内容为反编译后的 FileServerApi.java 源代码,内容仅作参考
package org.session.libsession.messaging.file_server;
import android.provider.Downloads;
import com.google.android.exoplayer2.text.ttml.TtmlNode;
import java.util.Arrays;
import java.util.Map;
import kotlin.Metadata;
import kotlin.TuplesKt;
import kotlin.Unit;
import kotlin.collections.MapsKt;
import kotlin.jvm.functions.Function1;
import kotlin.jvm.internal.DefaultConstructorMarker;
import kotlin.jvm.internal.Intrinsics;
import nl.komponents.kovenant.Promise;
import nl.komponents.kovenant.functional.KovenantFnMoniadic;
import okhttp3.Headers;
import okhttp3.HttpUrl;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.RequestBody;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.http.HttpHeaders;
import org.session.libsession.messaging.file_server.FileServerApi;
import org.session.libsession.snode.OnionRequestAPI;
import org.session.libsession.snode.OnionResponse;
import org.session.libsignal.utilities.HTTP;
import org.session.libsignal.utilities.JsonUtil;
import org.session.libsignal.utilities.Log;
import org.thoughtcrime.securesms.mediasend.MediaSendActivity;
@Metadata(d1 = {"\u0000F\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\b\u0002\n\u0002\u0010\b\n\u0000\n\u0002\u0010\u000e\n\u0002\b\u0002\n\u0002\u0018\u0002\n\u0000\n\u0002\u0010\u0012\n\u0002\b\u0002\n\u0002\u0018\u0002\n\u0002\u0018\u0002\n\u0002\u0018\u0002\n\u0002\b\u0003\n\u0002\u0018\u0002\n\u0000\n\u0002\u0010\t\n\u0002\b\u0003\bÆ\u0002\u0018\u00002\u00020\u0001:\u0002\u0017\u0018B\u0007\b\u0002¢\u0006\u0002\u0010\u0002J\u001e\u0010\b\u001a\u0004\u0018\u00010\t2\b\u0010\n\u001a\u0004\u0018\u00010\u000b2\b\u0010\f\u001a\u0004\u0018\u00010\u0001H\u0002J\u001e\u0010\r\u001a\u0012\u0012\u0004\u0012\u00020\u000b\u0012\b\u0012\u00060\u000fj\u0002`\u00100\u000e2\u0006\u0010\u0011\u001a\u00020\u0006J \u0010\u0012\u001a\u0012\u0012\u0004\u0012\u00020\u000b\u0012\b\u0012\u00060\u000fj\u0002`\u00100\u000e2\u0006\u0010\u0013\u001a\u00020\u0014H\u0002J\u001e\u0010\u0015\u001a\u0012\u0012\u0004\u0012\u00020\u0016\u0012\b\u0012\u00060\u000fj\u0002`\u00100\u000e2\u0006\u0010\u0011\u001a\u00020\u000bR\u000e\u0010\u0003\u001a\u00020\u0004X\u0086T¢\u0006\u0002\n\u0000R\u000e\u0010\u0005\u001a\u00020\u0006X\u0086T¢\u0006\u0002\n\u0000R\u000e\u0010\u0007\u001a\u00020\u0006X\u0082T¢\u0006\u0002\n\u0000¨\u0006\u0019"}, d2 = {"Lorg/session/libsession/messaging/file_server/FileServerApi;", "", "()V", "maxFileSize", "", "server", "", "serverPublicKey", "createBody", "Lokhttp3/RequestBody;", "body", "", "parameters", "download", "Lnl/komponents/kovenant/Promise;", "Ljava/lang/Exception;", "Lkotlin/Exception;", "file", "send", "request", "Lorg/session/libsession/messaging/file_server/FileServerApi$Request;", "upload", "", "Error", "Request", "libsession_release"}, k = 1, mv = {1, 8, 0}, xi = 48)
public final class FileServerApi {
public static final FileServerApi INSTANCE = new FileServerApi();
public static final int maxFileSize = 10000000;
public static final String server = "http://filev2.getsession.org";
private static final String serverPublicKey = "da21e1d886c6fbaea313f75298bd64aab03a97ce985b46bb2dad9f2089c8ee59";
@Metadata(k = 3, mv = {1, 8, 0}, xi = 48)
public class WhenMappings {
public static final int[] $EnumSwitchMapping$0;
static {
int[] iArr = new int[HTTP.Verb.values().length];
try {
iArr[HTTP.Verb.GET.ordinal()] = 1;
} catch (NoSuchFieldError unused) {
}
try {
iArr[HTTP.Verb.PUT.ordinal()] = 2;
} catch (NoSuchFieldError unused2) {
}
try {
iArr[HTTP.Verb.POST.ordinal()] = 3;
} catch (NoSuchFieldError unused3) {
}
try {
iArr[HTTP.Verb.DELETE.ordinal()] = 4;
} catch (NoSuchFieldError unused4) {
}
$EnumSwitchMapping$0 = iArr;
}
}
private FileServerApi() {
}
@Metadata(d1 = {"\u0000 \n\u0002\u0018\u0002\n\u0002\u0018\u0002\n\u0002\u0018\u0002\n\u0000\n\u0002\u0010\u000e\n\u0002\b\u0003\n\u0002\u0018\u0002\n\u0002\u0018\u0002\n\u0000\b6\u0018\u00002\u00060\u0001j\u0002`\u0002:\u0002\u0006\u0007B\u000f\b\u0004\u0012\u0006\u0010\u0003\u001a\u00020\u0004¢\u0006\u0002\u0010\u0005\u0082\u0001\u0002\b\t¨\u0006\n"}, d2 = {"Lorg/session/libsession/messaging/file_server/FileServerApi$Error;", "Ljava/lang/Exception;", "Lkotlin/Exception;", MediaSendActivity.EXTRA_MESSAGE, "", "(Ljava/lang/String;)V", "InvalidURL", "ParsingFailed", "Lorg/session/libsession/messaging/file_server/FileServerApi$Error$InvalidURL;", "Lorg/session/libsession/messaging/file_server/FileServerApi$Error$ParsingFailed;", "libsession_release"}, k = 1, mv = {1, 8, 0}, xi = 48)
public static abstract class Error extends Exception {
public Error(String str, DefaultConstructorMarker defaultConstructorMarker) {
this(str);
}
@Metadata(d1 = {"\u0000\f\n\u0002\u0018\u0002\n\u0002\u0018\u0002\n\u0002\b\u0002\bÆ\u0002\u0018\u00002\u00020\u0001B\u0007\b\u0002¢\u0006\u0002\u0010\u0002¨\u0006\u0003"}, d2 = {"Lorg/session/libsession/messaging/file_server/FileServerApi$Error$ParsingFailed;", "Lorg/session/libsession/messaging/file_server/FileServerApi$Error;", "()V", "libsession_release"}, k = 1, mv = {1, 8, 0}, xi = 48)
public static final class ParsingFailed extends Error {
public static final ParsingFailed INSTANCE = new ParsingFailed();
private ParsingFailed() {
super("Invalid response.", null);
}
}
private Error(String str) {
super(str);
}
@Metadata(d1 = {"\u0000\f\n\u0002\u0018\u0002\n\u0002\u0018\u0002\n\u0002\b\u0002\bÆ\u0002\u0018\u00002\u00020\u0001B\u0007\b\u0002¢\u0006\u0002\u0010\u0002¨\u0006\u0003"}, d2 = {"Lorg/session/libsession/messaging/file_server/FileServerApi$Error$InvalidURL;", "Lorg/session/libsession/messaging/file_server/FileServerApi$Error;", "()V", "libsession_release"}, k = 1, mv = {1, 8, 0}, xi = 48)
public static final class InvalidURL extends Error {
public static final InvalidURL INSTANCE = new InvalidURL();
private InvalidURL() {
super("Invalid URL.", null);
}
}
}
@Metadata(d1 = {"\u00004\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0000\n\u0002\u0018\u0002\n\u0000\n\u0002\u0010\u000e\n\u0000\n\u0002\u0010$\n\u0002\b\u0003\n\u0002\u0010\u0012\n\u0000\n\u0002\u0010\u000b\n\u0002\b\u0019\n\u0002\u0010\b\n\u0002\b\u0002\b\u0086\b\u0018\u00002\u00020\u0001Bc\u0012\u0006\u0010\u0002\u001a\u00020\u0003\u0012\u0006\u0010\u0004\u001a\u00020\u0005\u0012\u0014\b\u0002\u0010\u0006\u001a\u000e\u0012\u0004\u0012\u00020\u0005\u0012\u0004\u0012\u00020\u00050\u0007\u0012\n\b\u0002\u0010\b\u001a\u0004\u0018\u00010\u0001\u0012\u0014\b\u0002\u0010\t\u001a\u000e\u0012\u0004\u0012\u00020\u0005\u0012\u0004\u0012\u00020\u00050\u0007\u0012\n\b\u0002\u0010\n\u001a\u0004\u0018\u00010\u000b\u0012\b\b\u0002\u0010\f\u001a\u00020\r¢\u0006\u0002\u0010\u000eJ\t\u0010\u001c\u001a\u00020\u0003HÆ\u0003J\t\u0010\u001d\u001a\u00020\u0005HÆ\u0003J\u0015\u0010\u001e\u001a\u000e\u0012\u0004\u0012\u00020\u0005\u0012\u0004\u0012\u00020\u00050\u0007HÆ\u0003J\u000b\u0010\u001f\u001a\u0004\u0018\u00010\u0001HÆ\u0003J\u0015\u0010 \u001a\u000e\u0012\u0004\u0012\u00020\u0005\u0012\u0004\u0012\u00020\u00050\u0007HÆ\u0003J\u000b\u0010!\u001a\u0004\u0018\u00010\u000bHÆ\u0003J\t\u0010\"\u001a\u00020\rHÆ\u0003Jk\u0010#\u001a\u00020\u00002\b\b\u0002\u0010\u0002\u001a\u00020\u00032\b\b\u0002\u0010\u0004\u001a\u00020\u00052\u0014\b\u0002\u0010\u0006\u001a\u000e\u0012\u0004\u0012\u00020\u0005\u0012\u0004\u0012\u00020\u00050\u00072\n\b\u0002\u0010\b\u001a\u0004\u0018\u00010\u00012\u0014\b\u0002\u0010\t\u001a\u000e\u0012\u0004\u0012\u00020\u0005\u0012\u0004\u0012\u00020\u00050\u00072\n\b\u0002\u0010\n\u001a\u0004\u0018\u00010\u000b2\b\b\u0002\u0010\f\u001a\u00020\rHÆ\u0001J\u0013\u0010$\u001a\u00020\r2\b\u0010%\u001a\u0004\u0018\u00010\u0001HÖ\u0003J\t\u0010&\u001a\u00020'HÖ\u0001J\t\u0010(\u001a\u00020\u0005HÖ\u0001R\u0013\u0010\n\u001a\u0004\u0018\u00010\u000b¢\u0006\b\n\u0000\u001a\u0004\b\u000f\u0010\u0010R\u0011\u0010\u0004\u001a\u00020\u0005¢\u0006\b\n\u0000\u001a\u0004\b\u0011\u0010\u0012R\u001d\u0010\t\u001a\u000e\u0012\u0004\u0012\u00020\u0005\u0012\u0004\u0012\u00020\u00050\u0007¢\u0006\b\n\u0000\u001a\u0004\b\u0013\u0010\u0014R\u0013\u0010\b\u001a\u0004\u0018\u00010\u0001¢\u0006\b\n\u0000\u001a\u0004\b\u0015\u0010\u0016R\u001d\u0010\u0006\u001a\u000e\u0012\u0004\u0012\u00020\u0005\u0012\u0004\u0012\u00020\u00050\u0007¢\u0006\b\n\u0000\u001a\u0004\b\u0017\u0010\u0014R\u0011\u0010\f\u001a\u00020\r¢\u0006\b\n\u0000\u001a\u0004\b\u0018\u0010\u0019R\u0011\u0010\u0002\u001a\u00020\u0003¢\u0006\b\n\u0000\u001a\u0004\b\u001a\u0010\u001b¨\u0006)"}, d2 = {"Lorg/session/libsession/messaging/file_server/FileServerApi$Request;", "", "verb", "Lorg/session/libsignal/utilities/HTTP$Verb;", "endpoint", "", "queryParameters", "", "parameters", Downloads.Impl.RequestHeaders.URI_SEGMENT, "body", "", "useOnionRouting", "", "(Lorg/session/libsignal/utilities/HTTP$Verb;Ljava/lang/String;Ljava/util/Map;Ljava/lang/Object;Ljava/util/Map;[BZ)V", "getBody", "()[B", "getEndpoint", "()Ljava/lang/String;", "getHeaders", "()Ljava/util/Map;", "getParameters", "()Ljava/lang/Object;", "getQueryParameters", "getUseOnionRouting", "()Z", "getVerb", "()Lorg/session/libsignal/utilities/HTTP$Verb;", "component1", "component2", "component3", "component4", "component5", "component6", "component7", "copy", "equals", "other", "hashCode", "", "toString", "libsession_release"}, k = 1, mv = {1, 8, 0}, xi = 48)
public static final class Request {
private final byte[] body;
private final String endpoint;
private final Map<String, String> headers;
private final Object parameters;
private final Map<String, String> queryParameters;
private final boolean useOnionRouting;
private final HTTP.Verb verb;
public static Request copy$default(Request request, HTTP.Verb verb, String str, Map map, Object obj, Map map2, byte[] bArr, boolean z, int i, Object obj2) {
if ((i & 1) != 0) {
verb = request.verb;
}
if ((i & 2) != 0) {
str = request.endpoint;
}
String str2 = str;
if ((i & 4) != 0) {
map = request.queryParameters;
}
Map map3 = map;
if ((i & 8) != 0) {
obj = request.parameters;
}
Object obj3 = obj;
if ((i & 16) != 0) {
map2 = request.headers;
}
Map map4 = map2;
if ((i & 32) != 0) {
bArr = request.body;
}
byte[] bArr2 = bArr;
if ((i & 64) != 0) {
z = request.useOnionRouting;
}
return request.copy(verb, str2, map3, obj3, map4, bArr2, z);
}
public final HTTP.Verb getVerb() {
return this.verb;
}
public final String getEndpoint() {
return this.endpoint;
}
public final Map<String, String> component3() {
return this.queryParameters;
}
public final Object getParameters() {
return this.parameters;
}
public final Map<String, String> component5() {
return this.headers;
}
public final byte[] getBody() {
return this.body;
}
public final boolean getUseOnionRouting() {
return this.useOnionRouting;
}
public final Request copy(HTTP.Verb verb, String endpoint, Map<String, String> queryParameters, Object parameters, Map<String, String> headers, byte[] body, boolean useOnionRouting) {
Intrinsics.checkNotNullParameter(verb, "verb");
Intrinsics.checkNotNullParameter(endpoint, "endpoint");
Intrinsics.checkNotNullParameter(queryParameters, "queryParameters");
Intrinsics.checkNotNullParameter(headers, "headers");
return new Request(verb, endpoint, queryParameters, parameters, headers, body, useOnionRouting);
}
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof Request)) {
return false;
}
Request request = (Request) other;
return this.verb == request.verb && Intrinsics.areEqual(this.endpoint, request.endpoint) && Intrinsics.areEqual(this.queryParameters, request.queryParameters) && Intrinsics.areEqual(this.parameters, request.parameters) && Intrinsics.areEqual(this.headers, request.headers) && Intrinsics.areEqual(this.body, request.body) && this.useOnionRouting == request.useOnionRouting;
}
public int hashCode() {
int hashCode = ((((this.verb.hashCode() * 31) + this.endpoint.hashCode()) * 31) + this.queryParameters.hashCode()) * 31;
Object obj = this.parameters;
int hashCode2 = (((hashCode + (obj == null ? 0 : obj.hashCode())) * 31) + this.headers.hashCode()) * 31;
byte[] bArr = this.body;
int hashCode3 = (hashCode2 + (bArr != null ? Arrays.hashCode(bArr) : 0)) * 31;
boolean z = this.useOnionRouting;
int i = z;
if (z != 0) {
i = 1;
}
return hashCode3 + i;
}
public String toString() {
return "Request(verb=" + this.verb + ", endpoint=" + this.endpoint + ", queryParameters=" + this.queryParameters + ", parameters=" + this.parameters + ", headers=" + this.headers + ", body=" + Arrays.toString(this.body) + ", useOnionRouting=" + this.useOnionRouting + PropertyUtils.MAPPED_DELIM2;
}
public Request(HTTP.Verb verb, String endpoint, Map<String, String> queryParameters, Object obj, Map<String, String> headers, byte[] bArr, boolean z) {
Intrinsics.checkNotNullParameter(verb, "verb");
Intrinsics.checkNotNullParameter(endpoint, "endpoint");
Intrinsics.checkNotNullParameter(queryParameters, "queryParameters");
Intrinsics.checkNotNullParameter(headers, "headers");
this.verb = verb;
this.endpoint = endpoint;
this.queryParameters = queryParameters;
this.parameters = obj;
this.headers = headers;
this.body = bArr;
this.useOnionRouting = z;
}
public final HTTP.Verb getVerb() {
return this.verb;
}
public final String getEndpoint() {
return this.endpoint;
}
public Request(HTTP.Verb verb, String str, Map map, Object obj, Map map2, byte[] bArr, boolean z, int i, DefaultConstructorMarker defaultConstructorMarker) {
this(verb, str, (i & 4) != 0 ? MapsKt.emptyMap() : map, (i & 8) != 0 ? null : obj, (i & 16) != 0 ? MapsKt.emptyMap() : map2, (i & 32) != 0 ? null : bArr, (i & 64) != 0 ? true : z);
}
public final Map<String, String> getQueryParameters() {
return this.queryParameters;
}
public final Object getParameters() {
return this.parameters;
}
public final Map<String, String> getHeaders() {
return this.headers;
}
public final byte[] getBody() {
return this.body;
}
public final boolean getUseOnionRouting() {
return this.useOnionRouting;
}
}
private final RequestBody createBody(byte[] body, Object parameters) {
if (body != null) {
return RequestBody.create(MediaType.get("application/octet-stream"), body);
}
if (parameters == null) {
return null;
}
return RequestBody.create(MediaType.get("application/json"), JsonUtil.toJson(parameters));
}
private final Promise<byte[], Exception> send(Request request) {
HttpUrl parse = HttpUrl.parse(server);
if (parse == null) {
return Promise.Companion.ofFail$default(Promise.INSTANCE, Error.InvalidURL.INSTANCE, null, 2, null);
}
HttpUrl.Builder addPathSegments = new HttpUrl.Builder().scheme(parse.scheme()).host(parse.host()).port(parse.port()).addPathSegments(request.getEndpoint());
if (request.getVerb() == HTTP.Verb.GET) {
for (Map.Entry<String, String> entry : request.getQueryParameters().entrySet()) {
addPathSegments.addQueryParameter(entry.getKey(), entry.getValue());
}
}
Request.Builder headers = new Request.Builder().url(addPathSegments.build()).headers(Headers.of(request.getHeaders()));
int i = WhenMappings.$EnumSwitchMapping$0[request.getVerb().ordinal()];
if (i == 1) {
headers.get();
} else if (i == 2) {
RequestBody createBody = createBody(request.getBody(), request.getParameters());
Intrinsics.checkNotNull(createBody);
headers.put(createBody);
} else if (i == 3) {
RequestBody createBody2 = createBody(request.getBody(), request.getParameters());
Intrinsics.checkNotNull(createBody2);
headers.post(createBody2);
} else if (i == 4) {
headers.delete(createBody(request.getBody(), request.getParameters()));
}
if (request.getUseOnionRouting()) {
OnionRequestAPI onionRequestAPI = OnionRequestAPI.INSTANCE;
okhttp3.Request build = headers.build();
Intrinsics.checkNotNullExpressionValue(build, "requestBuilder.build()");
return KovenantFnMoniadic.map(OnionRequestAPI.sendOnionRequest$default(onionRequestAPI, build, server, serverPublicKey, null, 8, null), new Function1<OnionResponse, byte[]>() {
@Override
public final byte[] invoke(OnionResponse it) {
Intrinsics.checkNotNullParameter(it, "it");
byte[] body = it.getBody();
if (body != null) {
return body;
}
throw FileServerApi.Error.ParsingFailed.INSTANCE;
}
}).fail(new Function1<Exception, Unit>() {
@Override
public Unit invoke(Exception exc) {
invoke2(exc);
return Unit.INSTANCE;
}
public final void invoke2(Exception e) {
Intrinsics.checkNotNullParameter(e, "e");
if (!(e instanceof HTTP.HTTPRequestFailedException)) {
Log.e("Loki", "File server request failed", e);
return;
}
Log.e("Loki", "File server request failed due to error: " + e.getMessage());
}
});
}
return Promise.Companion.ofFail$default(Promise.INSTANCE, new IllegalStateException("It's currently not allowed to send non onion routed requests."), null, 2, null);
}
public final Promise<Long, Exception> upload(byte[] file) {
Intrinsics.checkNotNullParameter(file, "file");
return KovenantFnMoniadic.map(send(new Request(HTTP.Verb.POST, "file", null, null, MapsKt.mapOf(TuplesKt.to("Content-Disposition", "attachment"), TuplesKt.to(HttpHeaders.CONTENT_TYPE, "application/octet-stream")), file, false, 76, null)), new Function1<byte[], Long>() {
@Override
public final Long invoke(byte[] response) {
Intrinsics.checkNotNullParameter(response, "response");
Map json = (Map) JsonUtil.fromJson(response, Map.class);
Intrinsics.checkNotNullExpressionValue(json, "json");
boolean containsKey = json.containsKey(TtmlNode.ATTR_ID);
Object orDefault = json.getOrDefault(TtmlNode.ATTR_ID, null);
StringBuilder sb = new StringBuilder();
sb.append("File Upload Response hasId: ");
sb.append(containsKey);
sb.append(" of type: ");
sb.append(orDefault != null ? orDefault.getClass() : null);
Log.d("Loki-FS", sb.toString());
String str = orDefault instanceof String ? (String) orDefault : null;
if (str != null) {
return Long.valueOf(Long.parseLong(str));
}
throw FileServerApi.Error.ParsingFailed.INSTANCE;
}
});
}
public final Promise<byte[], Exception> download(String file) {
Intrinsics.checkNotNullParameter(file, "file");
return send(new Request(HTTP.Verb.GET, "file/" + file, null, null, null, null, false, 124, null));
}
}