Author: bombe
Date: 2006-08-18 18:28:57 +0000 (Fri, 18 Aug 2006)
New Revision: 10199

Modified:
   trunk/freenet/src/freenet/clients/http/FProxyToadlet.java
   trunk/freenet/src/freenet/clients/http/QueueToadlet.java
   trunk/freenet/src/freenet/clients/http/filter/ContentFilter.java
   trunk/freenet/src/freenet/node/fcp/ClientGet.java
Log:
use content filter for downloading files from the queue page
create correct bucket on successful completion of a temp download

Modified: trunk/freenet/src/freenet/clients/http/FProxyToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/FProxyToadlet.java   2006-08-18 
18:26:53 UTC (rev 10198)
+++ trunk/freenet/src/freenet/clients/http/FProxyToadlet.java   2006-08-18 
18:28:57 UTC (rev 10199)
@@ -33,20 +33,20 @@
 import freenet.support.SizeUtil;
 import freenet.support.URLEncoder;
 import freenet.support.io.Bucket;
+import freenet.support.io.BucketFactory;

 public class FProxyToadlet extends Toadlet {

-       final byte[] random;
+       private static byte[] random;
        final NodeClientCore core;

        // ?force= links become invalid after 2 hours.
-       long FORCE_GRAIN_INTERVAL = 60*60*1000;
+       private static final long FORCE_GRAIN_INTERVAL = 60*60*1000;
        /** Maximum size for transparent pass-through, should be a config 
option */
        static final long MAX_LENGTH = 2*1024*1024; // 2MB

-       public FProxyToadlet(HighLevelSimpleClient client, byte[] random, 
NodeClientCore core) {
+       public FProxyToadlet(HighLevelSimpleClient client, NodeClientCore core) 
{
                super(client);
-               this.random = random;
                client.setMaxLength(MAX_LENGTH);
                client.setMaxIntermediateLength(MAX_LENGTH);
                this.core = core;
@@ -71,6 +71,70 @@

        }

+       public static void handleDownload(ToadletContext context, Bucket data, 
BucketFactory bucketFactory, String mimeType, String requestedMimeType, String 
forceString, boolean forceDownload, String basePath, FreenetURI key) throws 
ToadletContextClosedException, IOException {
+               System.out.println("mimetype: " + mimeType + ", reqmt: " + 
requestedMimeType + ", force: " + forceString + ", forceDownload: " + 
forceDownload + ", key: " + key);
+               if(requestedMimeType != null)
+                       mimeType = requestedMimeType;
+               
+               long now = System.currentTimeMillis();
+               boolean force = false;
+               if(forceString != null) {
+                       if(forceString.equals(getForceValue(key, now)) || 
+                                       forceString.equals(getForceValue(key, 
now-FORCE_GRAIN_INTERVAL)))
+                               force = true;
+               }
+
+               try {
+                       if(!force && !forceDownload) {
+                               FilterOutput fo = ContentFilter.filter(data, 
bucketFactory, mimeType, new URI(basePath + 
URLEncoder.encode(key.toString(false))), null);
+                               data = fo.data;
+                               mimeType = fo.type;
+                       }
+                       
+                       if (forceDownload) {
+                               MultiValueTable headers = new MultiValueTable();
+                               headers.put("Content-Disposition", "attachment; 
filename=\"" + key.getPreferredFilename() + "\"");
+                               context.sendReplyHeaders(200, "OK", headers, 
"application/x-msdownload", data.size());
+                               context.writeData(data);
+                       } else {
+                               // Send the data, intact
+                               context.sendReplyHeaders(200, "OK", new 
MultiValueTable(), mimeType, data.size());
+                               context.writeData(data);
+                       }
+               } catch (URISyntaxException use1) {
+                       /* shouldn't happen */
+                       use1.printStackTrace();
+                       Logger.error(FProxyToadlet.class, "could not create 
URI", use1);
+               } catch (UnsafeContentTypeException e) {
+                       HTMLNode pageNode = 
context.getPageMaker().getPageNode("Potentially Dangerous Content");
+                       HTMLNode contentNode = 
context.getPageMaker().getContentNode(pageNode);
+                       
+                       HTMLNode infobox = contentNode.addChild("div", "class", 
"infobox infobox-alert");
+                       infobox.addChild("div", "class", "infobox-header", 
e.getRawTitle());
+                       HTMLNode infoboxContent = infobox.addChild("div", 
"class", "infobox-content");
+                       infoboxContent.addChild(e.getHTMLExplanation());
+                       infoboxContent.addChild("p", "Your options are:");
+                       HTMLNode optionList = infoboxContent.addChild("ul");
+                       HTMLNode option = optionList.addChild("li");
+                       option.addChild("a", "href", basePath + 
key.toString(false) + "?type=text/plain", "Click here");
+                       option.addChild("#", " to open the file as plain text 
(this should not be dangerous but it may be garbled).");
+                       // FIXME: is this safe? See bug #131
+                       option = optionList.addChild("li");
+                       option.addChild("a", "href", basePath + 
key.toString(false) + "?forcedownload", "Click here");
+                       option.addChild("#", " to force your browser to 
download the file to disk.");
+                       option = optionList.addChild("li");
+                       option.addChild("a", "href", basePath + 
key.toString(false) + "?force=" + getForceValue(key, now), "Click here");
+                       option.addChild("#", " to open the file as " + mimeType 
+ ".");
+                       option = optionList.addChild("li");
+                       option.addChild("a", "href", "/", "Click here");
+                       option.addChild("#", " to go to the FProxy home page.");
+
+                       byte[] pageBytes = pageNode.generate().getBytes();
+                       context.sendReplyHeaders(200, "OK", new 
MultiValueTable(), "text/html; charset=utf-8", pageBytes.length);
+                       context.writeData(pageBytes);
+               }
+       }
+       
        public void handleGet(URI uri, ToadletContext ctx) 
                        throws ToadletContextClosedException, IOException, 
RedirectException {
                //String ks = uri.toString();
@@ -153,78 +217,11 @@
                        // Now, is it safe?

                        Bucket data = result.asBucket();
+                       String mimeType = result.getMimeType();
+                       String requestedMimeType = httprequest.getParam("type", 
null);

-                       String typeName = result.getMimeType();
+                       handleDownload(ctx, data, ctx.getBucketFactory(), 
mimeType, requestedMimeType, httprequest.getParam("force", null), 
httprequest.isParameterSet("forcedownload"), "/", key);

-                       String reqParam = httprequest.getParam("type", null);
-                       
-                       if(reqParam != null)
-                               typeName = reqParam;
-                       
-                       Logger.minor(this, "Type: "+typeName+" 
("+result.getMimeType()+" "+reqParam+")");
-                       
-                       long now = System.currentTimeMillis();
-                       
-                       String forceString = httprequest.getParam("force");
-                       boolean force = false;
-                       boolean forcedownload = false;
-                       if(forceString != null) {
-                               if(forceString.equals(getForceValue(key, now)) 
|| 
-                                               
forceString.equals(getForceValue(key, now-FORCE_GRAIN_INTERVAL)))
-                                       force = true;
-                       }
-
-                       if(httprequest.isParameterSet("forcedownload")) {
-                               // Download to disk, this should be safe, and 
is set when we do "force download to disk" from a dangerous-content-warning 
page.
-                               typeName = "application/x-msdownload";
-                               forcedownload = true;
-                       }
-                       
-                       try {
-                               if(!force && !forcedownload) {
-                                       FilterOutput fo = 
ContentFilter.filter(data, ctx.getBucketFactory(), typeName, uri, null);
-                                       data = fo.data;
-                                       typeName = fo.type;
-                               }
-                               
-                               if (forcedownload) {
-                                       MultiValueTable headers = new 
MultiValueTable();
-                                       
-                                       headers.put("Content-Disposition", 
"attachment");
-                                       ctx.sendReplyHeaders(200, "OK", 
headers, typeName, data.size());
-                                       ctx.writeData(data);
-                               } else {
-                                       // Send the data, intact
-                                       writeReply(ctx, 200, typeName, "OK", 
data);
-                               }
-                       } catch (UnsafeContentTypeException e) {
-                               HTMLNode pageNode = 
ctx.getPageMaker().getPageNode("Potentially dangerous content");
-                               HTMLNode contentNode = 
ctx.getPageMaker().getContentNode(pageNode);
-                               
-                               HTMLNode infobox = contentNode.addChild("div", 
"class", "infobox infobox-alert");
-                               infobox.addChild("div", "class", 
"infobox-header", e.getRawTitle());
-                               HTMLNode infoboxContent = 
infobox.addChild("div", "class", "infobox-content");
-                               infoboxContent.addChild(e.getHTMLExplanation());
-                               infoboxContent.addChild("p", "Your options 
are:");
-                               HTMLNode optionList = 
infoboxContent.addChild("ul");
-                               HTMLNode option = optionList.addChild("li");
-                               option.addChild("a", "href", "/" + 
key.toString(false) + "?type=text/plain", "Click here");
-                               option.addChild("#", " to open the file as 
plain text (this should not be dangerous but it may be garbled).");
-                               // FIXME: is this safe? See bug #131
-                               option = optionList.addChild("li");
-                               option.addChild("a", "href", "/" + 
key.toString(false) + "?forcedownload", "Click here");
-                               option.addChild("#", " to force your browser to 
download the file to disk.");
-                               option = optionList.addChild("li");
-                               option.addChild("a", "href", "/" + 
key.toString(false) + "?force=" + getForceValue(key, now), "Click here");
-                               option.addChild("#", " to open the file as " + 
typeName + ".");
-                               option = optionList.addChild("li");
-                               option.addChild("a", "href", "/", "Click here");
-                               option.addChild("#", " to go to the FProxy home 
page.");
-
-                               StringBuffer pageBuffer = new StringBuffer();
-                               pageNode.generate(pageBuffer);
-                               writeReply(ctx, 200, "text/html", "OK", 
pageBuffer.toString());
-                       }
                } catch (FetchException e) {
                        String msg = e.getMessage();
                        String extra = "";
@@ -321,7 +318,7 @@
                }
        }

-       private String getForceValue(FreenetURI key, long time) {
+       private static String getForceValue(FreenetURI key, long time) {
                try {
                        MessageDigest md5 = 
MessageDigest.getInstance("SHA-256");
                        md5.update(random);
@@ -342,9 +339,9 @@
                        HighLevelSimpleClient client = 
core.makeClient(RequestStarter.INTERACTIVE_PRIORITY_CLASS);

                        core.setToadletContainer(server);
-                       byte[] random = new byte[32];
+                       random = new byte[32];
                        core.random.nextBytes(random);
-                       FProxyToadlet fproxy = new FProxyToadlet(client, 
random, core);
+                       FProxyToadlet fproxy = new FProxyToadlet(client, core);
                        core.setFProxy(fproxy);
                        server.register(fproxy, "/", false, "Home", "homepage");


Modified: trunk/freenet/src/freenet/clients/http/QueueToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/QueueToadlet.java    2006-08-18 
18:26:53 UTC (rev 10198)
+++ trunk/freenet/src/freenet/clients/http/QueueToadlet.java    2006-08-18 
18:28:57 UTC (rev 10199)
@@ -267,6 +267,34 @@
                        return;
                }

+               HTTPRequest request = new HTTPRequest(uri, null, ctx);
+               String requestPath = 
request.getPath().substring("/queue/".length());
+               
+               if (requestPath.length() > 0) {
+                       /* okay, there is something in the path, check it. */
+                       try {
+                               FreenetURI key = new FreenetURI(requestPath);
+                               
+                               /* locate request */
+                               ClientRequest[] clientRequests = 
fcp.getGlobalRequests();
+                               for (int requestIndex = 0, requestCount = 
clientRequests.length; requestIndex < requestCount; requestIndex++) {
+                                       ClientRequest clientRequest = 
clientRequests[requestIndex];
+                                       if (clientRequest.hasFinished() && 
(clientRequest instanceof ClientGet)) {
+                                               ClientGet clientGet = 
(ClientGet) clientRequest;
+                                               if 
(clientGet.getURI().toString(false).equals(key.toString(false))) {
+                                                       Bucket data = 
clientGet.getBucket();
+                                                       String mimeType = 
clientGet.getMIMEType();
+                                                       String 
requestedMimeType = request.getParam("type", null);
+                                                       String forceString = 
request.getParam("force");
+                                                       
FProxyToadlet.handleDownload(ctx, data, ctx.getBucketFactory(), mimeType, 
requestedMimeType, forceString, request.isParameterSet("forcedownload"), 
"/queue/", key);
+                                                       return;
+                                               }
+                                       }
+                               }
+                       } catch (MalformedURLException mue1) {
+                       }
+               }
+               
                PageMaker pageMaker = ctx.getPageMaker();

                // First, get the queued requests, and separate them into 
different types.
@@ -675,10 +703,7 @@

        private HTMLNode createDownloadCell(PageMaker pageMaker, ClientGet p) {
                HTMLNode downloadCell = new HTMLNode("td", "class", 
"request-download");
-               HTMLNode downloadForm = downloadCell.addChild("form", new 
String[] { "action", "method" }, new String[] { "/queue/", "post" });
-               
downloadForm.addChild(pageMaker.createFormPasswordInput(core.formPassword));
-               downloadForm.addChild("input", new String[] { "type", "name", 
"value" }, new String[] { "hidden", "identifier", p.getIdentifier() });
-               downloadForm.addChild("input", new String[] { "type", "name", 
"value" }, new String[] { "submit", "get", "Download" });
+               downloadCell.addChild("a", "href", p.getURI().toString(false), 
"Download");
                return downloadCell;
        }


Modified: trunk/freenet/src/freenet/clients/http/filter/ContentFilter.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/filter/ContentFilter.java    
2006-08-18 18:26:53 UTC (rev 10198)
+++ trunk/freenet/src/freenet/clients/http/filter/ContentFilter.java    
2006-08-18 18:28:57 UTC (rev 10199)
@@ -154,7 +154,6 @@
                if(handler == null)
                        throw new UnknownContentTypeException(typeName);
                else {
-                       
                        if(handler.safeToRead) {
                                return new FilterOutput(data, typeName);
                        }

Modified: trunk/freenet/src/freenet/node/fcp/ClientGet.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/ClientGet.java   2006-08-18 18:26:53 UTC 
(rev 10198)
+++ trunk/freenet/src/freenet/node/fcp/ClientGet.java   2006-08-18 18:28:57 UTC 
(rev 10199)
@@ -39,7 +39,7 @@
        private final File targetFile;
        private final File tempFile;
        /** Bucket passed in to the ClientGetter to return data in. Null unless 
returntype=disk */
-       private final Bucket returnBucket;
+       private Bucket returnBucket;

        // Verbosity bitmasks
        private int VERBOSITY_SPLITFILE_PROGRESS = 1;
@@ -300,6 +300,7 @@
                                                postFetchProtocolErrorMessage = 
new ProtocolErrorMessage(ProtocolErrorMessage.COULD_NOT_RENAME_FILE, false, 
null, identifier);
                                                // Don't delete temp file, user 
might want it.
                                        }
+                                       returnBucket = new 
FileBucket(targetFile, false, false, false, false);
                                } catch (FileNotFoundException e) {
                                        postFetchProtocolErrorMessage = new 
ProtocolErrorMessage(ProtocolErrorMessage.COULD_NOT_WRITE_FILE, false, null, 
identifier);
                                } catch (IOException e) {


Reply via email to