mirror of
https://github.com/servalproject/serval-dna.git
synced 2024-12-18 20:57:56 +00:00
Add content type class for sending headers & matching responses
Note that android doesn't include javax so we can't use it.
This commit is contained in:
parent
262df2804d
commit
ad2f0364cf
@ -51,7 +51,7 @@ public abstract class AbstractId {
|
||||
return binary;
|
||||
}
|
||||
|
||||
public abstract String getMimeType();
|
||||
public abstract ContentType getMimeType();
|
||||
|
||||
public AbstractId(String hex) throws InvalidHexException {
|
||||
if (hex==null)
|
||||
|
@ -74,10 +74,15 @@ public abstract class AbstractJsonList<T, E extends Exception> {
|
||||
httpConnection = httpConnector.newServalDHttpConnection(request.verb, request.url);
|
||||
httpConnection.connect();
|
||||
|
||||
if ("application/json".equals(httpConnection.getContentType())){
|
||||
json = new JSONTokeniser(
|
||||
(httpConnection.getResponseCode() >= 300) ?
|
||||
httpConnection.getErrorStream() : httpConnection.getInputStream());
|
||||
try {
|
||||
ContentType contentType = new ContentType(httpConnection.getContentType());
|
||||
if (ContentType.applicationJson.matches(contentType)){
|
||||
json = new JSONTokeniser(
|
||||
(httpConnection.getResponseCode() >= 300) ?
|
||||
httpConnection.getErrorStream() : httpConnection.getInputStream());
|
||||
}
|
||||
} catch (ContentType.ContentTypeException e) {
|
||||
throw new ServalDInterfaceException("malformed HTTP Content-Type: " + httpConnection.getContentType(), e);
|
||||
}
|
||||
|
||||
if (httpConnection.getResponseCode()!=200){
|
||||
|
@ -37,8 +37,9 @@ public class BundleId extends SigningKey {
|
||||
super(binary);
|
||||
}
|
||||
|
||||
private static ContentType mimeType = ContentType.fromConstant("rhizome/bid; format=hex");
|
||||
@Override
|
||||
public String getMimeType() {
|
||||
return "rhizome/bid";
|
||||
public ContentType getMimeType() {
|
||||
return mimeType;
|
||||
}
|
||||
}
|
||||
|
@ -30,9 +30,10 @@ public class BundleKey extends AbstractId {
|
||||
return 32;
|
||||
}
|
||||
|
||||
private static ContentType mimeType = ContentType.fromConstant("rhizome/bundlekey; format=hex");
|
||||
@Override
|
||||
public String getMimeType() {
|
||||
return "rhizome/bundlekey";
|
||||
public ContentType getMimeType() {
|
||||
return mimeType;
|
||||
}
|
||||
|
||||
public BundleKey(String hex) throws InvalidHexException {
|
||||
|
@ -42,8 +42,9 @@ public class BundleSecret extends AbstractId {
|
||||
super(binary);
|
||||
}
|
||||
|
||||
private static ContentType mimeType = ContentType.fromConstant("rhizome/bundlesecret; format=hex");
|
||||
@Override
|
||||
public String getMimeType() {
|
||||
return "rhizome/bundlesecret";
|
||||
public ContentType getMimeType() {
|
||||
return mimeType;
|
||||
}
|
||||
}
|
||||
|
122
java-api/src/org/servalproject/servaldna/ContentType.java
Normal file
122
java-api/src/org/servalproject/servaldna/ContentType.java
Normal file
@ -0,0 +1,122 @@
|
||||
package org.servalproject.servaldna;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Android doesn't include javax.activation.MimeType, so we have to implement it ourselves
|
||||
*/
|
||||
|
||||
public class ContentType {
|
||||
public final String type;
|
||||
public final String subType;
|
||||
public final Map<String,String> parameters;
|
||||
|
||||
// a few common content types to match against
|
||||
public static ContentType textPlain = fromConstant("text/plain; charset=utf-8");
|
||||
public static ContentType applicationJson = fromConstant("application/json");
|
||||
public static ContentType applicationOctetStream = fromConstant("application/octet-stream");
|
||||
|
||||
public class ContentTypeException extends Exception{
|
||||
ContentTypeException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
||||
public ContentType(String contentType) throws ContentTypeException {
|
||||
int delim = contentType.indexOf(';');
|
||||
if (delim < 0)
|
||||
delim = contentType.length();
|
||||
int slash = contentType.indexOf('/');
|
||||
if (slash<0 || slash >delim)
|
||||
throw new ContentTypeException("Failed to parse "+contentType);
|
||||
type = contentType.substring(0,slash).trim().toLowerCase();
|
||||
subType = contentType.substring(slash+1,delim).trim().toLowerCase();
|
||||
parameters = new HashMap<>();
|
||||
while(delim < contentType.length()){
|
||||
int eq = contentType.indexOf('=',delim);
|
||||
String name = contentType.substring(delim+1,eq).trim().toLowerCase();
|
||||
String value;
|
||||
if (contentType.charAt(eq+1)=='"'){
|
||||
delim = eq+1;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
while(true){
|
||||
if (delim >= contentType.length())
|
||||
throw new ContentTypeException("Failed to parse "+contentType);
|
||||
char c=contentType.charAt(delim++);
|
||||
if (c == '"')
|
||||
break;
|
||||
if (c == '\\') {
|
||||
if (delim >= contentType.length())
|
||||
throw new ContentTypeException("Failed to parse "+contentType);
|
||||
c = contentType.charAt(delim++);
|
||||
}
|
||||
sb.append(c);
|
||||
}
|
||||
value = sb.toString();
|
||||
while(delim < contentType.length()){
|
||||
char c=contentType.charAt(delim++);
|
||||
if (c==';')
|
||||
break;
|
||||
if (c!=' ')
|
||||
throw new ContentTypeException("Failed to parse "+contentType);
|
||||
}
|
||||
}else{
|
||||
delim = contentType.indexOf(';',eq);
|
||||
if (delim <0)
|
||||
delim = contentType.length();
|
||||
value = contentType.substring(eq+1,delim).trim();
|
||||
}
|
||||
parameters.put(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean matches(ContentType other) {
|
||||
if (other==null)
|
||||
return false;
|
||||
if (type.equals(other.type) &&
|
||||
(subType.equals(other.subType) || subType.equals("*"))){
|
||||
for(Map.Entry<String,String> e: parameters.entrySet()){
|
||||
if (!e.getValue().equals(other.parameters.get(e.getKey())))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb
|
||||
.append(type)
|
||||
.append('/')
|
||||
.append(subType);
|
||||
if (!parameters.isEmpty()){
|
||||
for(Map.Entry<String,String> e: parameters.entrySet()){
|
||||
sb
|
||||
.append(';')
|
||||
.append(e.getKey())
|
||||
.append('=');
|
||||
String value = e.getValue();
|
||||
if (value.indexOf(';')>0 || value.indexOf('"')>0){
|
||||
sb
|
||||
.append('"')
|
||||
.append(value.replace("\"","\\\""))
|
||||
.append('"');
|
||||
}else{
|
||||
sb.append(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static ContentType fromConstant(String contentType){
|
||||
try {
|
||||
return new ContentType(contentType);
|
||||
} catch (ContentTypeException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
}
|
@ -32,9 +32,10 @@ public class FileHash extends AbstractId {
|
||||
return BINARY_SIZE;
|
||||
}
|
||||
|
||||
private static ContentType mimeType = ContentType.fromConstant("rhizome/filehash; format=hex");
|
||||
@Override
|
||||
public String getMimeType() {
|
||||
return "rhizome/filehash";
|
||||
public ContentType getMimeType() {
|
||||
return mimeType;
|
||||
}
|
||||
|
||||
public FileHash(String hex) throws InvalidHexException {
|
||||
|
@ -77,7 +77,7 @@ public class PostHelper {
|
||||
sb.append('"');
|
||||
}
|
||||
|
||||
protected void writeHeading(String name, String filename, String type, String encoding)
|
||||
protected void writeHeading(String name, String filename, ContentType type, String encoding)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("\r\n--").append(boundary).append("\r\n");
|
||||
@ -88,7 +88,7 @@ public class PostHelper {
|
||||
quoteString(sb, filename);
|
||||
}
|
||||
sb.append("\r\n");
|
||||
sb.append("Content-Type: ").append(type).append("\r\n");
|
||||
sb.append("Content-Type: ").append(type.toString()).append("\r\n");
|
||||
if (encoding!=null)
|
||||
sb.append("Content-Transfer-Encoding: ").append(encoding).append("\r\n");
|
||||
sb.append("\r\n");
|
||||
@ -96,17 +96,17 @@ public class PostHelper {
|
||||
}
|
||||
|
||||
public void writeField(String name, String value){
|
||||
writeHeading(name, null, "text/plain; charset=utf-8", null);
|
||||
writeHeading(name, null, ContentType.textPlain, null);
|
||||
writer.print(value);
|
||||
}
|
||||
|
||||
public void writeField(String name, AbstractId value){
|
||||
writeHeading(name, null, value.getMimeType() + "; format=hex", null);
|
||||
writeHeading(name, null, value.getMimeType(), null);
|
||||
writer.print(value.toHex());
|
||||
}
|
||||
|
||||
public OutputStream beginFileField(String name, String filename){
|
||||
writeHeading(name, filename, "application/octet-stream", "binary");
|
||||
writeHeading(name, filename, ContentType.applicationOctetStream, "binary");
|
||||
writer.flush();
|
||||
return output;
|
||||
}
|
||||
@ -119,13 +119,13 @@ public class PostHelper {
|
||||
output.write(buffer, 0, n);
|
||||
}
|
||||
|
||||
public void writeField(String name, String type, byte value[]) throws IOException {
|
||||
public void writeField(String name, ContentType type, byte value[]) throws IOException {
|
||||
writeHeading(name, null, type, "binary");
|
||||
writer.flush();
|
||||
output.write(value);
|
||||
}
|
||||
|
||||
public void writeField(String name, String type, byte value[], int offset, int length) throws IOException {
|
||||
public void writeField(String name, ContentType type, byte value[], int offset, int length) throws IOException {
|
||||
writeHeading(name, null, type, "binary");
|
||||
writer.flush();
|
||||
output.write(value, offset, length);
|
||||
|
@ -42,9 +42,10 @@ public class SigningKey extends AbstractId {
|
||||
return BINARY_SIZE;
|
||||
}
|
||||
|
||||
private static ContentType mimeType = ContentType.fromConstant("serval/identity; format=hex");
|
||||
@Override
|
||||
public String getMimeType() {
|
||||
return "serval/identity";
|
||||
public ContentType getMimeType() {
|
||||
return mimeType;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -31,9 +31,10 @@ public class SubscriberId extends AbstractId {
|
||||
return BINARY_SIZE;
|
||||
}
|
||||
|
||||
private static ContentType mimeType = ContentType.fromConstant("serval/sid; format=hex");
|
||||
@Override
|
||||
public String getMimeType() {
|
||||
return "serval/sid";
|
||||
public ContentType getMimeType() {
|
||||
return mimeType;
|
||||
}
|
||||
|
||||
public SubscriberId(String hex) throws InvalidHexException {
|
||||
|
@ -23,6 +23,7 @@ package org.servalproject.servaldna.keyring;
|
||||
|
||||
import org.servalproject.json.JSONInputException;
|
||||
import org.servalproject.json.JSONTokeniser;
|
||||
import org.servalproject.servaldna.ContentType;
|
||||
import org.servalproject.servaldna.ServalDHttpConnectionFactory;
|
||||
import org.servalproject.servaldna.ServalDInterfaceException;
|
||||
import org.servalproject.servaldna.ServalDNotImplementedException;
|
||||
@ -43,6 +44,7 @@ public class KeyringCommon
|
||||
{
|
||||
|
||||
public static class Status {
|
||||
ContentType contentType;
|
||||
InputStream input_stream;
|
||||
JSONTokeniser json;
|
||||
public int http_status_code;
|
||||
@ -61,14 +63,20 @@ public class KeyringCommon
|
||||
Status status = new Status();
|
||||
status.http_status_code = conn.getResponseCode();
|
||||
status.http_status_message = conn.getResponseMessage();
|
||||
try {
|
||||
status.contentType = new ContentType(conn.getContentType());
|
||||
} catch (ContentType.ContentTypeException e) {
|
||||
throw new ServalDInterfaceException("malformed HTTP Content-Type: " + conn.getContentType(),e);
|
||||
}
|
||||
|
||||
for (int code: expected_response_codes) {
|
||||
if (status.http_status_code == code) {
|
||||
status.input_stream = conn.getInputStream();
|
||||
return status;
|
||||
}
|
||||
}
|
||||
if (!conn.getContentType().equals("application/json"))
|
||||
throw new ServalDInterfaceException("unexpected HTTP Content-Type: " + conn.getContentType());
|
||||
if (!ContentType.applicationJson.matches(status.contentType))
|
||||
throw new ServalDInterfaceException("unexpected HTTP Content-Type: " + status.contentType);
|
||||
if (status.http_status_code >= 300) {
|
||||
status.json = new JSONTokeniser(conn.getErrorStream());
|
||||
decodeRestfulStatus(status);
|
||||
@ -97,8 +105,6 @@ public class KeyringCommon
|
||||
protected static Status receiveRestfulResponse(HttpURLConnection conn, int[] expected_response_codes) throws IOException, ServalDInterfaceException
|
||||
{
|
||||
Status status = receiveResponse(conn, expected_response_codes);
|
||||
if (!conn.getContentType().equals("application/json"))
|
||||
throw new ServalDInterfaceException("unexpected HTTP Content-Type: " + conn.getContentType());
|
||||
status.json = new JSONTokeniser(status.input_stream);
|
||||
return status;
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ package org.servalproject.servaldna.meshms;
|
||||
|
||||
import org.servalproject.json.JSONInputException;
|
||||
import org.servalproject.json.JSONTokeniser;
|
||||
import org.servalproject.servaldna.ContentType;
|
||||
import org.servalproject.servaldna.PostHelper;
|
||||
import org.servalproject.servaldna.ServalDFailureException;
|
||||
import org.servalproject.servaldna.ServalDHttpConnectionFactory;
|
||||
@ -44,18 +45,28 @@ public class MeshMSCommon
|
||||
|
||||
protected static JSONTokeniser receiveRestfulResponse(HttpURLConnection conn, int[] expected_response_codes) throws IOException, ServalDInterfaceException, MeshMSException
|
||||
{
|
||||
if (!"application/json".equals(conn.getContentType()))
|
||||
throw new ServalDInterfaceException("unexpected HTTP Content-Type: " + conn.getContentType());
|
||||
JSONTokeniser json = null;
|
||||
try {
|
||||
ContentType contentType = new ContentType(conn.getContentType());
|
||||
if (ContentType.applicationJson.matches(contentType)){
|
||||
if (conn.getResponseCode()>=300)
|
||||
json = new JSONTokeniser(conn.getErrorStream());
|
||||
else
|
||||
json = new JSONTokeniser(conn.getInputStream());
|
||||
}
|
||||
} catch (ContentType.ContentTypeException e) {
|
||||
throw new ServalDInterfaceException("malformed HTTP Content-Type: " + conn.getContentType());
|
||||
}
|
||||
for (int code: expected_response_codes) {
|
||||
if (conn.getResponseCode() == code) {
|
||||
JSONTokeniser json = new JSONTokeniser(conn.getInputStream());
|
||||
if (json == null)
|
||||
throw new ServalDInterfaceException("unexpected HTTP Content-Type: " + conn.getContentType());
|
||||
return json;
|
||||
}
|
||||
}
|
||||
switch (conn.getResponseCode()) {
|
||||
case HttpURLConnection.HTTP_NOT_FOUND:
|
||||
case 419: // Authentication Timeout, for missing secret
|
||||
JSONTokeniser json = new JSONTokeniser(conn.getErrorStream());
|
||||
Status status = decodeRestfulStatus(json);
|
||||
throwRestfulResponseExceptions(status, conn.getURL());
|
||||
throw new ServalDInterfaceException("unexpected MeshMS status = " + status.meshms_status_code + ", \"" + status.meshms_status_message + "\"");
|
||||
|
@ -26,6 +26,7 @@ import org.servalproject.json.JSONTokeniser;
|
||||
import org.servalproject.servaldna.BundleId;
|
||||
import org.servalproject.servaldna.BundleKey;
|
||||
import org.servalproject.servaldna.BundleSecret;
|
||||
import org.servalproject.servaldna.ContentType;
|
||||
import org.servalproject.servaldna.FileHash;
|
||||
import org.servalproject.servaldna.PostHelper;
|
||||
import org.servalproject.servaldna.ServalDFailureException;
|
||||
@ -49,25 +50,12 @@ import java.net.HttpURLConnection;
|
||||
import java.net.ProtocolException;
|
||||
import java.net.URL;
|
||||
import java.util.Enumeration;
|
||||
import javax.activation.MimeType;
|
||||
import javax.activation.MimeTypeParseException;
|
||||
|
||||
public class RhizomeCommon
|
||||
{
|
||||
public static final MimeType MIME_TYPE_RHIZOME_MANIFEST;
|
||||
|
||||
static {
|
||||
try {
|
||||
MIME_TYPE_RHIZOME_MANIFEST = new MimeType("rhizome/manifest; format=text+binarysig");
|
||||
}
|
||||
catch (MimeTypeParseException ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static class Status {
|
||||
URL url;
|
||||
String contentType;
|
||||
ContentType contentType;
|
||||
InputStream input_stream;
|
||||
public int http_status_code;
|
||||
public String http_status_message;
|
||||
@ -77,17 +65,6 @@ public class RhizomeCommon
|
||||
String payload_status_message;
|
||||
}
|
||||
|
||||
protected static boolean mimeTypeMatches(MimeType required, MimeType candidate) {
|
||||
if (!candidate.match(required))
|
||||
return false;
|
||||
for (Enumeration e = required.getParameters().getNames(); e.hasMoreElements(); ) {
|
||||
String name = (String) e.nextElement();
|
||||
if (!required.getParameter(name).equals(candidate.getParameter(name)))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected static Status receiveResponse(HttpURLConnection conn, int expected_response_code) throws IOException, ServalDInterfaceException
|
||||
{
|
||||
int[] expected_response_codes = { expected_response_code };
|
||||
@ -98,7 +75,11 @@ public class RhizomeCommon
|
||||
{
|
||||
Status status = new Status();
|
||||
status.url = conn.getURL();
|
||||
status.contentType = conn.getContentType();
|
||||
try {
|
||||
status.contentType = new ContentType(conn.getContentType());
|
||||
} catch (ContentType.ContentTypeException e) {
|
||||
throw new ServalDInterfaceException("malformed HTTP Content-Type: " + conn.getContentType(), e);
|
||||
}
|
||||
status.http_status_code = conn.getResponseCode();
|
||||
status.http_status_message = conn.getResponseMessage();
|
||||
for (int code: expected_response_codes) {
|
||||
@ -107,8 +88,8 @@ public class RhizomeCommon
|
||||
return status;
|
||||
}
|
||||
}
|
||||
if (!status.contentType.equals("application/json"))
|
||||
throw new ServalDInterfaceException("unexpected HTTP Content-Type: " + conn.getContentType());
|
||||
if (!ContentType.applicationJson.matches(status.contentType))
|
||||
throw new ServalDInterfaceException("unexpected HTTP Content-Type: " + status.contentType);
|
||||
|
||||
if (status.http_status_code >= 300) {
|
||||
JSONTokeniser json = new JSONTokeniser(conn.getErrorStream());
|
||||
@ -149,8 +130,8 @@ public class RhizomeCommon
|
||||
protected static JSONTokeniser receiveRestfulResponse(HttpURLConnection conn, int[] expected_response_codes) throws IOException, ServalDInterfaceException
|
||||
{
|
||||
Status status = receiveResponse(conn, expected_response_codes);
|
||||
if (!conn.getContentType().equals("application/json"))
|
||||
throw new ServalDInterfaceException("unexpected HTTP Content-Type: " + conn.getContentType());
|
||||
if (!ContentType.applicationJson.matches(status.contentType))
|
||||
throw new ServalDInterfaceException("unexpected HTTP Content-Type: " + status.contentType);
|
||||
if (status.input_stream == null)
|
||||
throw new ServalDInterfaceException("unexpected HTTP response: " + status.http_status_code + " " + status.http_status_message);
|
||||
return new JSONTokeniser(status.input_stream);
|
||||
@ -255,26 +236,18 @@ public class RhizomeCommon
|
||||
case NEW:
|
||||
return null;
|
||||
case SAME:
|
||||
try {
|
||||
MimeType content_type = new MimeType(conn.getContentType());
|
||||
if (mimeTypeMatches(MIME_TYPE_RHIZOME_MANIFEST, content_type)) {
|
||||
RhizomeManifest manifest = RhizomeManifest.fromTextFormat(status.input_stream);
|
||||
BundleExtra extra = bundleExtraFromHeaders(conn);
|
||||
return new RhizomeManifestBundle(manifest, extra.rowId, extra.insertTime, extra.author, extra.secret);
|
||||
}
|
||||
throw new ServalDInterfaceException("unexpected HTTP Content-Type: " + content_type);
|
||||
}
|
||||
catch (MimeTypeParseException ex) {
|
||||
throw new ServalDInterfaceException("invalid HTTP Content-Type: " + conn.getContentType());
|
||||
}
|
||||
if (!RhizomeManifest.MIME_TYPE.matches(status.contentType))
|
||||
throw new ServalDInterfaceException("unexpected HTTP Content-Type: " + status.contentType);
|
||||
RhizomeManifest manifest = RhizomeManifest.fromTextFormat(status.input_stream);
|
||||
BundleExtra extra = bundleExtraFromHeaders(conn);
|
||||
return new RhizomeManifestBundle(manifest, extra.rowId, extra.insertTime, extra.author, extra.secret);
|
||||
case ERROR:
|
||||
throw new ServalDFailureException("received rhizome_bundle_status_code=ERROR(-1) from " + conn.getURL());
|
||||
}
|
||||
}
|
||||
catch (RhizomeManifestParseException e) {
|
||||
throw new ServalDInterfaceException("malformed manifest from daemon", e);
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
if (status.input_stream != null)
|
||||
status.input_stream.close();
|
||||
}
|
||||
@ -310,8 +283,8 @@ public class RhizomeCommon
|
||||
}
|
||||
// FALL THROUGH
|
||||
case STORED: {
|
||||
if (status.input_stream != null && !conn.getContentType().equals("application/octet-stream"))
|
||||
throw new ServalDInterfaceException("unexpected HTTP Content-Type: " + conn.getContentType());
|
||||
if (status.input_stream != null && !ContentType.applicationOctetStream.matches(status.contentType))
|
||||
throw new ServalDInterfaceException("unexpected HTTP Content-Type: " + status.contentType);
|
||||
RhizomeManifest manifest = manifestFromHeaders(conn);
|
||||
BundleExtra extra = bundleExtraFromHeaders(conn);
|
||||
RhizomePayloadRawBundle ret = new RhizomePayloadRawBundle(manifest, status.input_stream, extra.rowId, extra.insertTime, extra.author, extra.secret);
|
||||
@ -386,8 +359,8 @@ public class RhizomeCommon
|
||||
}
|
||||
// FALL THROUGH
|
||||
case STORED: {
|
||||
if (status.input_stream != null && !conn.getContentType().equals("application/octet-stream"))
|
||||
throw new ServalDInterfaceException("unexpected HTTP Content-Type: " + conn.getContentType());
|
||||
if (status.input_stream != null && !ContentType.applicationOctetStream.matches(status.contentType))
|
||||
throw new ServalDInterfaceException("unexpected HTTP Content-Type: " + status.contentType);
|
||||
RhizomeManifest manifest = manifestFromHeaders(conn);
|
||||
BundleExtra extra = bundleExtraFromHeaders(conn);
|
||||
RhizomePayloadBundle ret = new RhizomePayloadBundle(manifest, status.input_stream, extra.rowId, extra.insertTime, extra.author, extra.secret);
|
||||
@ -484,9 +457,8 @@ public class RhizomeCommon
|
||||
decodeHeaderBundleStatus(status, conn);
|
||||
checkBundleStatus(status);
|
||||
|
||||
MimeType content_type = new MimeType(status.contentType);
|
||||
if (!mimeTypeMatches(MIME_TYPE_RHIZOME_MANIFEST, content_type))
|
||||
throw new ServalDInterfaceException("unexpected HTTP Content-Type " + content_type + " from " + status.url + ", expecting " + MIME_TYPE_RHIZOME_MANIFEST);
|
||||
if (!RhizomeManifest.MIME_TYPE.matches(status.contentType))
|
||||
throw new ServalDInterfaceException("unexpected HTTP Content-Type " + status.contentType + " from " + status.url);
|
||||
|
||||
RhizomeManifest returned_manifest = RhizomeManifest.fromTextFormat(status.input_stream);
|
||||
BundleExtra extra = bundleExtraFromHeaders(conn);
|
||||
@ -495,9 +467,6 @@ public class RhizomeCommon
|
||||
catch (RhizomeManifestParseException e) {
|
||||
throw new ServalDInterfaceException("malformed manifest from daemon", e);
|
||||
}
|
||||
catch (MimeTypeParseException ex) {
|
||||
throw new ServalDInterfaceException("invalid HTTP Content-Type: " + status.contentType);
|
||||
}
|
||||
finally {
|
||||
if (status.input_stream != null)
|
||||
status.input_stream.close();
|
||||
|
@ -35,6 +35,7 @@ import java.io.OutputStreamWriter;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import org.servalproject.servaldna.AbstractId;
|
||||
import org.servalproject.servaldna.ContentType;
|
||||
import org.servalproject.servaldna.SubscriberId;
|
||||
import org.servalproject.servaldna.BundleId;
|
||||
import org.servalproject.servaldna.FileHash;
|
||||
@ -43,7 +44,7 @@ import org.servalproject.servaldna.BundleKey;
|
||||
public class RhizomeManifest {
|
||||
|
||||
public final static int TEXT_FORMAT_MAX_SIZE = 8192;
|
||||
public static final String MIME_TYPE = "rhizome/manifest; format=text+binarysig";
|
||||
public static final ContentType MIME_TYPE = ContentType.fromConstant("rhizome/manifest; format=text+binarysig");
|
||||
|
||||
// Core fields used for routing and expiry (cannot be null)
|
||||
public final BundleId id;
|
||||
|
Loading…
Reference in New Issue
Block a user