Ticket #1550: review_patch.patch

File review_patch.patch, 7.0 KB (added by cacapo, 4 years ago)

Servlet solution for review

  • new file apps/routerconsole/java/src/net/i2p/router/web/CodedIconRendererServlet.java

    #
    # old_revision [01b0b5d0f5aae9882a6ada1fd1a9a7414adec7cb]
    #
    # add_file "apps/routerconsole/java/src/net/i2p/router/web/CodedIconRendererServlet.java"
    #  content [1c24d4cbf1fff07c0d80e0f4a82ba46ecd2b443c]
    # 
    # patch "apps/routerconsole/java/src/net/i2p/router/web/NavHelper.java"
    #  from [4655e29db72cbee2e5ef3ad7c97a49fa8ee658fd]
    #    to [ec954e4d65664d9e4c6a3e7fcdba5cd70b89a3a8]
    # 
    # patch "apps/routerconsole/java/src/net/i2p/router/web/PluginStarter.java"
    #  from [b35b79830043aa82e73eff2f2f81ebd93406d607]
    #    to [eaa618b4fa07d9db49bb4f2a79f444ea32f7d2c8]
    # 
    # patch "apps/routerconsole/jsp/web.xml"
    #  from [2ce14b6c9b28b4e920247e79c7222878438fdb2a]
    #    to [5e2f2d5398e3d22ba76ff652d19fa1e45d845f43]
    #
    ============================================================
    - +  
     1package net.i2p.router.web;
     2
     3import java.io.IOException;
     4import java.io.OutputStream;
     5import java.io.File;
     6import java.util.Arrays;
     7import javax.servlet.http.HttpServlet;
     8import javax.servlet.http.HttpServletResponse;
     9import javax.servlet.http.HttpServletRequest;
     10import javax.servlet.GenericServlet;
     11import javax.servlet.ServletException;
     12import javax.servlet.ServletRequest;
     13import javax.servlet.ServletResponse;
     14import net.i2p.data.Base64;
     15 
     16
     17 /**
     18  *
     19  * @author cacapo
     20  */
     21
     22public class CodedIconRendererServlet extends HttpServlet {
     23 
     24     public static final long serialVersionUID = 16851750L;
     25 
     26    String base = net.i2p.I2PAppContext.getGlobalContext().getBaseDir().getAbsolutePath();
     27    String file = "docs" + java.io.File.separatorChar + "themes" + java.io.File.separatorChar + "console" +  java.io.File.separatorChar + "images" + java.io.File.separatorChar + "plugin.png";
     28       
     29
     30
     31     @Override
     32
     33    protected void service(HttpServletRequest srq, HttpServletResponse srs) throws ServletException, IOException {
     34        byte[] data;
     35        String name = srq.getParameter("plugin");
     36        data  = NavHelper.getBinary(name);
     37
     38        //set as many headers as are common to any outcome
     39
     40        srs.setContentType("image/png");
     41        srs.setDateHeader("Expires", net.i2p.I2PAppContext.getGlobalContext().clock().now() + 86400000l);
     42        srs.setHeader("Cache-Control", "public, max-age=86400");
     43        OutputStream os = srs.getOutputStream();
     44       
     45        //Binary data is present
     46        if(data != null){
     47            srs.setHeader("Content-Length", Integer.toString(data.length));
     48            int content = Arrays.hashCode(data);
     49            int chksum = srq.getIntHeader("If-None-Match");//returns -1 if no such header
     50            //Don't render if icon already present
     51            if(content != chksum){
     52                srs.setIntHeader("ETag", content);
     53                try{
     54                    os.write(data);
     55                    os.flush();
     56                    os.close();
     57                }catch(IOException e){
     58                    net.i2p.I2PAppContext.getGlobalContext().logManager().getLog(getClass()).warn("Error writing binary image data for plugin", e);
     59                }
     60            }
     61            else {
     62                srs.sendError(304, "Not Modified");
     63            }
     64        }
     65
     66        //Binary data is not present but must be substituted by file on disk
     67
     68        else{
     69            File pfile = new java.io.File(base, file);
     70            srs.setHeader("Content-Length", Long.toString(pfile.length()));
     71            try{
     72                long lastmod = pfile.lastModified();
     73                if(lastmod > 0){
     74                    long iflast = srq.getDateHeader("If-Modified-Since");
     75                    if(iflast >= ((lastmod/1000) * 1000)){
     76                        srs.sendError(304, "Not Modified");
     77                    }
     78                    else {
     79                        srs.setDateHeader("Last-Modified", lastmod);
     80                        net.i2p.util.FileUtil.readFile(file, base, os);
     81                    }
     82                   
     83                }
     84            }catch(java.io.IOException e) {
     85                if (!srs.isCommitted()) {
     86                    srs.sendError(403, e.toString());
     87                } 
     88                else {
     89                    net.i2p.I2PAppContext.getGlobalContext().logManager().getLog(getClass()).warn("Error serving plugin.png", e);
     90                    throw e;
     91                }
     92            }
     93               
     94        }
     95     }
     96       
     97   
     98}
  • apps/routerconsole/java/src/net/i2p/router/web/NavHelper.java

    ============================================================
    public class NavHelper { 
    1313    private static final Map<String, String> _apps = new ConcurrentHashMap<String, String>(4);
    1414    private static final Map<String, String> _tooltips = new ConcurrentHashMap<String, String>(4);
    1515    private static final Map<String, String> _icons = new ConcurrentHashMap<String, String>(4);
     16
     17    private static final Map<String, byte[]> _binary = new ConcurrentHashMap<String, byte[]>(4);
    1618   
    1719    /**
    1820     * To register a new client application so that it shows up on the router
    public class NavHelper { 
    4042        _icons.remove(name);
    4143    }
    4244   
     45
     46    public static byte[] getBinary(String name){
     47
     48        return _binary.get(name);
     49    }
     50
     51
     52    public static void setBinary(String name, byte[] arr){
     53        _binary.put(name, arr);
     54    }
     55
     56
    4357    /**
    4458     *  Translated string is loaded by PluginStarter
    4559     *  @param ctx unused
  • apps/routerconsole/java/src/net/i2p/router/web/PluginStarter.java

    ============================================================
    import net.i2p.data.DataHelper; 
    2222import net.i2p.app.ClientApp;
    2323import net.i2p.app.ClientAppState;
    2424import net.i2p.data.DataHelper;
     25import net.i2p.data.Base64;
    2526import net.i2p.router.RouterContext;
    2627import net.i2p.router.RouterVersion;
    2728import net.i2p.router.startup.ClientAppConfig;
    public class PluginStarter implements Ru 
    353354            }
    354355        }
    355356
     357
     358        //handle console icons for plugins without web-resources through prop icon-code
     359        String fullprop = ConfigClientsHelper.stripHTML(props, "icon-code");
     360        if(fullprop != null && fullprop.length() > 1){
     361            byte[] decoded = Base64.decode(fullprop);
     362            if(decoded != null) {
     363                NavHelper.setBinary(appName, decoded);
     364                iconfile = "/Plugins/pluginicon?plugin=" + appName;
     365            }
     366            else
     367                iconfile = "/themes/console/images/plugin.png";
     368        }
     369
     370
    356371        // load and start things in clients.config
    357372        File clientConfig = new File(pluginDir, "clients.config");
    358373        if (clientConfig.exists()) {
  • apps/routerconsole/jsp/web.xml

    ============================================================
     
    1414    </filter-mapping>
    1515
    1616    <!-- precompiled servlets -->
     17
     18    <servlet>
     19      <servlet-name>net.i2p.router.web.CodedIconRendererServlet</servlet-name>
     20      <servlet-class>net.i2p.router.web.CodedIconRendererServlet</servlet-class>
     21    </servlet>
     22
     23    <servlet-mapping>
     24      <servlet-name>net.i2p.router.web.CodedIconRendererServlet</servlet-name>
     25      <url-pattern>/Plugins/*</url-pattern>
     26    </servlet-mapping>
     27
     28
    1729   
    1830    <!-- yeah, i'm lazy, using a jsp instead of a servlet.. -->
    1931    <servlet-mapping>