package peergos.server.mutable; import com.sun.net.httpserver.*; import peergos.shared.cbor.*; import peergos.shared.corenode.*; import peergos.shared.crypto.asymmetric.*; import peergos.shared.merklebtree.*; import peergos.shared.mutable.*; import peergos.shared.util.*; import java.io.*; import java.net.*; import java.util.concurrent.*; public class HttpMutablePointerServer { public static final int PORT = 9998; private static final boolean LOGGING = true; private static final int CONNECTION_BACKLOG = 100; private static final int HANDLER_THREAD_COUNT = 100; public static final String MUTABLE_POINTERS_URL = "mutable/"; public static class MutationHandler implements HttpHandler { private final MutablePointers mutable; public MutationHandler(MutablePointers mutable) { this.mutable = mutable; } public void handle(HttpExchange exchange) throws IOException { long t1 = System.currentTimeMillis(); DataInputStream din = new DataInputStream(exchange.getRequestBody()); ByteArrayOutputStream bout = new ByteArrayOutputStream(); DataOutputStream dout = new DataOutputStream(bout); String path = exchange.getRequestURI().getPath(); if (path.startsWith("/")) path = path.substring(1); String[] subComponents = path.substring(MUTABLE_POINTERS_URL.length()).split("/"); String method = subComponents[0]; // System.out.println("core method "+ method +" from path "+ path); try { switch (method) { case "setPointer": setPointer(din, dout); break; case "getPointer": getPointer(din, dout); break; default: throw new IOException("Unknown method "+ method); } dout.flush(); dout.close(); byte[] b = bout.toByteArray(); exchange.sendResponseHeaders(200, b.length); exchange.getResponseBody().write(b); } catch (Exception e) { e.printStackTrace(); exchange.sendResponseHeaders(400, 0); OutputStream body = exchange.getResponseBody(); body.write(e.getMessage().getBytes()); } finally { exchange.close(); long t2 = System.currentTimeMillis(); if (LOGGING) System.out.println("Mutable pointers server handled " + method + " request in: " + (t2 - t1) + " mS"); } } void setPointer(DataInputStream din, DataOutputStream dout) throws Exception { byte[] ownerPublicKey = CoreNodeUtils.deserializeByteArray(din); byte[] encodedSharingPublicKey = CoreNodeUtils.deserializeByteArray(din); byte[] signedPayload = CoreNodeUtils.deserializeByteArray(din); boolean isAdded = mutable.setPointer( PublicSigningKey.fromByteArray(ownerPublicKey), PublicSigningKey.fromByteArray(encodedSharingPublicKey), signedPayload).get(); dout.writeBoolean(isAdded); } void getPointer(DataInputStream din, DataOutputStream dout) throws Exception { PublicSigningKey encodedSharingKey = PublicSigningKey.fromCbor(CborObject.deserialize(new CborDecoder(din))); MaybeMultihash metadataBlob = mutable.getPointer(encodedSharingKey).get(); dout.write(metadataBlob.serialize()); } } private final HttpServer server; private final InetSocketAddress address; private final MutationHandler ch; public HttpMutablePointerServer(MutablePointers mutable, InetSocketAddress address) throws IOException { this.address = address; if (address.getHostName().contains("local")) server = HttpServer.create(address, CONNECTION_BACKLOG); else server = HttpServer.create(new InetSocketAddress(InetAddress.getLocalHost(), address.getPort()), CONNECTION_BACKLOG); ch = new MutationHandler(mutable); server.createContext("/" + MUTABLE_POINTERS_URL, ch); server.setExecutor(Executors.newFixedThreadPool(HANDLER_THREAD_COUNT)); } public void start() throws IOException { server.start(); } public void close() throws IOException { server.stop(5); } }