- Timestamp:
- 2018-09-06T22:32:58+12:00 (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
main/trunk/greenstone3/src/java/org/greenstone/util/ProtocolPortProperties.java
r32419 r32429 22 22 23 23 /* 24 * Utility class to set the protocol and port values from the Properties provided,24 * Utility class to set the protocol and port values from the Properties instance provided, 25 25 * which can be a Properties object loaded from either build.properties or global.properties 26 * Currently used by ServletRealmCheck and FedoraServiceProxy. 27 * (Could also be used by Server3.java and GlobalProperties in future, if applicable.) 26 * Currently used by Server3.java, ServletRealmCheck, FedoraServiceProxy and solr java code 27 * GS2SolrSearch and SolrSearch. 28 * (Could perhaps also be used by GlobalProperties in future, if applicable.) 28 29 * Can adjust fallback behaviour in this one location to make them all work consistently. 30 * 31 * NOTE: although global.properties contains many additional programmatically set properties 32 * that could simplify this class, the fact that this class should work for both build.properties 33 * and global.properties means that this class will work only with the properties common to 34 * both property files. 29 35 */ 30 public class ProtocolPortProperties { 31 32 public final boolean legacyMode; // true if before https protocol supported 36 public class ProtocolPortProperties { 33 37 34 38 public static final int ALL_CORRECT = 0; 35 39 public static final int SECONDARY_PORT_NON_NUMERIC = 1; 36 40 public static final int INVALID_PRIMARY_PORT = 2; 37 public static final int OLD_TOMCATPORT_BUT_NO_VALUE= 3;38 public static final int NO_PROTOCOL_OR_PORT= 4;39 public static final int INVALID_PROTOCOL= 5;40 public static final int HTTPS_INCONSISTENCY= 6;41 42 private static final String defProtocol= "http";43 private static final String defHttpPort= "8383";44 private static final String defHttpsPort= "8443";45 46 private String protocol; //= defProtocol;47 private String port; //defHttpPort; //defProtocol.equals("https") ? defHttpsPort : defHttpPort; // port that matches protocol as String48 private String httpPort; //defHttpPort;49 private String httpsPort; //defHttpsPort;41 public static final int NO_PROTOCOL = 3; 42 public static final int INVALID_PROTOCOL = 4; 43 public static final int NO_HTTP_PORT = 5; 44 public static final int NO_HTTPS_PORT = 6; 45 46 private static final String FALLBACK_PROTOCOL = "http"; 47 private static final String FALLBACK_HTTP_PORT = "8383"; 48 private static final String FALLBACK_HTTPS_PORT = "8443"; 49 50 private String protocol; 51 private String port; 52 private String httpPort; 53 private String httpsPort; 50 54 //private int portNum = -1; // port that matches protocol as int 51 55 52 56 private String errorMsg; 53 private int errorCode; 54 55 public String getProtocol() { return protocol; } 57 private int errorCode = ALL_CORRECT; 58 59 private boolean httpRestrictedToLocal = true; 60 private boolean supportsHttps = false; 61 private String defaultPortPropertyName = "localhost.port.http"; 62 63 // default protocol if multiple supported 64 public String getProtocol() { return protocol; } 65 // default port (port for default protocol) 56 66 public String getPort() { return port; } 67 68 // httpPort is always set, but http may or may not be public 57 69 public String getHttpPort() { return httpPort; } 70 // httpsPort is null if https not supported 58 71 public String getHttpsPort() { return httpsPort; } 59 public int getPortNum() { return Integer.parseInt(port); } 72 public int getPortNum() { return Integer.parseInt(port); } 73 74 // http is always available locally (over 127.0.0.1). But http may or may not be public. 75 // Returns true if public http support requested 76 public boolean supportsHttp() { return !httpRestrictedToLocal; } 77 // true if https is supported 78 public boolean supportsHttps() { return supportsHttps; } 79 80 // used by Server3.java to know the name of the port property to load 81 public String getDefaultPortPropertyName() { return defaultPortPropertyName; } 60 82 61 83 public String getErrorMsg() { return errorMsg; } … … 64 86 public boolean hadError() { return errorCode != ALL_CORRECT; } 65 87 66 // Won't attempt to recover on error. 67 // This means on error, port etc values will be invalid 88 // Use 127.0.0.1 instead of localhost since localhost is unsafe (can be mapped 89 // to something other than 127.0.0.1). See https://letsencrypt.org/docs/certificates-for-localhost/ 90 public String getLocalHttpBaseAddress() { 91 // httpPort is set during the constructor, 92 // so knowing httpPort, we can set the internal/local access http URL: 93 String portSuffix = httpPort.equals("80") ? "" : (":"+httpPort); 94 return "http://127.0.0.1"+portSuffix; 95 96 } 97 98 // Constructor that will throw an Exception on ports/protocol configuration error or inconsistency 68 99 public ProtocolPortProperties(Properties props) throws Exception { 69 100 this(props, false); 70 101 } 71 102 103 // If param recover is true, will attempt to fallback to sane values for protocol and ports. 104 // You can still check for error by calling hadError(), getErrorMsg() and getErrorCode(). 105 // If param recover is false, will throw an Exception on bad ports/protocol configuration 106 // and the error message is available as the exception description. 72 107 public ProtocolPortProperties(Properties props, boolean recover) throws Exception 73 108 { 74 109 StringBuffer msg = new StringBuffer(); 75 110 76 port = props.getProperty("tomcat.port"); 77 78 // We could either be dealing with properties files from before https support was introduced, in which case we want to be backwards compatible 79 // Or we're dealing with properties files after https support was introduced. 80 // To determine which, can ignore server.protocol: server.protocol was introduced at a time when tomcat.port was still in effect, 81 // server.protocol's presence does not indicate whether our GS3 installation supports https or not. Only the tomcat.port properties 82 // indicates that: if tomcat.port exists BUT tomcat.port.http(s) don't, then it's an older GS3 that has no https support, so default to http. 83 // If there is no tomcat.port at all, but there is a server.protocol check for the newer tomcat.port.<protocol> properties. 84 // NOTE: global.properties still has a property called tomcat.port. We're only dealing with the old tomcat.port-only way if tomcat.port.http(s) don't exist 85 86 if(props.getProperty("tomcat.port.http") == null && props.getProperty("tomcat.port.https") == null && port != null) { 87 // tomcat.port exists but tomcat.port.http(s) don't, so this is a GS3 before https support. 88 legacyMode = true; 89 90 // Back when tomcat.port was used AND tomcat.port.http(s) didn't exist, server.protocol if specified 91 // would always be treated as http regardless of what it was set to 92 93 protocol = defProtocol; // tomcat.port.http(s) doesn't exist, just use http 94 95 96 if(port.equals("")) { 97 errorCode = OLD_TOMCATPORT_BUT_NO_VALUE; 98 msg.append("tomcat.port enabled but did not have a value."); 99 if(recover) { 100 port = httpPort = defHttpPort; 111 httpPort = props.getProperty("localhost.port.http"); 112 if(httpPort == null || httpPort.equals("")) { 113 errorCode = NO_HTTP_PORT; 114 msg.append("compulsory property localhost.port.http has no value (must be set to a valid port number not already in use)."); 115 httpPort = FALLBACK_HTTP_PORT; 116 } 117 118 String supportedProtocols = props.getProperty("server.protocols"); 119 if(supportedProtocols == null || supportedProtocols.equals("")) { 120 errorCode = NO_PROTOCOL; 121 msg.append("server.protocols not set."); 122 protocol = FALLBACK_PROTOCOL; // fallback to http as default (and sole) protocol 123 port = httpPort; // set default port to httpPort 124 } 125 else { // supportedProtocols was assigned something 126 127 if(!supportedProtocols.contains("http")) { 128 errorCode = INVALID_PROTOCOL; 129 msg.append("server.protocols must contain http or https, or both (in order of preference) separated by commas."); 130 protocol = FALLBACK_PROTOCOL; 131 port = httpPort; 132 } 133 134 // set available protocols with their ports 135 if(supportedProtocols.contains("https")) { 136 supportsHttps = true; 137 httpsPort = props.getProperty("tomcat.port.https"); 138 if(httpsPort == null || httpsPort.equals("")) { 139 errorCode = NO_HTTPS_PORT; 140 msg.append("server.protocols includes https but property tomcat.port.https has no value (must be set to a valid port number not already in use)."); 141 httpsPort = FALLBACK_HTTPS_PORT; 101 142 } 102 } else { // No issues: using tomcat.port is the pre-https way. 103 errorCode = ALL_CORRECT; 104 httpPort = port; 105 } 106 } 107 else { 108 legacyMode = false; 109 110 protocol = props.getProperty("server.protocol"); 111 if(protocol == null || (!protocol.equals("http") && !protocol.equals("https"))) { 112 if(port == null) { // if tomcat.port is null AND server.protocol is null or wrong. Something very wrong with the properties file 113 errorCode = NO_PROTOCOL_OR_PORT; 114 msg.append("server.protocol not set. And can't determine port."); 115 } else if(protocol == null) { 116 errorCode = NO_PROTOCOL_OR_PORT; 117 msg.append("server.protocol not set."); 118 } else { 119 errorCode = INVALID_PROTOCOL; 120 msg.append("server.protocol property must be http or https, but is set to invalid value. And can't determine port."); 121 } 122 123 if(recover) { 124 protocol = defProtocol; 125 port = httpPort = defHttpPort; 126 } 127 128 } else { // server.protocol was explicitly set and set to an acceptable value, try to find matching tomcat.port 129 130 port = props.getProperty("tomcat.port."+protocol); // tomcat.port.http or tomcat.port.https, depending on server.protocol. 131 132 // Handle cases where there's some inconsistency in the properties file between protocol and port. 133 // i.e. if server.protocol=http, then tomcat.port.http must be set too. 134 if(port == null || port.equals("")) { 135 errorCode = INVALID_PROTOCOL; 136 msg.append("server.protocol="+protocol+", but matching tomcat.port."+protocol+"not enabled or set."); 137 138 if(recover) { 139 protocol = defProtocol; 140 if(protocol.startsWith("https")) { // server.protocol=https yet tomcat.port.https not provided 141 port = httpsPort = defHttpsPort; // use default https port to set 142 } else { 143 port = httpPort = defHttpPort; 144 } 145 } 146 147 } else { //tomcat.port.<protocol> property matching server.protocol is set, not checking if it's an int and a valid port, though 148 errorCode = ALL_CORRECT; 149 // port is set 150 151 if(protocol.startsWith("https")) { 152 httpsPort = port; 153 httpPort = props.getProperty("tomcat.port.http"); // httpPort will remain null if tomcat.port.http not set 154 } else { // protocol=http 155 httpPort = port; 156 httpsPort = props.getProperty("tomcat.port.https"); // httpsPort will remain null if tomcat.port.https not set 157 } 158 } 159 } 160 } 161 162 if(errorCode == ALL_CORRECT) { // then check any assigned ports are valid 143 } 144 if(supportedProtocols.matches("http(,|\\s+|$)")) { 145 httpRestrictedToLocal = false; 146 } 147 148 // set default protocol and default port: the first protocol in the supportedProtocols list 149 if(supportedProtocols.matches("^[,\\s]*https")) { 150 protocol = "https"; 151 port = httpsPort; 152 } else { 153 protocol = "http"; 154 port = httpPort; 155 } 156 } 157 158 if(!recover && errorCode == ALL_CORRECT) { // then check any assigned ports are valid 163 159 if(httpPort != null) { 164 160 try { 165 161 Integer.parseInt(httpPort); 166 162 } catch(NumberFormatException nfe) { 167 msg.append("\nInvalid port specified for over http: notnumeric.");163 msg.append("\nInvalid localhost.port.http specified: must be numeric."); 168 164 if(port == httpPort) { 169 errorCode = INVALID_PRIMARY_PORT; 170 if(recover) { 171 port = httpPort = defHttpPort; 172 } else { // no recovery requested, so if port for protocol is non-numeric, consider it a 'fatal' error 173 port = httpPort = httpsPort = null; 174 } 175 } else { // secondary protocol's port is non-numeric, not fatal? 165 errorCode = INVALID_PRIMARY_PORT; 166 port = httpPort = FALLBACK_HTTP_PORT; // recovery values that can work with default protocol 167 } else { // secondary protocol's port is non-numeric, not fatal in recovery mode 176 168 errorCode = SECONDARY_PORT_NON_NUMERIC; 177 if(recover) { 178 msg.append("\nNot using this port"); 179 } 180 httpPort = null; 169 httpPort = null; 170 if(recover) msg.append("\nNot using this port"); 181 171 } 182 172 } … … 187 177 Integer.parseInt(httpsPort); 188 178 } catch(NumberFormatException nfe) { 189 msg.append("\nInvalid port specified for over https : notnumeric.");179 msg.append("\nInvalid port specified for over https (tomcat.port.https): must be numeric."); 190 180 if(port == httpsPort) { 191 errorCode = INVALID_PRIMARY_PORT; 192 if(recover) { 193 port = httpsPort = defHttpsPort; 194 } else { // primary port affected and not asked to recover, treat as fatal 195 port = httpsPort = httpPort = null; 196 } 197 } else { // non primary port is invalid/non-numeric, not fatal 181 errorCode = INVALID_PRIMARY_PORT; 182 port = httpsPort = FALLBACK_HTTPS_PORT; // recovery values that work with default protocol 183 } else { // non primary port is invalid/non-numeric, not fatal in recovery mode 198 184 errorCode = SECONDARY_PORT_NON_NUMERIC; 199 if(recover) {200 msg.append("\nNot using this port");201 }202 185 httpsPort = null; 186 if(recover) msg.append("\nNot using this port"); 203 187 } 204 188 } … … 206 190 } 207 191 192 // if the default port is the httpsPort, then modify the defaultPortPropertyName to match 193 // (else it will remain at the property name for the http port) 194 if(port == httpsPort) { 195 defaultPortPropertyName = "tomcat.port.https"; 196 } 208 197 209 198 if(recover) { 210 199 msg.append("\nFalling back to port ").append(port).append(" and protocol ").append(protocol).append("."); 211 200 } 212 // else if(errorCode == ALL_CORRECT) {213 // msg.append("\nUsing port ").append(port).append(" and protocol ").append(protocol).append(".");214 //} // else invalid property value(s) and we've not been asked to recover. msg alreay set.215 201 216 202 errorMsg = msg.toString();
Note:
See TracChangeset
for help on using the changeset viewer.