From c76ed51541b7cae85dfedf1124bbf06daf3b4711 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Thu, 31 Jan 2013 22:31:04 +0000 Subject: [PATCH] SMACK-385 Reuse the KeyStore in order to reduce memory usage. Extended ServerTrustManager with a 'stores' (Hash)Map that allows the reuse of an existing KeyStore. Before that, every call of KeyStore.getInstance() created a new instance which consumes about 250KiB. git-svn-id: http://svn.igniterealtime.org/svn/repos/smack/trunk@13419 b35dd754-fafc-0310-a699-88a17e54d16e --- .../smack/ServerTrustManager.java | 103 +++++++++++++++--- 1 file changed, 87 insertions(+), 16 deletions(-) diff --git a/source/org/jivesoftware/smack/ServerTrustManager.java b/source/org/jivesoftware/smack/ServerTrustManager.java index a54d0fcf9..ea0a4a135 100644 --- a/source/org/jivesoftware/smack/ServerTrustManager.java +++ b/source/org/jivesoftware/smack/ServerTrustManager.java @@ -52,30 +52,40 @@ class ServerTrustManager implements X509TrustManager { private String server; private KeyStore trustStore; + private static Map stores = new HashMap(); + public ServerTrustManager(String server, ConnectionConfiguration configuration) { this.configuration = configuration; this.server = server; InputStream in = null; - try { - trustStore = KeyStore.getInstance(configuration.getTruststoreType()); - in = new FileInputStream(configuration.getTruststorePath()); - trustStore.load(in, configuration.getTruststorePassword().toCharArray()); - } - catch (Exception e) { - e.printStackTrace(); - // Disable root CA checking - configuration.setVerifyRootCAEnabled(false); - } - finally { - if (in != null) { + synchronized (stores) { + KeyStoreOptions options = new KeyStoreOptions(configuration.getTruststoreType(), + configuration.getTruststorePath(), configuration.getTruststorePassword()); + if (stores.containsKey(options)) { + trustStore = stores.get(options); + } else { try { - in.close(); - } - catch (IOException ioe) { - // Ignore. + trustStore = KeyStore.getInstance(options.getType()); + in = new FileInputStream(options.getPath()); + trustStore.load(in, options.getPassword().toCharArray()); + } catch (Exception e) { + trustStore = null; + e.printStackTrace(); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException ioe) { + // Ignore. + } + } } + stores.put(options, trustStore); } + if (trustStore == null) + // Disable root CA checking + configuration.setVerifyRootCAEnabled(false); } } @@ -256,4 +266,65 @@ class ServerTrustManager implements X509TrustManager { return identities; } + private static class KeyStoreOptions { + private final String type; + private final String path; + private final String password; + + public KeyStoreOptions(String type, String path, String password) { + super(); + this.type = type; + this.path = path; + this.password = password; + } + + public String getType() { + return type; + } + + public String getPath() { + return path; + } + + public String getPassword() { + return password; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((password == null) ? 0 : password.hashCode()); + result = prime * result + ((path == null) ? 0 : path.hashCode()); + result = prime * result + ((type == null) ? 0 : type.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + KeyStoreOptions other = (KeyStoreOptions) obj; + if (password == null) { + if (other.password != null) + return false; + } else if (!password.equals(other.password)) + return false; + if (path == null) { + if (other.path != null) + return false; + } else if (!path.equals(other.path)) + return false; + if (type == null) { + if (other.type != null) + return false; + } else if (!type.equals(other.type)) + return false; + return true; + } + } }