11package org .peergos .net ;
22
33import io .ipfs .cid .Cid ;
4+ import io .ipfs .multihash .*;
45import io .libp2p .core .PeerId ;
6+ import io .libp2p .crypto .keys .*;
57import org .peergos .*;
8+ import org .peergos .protocol .ipns .*;
9+ import org .peergos .protocol .ipns .pb .*;
610import org .peergos .util .*;
711import com .sun .net .httpserver .HttpExchange ;
812
9- import java .io .IOException ;
13+ import java .io .*;
14+ import java .nio .*;
1015import java .util .*;
1116import java .util .logging .Logger ;
1217import java .util .stream .*;
1318
1419public class APIHandler extends Handler {
1520 public static final String API_URL = "/api/v0/" ;
16- public static final Version CURRENT_VERSION = Version .parse ("0.7.2 " );
21+ public static final Version CURRENT_VERSION = Version .parse ("0.7.5 " );
1722 private static final Logger LOG = Logging .LOG ();
1823
1924 private static final boolean LOGGING = true ;
@@ -23,12 +28,14 @@ public class APIHandler extends Handler {
2328 public static final String GET = "block/get" ;
2429 public static final String PUT = "block/put" ;
2530 public static final String RM = "block/rm" ;
31+ public static final String RM_BULK = "block/rm/bulk" ;
2632 public static final String STAT = "block/stat" ;
2733 public static final String REFS_LOCAL = "refs/local" ;
2834 public static final String BLOOM_ADD = "bloom/add" ;
2935 public static final String HAS = "block/has" ;
3036
3137 public static final String FIND_PROVS = "dht/findprovs" ;
38+ public static final String IPNS_GET = "ipns/get" ;
3239
3340 private final EmbeddedIpfs ipfs ;
3441 private final int maxBlockSize ;
@@ -141,6 +148,31 @@ public void handleCallToAPI(HttpExchange httpExchange) {
141148 }
142149 break ;
143150 }
151+ case RM_BULK : {
152+ AggregatedMetrics .API_BLOCK_RM_BULK .inc ();
153+ Map <String , Object > json = (Map <String , Object >) JSONParser .parse (new String (readFully (httpExchange .getRequestBody ())));
154+ List <Cid > cids = ((List <String >)json .get ("cids" ))
155+ .stream ()
156+ .map (Cid ::decode )
157+ .collect (Collectors .toList ());
158+ boolean deleted = true ;
159+ for (Cid cid : cids ) {
160+ deleted &= ipfs .blockstore .rm (cid ).join ();
161+ }
162+
163+ if (deleted ) {
164+ Map res = new HashMap <>();
165+ res .put ("Res" , "true" );
166+ replyJson (httpExchange , JSONParser .toString (res ));
167+ } else {
168+ try {
169+ httpExchange .sendResponseHeaders (400 , 0 );
170+ } catch (IOException ioe ) {
171+ HttpUtil .replyError (httpExchange , ioe );
172+ }
173+ }
174+ break ;
175+ }
144176 case STAT : { // https://docs.ipfs.tech/reference/kubo/rpc/#api-v0-block-stat
145177 AggregatedMetrics .API_BLOCK_STAT .inc ();
146178 if (args == null || args .size () != 1 ) {
@@ -217,6 +249,31 @@ public void handleCallToAPI(HttpExchange httpExchange) {
217249 replyBytes (httpExchange , sb .toString ().getBytes ());
218250 break ;
219251 }
252+ case IPNS_GET : {
253+ AggregatedMetrics .API_IPNS_GET .inc ();
254+ if (args == null || args .size () != 1 ) {
255+ throw new APIException ("argument \" signer\" is required" );
256+ }
257+ Multihash signer = Multihash .fromBase58 (args .get (0 ));
258+ if (signer .getType () != Multihash .Type .id )
259+ throw new IllegalStateException ("Can only resolve Ed25519 ipns mappings" );
260+ byte [] pubKeymaterial = Arrays .copyOfRange (signer .getHash (), 4 , 36 );
261+ io .libp2p .core .crypto .PubKey pub = new Ed25519PublicKey (new org .bouncycastle .crypto .params .Ed25519PublicKeyParameters (pubKeymaterial , 0 ));
262+ List <IpnsRecord > records = ipfs .resolveRecords (pub , 1 )
263+ .stream ()
264+ .sorted ()
265+ .collect (Collectors .toList ());
266+ if (records .isEmpty ())
267+ throw new IllegalStateException ("Couldn't resolve " + signer );
268+ IpnsRecord latest = records .get (records .size () - 1 );
269+ Ipns .IpnsEntry entry = Ipns .IpnsEntry .parseFrom (ByteBuffer .wrap (latest .raw ));
270+ Map <String , Object > res = new HashMap <>();
271+ res .put ("sig" , ArrayOps .bytesToHex (entry .getSignatureV2 ().toByteArray ()));
272+ res .put ("data" , ArrayOps .bytesToHex (entry .getData ().toByteArray ()));
273+ String json = JSONParser .toString (res );
274+ replyJson (httpExchange , json );
275+ break ;
276+ }
220277 default : {
221278 httpExchange .sendResponseHeaders (404 , 0 );
222279 break ;
@@ -231,4 +288,14 @@ public void handleCallToAPI(HttpExchange httpExchange) {
231288 LOG .info ("API Handler handled " + path + " query in: " + (t2 - t1 ) + " mS" );
232289 }
233290 }
291+
292+ private byte [] readFully (InputStream in ) throws IOException {
293+ ByteArrayOutputStream bout = new ByteArrayOutputStream ();
294+ byte [] b = new byte [0x1000 ];
295+ int nRead ;
296+ while ((nRead = in .read (b , 0 , b .length )) != -1 )
297+ bout .write (b , 0 , nRead );
298+ in .close ();
299+ return bout .toByteArray ();
300+ }
234301}
0 commit comments