Rhizome Java API: get decrypted payload

This commit is contained in:
Andrew Bettison 2014-07-03 17:23:11 +09:30
parent d16be8f42d
commit 2aec8f31a4
15 changed files with 597 additions and 32 deletions

View File

@ -54,6 +54,10 @@ public class JSONTokeniser {
public static class UnexpectedException extends JSONInputException
{
public UnexpectedException(String got) {
super("unexpected " + got);
}
public UnexpectedException(String got, Class expecting) {
super("unexpected " + got + ", expecting " + expecting.getName());
}
@ -78,6 +82,10 @@ public class JSONTokeniser {
public static class UnexpectedTokenException extends UnexpectedException
{
public UnexpectedTokenException(Object got) {
super(jsonTokenDescription(got));
}
public UnexpectedTokenException(Object got, Class expecting) {
super(jsonTokenDescription(got), expecting);
}
@ -115,6 +123,11 @@ public class JSONTokeniser {
return n;
}
public static void unexpected(Object tok) throws UnexpectedTokenException
{
throw new UnexpectedTokenException(tok);
}
public static void match(Object tok, Token exactly) throws SyntaxException
{
if (tok != exactly)

View File

@ -39,6 +39,8 @@ import org.servalproject.servaldna.rhizome.RhizomeCommon;
import org.servalproject.servaldna.rhizome.RhizomeBundleList;
import org.servalproject.servaldna.rhizome.RhizomeManifestBundle;
import org.servalproject.servaldna.rhizome.RhizomePayloadRawBundle;
import org.servalproject.servaldna.rhizome.RhizomePayloadBundle;
import org.servalproject.servaldna.rhizome.RhizomeException;
import org.servalproject.servaldna.meshms.MeshMSCommon;
import org.servalproject.servaldna.meshms.MeshMSConversationList;
import org.servalproject.servaldna.meshms.MeshMSMessageList;
@ -63,23 +65,28 @@ public class ServalDClient implements ServalDHttpConnectionFactory
this.restfulPassword = restfulPassword;
}
public RhizomeBundleList rhizomeListBundles() throws ServalDInterfaceException, IOException
public RhizomeBundleList rhizomeListBundles() throws ServalDInterfaceException, IOException, RhizomeException
{
RhizomeBundleList list = new RhizomeBundleList(this);
list.connect();
return list;
}
public RhizomeManifestBundle rhizomeManifest(BundleId bid) throws ServalDInterfaceException, IOException
public RhizomeManifestBundle rhizomeManifest(BundleId bid) throws ServalDInterfaceException, IOException, RhizomeException
{
return RhizomeCommon.rhizomeManifest(this, bid);
}
public RhizomePayloadRawBundle rhizomePayloadRaw(BundleId bid) throws ServalDInterfaceException, IOException
public RhizomePayloadRawBundle rhizomePayloadRaw(BundleId bid) throws ServalDInterfaceException, IOException, RhizomeException
{
return RhizomeCommon.rhizomePayloadRaw(this, bid);
}
public RhizomePayloadBundle rhizomePayload(BundleId bid) throws ServalDInterfaceException, IOException, RhizomeException
{
return RhizomeCommon.rhizomePayload(this, bid);
}
public MeshMSConversationList meshmsListConversations(SubscriberId sid) throws ServalDInterfaceException, IOException, MeshMSException
{
MeshMSConversationList list = new MeshMSConversationList(this, sid);

View File

@ -68,7 +68,7 @@ public class RhizomeBundleList {
return this.json != null;
}
public void connect() throws IOException, ServalDInterfaceException
public void connect() throws IOException, ServalDInterfaceException, RhizomeException
{
try {
rowCount = 0;

View File

@ -0,0 +1,71 @@
/**
* Copyright (C) 2014 Serval Project Inc.
*
* This file is part of Serval Software (http://www.servalproject.org)
*
* Serval Software is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This source code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this source code; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.servalproject.servaldna.rhizome;
import org.servalproject.servaldna.ServalDInterfaceException;
/* This enum is a direct isomorphism from the C "enum rhizome_bundle_status" defined in rhizome.h.
*/
public enum RhizomeBundleStatus {
ERROR(-1), // internal error
NEW(0), // bundle is newer than store
SAME(1), // same version already in store
DUPLICATE(2), // equivalent bundle already in store
OLD(3), // newer version already in store
INVALID(4), // manifest is invalid
FAKE(5), // manifest signature not valid
INCONSISTENT(6), // manifest filesize/filehash does not match supplied payload
NO_ROOM(7) // doesn't fit; store may contain more important bundles
;
final public int code;
private RhizomeBundleStatus(int code) {
this.code = code;
}
public static RhizomeBundleStatus fromCode(int code) throws InvalidException
{
RhizomeBundleStatus status = null;
switch (code) {
case -1: status = ERROR; break;
case 0: status = NEW; break;
case 1: status = SAME; break;
case 2: status = DUPLICATE; break;
case 3: status = OLD; break;
case 4: status = INVALID; break;
case 5: status = FAKE; break;
case 6: status = INCONSISTENT; break;
case 7: status = NO_ROOM; break;
default: throw new InvalidException(code);
}
assert status.code == code;
return status;
}
public static class InvalidException extends ServalDInterfaceException
{
public InvalidException(int code) {
super("invalid Rhizome bundle status code = " + code);
}
}
}

View File

@ -28,6 +28,7 @@ import java.io.IOException;
import java.io.PrintStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.HttpURLConnection;
import org.servalproject.json.JSONTokeniser;
import org.servalproject.json.JSONInputException;
@ -43,13 +44,22 @@ import org.servalproject.servaldna.ServalDFailureException;
public class RhizomeCommon
{
protected static InputStream receiveResponse(HttpURLConnection conn, int expected_response_code) throws IOException, ServalDInterfaceException
private static class Status {
public int http_status_code;
public String http_status_message;
RhizomeBundleStatus bundle_status_code;
String bundle_status_message;
RhizomePayloadStatus payload_status_code;
String payload_status_message;
}
protected static InputStream receiveResponse(HttpURLConnection conn, int expected_response_code) throws IOException, ServalDInterfaceException, RhizomeException
{
int[] expected_response_codes = { expected_response_code };
return receiveResponse(conn, expected_response_codes);
}
protected static InputStream receiveResponse(HttpURLConnection conn, int[] expected_response_codes) throws IOException, ServalDInterfaceException
protected static InputStream receiveResponse(HttpURLConnection conn, int[] expected_response_codes) throws IOException, ServalDInterfaceException, RhizomeException
{
for (int code: expected_response_codes) {
if (conn.getResponseCode() == code)
@ -60,18 +70,64 @@ public class RhizomeCommon
if (conn.getResponseCode() == HttpURLConnection.HTTP_FORBIDDEN) {
JSONTokeniser json = new JSONTokeniser(new InputStreamReader(conn.getErrorStream(), "US-ASCII"));
Status status = decodeRestfulStatus(json);
throw new ServalDInterfaceException("unexpected Rhizome failure, \"" + status.message + "\"");
throwRestfulResponseExceptions(status, conn.getURL());
throw new ServalDInterfaceException(
"unexpected Rhizome failure, \"" + status.http_status_message + "\""
+ (status.bundle_status_code == null ? "" : ", " + status.bundle_status_code)
+ (status.bundle_status_message == null ? "" : " \"" + status.bundle_status_message + "\"")
+ (status.payload_status_code == null ? "" : ", " + status.payload_status_code)
+ (status.payload_status_message == null ? "" : ", " + status.payload_status_message + "\"")
);
}
throw new ServalDInterfaceException("unexpected HTTP response code: " + conn.getResponseCode());
}
protected static JSONTokeniser receiveRestfulResponse(HttpURLConnection conn, int expected_response_code) throws IOException, ServalDInterfaceException
protected static void throwRestfulResponseExceptions(Status status, URL url) throws RhizomeException, ServalDFailureException
{
if (status.bundle_status_code != null) {
switch (status.bundle_status_code) {
case ERROR:
throw new ServalDFailureException("received rhizome_bundle_status_code=ERROR(-1) from " + url);
case NEW:
case SAME:
case DUPLICATE:
case OLD:
case NO_ROOM:
break;
case INVALID:
throw new RhizomeInvalidManifestException(url);
case FAKE:
throw new RhizomeFakeManifestException(url);
case INCONSISTENT:
throw new RhizomeInconsistencyException(url);
}
}
if (status.payload_status_code != null) {
switch (status.payload_status_code) {
case ERROR:
throw new ServalDFailureException("received rhizome_payload_status_code=ERROR(-1) from " + url);
case EMPTY:
case NEW:
case STORED:
case TOO_BIG:
case EVICTED:
break;
case WRONG_SIZE:
case WRONG_HASH:
throw new RhizomeInconsistencyException(url);
case CRYPTO_FAIL:
throw new RhizomeDecryptionException(url);
}
}
}
protected static JSONTokeniser receiveRestfulResponse(HttpURLConnection conn, int expected_response_code) throws IOException, ServalDInterfaceException, RhizomeException
{
int[] expected_response_codes = { expected_response_code };
return receiveRestfulResponse(conn, expected_response_codes);
}
protected static JSONTokeniser receiveRestfulResponse(HttpURLConnection conn, int[] expected_response_codes) throws IOException, ServalDInterfaceException
protected static JSONTokeniser receiveRestfulResponse(HttpURLConnection conn, int[] expected_response_codes) throws IOException, ServalDInterfaceException, RhizomeException
{
InputStream in = receiveResponse(conn, expected_response_codes);
if (!conn.getContentType().equals("application/json"))
@ -79,10 +135,6 @@ public class RhizomeCommon
return new JSONTokeniser(new InputStreamReader(in, "US-ASCII"));
}
private static class Status {
public String message;
}
protected static Status decodeRestfulStatus(JSONTokeniser json) throws IOException, ServalDInterfaceException
{
try {
@ -90,12 +142,28 @@ public class RhizomeCommon
json.consume(JSONTokeniser.Token.START_OBJECT);
json.consume("http_status_code");
json.consume(JSONTokeniser.Token.COLON);
json.consume(Integer.class);
status.http_status_code = json.consume(Integer.class);
json.consume(JSONTokeniser.Token.COMMA);
status.message = json.consume("http_status_message");
json.consume("http_status_message");
json.consume(JSONTokeniser.Token.COLON);
String message = json.consume(String.class);
json.consume(JSONTokeniser.Token.END_OBJECT);
status.http_status_message = json.consume(String.class);
Object tok = json.nextToken();
while (tok == JSONTokeniser.Token.COMMA) {
String label = json.consume(String.class);
json.consume(JSONTokeniser.Token.COLON);
if (label.equals("rhizome_bundle_status_code"))
status.bundle_status_code = RhizomeBundleStatus.fromCode(json.consume(Integer.class));
else if (label.equals("rhizome_bundle_status_message"))
status.bundle_status_message = json.consume(String.class);
else if (label.equals("rhizome_payload_status_code"))
status.payload_status_code = RhizomePayloadStatus.fromCode(json.consume(Integer.class));
else if (label.equals("rhizome_payload_status_message"))
status.payload_status_message = json.consume(String.class);
else
json.unexpected(label);
tok = json.nextToken();
}
json.match(tok, JSONTokeniser.Token.END_OBJECT);
json.consume(JSONTokeniser.Token.EOF);
return status;
}
@ -104,7 +172,7 @@ public class RhizomeCommon
}
}
public static RhizomeManifestBundle rhizomeManifest(ServalDHttpConnectionFactory connector, BundleId bid) throws IOException, ServalDInterfaceException
public static RhizomeManifestBundle rhizomeManifest(ServalDHttpConnectionFactory connector, BundleId bid) throws IOException, ServalDInterfaceException, RhizomeException
{
HttpURLConnection conn = connector.newServalDHttpConnection("/restful/rhizome/" + bid.toHex() + ".rhm");
conn.connect();
@ -128,7 +196,7 @@ public class RhizomeCommon
return new RhizomeManifestBundle(manifest, insertTime, author, secret);
}
public static RhizomePayloadRawBundle rhizomePayloadRaw(ServalDHttpConnectionFactory connector, BundleId bid) throws IOException, ServalDInterfaceException
public static RhizomePayloadRawBundle rhizomePayloadRaw(ServalDHttpConnectionFactory connector, BundleId bid) throws IOException, ServalDInterfaceException, RhizomeException
{
HttpURLConnection conn = connector.newServalDHttpConnection("/restful/rhizome/" + bid.toHex() + "/raw.bin");
conn.connect();
@ -143,6 +211,21 @@ public class RhizomeCommon
return new RhizomePayloadRawBundle(manifest, in, insertTime, author, secret);
}
public static RhizomePayloadBundle rhizomePayload(ServalDHttpConnectionFactory connector, BundleId bid) throws IOException, ServalDInterfaceException, RhizomeException
{
HttpURLConnection conn = connector.newServalDHttpConnection("/restful/rhizome/" + bid.toHex() + "/decrypted.bin");
conn.connect();
InputStream in = RhizomeCommon.receiveResponse(conn, HttpURLConnection.HTTP_OK);
if (!conn.getContentType().equals("application/octet-stream"))
throw new ServalDInterfaceException("unexpected HTTP Content-Type: " + conn.getContentType());
dumpHeaders(conn, System.err);
RhizomeManifest manifest = manifestFromHeaders(conn);
long insertTime = headerUnsignedLong(conn, "Serval-Rhizome-Bundle-Inserttime");
SubscriberId author = header(conn, "Serval-Rhizome-Bundle-Author", SubscriberId.class);
BundleSecret secret = header(conn, "Serval-Rhizome-Bundle-Secret", BundleSecret.class);
return new RhizomePayloadBundle(manifest, in, insertTime, author, secret);
}
private static void dumpHeaders(HttpURLConnection conn, PrintStream out)
{
for (Map.Entry<String,List<String>> e: conn.getHeaderFields().entrySet())

View File

@ -0,0 +1,37 @@
/**
* Copyright (C) 2014 Serval Project Inc.
*
* This file is part of Serval Software (http://www.servalproject.org)
*
* Serval Software is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This source code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this source code; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.servalproject.servaldna.rhizome;
import java.net.URL;
/**
* Thrown when a Rhizome API method is asked to decrypt a payload without possessing the necessary
* recipient identity (ie, is locked or not in the keyring).
*
* @author Andrew Bettison <andrew@servalproject.com>
*/
public class RhizomeDecryptionException extends RhizomeException
{
public RhizomeDecryptionException(URL url) {
super("cannot decrypt payload", url);
}
}

View File

@ -0,0 +1,40 @@
/**
* Copyright (C) 2014 Serval Project Inc.
*
* This file is part of Serval Software (http://www.servalproject.org)
*
* Serval Software is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This source code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this source code; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.servalproject.servaldna.rhizome;
import java.net.URL;
/**
* Thrown when a Rhizome API encounters an exceptional condition. This exception is subclassed for
* specific causes.
*
* @author Andrew Bettison <andrew@servalproject.com>
*/
public abstract class RhizomeException extends Exception
{
public final URL url;
public RhizomeException(String message, URL url) {
super(message + "; " + url);
this.url = url;
}
}

View File

@ -0,0 +1,36 @@
/**
* Copyright (C) 2014 Serval Project Inc.
*
* This file is part of Serval Software (http://www.servalproject.org)
*
* Serval Software is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This source code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this source code; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.servalproject.servaldna.rhizome;
import java.net.URL;
/**
* Thrown when a Rhizome API method is passed a manifest with an invalid or missing signature.
*
* @author Andrew Bettison <andrew@servalproject.com>
*/
public class RhizomeFakeManifestException extends RhizomeException
{
public RhizomeFakeManifestException(URL url) {
super("unsigned manifest", url);
}
}

View File

@ -0,0 +1,37 @@
/**
* Copyright (C) 2014 Serval Project Inc.
*
* This file is part of Serval Software (http://www.servalproject.org)
*
* Serval Software is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This source code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this source code; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.servalproject.servaldna.rhizome;
import java.net.URL;
/**
* Thrown when a Rhizome API method is passed a manifest which is inconsistent with a supplied
* payload. I.e., filesize or filehash does not match.
*
* @author Andrew Bettison <andrew@servalproject.com>
*/
public class RhizomeInconsistencyException extends RhizomeException
{
public RhizomeInconsistencyException(URL url) {
super("manifest inconsistent with payload", url);
}
}

View File

@ -0,0 +1,38 @@
/**
* Copyright (C) 2014 Serval Project Inc.
*
* This file is part of Serval Software (http://www.servalproject.org)
*
* Serval Software is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This source code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this source code; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.servalproject.servaldna.rhizome;
import java.net.URL;
/**
* Thrown when a Rhizome API method is passed an invalid manifest. This is not an error within the
* Serval DNA interface, so it is not a subclass of ServalDInterfaceException. The programmer must
* explicitly deal with it instead of just absorbing it as an interface malfunction.
*
* @author Andrew Bettison <andrew@servalproject.com>
*/
public class RhizomeInvalidManifestException extends RhizomeException
{
public RhizomeInvalidManifestException(URL url) {
super("invalid manifest", url);
}
}

View File

@ -0,0 +1,50 @@
/**
* Copyright (C) 2014 Serval Project Inc.
*
* This file is part of Serval Software (http://www.servalproject.org)
*
* Serval Software is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This source code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this source code; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.servalproject.servaldna.rhizome;
import java.io.InputStream;
import org.servalproject.servaldna.SubscriberId;
import org.servalproject.servaldna.BundleSecret;
import org.servalproject.servaldna.ServalDInterfaceException;
public class RhizomePayloadBundle {
public final RhizomeManifest manifest;
public final InputStream payloadInputStream;
public final long insertTime;
public final SubscriberId author;
public final BundleSecret secret;
protected RhizomePayloadBundle(RhizomeManifest manifest,
InputStream payloadInputStream,
long insertTime,
SubscriberId author,
BundleSecret secret)
{
this.payloadInputStream = payloadInputStream;
this.manifest = manifest;
this.insertTime = insertTime;
this.author = author;
this.secret = secret;
}
}

View File

@ -0,0 +1,71 @@
/**
* Copyright (C) 2014 Serval Project Inc.
*
* This file is part of Serval Software (http://www.servalproject.org)
*
* Serval Software is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This source code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this source code; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.servalproject.servaldna.rhizome;
import org.servalproject.servaldna.ServalDInterfaceException;
/* This enum is a direct isomorphism from the C "enum rhizome_payload_status" defined in rhizome.h.
*/
public enum RhizomePayloadStatus {
ERROR(-1), // unexpected error (underlying failure)
EMPTY(0), // payload is empty (zero length)
NEW(1), // payload is not yet in store (added)
STORED(2), // payload is already in store
WRONG_SIZE(3), // payload's size does not match manifest
WRONG_HASH(4), // payload's hash does not match manifest
CRYPTO_FAIL(5), // cannot encrypt/decrypt (payload key unknown)
TOO_BIG(6), // payload will never fit in our store
EVICTED(7) // other payloads in our store are more important
;
final public int code;
private RhizomePayloadStatus(int code) {
this.code = code;
}
public static RhizomePayloadStatus fromCode(int code) throws InvalidException
{
RhizomePayloadStatus status = null;
switch (code) {
case -1: status = ERROR; break;
case 0: status = EMPTY; break;
case 1: status = NEW; break;
case 2: status = STORED; break;
case 3: status = WRONG_SIZE; break;
case 4: status = WRONG_HASH; break;
case 5: status = CRYPTO_FAIL; break;
case 6: status = TOO_BIG; break;
case 7: status = EVICTED; break;
default: throw new InvalidException(code);
}
assert status.code == code;
return status;
}
public static class InvalidException extends ServalDInterfaceException
{
public InvalidException(int code) {
super("invalid Rhizome payload status code = " + code);
}
}
}

View File

@ -33,6 +33,8 @@ import org.servalproject.servaldna.rhizome.RhizomeListBundle;
import org.servalproject.servaldna.rhizome.RhizomeBundleList;
import org.servalproject.servaldna.rhizome.RhizomeManifestBundle;
import org.servalproject.servaldna.rhizome.RhizomePayloadRawBundle;
import org.servalproject.servaldna.rhizome.RhizomePayloadBundle;
import org.servalproject.servaldna.rhizome.RhizomeException;
public class Rhizome {
@ -68,6 +70,9 @@ public class Rhizome {
);
}
}
catch (RhizomeException e) {
System.out.println(e.toString());
}
finally {
if (list != null)
list.close();
@ -77,17 +82,22 @@ public class Rhizome {
static void rhizome_manifest(BundleId bid, String dstpath) throws ServalDInterfaceException, IOException, InterruptedException
{
ServalDClient client = new ServerControl().getRestfulClient();
RhizomeManifestBundle bundle = client.rhizomeManifest(bid);
System.out.println(
"_insertTime=" + bundle.insertTime + "\n" +
"_author=" + bundle.author + "\n" +
"_secret=" + bundle.secret + "\n" +
manifestFields(bundle.manifest, "\n") + "\n"
);
FileOutputStream out = new FileOutputStream(dstpath);
out.write(bundle.manifestText());
out.close();
try {
ServalDClient client = new ServerControl().getRestfulClient();
RhizomeManifestBundle bundle = client.rhizomeManifest(bid);
System.out.println(
"_insertTime=" + bundle.insertTime + "\n" +
"_author=" + bundle.author + "\n" +
"_secret=" + bundle.secret + "\n" +
manifestFields(bundle.manifest, "\n") + "\n"
);
FileOutputStream out = new FileOutputStream(dstpath);
out.write(bundle.manifestText());
out.close();
}
catch (RhizomeException e) {
System.out.println(e.toString());
}
System.exit(0);
}
@ -112,6 +122,40 @@ public class Rhizome {
manifestFields(bundle.manifest, "\n") + "\n"
);
}
catch (RhizomeException e) {
System.out.println(e.toString());
}
finally {
if (out != null)
out.close();
}
System.exit(0);
}
static void rhizome_payload_decrypted(BundleId bid, String dstpath) throws ServalDInterfaceException, IOException, InterruptedException
{
ServalDClient client = new ServerControl().getRestfulClient();
FileOutputStream out = new FileOutputStream(dstpath);
try {
RhizomePayloadBundle bundle = client.rhizomePayload(bid);
InputStream in = bundle.payloadInputStream;
byte[] buf = new byte[4096];
int n;
while ((n = in.read(buf)) > 0)
out.write(buf, 0, n);
in.close();
out.close();
out = null;
System.out.println(
"_insertTime=" + bundle.insertTime + "\n" +
"_author=" + bundle.author + "\n" +
"_secret=" + bundle.secret + "\n" +
manifestFields(bundle.manifest, "\n") + "\n"
);
}
catch (RhizomeException e) {
System.out.println(e.toString());
}
finally {
if (out != null)
out.close();
@ -131,6 +175,8 @@ public class Rhizome {
rhizome_manifest(new BundleId(args[1]), args[2]);
else if (methodName.equals("rhizome-payload-raw"))
rhizome_payload_raw(new BundleId(args[1]), args[2]);
else if (methodName.equals("rhizome-payload-decrypted"))
rhizome_payload_decrypted(new BundleId(args[1]), args[2]);
} catch (Exception e) {
e.printStackTrace();
System.exit(1);

View File

@ -727,7 +727,7 @@ static int restful_rhizome_bid_raw_bin(httpd_request *r, const char *remainder)
}
int ret = rhizome_response_content_init_filehash(r, &r->manifest->filehash);
if (ret)
return ret;
return http_request_rhizome_response(r, ret, NULL, NULL);
http_request_response_generated(&r->http, 200, CONTENT_TYPE_BLOB, rhizome_payload_content);
return 1;
}
@ -745,7 +745,7 @@ static int restful_rhizome_bid_decrypted_bin(httpd_request *r, const char *remai
}
int ret = rhizome_response_content_init_payload(r, r->manifest);
if (ret)
return ret;
return http_request_rhizome_response(r, ret, NULL, NULL);
// TODO use Content Type from manifest (once it is implemented)
http_request_response_generated(&r->http, 200, CONTENT_TYPE_BLOB, rhizome_payload_content);
return 1;

View File

@ -180,8 +180,44 @@ test_RhizomePayloadRaw() {
executeJavaOk org.servalproject.test.Rhizome rhizome-payload-raw "${BID[$n]}" raw.bin$n
tfw_cat --stdout --stderr
assert_metadata $n
done
for n in 0 1 2 3; do
assert cmp raw$n raw.bin$n
done
}
doc_RhizomePayloadDecrypted="Java API fetch Rhizome decrypted payload"
setup_RhizomePayloadDecrypted() {
setup
rhizome_add_bundles $SIDA1 0 1
rhizome_add_bundles --encrypted $SIDA1 2 3
}
test_RhizomePayloadDecrypted() {
for n in 0 1 2 3; do
executeJavaOk org.servalproject.test.Rhizome rhizome-payload-decrypted "${BID[$n]}" decrypted.bin$n
tfw_cat --stdout --stderr
assert_metadata $n
done
for n in 0 1 2 3; do
assert cmp file$n decrypted.bin$n
done
}
doc_RhizomePayloadDecryptedForeign="Java API cannot fetch foreign Rhizome decrypted payload"
setup_RhizomePayloadDecryptedForeign() {
setup
rhizome_add_bundles --encrypted $SIDA1 0 0
set_instance +B
create_single_identity
rhizome_add_bundles --encrypted $SIDB 1 1
executeOk_servald rhizome export manifest "${BID[1]}" file1.manifest
set_instance +A
executeOk_servald rhizome import bundle raw1 file1.manifest
}
test_RhizomePayloadDecryptedForeign() {
executeJavaOk org.servalproject.test.Rhizome rhizome-payload-decrypted "${BID[1]}" decrypted.bin$n
tfw_cat --stdout --stderr
assertStdoutGrep RhizomeDecryptionException
}
runTests "$@"