Author: toad
Date: 2005-10-28 15:12:45 +0000 (Fri, 28 Oct 2005)
New Revision: 7461
Modified:
trunk/freenet/src/freenet/client/ArchiveHandler.java
trunk/freenet/src/freenet/client/ArchiveManager.java
trunk/freenet/src/freenet/client/ArchiveStoreContext.java
trunk/freenet/src/freenet/client/FetchException.java
trunk/freenet/src/freenet/client/Fetcher.java
trunk/freenet/src/freenet/client/FetcherContext.java
trunk/freenet/src/freenet/client/HighLevelSimpleClientImpl.java
Log:
Implicit archive support.
Modified: trunk/freenet/src/freenet/client/ArchiveHandler.java
===================================================================
--- trunk/freenet/src/freenet/client/ArchiveHandler.java 2005-10-27
22:02:36 UTC (rev 7460)
+++ trunk/freenet/src/freenet/client/ArchiveHandler.java 2005-10-28
15:12:45 UTC (rev 7461)
@@ -14,7 +14,8 @@
* @throws MetadataParseException If there was an error parsing
intermediary metadata.
*/
public abstract Bucket getMetadata(ArchiveContext archiveContext,
- FetcherContext fetchContext, ClientMetadata dm, int
recursionLevel)
+ FetcherContext fetchContext, ClientMetadata dm, int
recursionLevel,
+ boolean dontEnterImplicitArchives)
throws ArchiveFailureException, ArchiveRestartException,
MetadataParseException, FetchException;
@@ -30,7 +31,8 @@
*/
public abstract Bucket get(String internalName,
ArchiveContext archiveContext, FetcherContext
fetchContext,
- ClientMetadata dm, int recursionLevel)
+ ClientMetadata dm, int recursionLevel,
+ boolean dontEnterImplicitArchives)
throws ArchiveFailureException, ArchiveRestartException,
MetadataParseException, FetchException;
Modified: trunk/freenet/src/freenet/client/ArchiveManager.java
===================================================================
--- trunk/freenet/src/freenet/client/ArchiveManager.java 2005-10-27
22:02:36 UTC (rev 7460)
+++ trunk/freenet/src/freenet/client/ArchiveManager.java 2005-10-28
15:12:45 UTC (rev 7461)
@@ -225,6 +225,7 @@
* - Turn the master Metadata object into binary metadata, with
all its subsidiaries.
* - Create a .metadata entry containing this data.
*/
+
// TODO implement!
}
@@ -280,4 +281,15 @@
throw new Error("Unsupported cipher: AES 256/256!", e);
}
}
+
+ public static boolean isUsableArchiveType(String type) {
+ return type.equals("application/zip") ||
type.equals("application/x-zip");
+ // Update when add new archive types
+ }
+
+ public static short getArchiveType(String type) {
+ if(type.equals("application/zip") ||
type.equals("application/x-zip"))
+ return Metadata.ARCHIVE_ZIP;
+ else throw new IllegalArgumentException();
+ }
}
Modified: trunk/freenet/src/freenet/client/ArchiveStoreContext.java
===================================================================
--- trunk/freenet/src/freenet/client/ArchiveStoreContext.java 2005-10-27
22:02:36 UTC (rev 7460)
+++ trunk/freenet/src/freenet/client/ArchiveStoreContext.java 2005-10-28
15:12:45 UTC (rev 7461)
@@ -30,17 +30,13 @@
// Need to do anything here?
}
- /* (non-Javadoc)
- * @see
freenet.client.ArchiveHandler#getMetadata(freenet.client.ArchiveContext,
freenet.client.FetcherContext, freenet.client.ClientMetadata, int)
- */
- public Bucket getMetadata(ArchiveContext archiveContext, FetcherContext
fetchContext, ClientMetadata dm, int recursionLevel) throws
ArchiveFailureException, ArchiveRestartException, MetadataParseException,
FetchException {
- return get(".metadata", archiveContext, fetchContext, dm,
recursionLevel);
+ public Bucket getMetadata(ArchiveContext archiveContext, FetcherContext
fetchContext, ClientMetadata dm, int recursionLevel,
+ boolean dontEnterImplicitArchives) throws
ArchiveFailureException, ArchiveRestartException, MetadataParseException,
FetchException {
+ return get(".metadata", archiveContext, fetchContext, dm,
recursionLevel, dontEnterImplicitArchives);
}
- /* (non-Javadoc)
- * @see freenet.client.ArchiveHandler#get(java.lang.String,
freenet.client.ArchiveContext, freenet.client.FetcherContext,
freenet.client.ClientMetadata, int)
- */
- public Bucket get(String internalName, ArchiveContext archiveContext,
FetcherContext fetchContext, ClientMetadata dm, int recursionLevel) throws
ArchiveFailureException, ArchiveRestartException, MetadataParseException,
FetchException {
+ public Bucket get(String internalName, ArchiveContext archiveContext,
FetcherContext fetchContext, ClientMetadata dm, int recursionLevel,
+ boolean dontEnterImplicitArchives) throws
ArchiveFailureException, ArchiveRestartException, MetadataParseException,
FetchException {
// Do loop detection on the archive that we are about to fetch.
archiveContext.doLoopDetection(key);
@@ -62,7 +58,7 @@
if(fetchContext == null) return null;
Fetcher fetcher = new Fetcher(key, fetchContext,
archiveContext);
- FetchResult result = fetcher.realRun(dm,
recursionLevel, key);
+ FetchResult result = fetcher.realRun(dm,
recursionLevel, key, dontEnterImplicitArchives);
manager.extractToCache(key, archiveType, result.data,
archiveContext, this);
return manager.getCached(key, internalName);
}
Modified: trunk/freenet/src/freenet/client/FetchException.java
===================================================================
--- trunk/freenet/src/freenet/client/FetchException.java 2005-10-27
22:02:36 UTC (rev 7460)
+++ trunk/freenet/src/freenet/client/FetchException.java 2005-10-28
15:12:45 UTC (rev 7461)
@@ -42,4 +42,6 @@
static final int TOO_MUCH_RECURSION = 9;
/** Tried to access an archive file but not in an archive */
static final int NOT_IN_ARCHIVE = 10;
+ /** Has more metastrings, can't fulfill them */
+ static final int HAS_MORE_METASTRINGS = 11;
}
Modified: trunk/freenet/src/freenet/client/Fetcher.java
===================================================================
--- trunk/freenet/src/freenet/client/Fetcher.java 2005-10-27 22:02:36 UTC
(rev 7460)
+++ trunk/freenet/src/freenet/client/Fetcher.java 2005-10-28 15:12:45 UTC
(rev 7461)
@@ -30,7 +30,7 @@
for(int i=0;i<ctx.maxArchiveRestarts;i++) {
try {
ClientMetadata dm = new ClientMetadata();
- return realRun(dm, 0, origURI);
+ return realRun(dm, 0, origURI,
ctx.dontEnterImplicitArchives);
} catch (ArchiveRestartException e) {
archiveContext = new ArchiveContext();
continue;
@@ -57,7 +57,7 @@
* @throws ArchiveFailureException If we could not extract data from an
archive.
* @throws ArchiveRestartException
*/
- FetchResult realRun(ClientMetadata dm, int recursionLevel, FreenetURI
uri)
+ FetchResult realRun(ClientMetadata dm, int recursionLevel, FreenetURI
uri, boolean dontEnterImplicitArchives)
throws FetchException, MetadataParseException, ArchiveFailureException,
ArchiveRestartException {
ClientKey key = ClientKey.getBaseKey(uri);
LinkedList metaStrings = uri.listMetaStrings();
@@ -89,7 +89,10 @@
Metadata metadata = Metadata.construct(data);
- return runMetadata(dm, recursionLevel, key, metaStrings,
metadata, null, key.getURI());
+ FetchResult result = runMetadata(dm, recursionLevel, key,
metaStrings, metadata, null, key.getURI(), dontEnterImplicitArchives);
+ if(metaStrings.isEmpty()) return result;
+ // Still got some meta-strings
+ throw new FetchException(FetchException.HAS_MORE_METASTRINGS);
}
/**
@@ -107,7 +110,9 @@
* @throws FetchException If the fetch failed for some reason.
* @throws ArchiveRestartException
*/
- private FetchResult runMetadata(ClientMetadata dm, int recursionLevel,
ClientKey key, LinkedList metaStrings, Metadata metadata, ArchiveHandler
container, FreenetURI thisKey) throws MetadataParseException, FetchException,
ArchiveFailureException, ArchiveRestartException {
+ private FetchResult runMetadata(ClientMetadata dm, int recursionLevel,
ClientKey key, LinkedList metaStrings,
+ Metadata metadata, ArchiveHandler container, FreenetURI
thisKey, boolean dontEnterImplicitArchives)
+ throws MetadataParseException, FetchException, ArchiveFailureException,
ArchiveRestartException {
if(metadata.isSimpleManifest()) {
String name = (String) metaStrings.removeFirst();
@@ -118,31 +123,68 @@
metadata = metadata.getDocument(name);
thisKey = thisKey.pushMetaString(name);
}
- return runMetadata(dm, recursionLevel, key,
metaStrings, metadata, container, thisKey);
+ return runMetadata(dm, recursionLevel, key,
metaStrings, metadata, container, thisKey, dontEnterImplicitArchives);
} else if(metadata.isArchiveManifest()) {
container = ctx.archiveManager.makeHandler(thisKey,
metadata.getArchiveType());
- Bucket metadataBucket =
container.getMetadata(archiveContext, ctx, dm, recursionLevel);
+ Bucket metadataBucket =
container.getMetadata(archiveContext, ctx, dm, recursionLevel, true);
metadata = Metadata.construct(metadataBucket);
- return runMetadata(dm, recursionLevel+1, key,
metaStrings, metadata, container, thisKey);
+ return runMetadata(dm, recursionLevel+1, key,
metaStrings, metadata, container, thisKey, dontEnterImplicitArchives);
} else if(metadata.isArchiveInternalRedirect()) {
if(container == null)
throw new
FetchException(FetchException.NOT_IN_ARCHIVE);
else {
- Bucket result =
container.get(metadata.getZIPInternalName(), archiveContext, ctx, dm,
recursionLevel);
+ /* Implicit archive handling:
+ * Sooner or later we reach a
SimpleFileRedirect to data, a Splitfile to data,
+ * or an ArchiveInternalRedirect to data.
+ *
+ * In this case, if it is an archive type, if
implicit archive handling is enabled, and if
+ * we have more meta-strings, we can try to
enter it.
+ */
+ if((!dontEnterImplicitArchives) &&
ArchiveManager.isUsableArchiveType(dm.getMIMEType()) &&
(!metaStrings.isEmpty())) {
+ // Possible implicit archive inside
archive?
+ container =
ctx.archiveManager.makeHandler(thisKey,
ArchiveManager.getArchiveType(dm.getMIMEType()));
+ Bucket metadataBucket =
container.getMetadata(archiveContext, ctx, dm, recursionLevel, true);
+ metadata =
Metadata.construct(metadataBucket);
+ return runMetadata(dm,
recursionLevel+1, key, metaStrings, metadata, container, thisKey,
dontEnterImplicitArchives);
+ }
+ Bucket result =
container.get(metadata.getZIPInternalName(), archiveContext, ctx, dm,
recursionLevel, true);
dm.mergeNoOverwrite(metadata.getClientMetadata());
return new FetchResult(dm, result);
}
} else if(metadata.isMultiLevelMetadata()) {
// Doesn't have to be a splitfile; could be from a ZIP
or a plain file.
metadata.setSimpleRedirect();
- FetchResult res = runMetadata(dm, recursionLevel, key,
metaStrings, metadata, container, thisKey);
+ FetchResult res = runMetadata(dm, recursionLevel, key,
metaStrings, metadata, container, thisKey, true);
metadata = Metadata.construct(res.data);
- return runMetadata(dm, recursionLevel, key,
metaStrings, metadata, container, thisKey);
+ return runMetadata(dm, recursionLevel, key,
metaStrings, metadata, container, thisKey, dontEnterImplicitArchives);
} else if(metadata.isSingleFileRedirect()) {
FreenetURI uri = metadata.getSingleTarget();
dm.mergeNoOverwrite(metadata.getClientMetadata());
- return realRun(dm, recursionLevel, uri);
+ if((!dontEnterImplicitArchives) &&
ArchiveManager.isUsableArchiveType(dm.getMIMEType()) &&
(!metaStrings.isEmpty())) {
+ ClientKey target = ClientKey.getBaseKey(uri);
+ if(!(target.isMetadata())) {
+ // Target *is not* metadata.
+ // Therefore target is a usable archive.
+ // We might not have to fetch it.
+ container =
ctx.archiveManager.makeHandler(uri,
ArchiveManager.getArchiveType(dm.getMIMEType()));
+ Bucket metadataBucket =
container.getMetadata(archiveContext, ctx, dm, recursionLevel, true);
+ metadata =
Metadata.construct(metadataBucket);
+ return runMetadata(dm,
recursionLevel+1, key, metaStrings, metadata, container, thisKey,
dontEnterImplicitArchives);
+ }
+ }
+ return realRun(dm, recursionLevel, uri,
dontEnterImplicitArchives);
} else if(metadata.isSplitfile()) {
+ // Straight data splitfile.
+ // Might be used by parents for something else, in
which case they will set dontEnterImplicitArchives.
+ dm.mergeNoOverwrite(metadata.getClientMetadata()); //
even splitfiles can have mime types!
+ if((!dontEnterImplicitArchives) &&
ArchiveManager.isUsableArchiveType(dm.getMIMEType()) &&
(!metaStrings.isEmpty())) {
+ // We know target is not metadata.
+ container =
ctx.archiveManager.makeHandler(thisKey,
ArchiveManager.getArchiveType(dm.getMIMEType()));
+ Bucket metadataBucket =
container.getMetadata(archiveContext, ctx, dm, recursionLevel, true);
+ metadata = Metadata.construct(metadataBucket);
+ return runMetadata(dm, recursionLevel+1, key,
metaStrings, metadata, container, thisKey, dontEnterImplicitArchives);
+ }
+
SplitFetcher sf = new SplitFetcher(metadata,
ctx.maxTempLength, archiveContext, ctx);
Bucket sfResult = sf.fetch(); // will throw in event of
error
return new FetchResult(dm, sfResult);
@@ -151,5 +193,4 @@
throw new
FetchException(FetchException.UNKNOWN_METADATA);
}
}
-
}
Modified: trunk/freenet/src/freenet/client/FetcherContext.java
===================================================================
--- trunk/freenet/src/freenet/client/FetcherContext.java 2005-10-27
22:02:36 UTC (rev 7460)
+++ trunk/freenet/src/freenet/client/FetcherContext.java 2005-10-28
15:12:45 UTC (rev 7461)
@@ -13,9 +13,11 @@
final BucketFactory bucketFactory;
final int maxRecursionLevel;
final int maxArchiveRestarts;
+ final boolean dontEnterImplicitArchives;
public FetcherContext(SimpleLowLevelClient client, long curMaxLength,
long curMaxTempLength, int maxRecursionLevel, int
maxArchiveRestarts,
+ boolean dontEnterImplicitArchives,
ArchiveManager archiveManager, BucketFactory
bucketFactory) {
this.client = client;
this.maxOutputLength = curMaxLength;
@@ -24,6 +26,7 @@
this.bucketFactory = bucketFactory;
this.maxRecursionLevel = maxRecursionLevel;
this.maxArchiveRestarts = maxArchiveRestarts;
+ this.dontEnterImplicitArchives = dontEnterImplicitArchives;
}
}
Modified: trunk/freenet/src/freenet/client/HighLevelSimpleClientImpl.java
===================================================================
--- trunk/freenet/src/freenet/client/HighLevelSimpleClientImpl.java
2005-10-27 22:02:36 UTC (rev 7460)
+++ trunk/freenet/src/freenet/client/HighLevelSimpleClientImpl.java
2005-10-28 15:12:45 UTC (rev 7461)
@@ -13,6 +13,7 @@
private long curMaxTempLength;
static final int MAX_RECURSION = 10;
static final int MAX_ARCHIVE_RESTARTS = 2;
+ static final boolean DONT_ENTER_IMPLICIT_ARCHIVES = true;
public HighLevelSimpleClientImpl(SimpleLowLevelClient client,
ArchiveManager mgr, BucketFactory bf) {
this.client = client;
@@ -30,7 +31,7 @@
public FetchResult fetch(FreenetURI uri) throws FetchException {
FetcherContext context = new FetcherContext(client,
curMaxLength, curMaxLength,
- MAX_RECURSION, MAX_ARCHIVE_RESTARTS,
archiveManager, bucketFactory);
+ MAX_RECURSION, MAX_ARCHIVE_RESTARTS,
DONT_ENTER_IMPLICIT_ARCHIVES, archiveManager, bucketFactory);
Fetcher f = new Fetcher(uri, context, new ArchiveContext());
return f.run();
}
_______________________________________________
cvs mailing list
[email protected]
http://emu.freenetproject.org/cgi-bin/mailman/listinfo/cvs