Changeset d3abbe8 for router


Ignore:
Timestamp:
Mar 1, 2017 4:42:57 PM (3 years ago)
Author:
zzz <zzz@…>
Branches:
master
Children:
b72085bc
Parents:
3631efa
Message:

Fix eepsite jetty.xml and jetty-ssl.xml files
Migration script for eepsite jetty.xml and jetty-ssl.xml files
Add exclude protocols

File:
1 edited

Legend:

Unmodified
Added
Removed
  • router/java/src/net/i2p/router/startup/MigrateJetty.java

    r3631efa rd3abbe8  
    77
    88import java.io.File;
     9import java.io.BufferedWriter;
     10import java.io.File;
     11import java.io.FileInputStream;
     12import java.io.OutputStreamWriter;
     13import java.io.IOException;
     14import java.io.PrintWriter;
    915import java.util.List;
    1016
     17import net.i2p.data.DataHelper;
    1118import net.i2p.router.RouterContext;
     19import net.i2p.util.FileUtil;
     20import net.i2p.util.I2PSSLSocketFactory;
     21import net.i2p.util.SecureFileOutputStream;
     22import net.i2p.util.VersionComparator;
    1223
    1324/**
    1425 *  Migrate the clients.config and jetty.xml files
    15  *  from Jetty 5/6 to Jetty 7.
     26 *  from Jetty 5/6 to Jetty 7/8.
     27 *  Also migrate jetty.xml from Jetty 7/8 to Jetty 9.
    1628 *
    1729 *  For each client for class org.mortbay.jetty.Server:
     
    3042 *  Saves new clients.config.
    3143 *
    32  *  Does NOT preserve port number, thread counts, etc.
     44 *  Does NOT preserve port number, thread counts, etc. in the migration to 7/8.
     45 *  DOES preserve everything in the migration to 9.
    3346 *
    3447 *  @since Jetty 6
     
    4356    private static final String TEST_CLASS = "org.eclipse.jetty.server.Server";
    4457    private static final String BACKUP_SUFFIX = ".jetty6";
     58    private static final String BACKUP_SUFFIX_8 = ".jetty8";
    4559    private static final String JETTY_TEMPLATE_DIR = "eepsite-jetty7";
    4660    private static final String JETTY_TEMPLATE_PKGDIR = "eepsite";
    4761    private static final String BASE_CONTEXT = "contexts/base-context.xml";
    4862    private static final String CGI_CONTEXT = "contexts/cgi-context.xml";
     63    private static final String PROP_JETTY9_MIGRATED = "router.startup.jetty9.migrated";
    4964   
    5065    /**
     
    5368     */
    5469    public static void migrate(RouterContext ctx, List<ClientAppConfig> apps) {
     70        if (ctx.getBooleanProperty(PROP_JETTY9_MIGRATED))
     71            return;
     72        String installed = ctx.getProperty("router.firstVersion");
     73        if (installed != null && VersionComparator.comp(installed, "0.9.30") >= 0) {
     74            ctx.router().saveConfig(PROP_JETTY9_MIGRATED, "true");
     75            return;
     76        }
    5577        boolean shouldSave = false;
     78        boolean jetty9success = false;
    5679        for (int i = 0; i < apps.size(); i++) {
    5780            ClientAppConfig app = apps.get(i);
    58             if (!(app.className.equals(OLD_CLASS) || app.className.equals(OLD_CLASS_6)))
    59                 continue;
    60             String client = "client application " + i + " [" + app.clientName +
    61                             "] from Jetty 5/6 " + app.className +
    62                             " to Jetty 7 " + NEW_CLASS;
     81            String client;
     82            String backupSuffix;
     83            if (app.className.equals(NEW_CLASS)) {
     84                client = "client application " + i + " [" + app.clientName +
     85                         "] from Jetty 7/8 to Jetty 9";
     86                backupSuffix = BACKUP_SUFFIX_8;
     87            } else if (app.className.equals(OLD_CLASS) || app.className.equals(OLD_CLASS_6)) {
     88                client = "client application " + i + " [" + app.clientName +
     89                         "] from Jetty 5/6 " + app.className +
     90                         " to Jetty 7 " + NEW_CLASS;
     91                backupSuffix = BACKUP_SUFFIX;
     92            } else {
     93                continue;
     94            }
    6395            if (!hasLatestJetty()) {
    6496                System.err.println("WARNING: Jetty 7 unavailable, cannot migrate " + client);
     
    81113            }
    82114            File eepsite = xmlFile.getParentFile();
    83             boolean ok = backupFile(xmlFile);
     115            boolean ok = backupFile(xmlFile, backupSuffix);
    84116            if (!ok) {
    85117                System.err.println("WARNING: Failed to backup up XML file " + xmlFile +
     
    87119                continue;
    88120            }
     121            if (app.className.equals(NEW_CLASS)) {
     122                // Do the migration of 8 to 9, handle additional command-line xml files too
     123                for (int j = 0; j < args.length; j++) {
     124                    if (j > 0) {
     125                        // probably jetty-ssl.xml
     126                        xmlFile = new File(args[j]);
     127                        ok = backupFile(xmlFile, backupSuffix);
     128                        if (!ok) {
     129                            System.err.println("WARNING: Failed to backup up XML file " + xmlFile +
     130                                               ", cannot migrate " + client);
     131                            continue;
     132                        }
     133                    }
     134                    boolean ok9 = migrateToJetty9(xmlFile);
     135                    if (ok9) {
     136                        System.err.println("WARNING: Migrated " + client + ".\n" +
     137                                           "Check the " + xmlFile.getName() + " file in " + eepsite + ".\n" +
     138                                           "Your old " + xmlFile.getName() + " file was backed up to " + xmlFile.getAbsolutePath() + BACKUP_SUFFIX_8);
     139                        jetty9success = true;
     140                    }
     141                }
     142                continue;
     143            }
     144
     145            // Below here is migration of 5/6 to 7/8
     146
    89147            File baseEep = new File(ctx.getBaseDir(), JETTY_TEMPLATE_DIR);
    90148            // in packages, or perhaps on an uninstall/reinstall, the files are in eepsite/
     
    145203            }
    146204        }
    147     }
     205        if (jetty9success)
     206            ctx.router().saveConfig(PROP_JETTY9_MIGRATED, "true");
     207    }
     208
     209    /**
     210     *  Migrate a jetty.xml file to Jetty 9.
     211     *  Unlike above, where we just migrate the new install file over for Jetty 7/8,
     212     *  here we modify the xml file in-place to preserve settings where possible.
     213     *
     214     *  @return success
     215     *  @since Jetty 9
     216     */
     217    private static boolean migrateToJetty9(File xmlFile) {
     218        // we don't re-migrate from the template, we just add the
     219        // necessary args for the QueuedThreadPool constructor in-place
     220        // and fixup the renamed set call
     221        boolean modified = false;
     222        File eepsite = xmlFile.getParentFile();
     223        File newFile = new File(eepsite, xmlFile.getName() + System.currentTimeMillis() + ".tmp");
     224        FileInputStream in = null;
     225        PrintWriter out = null;
     226        try {
     227            in = new FileInputStream(xmlFile);
     228            out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new SecureFileOutputStream(newFile), "UTF-8")));
     229            String s;
     230            boolean foundQTP = false;
     231            boolean foundSTP = false;
     232            boolean foundETP = false;
     233            boolean foundSCC = false;
     234            boolean foundHC = false;
     235            boolean foundSSCC = false;
     236            while ((s = DataHelper.readLine(in)) != null) {
     237                // readLine() doesn't strip \r
     238                if (s.endsWith("\r"))
     239                    s = s.substring(0, s.length() - 1);
     240                if (s.contains("org.eclipse.jetty.util.thread.QueuedThreadPool")) {
     241                    foundQTP = true;
     242                } else if (foundQTP) {
     243                    if (!(s.contains("Modified by") || s.contains("<Arg type=\"int\">"))) {
     244                        out.println("        <!-- Modified by I2P migration script for Jetty 9. Do not remove this line -->");
     245                        out.println("        <Arg type=\"int\">20</Arg>     <!-- maxThreads, overridden below -->");
     246                        out.println("        <Arg type=\"int\">3</Arg>      <!-- minThreads, overridden below -->");
     247                        out.println("        <Arg type=\"int\">60000</Arg>  <!-- maxIdleTimeMs, overridden below -->");
     248                        modified = true;
     249                    }
     250                    foundQTP = false;
     251                }
     252                if (s.contains("<Set name=\"maxIdleTimeMs\">")) {
     253                    // <Set name="maxIdleTimeMs">60000</Set>
     254                    s = s.replace("<Set name=\"maxIdleTimeMs\">", "<Set name=\"idleTimeout\">");
     255                    modified = true;
     256                } else if (s.contains("<Set name=\"ThreadPool\">")) {
     257                    // <Set name="ThreadPool">, must be changed to constructor arg
     258                    out.println("    <!-- Modified by I2P migration script for Jetty 9. Do not remove this line -->");
     259                    s = s.replace("<Set name=\"ThreadPool\">", "<Arg>");
     260                    foundSTP = true;
     261                    modified = true;
     262                } else if (foundSTP && !foundETP && s.contains("</Set>") && !s.contains("<Set")) {
     263                    // </Set> (close of <Set name="ThreadPool">)
     264                    // All the lines above have <Set>...</Set> on the same line, if they don't, this will break.
     265                    s = s.replace("</Set>", "</Arg>");
     266                    foundETP = true;
     267                } else if (s.contains("org.eclipse.jetty.server.nio.SelectChannelConnector")) {
     268                    s = s.replace("org.eclipse.jetty.server.nio.SelectChannelConnector", "org.eclipse.jetty.server.ServerConnector");
     269                    out.println("          <!-- Modified by I2P migration script for Jetty 9. Do not remove this line -->");
     270                    out.println(s);
     271                    out.println("            <Arg><Ref id=\"Server\" /></Arg>");
     272                    out.println("            <Arg type=\"int\">1</Arg>     <!-- number of acceptors -->");
     273                    out.println("            <Arg type=\"int\">0</Arg>     <!-- default number of selectors -->");
     274                    out.println("            <Arg>");
     275                    out.println("              <Array type=\"org.eclipse.jetty.server.ConnectionFactory\">    <!-- varargs so we need an array -->");
     276                    out.println("                <Item>");
     277                    out.println("                  <New class=\"org.eclipse.jetty.server.HttpConnectionFactory\">");
     278                    out.println("                    <Arg>");
     279                    out.println("                      <New class=\"org.eclipse.jetty.server.HttpConfiguration\">");
     280                    out.println("                        <Set name=\"sendServerVersion\">false</Set>");
     281                    out.println("                        <Set name=\"sendDateHeader\">true</Set>");
     282                    out.println("                      </New>");
     283                    out.println("                    </Arg>");
     284                    out.println("                  </New>");
     285                    out.println("                </Item>");
     286                    out.println("              </Array>");
     287                    out.println("            </Arg>");
     288                    modified = true;
     289                    continue;
     290             // SSL starts here
     291                } else if (s.contains("org.eclipse.jetty.http.ssl.SslContextFactory")) {
     292                    s = s.replace("org.eclipse.jetty.http.ssl.SslContextFactory", "org.eclipse.jetty.util.ssl.SslContextFactory");
     293                    out.println("  <!-- Modified by I2P migration script for Jetty 9. Do not remove this line -->");
     294                    out.println(s);
     295                    // don't try to migrate from below, just generate a new list
     296                    out.println("    <Set name=\"ExcludeCipherSuites\">");
     297                    out.println("      <Array type=\"java.lang.String\">");
     298                    for (String ss : I2PSSLSocketFactory.EXCLUDE_CIPHERS) {
     299                        out.println("        <Item>" + ss + "</Item>");
     300                    }
     301                    out.println("      </Array>");
     302                    out.println("    </Set>");
     303                    out.println("    <Set name=\"ExcludeProtocols\">");
     304                    out.println("      <Array type=\"java.lang.String\">");
     305                    for (String ss : I2PSSLSocketFactory.EXCLUDE_PROTOCOLS) {
     306                        out.println("        <Item>" + ss + "</Item>");
     307                    }
     308                    out.println("      </Array>");
     309                    out.println("    </Set>");
     310                    modified = true;
     311                    continue;
     312                } else if (s.contains("org.eclipse.jetty.server.ssl.SslSelectChannelConnector")) {
     313                    s = s.replace("org.eclipse.jetty.server.ssl.SslSelectChannelConnector", "org.eclipse.jetty.server.ServerConnector");
     314                    out.println("      <!-- Modified by I2P migration script for Jetty 9. Do not remove this line -->");
     315                    out.println(s);
     316                    out.println("        <Arg><Ref id=\"Server\" /></Arg>");
     317                    out.println("        <Arg type=\"int\">1</Arg>     <!-- number of acceptors -->");
     318                    out.println("        <Arg type=\"int\">0</Arg>     <!-- default number of selectors -->");
     319                    out.println("        <Arg>");
     320                    out.println("           <Array type=\"org.eclipse.jetty.server.ConnectionFactory\">    <!-- varargs so we need an array -->");
     321                    out.println("              <Item>");
     322                    out.println("                <New class=\"org.eclipse.jetty.server.SslConnectionFactory\">");
     323                    out.println("                  <Arg><Ref id=\"sslContextFactory\" /></Arg>");
     324                    out.println("                  <Arg>http/1.1</Arg>");
     325                    out.println("                </New>");
     326                    out.println("              </Item>");
     327                    out.println("              <Item>");
     328                    out.println("                <New class=\"org.eclipse.jetty.server.HttpConnectionFactory\">");
     329                    out.println("                  <Arg>");
     330                    out.println("                    <New class=\"org.eclipse.jetty.server.HttpConfiguration\">");
     331                    out.println("                      <Set name=\"sendServerVersion\">false</Set>");
     332                    out.println("                      <Set name=\"sendDateHeader\">true</Set>");
     333                    out.println("                    </New>");
     334                    out.println("                  </Arg>");
     335                    out.println("                </New>");
     336                    out.println("              </Item>");
     337                    out.println("            </Array>");
     338                    out.println("        </Arg>");
     339                    foundSSCC = true;
     340                    modified = true;
     341                    continue;
     342                } else if (foundSSCC && s.contains("<Set name=\"ExcludeCipherSuites\">")) {
     343                    // delete the old ExcludeCipherSuites in this section
     344                    do {
     345                        s = DataHelper.readLine(in);
     346                    } while(s != null && !s.contains("</Set>"));
     347                    modified = true;
     348                    continue;
     349                } else if (foundSSCC &&
     350                           s.contains("<Ref id=\"sslContextFactory\"")) {
     351                    // delete old one in this section, replaced above
     352                    modified = true;
     353                    continue;
     354                } else if (s.contains("<Set name=\"KeyStore\">")) {
     355                    s = s.replace("<Set name=\"KeyStore\">", "<Set name=\"KeyStorePath\">");
     356                    modified = true;
     357                } else if (s.contains("<Set name=\"TrustStore\">")) {
     358                    s = s.replace("<Set name=\"TrustStore\">", "<Set name=\"TrustStorePath\">");
     359                    modified = true;
     360             // SSL ends here
     361                } else if (s.contains("class=\"org.eclipse.jetty.deploy.providers.ContextProvider\">")) {
     362                    // WebAppProvider now also does what ContextProvider used to do
     363                    out.println("        <!-- Modified by I2P migration script for Jetty 9. Do not remove this line -->");
     364                    s = s.replace("class=\"org.eclipse.jetty.deploy.providers.ContextProvider\">", "class=\"org.eclipse.jetty.deploy.providers.WebAppProvider\">");
     365                    modified = true;
     366                } else if (s.contains("<Set name=\"maxIdleTime\">")) {
     367                    s = s.replace("<Set name=\"maxIdleTime\">", "<Set name=\"idleTimeout\">");
     368                    modified = true;
     369                } else if (s.contains("<Set name=\"gracefulShutdown\">")) {
     370                    s = s.replace("<Set name=\"gracefulShutdown\">", "<Set name=\"stopTimeout\">");
     371                    modified = true;
     372                } else if (s.contains("org.eclipse.jetty.server.HttpConfiguration")) {
     373                    foundHC = true;
     374                } else if (!foundHC &&
     375                           (s.contains("<Set name=\"sendServerVersion\">") ||
     376                            s.contains("<Set name=\"sendDateHeader\">"))) {
     377                    // old ones for Server, not in HTTPConfiguration section, delete
     378                    modified = true;
     379                    continue;
     380                } else if (s.contains("<Set name=\"Acceptors\">") ||
     381                           s.contains("<Set name=\"acceptors\">") ||
     382                           s.contains("<Set name=\"statsOn\">") ||
     383                           s.contains("<Set name=\"confidentialPort\">") ||
     384                           s.contains("<Set name=\"lowResourcesConnections\">") ||
     385                           s.contains("<Set name=\"lowResourcesMaxIdleTime\">") ||
     386                           s.contains("<Set name=\"useDirectBuffers\">")) {
     387                    // delete
     388                    modified = true;
     389                    continue;
     390                }
     391                out.println(s);
     392            }
     393        } catch (IOException ioe) {
     394            if (in != null) {
     395                System.err.println("FAILED migration of " + xmlFile + ": " + ioe);
     396            }
     397            return false;
     398        } finally {
     399            if (in != null) try { in.close(); } catch (IOException ioe) {}
     400            if (out != null) out.close();
     401        }
     402        if (modified) {
     403            return FileUtil.rename(newFile, xmlFile);
     404        } else {
     405            newFile.delete();
     406            return true;
     407        }
     408    }
     409
    148410
    149411    /** do we have Jetty 7? */
     
    165427     */
    166428    private static boolean backupFile(File from) {
     429        return backupFile(from, BACKUP_SUFFIX);
     430    }
     431
     432    /**
     433     *  Backup a file with given suffix
     434     *  @return success
     435     *  @since Jetty 9
     436     */
     437    private static boolean backupFile(File from, String suffix) {
    167438        if (!from.exists())
    168439            return true;
    169         File to = new File(from.getAbsolutePath() + BACKUP_SUFFIX);
     440        File to = new File(from.getAbsolutePath() + suffix);
    170441        if (to.exists())
    171442            to = new File(to.getAbsolutePath() + "." + System.currentTimeMillis());
Note: See TracChangeset for help on using the changeset viewer.