source: main/trunk/greenstone3/src/java/org/greenstone/util/ProtocolPortProperties.java@ 32549

Last change on this file since 32549 was 32432, checked in by ak19, 6 years ago
  1. Since there's a chance that 127.0.0.1 isn't always the loopback address or may not always work, we allow this to be specified by the new property localhost.server.http in build.properties. Updating recently commited code that is affected by this and where I had been hardcoding 127.0.0.1. 2. Fixing up the port and now the server host name used by the solr extension: these should be the correct property names, which are localhost.port.http and the new localhost.server.http instead of tomcat.server and the default port for the default protocol, since all GS3 internal communications with solr are done through the local HTTP url, whatever the public URL (with default protocol, matching port and server name) might be. I also updated the get-solr-servlet-url target in build.xml to use the local http base URL (see point 3), so that solr building will work correctly. 3. build.xml now has 2 new targets, one to get the local http base URL and one to get the local http default servlet URL. Both also use the new localhost.server.http property, besides the recently introduced localhost.port.http property. 4. Now the default behaviour of util.pm::get_full_greenstone_url_prefix() is to call the new get-local-http-servlet-url ant target, since only activate.pl's servercontrol.pm helper module uses it. If you want util.pm::get_full_greenstone_url_prefix() to return the non-local (public) servlet URL, pass in 1 (true) for the new 3rd parameter. The important decision here is that activate will use the internal (i.e. local http) greenstone servlet URL to issue pinging and (de)activating commands, since localhost (specifically 127.0.0.1) over http is now always available and because a domain named server over https will create complications to do with certification checks by wget, when wget gets run by activate.pl. Alternatively, activate.pl/servercontrol.pm could run wget with the no-cert-checking flag or we could make wget check the GS3 https certificate if one exists. But all that is convoluted and unnecessary: we've so far always worked with http, and usually with localhost over the httpport, and activate.pl so far has worked well with this, so have some confidence that using the local http URL internally should still work, even if the default GS3 URL has been set up to be a public (https) URL.
File size: 8.5 KB
Line 
1/*
2 * ProtocolPortProperties.java
3 * Copyright (C) 2008 New Zealand Digital Library, http://www.nzdl.org
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19package org.greenstone.util;
20
21import java.util.Properties;
22
23/*
24 * Utility class to set the protocol and port values from the Properties instance provided,
25 * which can be a Properties object loaded from either build.properties or global.properties
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.)
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.
35 */
36public class ProtocolPortProperties {
37
38 public static final int ALL_CORRECT = 0;
39 public static final int SECONDARY_PORT_NON_NUMERIC = 1;
40 public static final int INVALID_PRIMARY_PORT = 2;
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;
54 //private int portNum = -1; // port that matches protocol as int
55
56 private String errorMsg;
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 private String localHttpURL;
63
64 // default protocol if multiple supported
65 public String getProtocol() { return protocol; }
66 // default port (port for default protocol)
67 public String getPort() { return port; }
68
69 // httpPort is always set, but http may or may not be public
70 public String getHttpPort() { return httpPort; }
71 // httpsPort is null if https not supported
72 public String getHttpsPort() { return httpsPort; }
73 public int getPortNum() { return Integer.parseInt(port); }
74
75 // http is always available locally (over 127.0.0.1). But http may or may not be public.
76 // Returns true if public http support requested
77 public boolean supportsHttp() { return !httpRestrictedToLocal; }
78 // true if https is supported
79 public boolean supportsHttps() { return supportsHttps; }
80
81 // used by Server3.java to know the name of the port property to load
82 public String getDefaultPortPropertyName() { return defaultPortPropertyName; }
83
84 public String getErrorMsg() { return errorMsg; }
85 public int getErrorCode() { return errorCode; }
86
87 public boolean hadError() { return errorCode != ALL_CORRECT; }
88
89 // returns the local http base URL, something like http://127.0.0.1:<httpPort>
90 public String getLocalHttpBaseAddress() {
91 return localHttpURL;
92 }
93
94
95 // Constructor that will throw an Exception on ports/protocol configuration error or inconsistency
96 public ProtocolPortProperties(Properties props) throws Exception {
97 this(props, false);
98 }
99
100 // If param recover is true, will attempt to fallback to sane values for protocol and ports.
101 // You can still check for error by calling hadError(), getErrorMsg() and getErrorCode().
102 // If param recover is false, will throw an Exception on bad ports/protocol configuration
103 // and the error message is available as the exception description.
104 public ProtocolPortProperties(Properties props, boolean recover) throws Exception
105 {
106 StringBuffer msg = new StringBuffer();
107
108 httpPort = props.getProperty("localhost.port.http");
109 if(httpPort == null || httpPort.equals("")) {
110 errorCode = NO_HTTP_PORT;
111 msg.append("compulsory property localhost.port.http has no value (must be set to a valid port number not already in use).");
112 httpPort = FALLBACK_HTTP_PORT;
113 }
114
115 // Setting the internal/local access url, which has to be over http (see
116 // https://letsencrypt.org/docs/certificates-for-localhost/)
117 // localhost.server.http defaults to 127.0.0.1 instead of localhost, since
118 // localhost is unsafe as it can be mapped to something other than 127.0.0.1.
119 localHttpURL = "http://" + props.getProperty("localhost.server.http", "127.0.0.1");
120 if(!httpPort.equals("80")) {
121 localHttpURL = localHttpURL + ":" + httpPort;
122 }
123
124 String supportedProtocols = props.getProperty("server.protocols");
125 if(supportedProtocols == null || supportedProtocols.equals("")) {
126 errorCode = NO_PROTOCOL;
127 msg.append("server.protocols not set.");
128 protocol = FALLBACK_PROTOCOL; // fallback to http as default (and sole) protocol
129 port = httpPort; // set default port to httpPort
130 }
131 else { // supportedProtocols was assigned something
132
133 if(!supportedProtocols.contains("http")) {
134 errorCode = INVALID_PROTOCOL;
135 msg.append("server.protocols must contain http or https, or both (in order of preference) separated by commas.");
136 protocol = FALLBACK_PROTOCOL;
137 port = httpPort;
138 }
139
140 // set available protocols with their ports
141 if(supportedProtocols.contains("https")) {
142 supportsHttps = true;
143 httpsPort = props.getProperty("tomcat.port.https");
144 if(httpsPort == null || httpsPort.equals("")) {
145 errorCode = NO_HTTPS_PORT;
146 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).");
147 httpsPort = FALLBACK_HTTPS_PORT;
148 }
149 }
150 if(supportedProtocols.matches("http(,|\\s+|$)")) {
151 httpRestrictedToLocal = false;
152 }
153
154 // set default protocol and default port: the first protocol in the supportedProtocols list
155 if(supportedProtocols.matches("^[,\\s]*https")) {
156 protocol = "https";
157 port = httpsPort;
158 } else {
159 protocol = "http";
160 port = httpPort;
161 }
162 }
163
164 if(!recover && errorCode == ALL_CORRECT) { // then check any assigned ports are valid
165 if(httpPort != null) {
166 try {
167 Integer.parseInt(httpPort);
168 } catch(NumberFormatException nfe) {
169 msg.append("\nInvalid localhost.port.http specified: must be numeric.");
170 if(port == httpPort) {
171 errorCode = INVALID_PRIMARY_PORT;
172 port = httpPort = FALLBACK_HTTP_PORT; // recovery values that can work with default protocol
173 } else { // secondary protocol's port is non-numeric, not fatal in recovery mode
174 errorCode = SECONDARY_PORT_NON_NUMERIC;
175 httpPort = null;
176 if(recover) msg.append("\nNot using this port");
177 }
178 }
179 }
180
181 if(httpsPort != null) {
182 try {
183 Integer.parseInt(httpsPort);
184 } catch(NumberFormatException nfe) {
185 msg.append("\nInvalid port specified for over https (tomcat.port.https): must be numeric.");
186 if(port == httpsPort) {
187 errorCode = INVALID_PRIMARY_PORT;
188 port = httpsPort = FALLBACK_HTTPS_PORT; // recovery values that work with default protocol
189 } else { // non primary port is invalid/non-numeric, not fatal in recovery mode
190 errorCode = SECONDARY_PORT_NON_NUMERIC;
191 httpsPort = null;
192 if(recover) msg.append("\nNot using this port");
193 }
194 }
195 }
196 }
197
198 // if the default port is the httpsPort, then modify the defaultPortPropertyName to match
199 // (else it will remain at the property name for the http port)
200 if(port == httpsPort) {
201 defaultPortPropertyName = "tomcat.port.https";
202 }
203
204 if(recover) {
205 msg.append("\nFalling back to port ").append(port).append(" and protocol ").append(protocol).append(".");
206 }
207
208 errorMsg = msg.toString();
209
210 if(!recover && errorCode != ALL_CORRECT) {
211 throw new Exception(errorMsg);
212 }
213 }
214
215}
Note: See TracBrowser for help on using the repository browser.