package peergos.shared.corenode;
import peergos.shared.cbor.*;
import peergos.shared.crypto.asymmetric.*;
import peergos.shared.io.ipfs.api.*;
import peergos.shared.io.ipfs.cid.*;
import peergos.shared.merklebtree.*;
import peergos.shared.user.*;
import peergos.shared.util.*;
import java.net.*;
import java.io.*;
import java.util.*;
import java.util.concurrent.*;
public class HTTPCoreNode implements CoreNode
{
private static final boolean LOGGING = true;
private final HttpPoster poster;
public static CoreNode getInstance(URL coreURL) throws IOException {
return new HTTPCoreNode(new JavaPoster(coreURL));
}
public HTTPCoreNode(HttpPoster poster)
{
System.out.println("Creating HTTP Corenode API at " + poster);
this.poster = poster;
}
@Override public CompletableFuture<Optional<PublicSigningKey>> getPublicKey(String username)
{
try {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
DataOutputStream dout = new DataOutputStream(bout);
Serialize.serialize(username, dout);
dout.flush();
CompletableFuture<byte[]> fut = poster.postUnzip("core/getPublicKey", bout.toByteArray());
return fut.thenApply(res -> {
DataInputStream din = new DataInputStream(new ByteArrayInputStream(res));
try {
if (!din.readBoolean())
return Optional.empty();
byte[] publicKey = CoreNodeUtils.deserializeByteArray(din);
return Optional.of(PublicSigningKey.fromByteArray(publicKey));
} catch (IOException e) {
throw new RuntimeException(e);
}
});
} catch (IOException ioe) {
ioe.printStackTrace();
return CompletableFuture.completedFuture(Optional.empty());
}
}
@Override public CompletableFuture<String> getUsername(PublicSigningKey publicKey)
{
try
{
ByteArrayOutputStream bout = new ByteArrayOutputStream();
DataOutputStream dout = new DataOutputStream(bout);
Serialize.serialize(publicKey.serialize(), dout);
dout.flush();
CompletableFuture<byte[]> fut = poster.post("core/getUsername", bout.toByteArray(), true);
return fut.thenApply(res -> {
DataInputStream din = new DataInputStream(new ByteArrayInputStream(res));
try {
String username = Serialize.deserializeString(din, CoreNode.MAX_USERNAME_SIZE);
return username;
} catch (IOException e) {
throw new RuntimeException(e);
}
});
} catch (IOException ioe) {
System.err.println("Couldn't connect to " + poster);
ioe.printStackTrace();
return null;
}
}
@Override public CompletableFuture<List<UserPublicKeyLink>> getChain(String username) {
try
{
ByteArrayOutputStream bout = new ByteArrayOutputStream();
DataOutputStream dout = new DataOutputStream(bout);
Serialize.serialize(username, dout);
dout.flush();
return poster.postUnzip("core/getChain", bout.toByteArray()).thenApply(res -> {
DataSource din = new DataSource(res);
try {
int count = din.readInt();
List<UserPublicKeyLink> result = new ArrayList<>();
for (int i = 0; i < count; i++) {
PublicSigningKey owner = PublicSigningKey.fromByteArray(din.readArray());
result.add(UserPublicKeyLink.fromByteArray(owner, Serialize.deserializeByteArray(din, UserPublicKeyLink.MAX_SIZE)));
}
return result;
} catch (IOException e) {
throw new RuntimeException(e);
}
});
} catch (IOException ioe) {
ioe.printStackTrace();
throw new IllegalStateException(ioe);
}
}
@Override public CompletableFuture<Boolean> updateChain(String username, List<UserPublicKeyLink> chain) {
try
{
ByteArrayOutputStream bout = new ByteArrayOutputStream();
DataOutputStream dout = new DataOutputStream(bout);
Serialize.serialize(username, dout);
dout.writeInt(chain.size());
for (UserPublicKeyLink link : chain) {
Serialize.serialize(link.owner.serialize(), dout);
Serialize.serialize(link.toByteArray(), dout);
}
dout.flush();
return poster.postUnzip("core/updateChain", bout.toByteArray()).thenApply(res -> {
DataInputStream din = new DataInputStream(new ByteArrayInputStream(res));
try {
return din.readBoolean();
} catch (IOException e) {
throw new RuntimeException(e);
}
});
} catch (IOException ioe) {
ioe.printStackTrace();
return CompletableFuture.completedFuture(false);
}
}
@Override public CompletableFuture<Boolean> followRequest(PublicSigningKey target, byte[] encryptedPermission)
{
try
{
ByteArrayOutputStream bout = new ByteArrayOutputStream();
DataOutputStream dout = new DataOutputStream(bout);
Serialize.serialize(target.serialize(), dout);
Serialize.serialize(encryptedPermission, dout);
dout.flush();
return poster.postUnzip("core/followRequest", bout.toByteArray()).thenApply(res -> {
DataInputStream din = new DataInputStream(new ByteArrayInputStream(res));
try {
return din.readBoolean();
} catch (IOException e) {
throw new RuntimeException(e);
}
});
} catch (IOException ioe) {
ioe.printStackTrace();
return CompletableFuture.completedFuture(false);
}
}
@Override public CompletableFuture<List<String>> getUsernames(String prefix)
{
return poster.postUnzip("core/getUsernamesGzip/"+prefix, new byte[0])
.thenApply(raw -> (List) JSONParser.parse(new String(raw)));
}
@Override public CompletableFuture<byte[]> getFollowRequests(PublicSigningKey owner)
{
try
{
ByteArrayOutputStream bout = new ByteArrayOutputStream();
DataOutputStream dout = new DataOutputStream(bout);
Serialize.serialize(owner.serialize(), dout);
dout.flush();
return poster.postUnzip("core/getFollowRequests", bout.toByteArray()).thenApply(res -> {
DataInputStream din = new DataInputStream(new ByteArrayInputStream(res));
try {
return CoreNodeUtils.deserializeByteArray(din);
} catch (IOException e) {
throw new RuntimeException(e);
}
});
} catch (IOException ioe) {
ioe.printStackTrace();
return null;
}
}
@Override public CompletableFuture<Boolean> removeFollowRequest(PublicSigningKey owner, byte[] signedRequest)
{
try
{
ByteArrayOutputStream bout = new ByteArrayOutputStream();
DataOutputStream dout = new DataOutputStream(bout);
Serialize.serialize(owner.serialize(), dout);
Serialize.serialize(signedRequest, dout);
dout.flush();
return poster.postUnzip("core/removeFollowRequest", bout.toByteArray()).thenApply(res -> {
DataInputStream din = new DataInputStream(new ByteArrayInputStream(res));
try {
return din.readBoolean();
} catch (IOException e) {
throw new RuntimeException(e);
}
});
} catch (IOException ioe) {
ioe.printStackTrace();
return CompletableFuture.completedFuture(false);
}
}
@Override public void close() {}
}